AntTweakBar
view release on metacpan or search on metacpan
lib/AntTweakBar.xs view on Meta::CPAN
if(!result)
Perl_croak(aTHX_ "Refreshing error: %s", TwGetLastError());
}
void _set_bar_parameter(TwBar* bar, const char* param_name, const char* param_value) {
dTHX;
int result = TwSetParam(bar, NULL, param_name, TW_PARAM_CSTRING, 1, param_value);
if(!result)
Perl_croak(aTHX_ "Error applying value '%s' to parameter %s : %s",
param_value, param_name, TwGetLastError());
}
void _set_variable_parameter(TwBar* bar, const char* variable,
const char* param_name, const char* param_value) {
dTHX;
int result = TwSetParam(bar, variable, param_name, TW_PARAM_CSTRING, 1, param_value);
if(!result)
Perl_croak(aTHX_ "Error applying value '%s' of parameter %s to variable %s : %s",
param_value, param_name, variable, TwGetLastError());
}
/* CALLBACKS */
/* int/bool callbacks */
void TW_CALL _int_getter(void* value, void* data){
dTHX;
SV* sv = SvRV((SV*) data);
SvGETMAGIC(sv);
int iv = SvOK(sv) ? SvIV(sv) : 0;
*(int*)value = iv;
}
void TW_CALL _int_getter_cb(void* value, void* data){
dTHX;
SV** cb = hv_fetch(_cb_read_map, (char*) data, sizeof(SV*), 0);
dSP;
PUSHMARK(SP);
int count = call_sv(*cb, G_NOARGS|G_SCALAR);
SPAGAIN;
if (count != 1)
Perl_croak(aTHX_ "Expected 1 arg to be returned from _int_getter \n");
SV* sv = POPs;
*(int*)value = SvOK(sv) ? SvIV(sv) : 0;
}
void TW_CALL _int_setter(const void* value, void* data){
dTHX;
SV* sv = SvRV((SV*) data);
sv_setiv(sv, *(int*)value );
SvSETMAGIC(sv);
}
void TW_CALL _int_setter_cb(const void* value, void* data){
dTHX;
SV** cb = hv_fetch(_cb_write_map, (char*) data, sizeof(SV*), 0);
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSViv(*(int*)value)));
PUTBACK;
call_sv(*cb, G_DISCARD);
FREETMPS;
LEAVE;
}
/* number(double) callbacks */
void TW_CALL _number_getter(void* value, void* data){
dTHX;
SV* sv = SvRV((SV*) data);
SvGETMAGIC(sv);
double dv = SvOK(sv) ? SvNV(sv) : 0.0;
*(double*)value = dv;
}
void TW_CALL _number_setter(const void* value, void* data){
dTHX;
SV* sv = SvRV((SV*) data);
sv_setnv(sv, *(double*)value );
SvSETMAGIC(sv);
}
void TW_CALL _number_getter_cb(void* value, void* data){
dTHX;
SV** cb = hv_fetch(_cb_read_map, (char*) data, sizeof(SV*), 0);
dSP;
PUSHMARK(SP);
int count = call_sv(*cb, G_NOARGS|G_SCALAR);
SPAGAIN;
if (count != 1)
Perl_croak(aTHX_ "Expected 1 arg to be returned from _number_getter_cb \n");
SV* sv = POPs;
*(double*)value = SvOK(sv) ? SvNV(sv) : 0.0;
}
void TW_CALL _number_setter_cb(const void* value, void* data){
dTHX;
SV** cb = hv_fetch(_cb_write_map, (char*) data, sizeof(SV*), 0);
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVnv(*(double*)value)));
PUTBACK;
call_sv(*cb, G_DISCARD);
FREETMPS;
LEAVE;
}
/* string callbacks */
void TW_CALL _string_getter(void* value, void* data){
dTHX;
SV* sv = SvRV((SV*) data);
SvGETMAGIC(sv);
const char* string = SvOK(sv) ? SvPV_nolen(sv) : "";
*(const char**)value = string;
}
void TW_CALL _string_getter_cb(void* value, void* data){
dTHX;
SV** cb = hv_fetch(_cb_read_map, (char*) data, sizeof(SV*), 0);
dSP;
PUSHMARK(SP);
int count = call_sv(*cb, G_NOARGS|G_SCALAR);
SPAGAIN;
if (count != 1)
Perl_croak(aTHX_ "Expected 1 arg to be returned from _string_getter_cb \n");
SV* sv_string = POPs;
if(!SvPOK(sv_string)) {
Perl_croak(aTHX_ "_string_getter_cb got not a string\n");
}
*(const char**)value = SvPV_nolen(sv_string);
}
void TW_CALL _string_setter(const void* value, void* data){
dTHX;
SV* sv = SvRV((SV*) data);
const char* string = *(const char**)value;
printf("set string: %s\n", string);
sv_force_normal(sv);
sv_setpv(sv, string);
SvSETMAGIC(sv);
}
void TW_CALL _string_setter_cb(const void* value, void* data){
dTHX;
SV** cb = hv_fetch(_cb_write_map, (char*) data, sizeof(SV*), 0);
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVpv(*(char**)value, 0)));
PUTBACK;
call_sv(*cb, G_DISCARD);
FREETMPS;
LEAVE;
}
/* double/float array callback generators */
#define DOUBLE_CALLBACK_GETTER(NAME, NUMBER, TYPE) \
void TW_CALL NAME(void* value, void* data) { \
dTHX; \
SV* sv = SvRV((SV*) data); \
if(!(SvTYPE(SvRV(sv)) == SVt_PVAV)){ \
croak("reference does not point to array any more\n"); \
} \
SvGETMAGIC(sv); \
AV* av = (AV*)SvRV(sv); \
int my_last = (NUMBER-1); \
TYPE* values = (TYPE*) value; \
int i; \
for(i = 0; i <= my_last; i++) { \
SV** element = av_fetch(av, i, 0); \
if(element && SvNOK(*element)) { \
SvGETMAGIC(*element); \
values[i] = (TYPE)SvNV(*element); \
} \
} \
};
#define DOUBLE_CALLBACK_GETTER_CB(NAME, NUMBER, TYPE) \
void TW_CALL NAME(void* value, void* data) { \
dTHX;\
SV** cb = hv_fetch(_cb_read_map, (char*) data, sizeof(SV*), 0); \
dSP; \
PUSHMARK(SP); \
int count = call_sv(*cb, G_NOARGS|G_SCALAR); \
SPAGAIN; \
if (count != 1) {\
char buf[256] = {0}; \
sprintf(buf, "Expected 1 arg to be returned from %s \n", #NAME); \
croak(buf); \
} \
SV* sv = POPs; \
if(!(SvTYPE(SvRV(sv)) == SVt_PVAV)){ \
croak("reference does not point to array any more\n"); \
} \
SvGETMAGIC(sv); \
AV* av = (AV*)SvRV(sv); \
int my_last = (NUMBER-1); \
TYPE* values = (TYPE*) value; \
int i; \
for(i = 0; i <= my_last; i++) { \
SV** element = av_fetch(av, i, 0); \
if(element && SvNOK(*element)) { \
SvGETMAGIC(*element); \
values[i] = (TYPE)SvNV(*element); \
} \
} \
};
#define DOUBLE_CALLBACK_SETTER(NAME, NUMBER, TYPE) \
void TW_CALL NAME(const void* value, void* data) { \
dTHX;\
SV* sv = SvRV((SV*) data); \
if(!(SvTYPE(SvRV(sv)) == SVt_PVAV)){ \
croak("reference does not point to array any more\n"); \
} \
SvGETMAGIC(sv); \
AV* av = (AV*)SvRV(sv); \
int my_last = (NUMBER-1); \
TYPE* values = (TYPE*) value; \
int i; \
for(i = 0; i <= my_last; i++) { \
SV** element = av_fetch(av, i, 0); \
if(element) { \
double value = values[i]; \
sv_setnv(*element, value); \
SvGETMAGIC(*element); \
SvSETMAGIC(sv); \
} \
} \
};
#define DOUBLE_CALLBACK_SETTER_CB(NAME, NUMBER, TYPE) \
void TW_CALL NAME(const void* value, void* data) { \
dTHX;\
SV** cb = hv_fetch(_cb_write_map, (char*) data, sizeof(SV*), 0); \
dSP; \
ENTER; \
SAVETMPS; \
\
AV* av = (AV*)sv_2mortal((SV*)newAV()); \
TYPE* values = (TYPE*) value; \
int i; \
for(i = 0; i < NUMBER; i++) { \
av_push(av, newSVnv(values[i])); \
} \
\
PUSHMARK(SP); \
XPUSHs(sv_2mortal(newRV_inc((SV*)av))); \
PUTBACK; \
\
call_sv(*cb, G_DISCARD); \
\
FREETMPS; \
LEAVE; \
};
DOUBLE_CALLBACK_GETTER (_color3f_getter, 3, float);
DOUBLE_CALLBACK_GETTER_CB(_color3f_getter_cb, 3, float);
DOUBLE_CALLBACK_SETTER (_color3f_setter, 3, float);
DOUBLE_CALLBACK_SETTER_CB(_color3f_setter_cb, 3, float);
DOUBLE_CALLBACK_GETTER (_color4f_getter, 4, float);
DOUBLE_CALLBACK_GETTER_CB(_color4f_getter_cb, 4, float);
DOUBLE_CALLBACK_SETTER (_color4f_setter, 4, float);
DOUBLE_CALLBACK_SETTER_CB(_color4f_setter_cb, 4, float);
DOUBLE_CALLBACK_GETTER (_dir3d_getter, 3, double);
DOUBLE_CALLBACK_GETTER_CB(_dir3d_getter_cb, 3, double);
DOUBLE_CALLBACK_SETTER (_dir3d_setter, 3, double);
DOUBLE_CALLBACK_SETTER_CB(_dir3d_setter_cb, 3, double);
DOUBLE_CALLBACK_GETTER (_quat4d_getter, 4, double);
DOUBLE_CALLBACK_GETTER_CB(_quat4d_getter_cb, 4, double);
DOUBLE_CALLBACK_SETTER (_quat4d_setter, 4, double);
DOUBLE_CALLBACK_SETTER_CB(_quat4d_setter_cb, 4, double);
void _bootstap(){
dTHX;
HV *stash = gv_stashpv("AntTweakBar", TRUE);
CONSTANT(TW_OPENGL);
CONSTANT(TW_OPENGL_CORE);
CONSTANT(TW_DIRECT3D9);
CONSTANT(TW_DIRECT3D10);
CONSTANT(TW_DIRECT3D11);
_type_map = newHV();
_getters_map = newHV();
_setters_map = newHV();
_getters_cb_map = newHV();
_setters_cb_map = newHV();
_sv_copy_names = newHV();
_cb_read_map = newHV();
_cb_write_map = newHV();
_cb_marker_map = newHV();
_add_type("bool", TW_TYPE_BOOL32, _int_getter, _int_setter, _int_getter_cb, _int_setter_cb);
_add_type("integer", TW_TYPE_INT32, _int_getter, _int_setter, _int_getter_cb, _int_setter_cb);
_add_type("number", TW_TYPE_DOUBLE, _number_getter, _number_setter, _number_getter_cb, _number_setter_cb);
_add_type("string", TW_TYPE_CDSTRING, _string_getter, _string_setter, _string_getter_cb, _string_setter_cb);
_add_type("color3f", TW_TYPE_COLOR3F, _color3f_getter, _color3f_setter, _color3f_getter_cb, _color3f_setter_cb);
_add_type("color4f", TW_TYPE_COLOR4F, _color4f_getter, _color4f_setter, _color4f_getter_cb, _color4f_setter_cb);
_add_type("direction", TW_TYPE_DIR3D, _dir3d_getter, _dir3d_setter, _dir3d_getter_cb, _dir3d_setter_cb);
_add_type("quaternion", TW_TYPE_QUAT4D, _quat4d_getter, _quat4d_setter, _quat4d_getter_cb, _quat4d_setter_cb);
}
MODULE = AntTweakBar PACKAGE = AntTweakBar
BOOT:
_bootstap();
void
( run in 1.340 second using v1.01-cache-2.11-cpan-13bb782fe5a )