30 #if defined(JAVASCRIPT_DUK)
34 #include <libFreeWRL.h>
36 #include "../vrml_parser/Structs.h"
37 #include "../main/headers.h"
38 #include "../vrml_parser/CParseGeneral.h"
39 #include "../vrml_parser/CRoutes.h"
40 #include "../main/Snapshot.h"
41 #include "../scenegraph/Collision.h"
42 #include "../scenegraph/quaternion.h"
43 #include "../scenegraph/Viewer.h"
44 #include "../input/EAIHelpers.h"
45 #include "../input/SensInterps.h"
46 #include "../x3d_parser/Bindable.h"
50 #define FIELDTYPE_MFImage 43
54 #define malloc(A) MALLOCV(A)
55 #define free(A) FREE_IF_NZ(A)
56 #define realloc(A,B) REALLOC(A,B)
60 int FWTYPES_COUNT = 0;
62 void initVRMLBrowser(
FWTYPE** typeArray,
int *n);
63 void initVRMLFields(
FWTYPE** typeArray,
int *n);
65 initVRMLBrowser(fwtypesArray, &FWTYPES_COUNT);
66 initVRMLFields(fwtypesArray, &FWTYPES_COUNT);
68 FWTYPE *getFWTYPE(
int itype){
70 for(i=0;i<FWTYPES_COUNT;i++){
71 if(itype == fwtypesArray[i]->itype)
72 return fwtypesArray[i];
77 #define strcasecmp _stricmp
85 if(!strcasecmp(fs[i].name,key)){
99 if(!strcasecmp(ps[i].name,key)){
101 (*index) = ps[i].index;
110 if(ps)
while(ps[len].name) len++;
115 if(fs)
while(fs[len].name) len++;
118 int fwiterator_generic(
int index,
FWTYPE *fwt,
void *pointer,
const char **name,
int *lastProp,
int *jndex,
char *type,
char *readOnly){
122 int lenp, lenf, ifindex;
127 ps = fwt->Properties;
128 iterator = fwt->iterator;
131 lenp = len_properties(ps);
133 (*name) = ps[index].name;
134 (*jndex) = ps[index].index;
136 (*type) = ps[index].type;
137 (*readOnly) = ps[index].readOnly;
141 int iret = iterator(index, fwt, pointer, name, lastProp, jndex, type, readOnly);
142 if(iret > -1)
return iret;
149 lenf = len_functions(fs);
150 ifindex = index - 1 - (*lastProp);
152 (*name) = fs[ifindex].name;
160 int fwhas_generic(
FWTYPE *fwt,
void *pointer,
const char *key,
int *jndex,
char *type,
char *readOnly){
162 int lastProp, isSet, index = -1;
166 while( (index = fwiterator_generic(index,fwt,pointer,&name, &lastProp, jndex, type, readOnly)) > -1){
167 if(!strcasecmp(name,key)){
172 if(strlen(key)>4 && !strncmp(key,
"set_",4))
176 char* key2 = &key[4];
177 while( (index = fwiterator_generic(index,fwt,pointer,&name, &lastProp, jndex, type, readOnly)) > -1){
178 if(!strcasecmp(name,key2)){
194 void *JScript_constructor(){
195 void *v = MALLOCV(
sizeof(
struct pJScript));
196 memset(v,0,
sizeof(
struct pJScript));
199 void JScript_init(
struct tJScript *t){
201 t->JSglobal_return_val = NULL;
203 t->prv = JScript_constructor();
207 if(!FWTYPES_COUNT) initFWTYPEs();
213 void jsVRMLBrowser_init(
void *t){}
214 void jsUtils_init(
void *t){}
215 void jsVRMLClasses_init(
void *t){}
223 int isECMAtype(
int itype){
226 case FIELDTYPE_SFBool:
227 case FIELDTYPE_SFFloat:
228 case FIELDTYPE_SFTime:
229 case FIELDTYPE_SFDouble:
230 case FIELDTYPE_SFInt32:
231 case FIELDTYPE_SFString:
244 struct string_int lookup_fieldType[] = {
245 {
"Float", FIELDTYPE_SFFloat},
246 {
"Rotation", FIELDTYPE_SFRotation},
247 {
"Vec3f", FIELDTYPE_SFVec3f},
248 {
"Bool", FIELDTYPE_SFBool},
249 {
"Int32", FIELDTYPE_SFInt32},
250 {
"Node", FIELDTYPE_SFNode},
251 {
"Color", FIELDTYPE_SFColor},
252 {
"ColorRGBA", FIELDTYPE_SFColorRGBA},
253 {
"Time", FIELDTYPE_SFTime},
254 {
"String", FIELDTYPE_SFString},
255 {
"Vec2f", FIELDTYPE_SFVec2f},
256 {
"Image", FIELDTYPE_SFImage},
257 {
"Vec3d", FIELDTYPE_SFVec3d},
258 {
"Double", FIELDTYPE_SFDouble},
259 {
"Matrix3f", FIELDTYPE_SFMatrix3f},
260 {
"Matrix3d", FIELDTYPE_SFMatrix3d},
261 {
"Matrix4f", FIELDTYPE_SFMatrix4f},
262 {
"Matrix4d", FIELDTYPE_SFMatrix4d},
263 {
"Vec2d", FIELDTYPE_SFVec2d},
264 {
"Vec4f", FIELDTYPE_SFVec4f},
265 {
"Vec4d", FIELDTYPE_SFVec4d},
268 char * itype2string(
int itype){
270 while(lookup_fieldType[i].c){
271 if(lookup_fieldType[i].i == itype)
return lookup_fieldType[i].c;
277 int getFieldFromNodeAndName(
struct X3D_Node* node,
const char *fieldname,
int *type,
int *kind,
int *iifield,
union anyVrml **value);
280 int get_valueChanged_flag (
int fptr,
int actualscript){
283 int type, kind, ifield, found;
290 scriptcontrol = getScriptControlIndex(actualscript);
291 script = scriptcontrol->script;
292 node = script->ShaderScriptNode;
293 fullname = JSparamnames[fptr].name;
294 found = getFieldFromNodeAndName(node,fullname,&type,&kind,&ifield,&value);
296 field = Shader_Script_getScriptField(script, ifield);
297 gglobal()->JScript.JSglobal_return_val = (
void *)&field->value;
298 return field->valueChanged;
300 gglobal()->JScript.JSglobal_return_val = NULL;
303 void resetScriptTouchedFlag(
int actualscript,
int fptr){
306 int type, kind, ifield, found;
313 scriptcontrol = getScriptControlIndex(actualscript);
314 script = scriptcontrol->script;
315 node = script->ShaderScriptNode;
316 fullname = JSparamnames[fptr].name;
317 found = getFieldFromNodeAndName(node,fullname,&type,&kind,&ifield,&value);
319 field = Shader_Script_getScriptField(script, ifield);
320 field->valueChanged = 0;
328 int fwType2itype(
const char *fwType){
329 int i, isSF, isMF, ifield = -1;
331 isSF = !strncmp(fwType,
"SF",2);
332 isMF = !strncmp(fwType,
"MF",2);
336 while(lookup_fieldType[i].c){
337 if(!strcasecmp(suffix,lookup_fieldType[i].c)){
338 ifield = lookup_fieldType[i].i;
343 if(ifield > -1 && isMF ) ifield++;
346 if(!strcasecmp(fwType,
"Browser")) ifield = AUXTYPE_X3DBrowser;
347 if(!strcasecmp(fwType,
"X3DConstants")) ifield = AUXTYPE_X3DConstants;
351 void freeField(
int itype,
void* any){
352 if(isSForMFType(itype) == 0){
359 }
else if(isSForMFType(itype) == 1){
377 unsigned long upper_power_of_two(
unsigned long v);
378 void deleteMallocedFieldValue(
int type,
union anyVrml *fieldPtr);
379 void medium_copy_field0(
int itype,
void* source,
void* dest)
386 int i, sfsize,sformf;
390 sformf = isSForMFType(itype);
392 printf(
"bad type in medium_copy_field0\n");
396 sftype = type2SF(itype);
398 sfsize = sizeofSF(sftype);
406 deleteMallocedFieldValue(itype,dest);
408 if( sftype == FIELDTYPE_SFNode ) nele = (int) upper_power_of_two(nele);
409 mfd->p = malloc(sfsize*nele);
413 for(i=0;i<mfs->n;i++)
422 memcpy(dest,source,sfsize);
425 void medium_copy_field(
int itype,
void* source,
void** dest){
429 (*dest) = malloc(sizeofSForMF(itype));
430 memset((*dest),0,sizeofSForMF(itype));
431 medium_copy_field0(itype,source,(*dest));
435 static char *DefaultScriptMethodsA =
"function initialize() {}; " \
436 " function shutdown() {}; " \
437 " function eventsProcessed() {}; " \
438 " TRUE=true; FALSE=false; " \
442 static char *DefaultScriptMethodsB =
" function print(x) {Browser.print(x)}; " \
443 " function println(x) {Browser.println(x)}; " \
444 " function getName() {return Browser.getName()}; "\
445 " function getVersion() {return Browser.getVersion()}; "\
446 " function getCurrentSpeed() {return Browser.getCurrentSpeed()}; "\
447 " function getCurrentFrameRate() {return Browser.getCurrentFrameRate()}; "\
448 " function getWorldURL() {return Browser.getWorldURL()}; "\
449 " function replaceWorld(x) {Browser.replaceWorld(x)}; "\
450 " function loadURL(x,y) {Browser.loadURL(x,y)}; "\
451 " function setDescription(x) {Browser.setDescription(x)}; "\
452 " function createVrmlFromString(x) {Browser.createVrmlFromString(x)}; "\
453 " function createVrmlFromURL(x,y,z) {Browser.createVrmlFromURL(x,y,z)}; "\
454 " function createX3DFromString(x) {Browser.createX3DFromString(x)}; "\
455 " function createX3DFromURL(x,y,z) {Browser.createX3DFromURL(x,y,z)}; "\
456 " function addRoute(a,b,c,d) {Browser.addRoute(a,b,c,d)}; "\
457 " function deleteRoute(a,b,c,d) {Browser.deleteRoute(a,b,c,d)}; "
468 #include "duktape/duktape.h"
470 const char *duk_type_to_string(
int duktype){
471 const char* r = NULL;
473 case DUK_TYPE_NUMBER: r =
"DUK_TYPE_NUMBER";
break;
474 case DUK_TYPE_BOOLEAN: r =
"DUK_TYPE_BOOLEAN";
break;
475 case DUK_TYPE_STRING: r =
"DUK_TYPE_STRING";
break;
476 case DUK_TYPE_OBJECT: r =
"DUK_TYPE_OBJECT";
break;
477 case DUK_TYPE_NONE: r =
"DUK_TYPE_NONE";
break;
478 case DUK_TYPE_UNDEFINED: r =
"DUK_TYPE_UNDEFINED";
break;
479 case DUK_TYPE_NULL: r =
"DUK_TYPE_NULL";
break;
480 case DUK_TYPE_POINTER: r =
"DUK_TYPE_POINTER";
break;
490 int i, itop = duk_get_top(ctx);
491 if(comment) printf(
"%s top=%d\n",comment,itop);
493 printf(
"%10s%10s\n",
"position",
"type");
496 int t = duk_get_type(ctx, ipos);
498 const char * amore =
"";
500 case DUK_TYPE_NUMBER: stype =
"number";
break;
501 case DUK_TYPE_STRING: stype =
"string";
break;
503 case DUK_TYPE_OBJECT: stype =
"object";
break;
504 case DUK_TYPE_NONE: stype =
"none";
break;
505 case DUK_TYPE_UNDEFINED: stype =
"undefined";
break;
506 case DUK_TYPE_BOOLEAN: stype =
"boolean";
break;
507 case DUK_TYPE_NULL: stype =
"null";
break;
508 case DUK_TYPE_POINTER: stype =
"pointer";
break;
512 if(duk_is_function(ctx,ipos)){
514 afunc = duk_is_c_function(ctx,ipos) ?
"Cfunc" : afunc;
515 afunc = duk_is_ecmascript_function(ctx,ipos) ?
"jsfunc" : afunc;
516 afunc = duk_is_bound_function(ctx,ipos) ?
"boundfunc" : afunc;
519 if(duk_is_nan(ctx,ipos)){
522 if(duk_is_object(ctx,ipos)){
525 printf(
"%10d%10s %s\n",ipos,stype,amore);
550 static Stack * proxycaches = NULL;
551 typedef struct cache_table_entry {
555 typedef struct proxy_cache_entry {
562 cache_entry * lookup_ctx_proxy_cache(
duk_context *ctx){
564 cache_entry *ret = NULL;
565 if(proxycaches == NULL){
566 proxycaches = newStack(cache_entry *);
568 for(i=0;i<vectorSize(proxycaches);i++){
569 cache_entry * ce = vector_get(cache_entry*,proxycaches,i);
576 cache_entry *ce = MALLOC(cache_entry*,
sizeof(cache_entry));
577 stack_push(cache_entry*,proxycaches,ce);
579 ce->cache = newStack(proxy_entry*);
584 proxy_entry *lookup_ctx_proxycache_entry_by_nodeptr(
duk_context *ctx,
struct X3D_Node *node){
585 proxy_entry *ret = NULL;
586 cache_entry* cache = lookup_ctx_proxy_cache(ctx);
589 for(i=0;i<vectorSize(cache->cache);i++){
590 proxy_entry *pe = vector_get(proxy_entry*,cache->cache,i);
591 if(pe && pe->node == node){
598 proxy_entry *add_ctx_proxycache_entry(
duk_context *ctx,
struct X3D_Node *node,
void *jsproxy){
601 proxy_entry *ret = NULL;
602 cache_entry *cache = lookup_ctx_proxy_cache(ctx);
605 proxy_entry *pe = MALLOC(proxy_entry*,
sizeof(proxy_entry));
607 pe->jsproxy = jsproxy;
610 for(i=0;i<vectorSize(cache->cache);i++){
611 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
614 vector_set(proxy_entry*,cache->cache,i,pe);
620 stack_push(proxy_entry*,cache->cache,pe);
624 printf(
"cache after add proxy\n");
625 for(i=0;i<vectorSize(cache->cache);i++){
626 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
628 printf(
"%d %x %x\n",i,pe0->node,pe0->jsproxy);
630 printf(
"%d NULL\n",i);
639 proxy_entry *ret = NULL;
640 cache_entry *cache = lookup_ctx_proxy_cache(ctx);
643 for(i=0;i<vectorSize(cache->cache);i++){
644 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
645 if(pe0 && pe0->node == node){
646 vector_set(proxy_entry*,cache->cache,i,NULL);
652 printf(
"after cache clean\n");
653 for(i=0;i<vectorSize(cache->cache);i++){
654 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
656 printf(
"%d %x %x\n",i,pe0->node,pe0->jsproxy);
658 printf(
"%d NULL\n",i);
663 void remove_ctx_proxycache_entry_by_jsproxy(
duk_context *ctx,
void *jsproxy){
665 proxy_entry *ret = NULL;
666 cache_entry *cache = lookup_ctx_proxy_cache(ctx);
669 for(i=0;i<vectorSize(cache->cache);i++){
670 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
671 if(pe0 && pe0->jsproxy == jsproxy){
672 vector_set(proxy_entry*,cache->cache,i,NULL);
683 void *fwpointer = NULL;
685 rc = duk_get_prop_string(ctx,0,
"fwItype");
686 if(rc == 1) itype = duk_to_int(ctx,-1);
688 rc = duk_get_prop_string(ctx,0,
"fwGC");
689 if(rc == 1) igc = duk_to_boolean(ctx,-1);
691 rc = duk_get_prop_string(ctx,0,
"fwField");
692 if(rc == 1) fwpointer = duk_to_pointer(ctx,-1);
697 if(itype == FIELDTYPE_SFNode && fwpointer){
704 remove_ctx_proxycache_entry_by_nodeptr(ctx, node);
706 if(igc > 0 && itype > -1 && fwpointer){
707 if(itype < AUXTYPE_X3DConstants){
709 freeField(itype,fwpointer);
718 static int doingFinalizer = 1;
719 void push_typed_proxy(
duk_context *ctx,
int itype,
void *fwpointer,
int* valueChanged)
723 proxy_entry *pe = NULL;
724 if(itype == FIELDTYPE_SFNode){
727 pe = lookup_ctx_proxycache_entry_by_nodeptr(ctx, node);
730 duk_push_heapptr(ctx, pe->jsproxy);
733 duk_eval_string(ctx,
"Proxy");
735 duk_push_pointer(ctx,fwpointer);
736 duk_put_prop_string(ctx,-2,
"fwField");
737 duk_push_pointer(ctx,valueChanged);
738 duk_put_prop_string(ctx,-2,
"fwChanged");
739 duk_push_int(ctx,itype);
740 duk_put_prop_string(ctx,-2,
"fwItype");
742 duk_push_boolean(ctx,TRUE);
743 duk_put_prop_string(ctx,-2,
"fwGC");
745 duk_eval_string(ctx,
"handler");
761 if(itype == FIELDTYPE_SFNode){
763 void *jsproxy = duk_get_heapptr(ctx, -1);
764 add_ctx_proxycache_entry(ctx, node, jsproxy);
766 duk_eval_string(ctx,
"Duktape.fin");
768 duk_push_c_function(ctx,cfinalizer,1);
775 int push_typed_proxy2(
duk_context *ctx,
int itype,
int kind,
void *fwpointer,
int* valueChanged,
char doGC)
781 proxy_entry *pe = NULL;
782 int idogc = doGC ? TRUE : FALSE;
783 if(itype == FIELDTYPE_SFNode){
786 pe = lookup_ctx_proxycache_entry_by_nodeptr(ctx, node);
789 duk_push_heapptr(ctx, pe->jsproxy);
791 duk_eval_string(ctx,
"Proxy");
792 duk_push_object(ctx);
793 duk_push_pointer(ctx,fwpointer);
794 duk_put_prop_string(ctx,-2,
"fwField");
795 duk_push_pointer(ctx,valueChanged);
796 duk_put_prop_string(ctx,-2,
"fwChanged");
797 duk_push_int(ctx,itype);
798 duk_put_prop_string(ctx,-2,
"fwItype");
799 duk_push_int(ctx,kind);
800 duk_put_prop_string(ctx,-2,
"fwKind");
803 duk_push_boolean(ctx,idogc);
804 duk_put_prop_string(ctx,-2,
"fwGC");
807 duk_eval_string(ctx,
"handler");
819 if(itype == FIELDTYPE_SFNode){
821 void *jsproxy = duk_get_heapptr(ctx, -1);
822 add_ctx_proxycache_entry(ctx, node, jsproxy);
825 duk_eval_string(ctx,
"Duktape.fin");
827 duk_push_c_function(ctx,cfinalizer,1);
839 int nUsable,nNeeded, i, ii;
842 nUsable = arglist.iVarArgStartsAt > -1 ? nargs : arglist.nfixedArg;
843 nNeeded = max(nUsable,arglist.nfixedArg);
844 pars = malloc(nNeeded*
sizeof(
FWVAL));
848 for(i=0;i<nUsable;i++){
853 if(i < arglist.nfixedArg)
854 ctype = arglist.argtypes[i];
856 ctype = arglist.argtypes[arglist.iVarArgStartsAt];
857 pars[i].itype = ctype;
858 if( duk_is_object(ctx, ii)){
861 rc = duk_get_prop_string(ctx,ii,
"fwItype");
863 isPrimitive = rc == 0;
867 duk_to_primitive(ctx,ii,DUK_HINT_NONE);
871 trhs = duk_get_type(ctx, ii);
890 int bb = duk_get_boolean(ctx,ii);
891 pars[i]._boolean = bb;
894 case 'I': pars[i]._integer = duk_to_int(ctx,ii);
break;
895 case 'F': pars[i]._numeric = duk_to_number(ctx,ii);
break;
896 case 'D': pars[i]._numeric = duk_to_number(ctx,ii);
break;
897 case 'S': pars[i]._string = duk_to_string(ctx,ii);
break;
899 if(duk_is_string(ctx,ii)){
900 pars[i]._string = duk_get_string(ctx,ii);
904 if(!duk_is_object(ctx,i))
908 int rc, isOK, itypeRHS = -1;
909 union anyVrml *fieldRHS = NULL;
910 if(trhs == DUK_TYPE_NULL){
912 fieldRHS = malloc(
sizeof(
union anyVrml));
913 fieldRHS->sfnode = NULL;
914 }
else if(trhs == DUK_TYPE_OBJECT){
915 rc = duk_get_prop_string(ctx,ii,
"fwItype");
917 itypeRHS = duk_to_int(ctx,-1);
920 rc = duk_get_prop_string(ctx,ii,
"fwField");
921 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
930 pars[i]._web3dval.native = fieldRHS;
931 pars[i]._web3dval.fieldType = itypeRHS;
939 int rc, isOK, itypeRHS = -1;
940 union anyVrml *fieldRHS = NULL;
941 rc = duk_get_prop_string(ctx,ii,
"fwItype");
944 itypeRHS = duk_to_int(ctx,-1);
947 rc = duk_get_prop_string(ctx,ii,
"fwField");
948 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
952 if(fieldRHS != NULL && itypeRHS >= AUXTYPE_X3DConstants){
954 pars[i]._pointer.native = fieldRHS;
955 pars[i]._pointer.fieldType = itypeRHS;
967 for(i=nUsable;i<nNeeded;i++){
969 char ctype = arglist.argtypes[i];
970 pars[i].itype = ctype;
972 case 'B': pars[i]._boolean = FALSE;
break;
973 case 'I': pars[i]._integer = 0;
break;
974 case 'F': pars[i]._numeric = 0.0;
break;
975 case 'D': pars[i]._numeric = 0.0;
break;
976 case 'S': pars[i]._string = NULL;
break;
977 case 'Z': pars[i]._string = NULL; pars[i].itype =
'S';
break;
979 pars[i]._web3dval.fieldType = FIELDTYPE_SFNode;
980 pars[i]._web3dval.native = NULL;
break;
985 pars[i]._jsobject = NULL;
break;
994 int i, j, rc, nargs, argc, ifound;
998 int *valueChanged = NULL;
1000 nargs = duk_get_top(ctx);
1004 duk_push_current_function(ctx);
1005 rc = duk_get_prop_string(ctx,-1,
"fwItype");
1006 if(rc == 1) itype = duk_to_int(ctx,-1);
1012 if(itype < 0)
return 0;
1013 fwt = getFWTYPE(itype);
1014 if(!fwt->Constructor)
return 0;
1019 while(fwt->ConstructorArgs[i].nfixedArg > -1){
1020 int nfixed = fwt->ConstructorArgs[i].nfixedArg;
1021 int ivarsa = fwt->ConstructorArgs[i].iVarArgStartsAt;
1022 char *neededTypes = fwt->ConstructorArgs[i].argtypes;
1023 int fill = fwt->ConstructorArgs[i].fillMissingFixedWithZero ==
'T';
1024 if( nargs == nfixed || (ivarsa > -1 && nargs >= nfixed ) || (ivarsa > -1 && fill)){
1028 for(j=0;j<nargs;j++){
1030 int isOK, RHS_duk_type = duk_get_type(ctx, j);
1032 neededType = j >= nfixed ? neededTypes[ivarsa] : neededTypes[j];
1035 switch(RHS_duk_type){
1036 case DUK_TYPE_NUMBER:
1037 if(neededType ==
'F' || neededType ==
'D' || neededType ==
'I') isOK = TRUE;
1039 case DUK_TYPE_BOOLEAN:
1040 if(neededType ==
'B') isOK = TRUE;
1042 case DUK_TYPE_STRING:
1043 if(neededType ==
'S' || neededType ==
'Z') isOK = TRUE;
1045 case DUK_TYPE_OBJECT:
1046 if(neededType ==
'W' || neededType ==
'P'){
1047 int rc, itypeRHS = -1;
1048 union anyVrml *fieldRHS = NULL;
1049 rc = duk_get_prop_string(ctx,j,
"fwItype");
1052 itypeRHS = duk_to_int(ctx,-1);
1055 rc = duk_get_prop_string(ctx,j,
"fwField");
1056 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
1060 if(fieldRHS != NULL && itypeRHS > -1){
1067 case DUK_TYPE_UNDEFINED:
1070 case DUK_TYPE_POINTER:
1076 allOK = allOK && isOK;
1079 for(j=nargs;j<nfixed;j++){
1102 convert_duk_to_fwvals(ctx, nargs, 0, fwt->ConstructorArgs[i], &args, &argc);
1103 if(fwt->ConstructorArgs[ifound].fillMissingFixedWithZero ==
'T' && nargs < fwt->ConstructorArgs[ifound].nfixedArg){
1104 int nfixed = fwt->ConstructorArgs[ifound].nfixedArg;
1106 char *neededTypes = fwt->ConstructorArgs[ifound].argtypes;
1108 args = realloc(args,nfixed *
sizeof(
FWVAL));
1109 for(j=nargs;j<nfixed;j++){
1110 switch(neededTypes[j]){
1112 args[j]._boolean = FALSE;
break;
1114 args[j]._integer = 0;
break;
1116 args[j]._numeric = 0.0;
break;
1118 args[j]._numeric = 0.0;
break;
1120 args[j]._string =
"";
break;
1129 fwpointer = fwt->Constructor(fwt,argc,args);
1131 push_typed_proxy(ctx,itype, fwpointer, valueChanged);
1136 int rc, itype, *valueChanged;
1139 char type, readOnly;
1145 rc = duk_get_prop_string(ctx,0,
"fwItype");
1146 if(rc==1) itype = duk_get_int(ctx,-1);
1149 rc = duk_get_prop_string(ctx,0,
"fwField");
1150 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1153 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1154 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1156 key = duk_require_string(ctx,-1);
1160 fwt = getFWTYPE(itype);
1161 if(fwhas_generic(fwt,parent,key,&index,&type,&readOnly)){
1164 duk_push_false(ctx);
1172 int rc, itype, *valueChanged, arr_idx;
1173 void *parent = NULL;
1176 int lastProp, jndex;
1177 char type, readOnly;
1183 rc = duk_get_prop_string(ctx,0,
"fwItype");
1184 if(rc==1) itype = duk_get_int(ctx,-1);
1187 rc = duk_get_prop_string(ctx,0,
"fwField");
1188 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1191 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1192 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1195 arr_idx = duk_push_array(ctx);
1196 if(itype < 0 || (itype < AUXTYPE_X3DConstants && parent == NULL))
1199 fwt = getFWTYPE(itype);
1201 while( (i = fwiterator_generic(i,fwt,parent,&fieldname,&lastProp,&jndex,&type,&readOnly)) > -1 ){
1202 duk_push_string(ctx, fieldname);
1203 duk_put_prop_index(ctx, arr_idx, i);
1209 int rc, itype, *valueChanged;
1213 int lastProp, jndex;
1214 char type, readOnly;
1220 rc = duk_get_prop_string(ctx,0,
"fwItype");
1221 if(rc==1) itype = duk_get_int(ctx,-1);
1224 rc = duk_get_prop_string(ctx,0,
"fwField");
1225 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1228 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1229 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1232 arr_idx = duk_push_array(ctx);
1234 fwt = getFWTYPE(itype);
1236 while( (i = fwiterator_generic(i,fwt,parent,&fieldname,&lastProp,&jndex,&type,&readOnly)) > -1 ){
1238 duk_push_string(ctx, fieldname);
1239 duk_put_prop_index(ctx, arr_idx, i);
1257 case FIELDTYPE_SFBool:
1258 duk_push_boolean(ctx,fieldvalue->sfbool);
break;
1259 case FIELDTYPE_SFFloat:
1260 duk_push_number(ctx,fieldvalue->sffloat);
break;
1261 case FIELDTYPE_SFTime:
1262 duk_push_number(ctx,fieldvalue->sftime);
break;
1263 case FIELDTYPE_SFDouble:
1264 duk_push_number(ctx,fieldvalue->sfdouble);
break;
1265 case FIELDTYPE_SFInt32:
1266 duk_push_int(ctx,fieldvalue->sfint32);
break;
1267 case FIELDTYPE_SFString:
1268 duk_push_string(ctx,fieldvalue->sfstring->strptr);
break;
1277 static int SCALARS_ARE_PRIMITIVES = TRUE;
1296 switch(fwretval->itype){
1299 duk_push_boolean(ctx,fwretval->_boolean);
break;
1301 duk_push_int(ctx,fwretval->_integer);
break;
1303 duk_push_number(ctx,fwretval->_numeric);
break;
1305 duk_push_number(ctx,fwretval->_numeric);
break;
1307 duk_push_string(ctx,fwretval->_string);
break;
1310 if(SCALARS_ARE_PRIMITIVES){
1312 switch(fwretval->_web3dval.fieldType){
1313 case FIELDTYPE_SFBool:
1314 duk_push_boolean(ctx,fwretval->_web3dval.anyvrml->sfbool);
break;
1315 case FIELDTYPE_SFInt32:
1316 duk_push_int(ctx,fwretval->_web3dval.anyvrml->sfint32);
break;
1317 case FIELDTYPE_SFFloat:
1318 duk_push_number(ctx,(
double)fwretval->_web3dval.anyvrml->sffloat);
break;
1319 case FIELDTYPE_SFDouble:
1320 case FIELDTYPE_SFTime:
1321 duk_push_number(ctx,fwretval->_web3dval.anyvrml->sfdouble);
break;
1322 case FIELDTYPE_SFString:
1323 duk_push_string(ctx,fwretval->_web3dval.anyvrml->sfstring->strptr);
break;
1325 push_typed_proxy2(ctx,fwretval->_web3dval.fieldType,fwretval->_web3dval.kind,fwretval->_web3dval.native,valueChanged,fwretval->_web3dval.gc);
1329 push_typed_proxy2(ctx,fwretval->_web3dval.fieldType,fwretval->_web3dval.kind,fwretval->_web3dval.native,valueChanged,fwretval->_web3dval.gc);
1333 duk_push_pointer(ctx,fwretval->_jsobject);
1337 push_typed_proxy2(ctx,fwretval->_pointer.fieldType,fwretval->_pointer.kind,fwretval->_pointer.native,valueChanged,fwretval->_pointer.gc);
1347 int rc, nr, itype, kind, nargs;
1348 const char *fwFunc = NULL;
1354 nargs = duk_get_top(ctx);
1356 duk_push_current_function(ctx);
1358 rc = duk_get_prop_string(ctx,-1,
"fwItype");
1359 if(rc==1) itype = duk_get_int(ctx,-1);
1362 rc = duk_get_prop_string(ctx,-1,
"fwKind");
1363 if(rc==1) kind = duk_get_int(ctx,-1);
1366 rc = duk_get_prop_string(ctx,-1,
"fwFunc");
1367 if(rc == 1) fwFunc = duk_to_string(ctx,-1);
1371 if(!strcasecmp(fwFunc,
"getType")){
1372 duk_push_int(ctx,itype);
1375 if(!strcmp(fwFunc,
"isReadable")){
1376 int isreadable = TRUE;
1378 isreadable = isreadable && (kind == PKW_inputOutput || kind == PKW_initializeOnly);
1379 if(isreadable) duk_push_true(ctx);
1380 else duk_push_false(ctx);
1383 if(!strcmp(fwFunc,
"isWritable")){
1384 int iswritable = TRUE;
1386 iswritable = iswritable && (kind == PKW_inputOutput || kind == PKW_outputOnly);
1387 if(iswritable) duk_push_true(ctx);
1388 else duk_push_false(ctx);
1394 int rc, nr, itype, nargs, *valueChanged = NULL;
1395 const char *fwFunc = NULL;
1402 nargs = duk_get_top(ctx);
1404 duk_push_current_function(ctx);
1406 rc = duk_get_prop_string(ctx,-1,
"fwItype");
1407 if(rc==1) itype = duk_get_int(ctx,-1);
1410 rc = duk_get_prop_string(ctx,-1,
"fwField");
1411 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1414 rc = duk_get_prop_string(ctx,-1,
"fwChanged");
1415 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1418 rc = duk_get_prop_string(ctx,-1,
"fwFunc");
1419 if(rc == 1) fwFunc = duk_to_string(ctx,-1);
1425 fwt = getFWTYPE(itype);
1427 fs = getFWFunc(fwt,fwFunc);
1434 convert_duk_to_fwvals(ctx, nargs, 0, fs->arglist, &pars, &argc);
1438 duk_eval_string(ctx,
"__script");
1439 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
1442 ec = (
void *)scriptnode->_executionContext;
1444 nr = fs->call(fwt,ec,parent,argc,pars,&fwretval);
1446 nr = fwval_duk_push(ctx,&fwretval,valueChanged);
1447 if(nr && !strcasecmp(fwFunc,
"toString")){
1448 if(fwretval.itype ==
'S' && fwretval._string){
1450 free(fwretval._string);
1454 if(valueChanged) *valueChanged = TRUE;
1461 int rc, nr, itype, kind, *valueChanged = NULL;
1469 rc = duk_get_prop_string(ctx,0,
"fwItype");
1470 if(rc==1) itype = duk_get_int(ctx,-1);
1473 rc = duk_get_prop_string(ctx,0,
"fwKind");
1474 if(rc==1) kind = duk_get_int(ctx,-1);
1477 rc = duk_get_prop_string(ctx,0,
"fwField");
1478 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1481 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1482 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1488 switch(duk_get_type(ctx,-2)){
1489 case DUK_TYPE_NUMBER:{
1495 const char *key = duk_require_string(ctx,-2);
1497 if(!strcmp(key,
"fwItype")){
1499 duk_push_int(ctx,itype);
1503 if(!strcmp(key,
"fwGC")){
1506 duk_push_boolean(ctx,FALSE);
1510 if(!strcmp(key,
"fwField")){
1512 duk_push_pointer(ctx,parent);
1516 if(!strcasecmp(key,
"getType") || !strcmp(key,
"isReadable") || !strcmp(key,
"isWritable")){
1518 duk_push_c_function(ctx,ctypefunction,DUK_VARARGS);
1519 duk_push_int(ctx,itype);
1520 duk_put_prop_string(ctx,-2,
"fwItype");
1521 duk_push_int(ctx,kind);
1522 duk_put_prop_string(ctx,-2,
"fwKind");
1523 duk_push_string(ctx,key);
1524 duk_put_prop_string(ctx,-2,
"fwFunc");
1535 const char *key = NULL;
1536 FWTYPE *fwt = getFWTYPE(itype);
1538 char type, readOnly;
1542 if(duk_is_number(ctx,-2)){
1544 int index = duk_get_int(ctx,-2);
1545 if(fwt->takesIndexer){
1546 type = fwt->takesIndexer;
1547 readOnly = fwt->indexerReadOnly;
1554 index = fwiterator_generic(index -1,fwt,parent,&name,&lastProp,&jndex,&type,&readOnly);
1555 if(index > -1) found = 1;
1560 key = duk_get_string(ctx,-2);
1561 found = fwhas_generic(fwt,parent,key,&jndex,&type,&readOnly);
1562 if(!found && strcmp(key,
"valueOf")){
1564 static int once = 0;
1566 ConsoleMessage(
"type %s has no property or function %s - please check your typing\n",fwt->name,key);
1570 if(found && type==
'f'){
1574 duk_push_c_function(ctx,cfunction,DUK_VARARGS);
1575 duk_push_pointer(ctx,parent);
1576 duk_put_prop_string(ctx,-2,
"fwField");
1577 duk_push_pointer(ctx,valueChanged);
1578 duk_put_prop_string(ctx,-2,
"fwChanged");
1579 duk_push_int(ctx,itype);
1580 duk_put_prop_string(ctx,-2,
"fwItype");
1581 duk_push_string(ctx,key);
1582 duk_put_prop_string(ctx,-2,
"fwFunc");
1585 }
else if(found && fwt->Getter){
1590 duk_eval_string(ctx,
"__script");
1591 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
1594 ec = (
void *)scriptnode->_executionContext;
1597 nr = fwt->Getter(fwt,jndex,ec,parent,&fwretval);
1599 nr = fwval_duk_push(ctx,&fwretval,valueChanged);
1606 int rc, itype, *valueChanged = NULL;
1610 rc = duk_get_prop_string(ctx,0,
"fwItype");
1611 if(rc==1) itype = duk_get_int(ctx,-1);
1614 rc = duk_get_prop_string(ctx,0,
"fwField");
1615 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1618 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1619 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1623 switch(duk_get_type(ctx,-3)){
1624 case DUK_TYPE_NUMBER:{
1635 switch(duk_get_type(ctx,-2)){
1636 case DUK_TYPE_NUMBER:{
1637 int ival = duk_get_int(ctx,-2);
1641 case DUK_TYPE_STRING:{
1642 const char *cval = duk_get_string(ctx,-2);
1655 FWTYPE *fwt = getFWTYPE(itype);
1657 char type, readOnly;
1659 if(duk_is_number(ctx,-3) && fwt->takesIndexer){
1661 jndex = duk_get_int(ctx,-3);
1662 type = fwt->takesIndexer;
1663 readOnly = fwt->indexerReadOnly;
1668 key = duk_get_string(ctx,-3);
1669 found = fwhas_generic(fwt,parent,key,&jndex,&type,&readOnly) && (type !=
'f');
1671 if(found && (readOnly !=
'T') && fwt->Setter){
1672 FWval fwsetval = NULL;
1675 arglist.argtypes = &type;
1676 arglist.fillMissingFixedWithZero = 0;
1677 arglist.nfixedArg = 1;
1678 arglist.iVarArgStartsAt = -1;
1679 convert_duk_to_fwvals(ctx, 1, -2, arglist, &fwsetval, &argc);
1684 duk_eval_string(ctx,
"__script");
1685 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
1688 ec = (
void *)scriptnode->_executionContext;
1691 fwt->Setter(fwt,jndex,ec,parent,fwsetval);
1693 (*valueChanged) = 1;
1701 int rc, itype, *valueChanged;
1705 rc = duk_get_prop_string(ctx,0,
"fwItype");
1706 if(rc==1) itype = duk_get_int(ctx,-1);
1710 rc = duk_get_prop_string(ctx,0,
"fwField");
1711 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1714 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1715 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1718 show_stack(ctx,
"in cdel");
1725 int iglobal, ihandler;
1726 iglobal = duk_get_top(ctx) -1;
1728 duk_push_object(ctx);
1729 duk_put_prop_string(ctx, iglobal,
"handler");
1731 duk_get_prop_string(ctx,iglobal,
"handler");
1732 ihandler = duk_get_top(ctx) -1;
1733 duk_push_c_function(ctx,chas,2);
1734 duk_put_prop_string(ctx, ihandler,
"has");
1735 duk_push_c_function(ctx,cownKeys,1);
1736 duk_put_prop_string(ctx, ihandler,
"ownKeys");
1737 duk_push_c_function(ctx,cenumerate,1);
1738 duk_put_prop_string(ctx, ihandler,
"enumerate");
1739 duk_push_c_function(ctx,cget,3);
1740 duk_put_prop_string(ctx, ihandler,
"get");
1741 duk_push_c_function(ctx,cset,4);
1742 duk_put_prop_string(ctx, ihandler,
"set");
1743 duk_push_c_function(ctx,cdel,2);
1744 duk_put_prop_string(ctx, ihandler,
"del");
1748 void addCustomProxyType(
duk_context *ctx,
int iglobal,
const char *typeName)
1751 duk_push_c_function(ctx,cfwconstructor,DUK_VARARGS);
1753 itype = fwType2itype(typeName);
1754 duk_push_int(ctx,itype);
1755 duk_put_prop_string(ctx,-2,
"fwItype");
1757 duk_put_prop_string(ctx,iglobal,typeName);
1759 void add_duk_global_property(
duk_context *ctx,
int itype,
const char *fieldname,
int *valueChanged,
struct X3D_Node *node);
1764 static char *eval_string_defineAccessor =
"\
1765 function defineAccessor(obj, key, set, get) { \
1766 Object.defineProperty(obj, key, { \
1767 enumerable: true, configurable: true, \
1768 set: set, get: get \
1776 void JSCreateScriptContext(
int num) {
1787 ScriptControl = getScriptControlIndex(num);
1788 script = ScriptControl->script;
1789 scriptnode = script->ShaderScriptNode;
1791 ctx = duk_create_heap_default();
1794 duk_push_global_object(ctx);
1795 iglobal = duk_get_top(ctx) -1;
1798 ScriptControl->cx = ctx;
1801 ((
int *)&ScriptControl->glob)[0] = iglobal;
1804 duk_push_pointer(ctx,scriptnode);
1805 duk_put_prop_string(ctx,iglobal,
"__script");
1807 duk_push_string(ctx,eval_string_defineAccessor);
1816 for(i=0;i<FWTYPES_COUNT;i++)
1817 if(fwtypesArray[i]->Constructor)
1818 addCustomProxyType(ctx,iglobal,fwtypesArray[i]->name);
1821 add_duk_global_property(ctx, AUXTYPE_X3DBrowser,
"Browser", NULL, NULL);
1822 add_duk_global_property(ctx, AUXTYPE_X3DConstants,
"X3DConstants", NULL, NULL);
1824 duk_eval_string(ctx,DefaultScriptMethodsA);
1826 duk_eval_string(ctx,DefaultScriptMethodsB);
1830 CRoutes_js_new (num, JAVASCRIPT);
1838 duk_eval_string(ctx,
"__script");
1839 scriptnode = duk_to_pointer(ctx,-1);
1841 snode = (
struct X3D_Node *)scriptnode;
1845 duk_eval_string(ctx,
"print(Object.keys(Browser));");
1847 duk_eval_string(ctx,
"print(Object.getOwnPropertyNames(Browser));");
1849 duk_eval_string(ctx,
"for (k in Browser) {print(k);}");
1851 duk_eval_string(ctx,
"if('println' in Browser) print('have println'); else print('no println');");
1853 duk_eval_string(ctx,
"print('X3DConstants.outputOnly='); print(X3DConstants.outputOnly);");
1855 duk_eval_string(ctx,
"print(Object.keys(X3DConstants));");
1859 duk_eval_string(ctx,
"Browser.println('hi from brwsr.println');");
1861 duk_eval_string(ctx,
"Browser.description = 'funny description happened on the way to ..';");
1863 duk_eval_string(ctx,
"Browser.println(Browser.description);");
1865 duk_eval_string(ctx,
"print('hi from print');");
1867 duk_eval_string(ctx,
"print(Browser.version);");
1872 duk_eval_string(ctx,
"print('Browser.supportedComponents.length = ');");duk_pop(ctx);
1873 duk_eval_string(ctx,
"print(Browser.supportedComponents.length);"); duk_pop(ctx);
1874 duk_eval_string(ctx,
"for(var i=0;i<Browser.supportedComponents.length;i++) {print(Browser.supportedComponents[i].name + ' '+Browser.supportedComponents[i].level);}"); duk_pop(ctx);
1877 duk_eval_string(ctx,
"var myvec3 = new SFVec3f(1.0,2.0,3.0);");
1879 duk_eval_string(ctx,
"print(myvec3.x.toString());");
1881 duk_eval_string(ctx,
"myvec3.y = 45.0;");
1883 duk_eval_string(ctx,
"print('sb45='+myvec3.y);");
1897 int SFNode_Setter0(
FWType fwt,
int index,
void *ec,
void * fwn,
FWval fwval,
int isCurrentScriptNode);
1906 int rc, itype, *valueChanged;
1910 nargs = duk_get_top(ctx);
1916 key = duk_require_string(ctx,1);
1922 duk_push_current_function(ctx);
1924 rc = duk_get_prop_string(ctx,-1,
"fwItype");
1925 if(rc==1) itype = duk_get_int(ctx,-1);
1927 if(itype > -1 && itype < AUXTYPE_X3DConstants){
1929 rc = duk_get_prop_string(ctx,-1,
"fwNode");
1930 if(rc==1) parent = duk_to_pointer(ctx,-1);
1933 rc = duk_get_prop_string(ctx,-1,
"fwChanged");
1934 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1939 if(itype > -1 && itype < AUXTYPE_X3DConstants){
1942 FWTYPE *fwt = getFWTYPE(FIELDTYPE_SFNode);
1944 char type, readOnly;
1948 any.sfnode = parent;
1950 found = fwhas_generic(fwt,&any,key,&jndex,&type,&readOnly) && (type !=
'f');
1952 FWval fwsetval = NULL;
1955 arglist.argtypes = &type;
1956 arglist.fillMissingFixedWithZero = 0;
1957 arglist.nfixedArg = 1;
1958 arglist.iVarArgStartsAt = -1;
1959 convert_duk_to_fwvals(ctx, 1, -2, arglist, &fwsetval, &argc);
1964 duk_eval_string(ctx,
"__script");
1965 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
1968 ec = (
void *)scriptnode->_executionContext;
1971 SFNode_Setter0(fwt,jndex,ec,&any,fwsetval,TRUE);
1981 void push_typed_proxy_fwgetter(
duk_context *ctx,
int itype,
int mode,
const char* fieldname,
void *fwpointer,
int* valueChanged)
1988 proxy_entry *pe = NULL;
1989 if(itype == FIELDTYPE_SFNode){
1991 printf(
"pushtyped2 nodetype %d\n",node->_nodeType);
1992 pe = lookup_ctx_proxycache_entry_by_nodeptr(ctx, node);
1995 duk_push_heapptr(ctx,pe->jsproxy);
1998 duk_eval_string(ctx,
"Proxy");
1999 duk_push_object(ctx);
2000 duk_push_pointer(ctx,fwpointer);
2001 duk_put_prop_string(ctx,-2,
"fwField");
2002 duk_push_pointer(ctx,valueChanged);
2003 duk_put_prop_string(ctx,-2,
"fwChanged");
2004 duk_push_int(ctx,itype);
2005 duk_put_prop_string(ctx,-2,
"fwItype");
2006 duk_eval_string(ctx,
"handler");
2010 if(doingFinalizer) {
2020 if(itype == FIELDTYPE_SFNode){
2022 void *jsproxy = duk_get_heapptr(ctx, -1);
2023 add_ctx_proxycache_entry(ctx, node, jsproxy);
2025 duk_eval_string(ctx,
"Duktape.fin");
2027 duk_push_c_function(ctx,cfinalizer,1);
2036 int push_duk_fieldvalue(
duk_context *ctx,
int itype,
int mode,
const char* fieldname,
union anyVrml *field,
int *valueChanged)
2050 case FIELDTYPE_SFBool:
2051 duk_push_boolean(ctx,field->sfbool);
break;
2052 case FIELDTYPE_SFFloat:
2053 duk_push_number(ctx,field->sffloat);
break;
2054 case FIELDTYPE_SFTime:
2055 duk_push_number(ctx,field->sftime);
break;
2056 case FIELDTYPE_SFDouble:
2057 duk_push_number(ctx,field->sfdouble);
break;
2058 case FIELDTYPE_SFInt32:
2059 duk_push_int(ctx,field->sfint32);
break;
2060 case FIELDTYPE_SFString:
2061 duk_push_string(ctx,field->sfstring->strptr);
break;
2065 if(itype == FIELDTYPE_SFNode){
2074 (memcpy(&anode,field,
sizeof(
void *)));
2075 printf(
"anode._nodeType=%d ",anode->_nodeType);
2076 printf(
"anyvrml.sfnode._nodetype=%d\n",field->sfnode->_nodeType);
2077 anode = field->sfnode;
2078 printf(
"anode = anyvrml.sfnode ._nodetype=%d\n",anode->_nodeType);
2082 push_typed_proxy_fwgetter(ctx, itype, mode, fieldname, field, valueChanged);
2091 int fwgetter0(
duk_context *ctx,
void *parent,
int itype,
char *key,
int *valueChanged){
2093 FWTYPE *fwt = getFWTYPE(itype);
2094 int jndex, found, nr;
2095 char type, readOnly;
2098 found = fwhas_generic(fwt,parent,key,&jndex,&type,&readOnly);
2099 if(found && fwt->Getter){
2104 duk_eval_string(ctx,
"__script");
2105 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
2108 ec = (
void *)scriptnode->_executionContext;
2111 nr = fwt->Getter(fwt,jndex,ec,parent,&fwretval);
2113 nr = fwval_duk_push(ctx,&fwretval,valueChanged);
2127 int rc, itype, *valueChanged = NULL;
2129 const char *fieldname;
2130 struct X3D_Node *thisScriptNode = NULL;
2133 nargs = duk_get_top(ctx);
2137 fieldname = duk_require_string(ctx,0);
2141 duk_push_current_function(ctx);
2143 rc = duk_get_prop_string(ctx,-1,
"fwItype");
2144 if(rc==1) itype = duk_get_int(ctx,-1);
2146 if(itype < AUXTYPE_X3DConstants){
2148 rc = duk_get_prop_string(ctx,-1,
"fwNode");
2149 if(rc==1) thisScriptNode = duk_to_pointer(ctx,-1);
2152 rc = duk_get_prop_string(ctx,-1,
"fwChanged");
2153 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
2160 if(itype < AUXTYPE_X3DConstants){
2163 any.sfnode = thisScriptNode;
2164 nr = fwgetter0(ctx,&any,FIELDTYPE_SFNode,fieldname,valueChanged);
2167 push_typed_proxy_fwgetter(ctx, itype, PKW_initializeOnly, fieldname, NULL, NULL);
2173 void add_duk_global_property(
duk_context *ctx,
int itype,
const char *fieldname,
int *valueChanged,
struct X3D_Node *node ){
2177 duk_eval_string(ctx,
"defineAccessor");
2179 duk_eval_string(ctx,
"this");
2181 duk_push_string(ctx,fieldname);
2183 duk_push_c_function(ctx,fwsetterNS,2);
2184 if(itype < AUXTYPE_X3DConstants){
2185 duk_push_pointer(ctx,valueChanged);
2186 duk_put_prop_string(ctx,-2,
"fwChanged");
2187 duk_push_pointer(ctx,node);
2188 duk_put_prop_string(ctx,-2,
"fwNode");
2190 duk_push_int(ctx,itype);
2191 duk_put_prop_string(ctx,-2,
"fwItype");
2193 duk_push_c_function(ctx,fwgetterNS,1);
2194 if(itype < AUXTYPE_X3DConstants){
2195 duk_push_pointer(ctx,node);
2196 duk_put_prop_string(ctx,-2,
"fwNode");
2197 duk_push_pointer(ctx,valueChanged);
2198 duk_put_prop_string(ctx,-2,
"fwChanged");
2200 duk_push_int(ctx,itype);
2201 duk_put_prop_string(ctx,-2,
"fwItype");
2207 void InitScriptField2(
struct CRscriptStruct *scriptcontrol,
int itype,
const char* fieldname,
int *valueChanged,
struct X3D_Node* parent)
2224 ctx = scriptcontrol->cx;
2226 add_duk_global_property(ctx,itype,fieldname, valueChanged,parent);
2231 void JSInitializeScriptAndFields (
int num) {
2238 int i,nfields, kind, itype;
2239 const char *fieldname;
2242 scriptcontrol = getScriptControlIndex(num);
2246 script = scriptcontrol->script;
2248 nfields = Shader_Script_getScriptFieldCount(script);
2249 for(i=0;i<nfields;i++){
2250 field = Shader_Script_getScriptField(script,i);
2251 fieldname = ScriptFieldDecl_getName(field);
2252 kind = ScriptFieldDecl_getMode(field);
2253 itype = ScriptFieldDecl_getType(field);
2254 if (kind != PKW_inputOnly) {
2256 field->valueChanged = 0;
2257 InitScriptField2(scriptcontrol, itype, fieldname, &field->valueChanged, script->ShaderScriptNode);
2261 if (!jsActualrunScript(num, scriptcontrol->scriptText)) {
2262 ConsoleMessage (
"JSInitializeScriptAndFields, script failure\n");
2263 scriptcontrol->scriptOK = FALSE;
2264 scriptcontrol->_initialized = TRUE;
2267 FREE_IF_NZ(scriptcontrol->scriptText);
2268 scriptcontrol->_initialized = TRUE;
2269 scriptcontrol->scriptOK = TRUE;
2274 int jsActualrunScript(
int num,
char *script){
2281 ScriptControl = getScriptControlIndex(num);
2285 iglobal = ((
int *)&ScriptControl->glob)[0];
2289 len = (int) strlen(script);
2294 duk_eval_string(ctx, script);
2296 printf (
"ActualrunScript - JS_EvaluateScript failed for %s", script);
2298 ConsoleMessage (
"ActualrunScript - JS_EvaluateScript failed for %s", script);
2304 duk_push_string(ctx, script);
2305 if (duk_peval(ctx) != 0) {
2306 ConsoleMessage(
"eval failed: %s\n", duk_safe_to_string(ctx, -1));
2309 printf(
"result is: %s\n", duk_safe_to_string(ctx, -1));
2317 void SaveScriptField (
int num, indexT kind, indexT type,
const char* field,
union anyVrml value){
2320 static int duk_once = 0;
2321 void process_eventsProcessed(){
2335 for (counter = 0; counter <= tg->CRoutes.max_script_found_and_initialized; counter++) {
2336 scriptcontrol = getScriptControlIndex(counter);
2342 ctx = scriptcontrol->cx;
2343 if(scriptcontrol->thisScriptType != NOSCRIPT && ctx){
2344 duk_eval_string(ctx,
"eventsProcessed");
2346 duk_push_number(ctx,TickTime());
2347 rc = duk_pcall(ctx, 1);
2348 if (rc != DUK_EXEC_SUCCESS) {
2349 printf(
"error: '%s' happened in js function %s called from process_eventsProcessed\n", duk_to_string(ctx, -1),
"eventsProcessed");
2358 void js_cleanup_script_context(
int counter){
2362 void js_setField_javascriptEventOut_B(
union anyVrml* any,
int fieldType,
unsigned len,
int extraData,
int actualscript){
2370 void setField_javascriptEventOut(
struct X3D_Node *tn,
unsigned int tptr,
int fieldType,
unsigned len,
int extraData) {
2380 memptr = offsetPointer_deref(
char *, tn, tptr);
2382 fromptr = tg->JScript.JSglobal_return_val;
2384 medium_copy_field0(fieldType,fromptr,memptr);
2387 void js_setField_javascriptEventOut(
struct X3D_Node *tn,
unsigned int tptr,
int fieldType,
unsigned len,
int extraData,
int actualscript) {
2390 scriptcontrol = getScriptControlIndex(actualscript);
2391 setField_javascriptEventOut(tn,tptr,fieldType, len, extraData);
2397 void set_one_ECMAtype (
int tonode,
int toname,
int dataType,
void *Data,
int datalen) {
2407 #ifdef SETFIELDVERBOSE
2408 printf (
"set_one_ECMAtype, to %d namepointer %d, fieldname %s, datatype %d length %d\n",
2409 tonode,toname,JSparamnames[toname].name,dataType,datalen);
2413 ScriptControl = getScriptControlIndex(tonode);
2418 obj = ((
int*)&ScriptControl->glob)[0];
2422 duk_eval_string(ctx,JSparamnames[toname].name);
2428 fwval._web3dval.native = Data;
2429 fwval._web3dval.fieldType = dataType;
2430 fwval._web3dval.gc = 0;
2432 rc = fwval_duk_push(ctx, &fwval, NULL);
2436 duk_push_number(ctx,TickTime());
2438 rc = duk_pcall(ctx, 2);
2439 if (rc != DUK_EXEC_SUCCESS) {
2440 printf(
"error: '%s' happened in js function %s called from set_one_ECMAType\n", duk_to_string(ctx, -1),JSparamnames[toname].name);
2458 void setScriptECMAtype (
int num) {
2464 struct CRStruct *CRoutes = getCRoutes();
2467 fn = offsetPointer_deref(
void *, CRoutes[num].routeFromNode, CRoutes[num].fnptr);
2468 len = CRoutes[num].len;
2470 for (to_counter = 0; to_counter < CRoutes[num].tonode_count; to_counter++) {
2473 to_ptr = &(CRoutes[num].tonodes[to_counter]);
2474 myObj = X3D_SCRIPT(to_ptr->routeToNode)->__scriptObj;
2476 tptr = to_ptr->foffset;
2477 set_one_ECMAtype (myObj->num, tptr, JSparamnames[tptr].type, fn,len);
2481 void set_one_MultiElementType (
int tonode,
int tnfield,
void *Data,
int dataLen){
2494 ScriptControl = getScriptControlIndex(tonode);
2499 obj = ((
int*)&ScriptControl->glob)[0];
2503 duk_eval_string(ctx,JSparamnames[tnfield].name);
2504 itype = JSparamnames[tnfield].type;
2507 medium_copy_field(itype,Data,&datacopy);
2508 push_typed_proxy2(ctx,itype,PKW_inputOutput,datacopy,NULL,
'T');
2509 duk_push_number(ctx,TickTime());
2511 rc = duk_pcall(ctx, 2);
2512 if (rc != DUK_EXEC_SUCCESS) {
2513 printf(
"error: '%s' happened in js function %s called from set_one_Multi_ElementType\n", duk_to_string(ctx, -1),JSparamnames[tnfield].name);
2519 void set_one_MFElementType(
int tonode,
int toname,
int dataType,
void *Data,
int datalen){
2529 void *datacopy = NULL;
2536 ScriptControl = getScriptControlIndex(tonode);
2541 obj = ((
int*)&ScriptControl->glob)[0];
2545 duk_eval_string(ctx,JSparamnames[toname].name);
2550 source = (
char *)&maData;
2551 any = (
void*)source;
2553 medium_copy_field(itype,source,&datacopy);
2555 push_typed_proxy2(ctx,itype,PKW_inputOutput,datacopy,NULL,
'T');
2556 duk_push_number(ctx,TickTime());
2566 void JSDeleteScriptContext(
int num){
2569 ScriptControl = getScriptControlIndex(num);
2570 duk_destroy_heap(ScriptControl->cx);
2577 void jsClearScriptControlEntries(
int num){
2642 int isScriptControlOK(
int actualscript);
2643 int isScriptControlInitialized(
int actualscript);
2644 void getField_ToJavascript_B(
int shader_num,
int fieldOffset,
int type,
union anyVrml *any,
int len);
2645 int runQueuedDirectOutputs()
2680 int i,num,kind, itype;
2681 const char *fieldname;
2682 static int doneOnce = 0;
2689 printf(
"duktape javascript engine version %ld\n", DUK_VERSION);
2693 for(num=0;num< tg->CRoutes.max_script_found_and_initialized;num++){
2694 scriptcontrol = getScriptControlIndex(num);
2697 script = scriptcontrol->script;
2698 if(scriptcontrol->thisScriptType != NOSCRIPT && script){
2699 if(isScriptControlInitialized(script->num) && isScriptControlOK(script->num)){
2700 int nfields = Shader_Script_getScriptFieldCount(script);
2701 for(i=0;i<nfields;i++){
2702 field = Shader_Script_getScriptField(script,i);
2703 fieldname = ScriptFieldDecl_getName(field);
2704 kind = ScriptFieldDecl_getMode(field);
2705 itype = ScriptFieldDecl_getType(field);
2706 if(field->eventInSet){
2707 if( (kind == PKW_inputOnly || kind == PKW_inputOutput)){
2708 int isMF, sftype, len, isize;
2709 int JSparamNameIndex = field->fieldDecl->JSparamNameIndex;
2710 mark_script(script->num);
2713 sftype = itype - isMF;
2715 isize = returnElementLength(sftype) * returnElementRowSize(sftype);
2716 if(isMF) len =
sizeof(int) +
sizeof(
void*);
2719 field->eventInSet = FALSE;
2720 getField_ToJavascript_B(script->num, JSparamNameIndex, itype, &field->value, len);
2725 field->eventInSet = FALSE;