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"
54#define malloc(A) MALLOCV(A)
55#define free(A) FREE_IF_NZ(A)
56#define realloc(A,B) REALLOC(A,B)
59FWType fwtypesArray[60];
62void initVRMLBrowser(FWType* typeArray,
int *n);
63void initVRMLFields(FWType* typeArray,
int *n);
65 initVRMLBrowser(fwtypesArray, &FWTYPES_COUNT);
66 initVRMLFields(fwtypesArray, &FWTYPES_COUNT);
69FWType getFWTYPE(
int itype){
71 for(i=0;i<FWTYPES_COUNT;i++){
72 if (itype == fwtypesArray[i]->itype) {
73 return fwtypesArray[i];
79#define strcasecmp _stricmp
87 if(!strcasecmp(fs[i].name,
key)){
101 if(!strcasecmp(ps[i].name,
key)){
103 (*index) = ps[i].index;
112 if(ps)
while(ps[len].name) len++;
117 if(fs)
while(fs[len].name) len++;
120int fwiterator_generic(
int index, FWType fwt,
void *pointer,
const char **name,
int *lastProp,
int *jndex,
char *type,
char *readOnly){
124 int lenp, lenf, ifindex;
129 ps = fwt->Properties;
130 iterator = fwt->iterator;
133 lenp = len_properties(ps);
135 (*name) = ps[index].name;
136 (*jndex) = ps[index].index;
138 (*type) = ps[index].type;
139 (*readOnly) = ps[index].readOnly;
143 int iret = iterator(index, fwt, pointer, name, lastProp, jndex, type, readOnly);
144 if(iret > -1)
return iret;
151 lenf = len_functions(fs);
152 ifindex = index - 1 - (*lastProp);
154 (*name) = fs[ifindex].name;
162int fwhas_generic(FWType fwt,
void *pointer,
const char *
key,
int *jndex,
char *type,
char *readOnly){
164 int lastProp, isSet, index = -1;
168 while( (index = fwiterator_generic(index,fwt,pointer,&name, &lastProp, jndex, type, readOnly)) > -1){
169 if(!strcasecmp(name,
key)){
174 if(strlen(
key)>4 && !strncmp(
key,
"set_",4))
178 const char* key2 = &
key[4];
179 while( (index = fwiterator_generic(index,fwt,pointer,&name, &lastProp, jndex, type, readOnly)) > -1){
180 if(!strcasecmp(name,key2)){
191typedef struct pJScript_duk{
196void *JScript_duk_constructor(){
197 void *v = MALLOCV(
sizeof(
struct pJScript_duk));
198 memset(v,0,
sizeof(
struct pJScript_duk));
201void JScript_duk_init(
struct tJScript_duk *t){
203 t->JSglobal_return_val = NULL;
205 t->prv = JScript_duk_constructor();
209 if(!FWTYPES_COUNT) initFWTYPEs();
225int isECMAtype(
int itype){
228 case FIELDTYPE_SFBool:
229 case FIELDTYPE_SFFloat:
230 case FIELDTYPE_SFTime:
231 case FIELDTYPE_SFDouble:
232 case FIELDTYPE_SFInt32:
233 case FIELDTYPE_SFString:
246struct string_int lookup_fieldType[] = {
247 {
"Float", FIELDTYPE_SFFloat},
248 {
"Bool", FIELDTYPE_SFBool},
249 {
"Int32", FIELDTYPE_SFInt32},
250 {
"Time", FIELDTYPE_SFTime},
251 {
"Double", FIELDTYPE_SFDouble},
252 {
"Node", FIELDTYPE_SFNode},
253 {
"Color", FIELDTYPE_SFColor},
254 {
"ColorRGBA", FIELDTYPE_SFColorRGBA},
255 {
"Rotation", FIELDTYPE_SFRotation},
256 {
"Vec2f", FIELDTYPE_SFVec2f},
257 {
"Vec3f", FIELDTYPE_SFVec3f},
258 {
"Vec4f", FIELDTYPE_SFVec4f},
259 {
"Vec2d", FIELDTYPE_SFVec2d},
260 {
"Vec3d", FIELDTYPE_SFVec3d},
261 {
"Vec4d", FIELDTYPE_SFVec4d},
262 {
"String", FIELDTYPE_SFString},
263 {
"Image", FIELDTYPE_SFImage},
264 {
"Matrix3f", FIELDTYPE_SFMatrix3f},
265 {
"Matrix4f", FIELDTYPE_SFMatrix4f},
266 {
"Matrix3d", FIELDTYPE_SFMatrix3d},
267 {
"Matrix4d", FIELDTYPE_SFMatrix4d},
270char * itype2string(
int itype){
272 while(lookup_fieldType[i].c){
273 if(lookup_fieldType[i].i == itype)
return lookup_fieldType[i].c;
279int getFieldFromNodeAndName(
struct X3D_Node* node,
const char *fieldname,
int *type,
int *kind,
int *iifield,
union anyVrml **value);
282int duk_get_valueChanged_flag (
int fptr,
int actualscript){
285 int type, kind, ifield, found;
292 scriptcontrol = getScriptControlIndex(actualscript);
293 script = scriptcontrol->script;
294 node = script->ShaderScriptNode;
295 fullname = JSparamnames[fptr].name;
296 found = getFieldFromNodeAndName(node,fullname,&type,&kind,&ifield,&value);
298 field = Shader_Script_getScriptField(script, ifield);
299 gglobal()->JScript_duk.JSglobal_return_val = (
void *)&field->value;
300 return field->valueChanged;
302 gglobal()->JScript_duk.JSglobal_return_val = NULL;
305void duk_resetScriptTouchedFlag(
int actualscript,
int fptr){
308 int type, kind, ifield, found;
315 scriptcontrol = getScriptControlIndex(actualscript);
316 script = scriptcontrol->script;
317 node = script->ShaderScriptNode;
318 fullname = JSparamnames[fptr].name;
319 found = getFieldFromNodeAndName(node,fullname,&type,&kind,&ifield,&value);
321 field = Shader_Script_getScriptField(script, ifield);
322 field->valueChanged = 0;
330int fwType2itype(
const char *fwType){
331 int i, isSF, isMF, ifield = -1;
333 isSF = !strncmp(fwType,
"SF",2);
334 isMF = !strncmp(fwType,
"MF",2);
338 while(lookup_fieldType[i].c){
339 if(!strcasecmp(suffix,lookup_fieldType[i].c)){
340 ifield = lookup_fieldType[i].i;
345 if(ifield > -1 && isMF ) ifield++;
348 if(!strcasecmp(fwType,
"Browser")) ifield = AUXTYPE_X3DBrowser;
349 if(!strcasecmp(fwType,
"X3DConstants")) ifield = AUXTYPE_X3DConstants;
350 if(!strcasecmp(fwType,
"X3DMatrix3")) ifield = AUXTYPE_X3DMatrix3;
351 if(!strcasecmp(fwType,
"X3DMatrix4")) ifield = AUXTYPE_X3DMatrix4;
352 if(!strcasecmp(fwType,
"VrmlMatrix")) ifield = AUXTYPE_VrmlMatrix;
357void freeField(
int itype,
void* any){
358 if(isSForMFType(itype) == 0){
365 }
else if(isSForMFType(itype) == 1){
383unsigned long upper_power_of_two(
unsigned long v);
384void deleteMallocedFieldValue(
int type,
union anyVrml *fieldPtr);
385void medium_copy_field0(
int itype,
void* source,
void* dest)
392 int i, sfsize,sformf;
396 sformf = isSForMFType(itype);
398 printf(
"bad type in medium_copy_field0\n");
402 sftype = type2SF(itype);
404 sfsize = sizeofSF(sftype);
412 deleteMallocedFieldValue(itype,dest);
414 if( sftype == FIELDTYPE_SFNode ) nele = (int) upper_power_of_two(nele);
415 mfd->p = malloc(sfsize*nele);
419 for(i=0;i<mfs->n;i++)
428 memcpy(dest,source,sfsize);
431void medium_copy_field(
int itype,
void* source,
void** dest){
435 (*dest) = malloc(sizeofSForMF(itype));
436 memset((*dest),0,sizeofSForMF(itype));
437 medium_copy_field0(itype,source,(*dest));
441static char *DefaultScriptMethodsA =
"function initialize() {}; " \
442 " function shutdown() {}; " \
443 " function eventsProcessed() {}; " \
444 " TRUE=true; FALSE=false; " \
448static char *DefaultScriptMethodsB =
" function print(x) {Browser.print(x)}; " \
449 " function println(x) {Browser.println(x)}; " \
450 " function getName() {return Browser.getName()}; "\
451 " function getVersion() {return Browser.getVersion()}; "\
452 " function getCurrentSpeed() {return Browser.getCurrentSpeed()}; "\
453 " function getCurrentFrameRate() {return Browser.getCurrentFrameRate()}; "\
454 " function getWorldURL() {return Browser.getWorldURL()}; "\
455 " function replaceWorld(x) {Browser.replaceWorld(x)}; "\
456 " function loadURL(x,y) {Browser.loadURL(x,y)}; "\
457 " function setDescription(x) {Browser.setDescription(x)}; "\
458 " function createVrmlFromString(x) {Browser.createVrmlFromString(x)}; "\
459 " function createVrmlFromURL(x,y,z) {Browser.createVrmlFromURL(x,y,z)}; "\
460 " function createX3DFromString(x) {Browser.createX3DFromString(x)}; "\
461 " function createX3DFromURL(x,y,z) {Browser.createX3DFromURL(x,y,z)}; "\
462 " function addRoute(a,b,c,d) {Browser.addRoute(a,b,c,d)}; "\
463 " function deleteRoute(a,b,c,d) {Browser.deleteRoute(a,b,c,d)}; "\
464 " function _rename_function(obj,oldf,newf) {if(typeof obj[oldf] === 'function') {obj[newf]=obj[oldf]; delete obj[oldf];}}; "\
476#include "duktape/duktape.h"
478const char *duk_type_to_string(
int duktype){
479 const char* r = NULL;
481 case DUK_TYPE_NUMBER: r =
"DUK_TYPE_NUMBER";
break;
482 case DUK_TYPE_BOOLEAN: r =
"DUK_TYPE_BOOLEAN";
break;
483 case DUK_TYPE_STRING: r =
"DUK_TYPE_STRING";
break;
484 case DUK_TYPE_OBJECT: r =
"DUK_TYPE_OBJECT";
break;
485 case DUK_TYPE_NONE: r =
"DUK_TYPE_NONE";
break;
486 case DUK_TYPE_UNDEFINED: r =
"DUK_TYPE_UNDEFINED";
break;
487 case DUK_TYPE_NULL: r =
"DUK_TYPE_NULL";
break;
488 case DUK_TYPE_POINTER: r =
"DUK_TYPE_POINTER";
break;
496void show_stack(duk_context *ctx,
char* comment)
498 int i, itop = duk_get_top(ctx);
499 if(comment) printf(
"%s top=%d\n",comment,itop);
501 printf(
"%10s%10s\n",
"position",
"type");
504 int t = duk_get_type(ctx, ipos);
506 const char * amore =
"";
508 case DUK_TYPE_NUMBER: stype =
"number";
break;
509 case DUK_TYPE_STRING: stype =
"string";
break;
511 case DUK_TYPE_OBJECT: stype =
"object";
break;
512 case DUK_TYPE_NONE: stype =
"none";
break;
513 case DUK_TYPE_UNDEFINED: stype =
"undefined";
break;
514 case DUK_TYPE_BOOLEAN: stype =
"boolean";
break;
515 case DUK_TYPE_NULL: stype =
"null";
break;
516 case DUK_TYPE_POINTER: stype =
"pointer";
break;
520 if(duk_is_function(ctx,ipos)){
522 afunc = duk_is_c_function(ctx,ipos) ?
"Cfunc" : afunc;
523 afunc = duk_is_ecmascript_function(ctx,ipos) ?
"jsfunc" : afunc;
524 afunc = duk_is_bound_function(ctx,ipos) ?
"boundfunc" : afunc;
527 if(duk_is_nan(ctx,ipos)){
530 if(duk_is_object(ctx,ipos)){
533 printf(
"%10d%10s %s\n",ipos,stype,amore);
558static Stack * proxycaches = NULL;
559typedef struct cache_table_entry {
563typedef struct proxy_cache_entry {
564 struct X3D_Node *node;
570cache_entry * lookup_ctx_proxy_cache(duk_context *ctx){
572 cache_entry *ret = NULL;
573 if(proxycaches == NULL){
574 proxycaches = newStack(cache_entry *);
576 for(i=0;i<vectorSize(proxycaches);i++){
577 cache_entry * ce = vector_get(cache_entry*,proxycaches,i);
584 cache_entry *ce = MALLOC(cache_entry*,
sizeof(cache_entry));
585 stack_push(cache_entry*,proxycaches,ce);
587 ce->cache = newStack(proxy_entry*);
592proxy_entry *lookup_ctx_proxycache_entry_by_nodeptr(duk_context *ctx,
struct X3D_Node *node){
593 proxy_entry *ret = NULL;
594 cache_entry* cache = lookup_ctx_proxy_cache(ctx);
597 for(i=0;i<vectorSize(cache->cache);i++){
598 proxy_entry *pe = vector_get(proxy_entry*,cache->cache,i);
599 if(pe && pe->node == node){
606proxy_entry *add_ctx_proxycache_entry(duk_context *ctx,
struct X3D_Node *node,
void *jsproxy){
609 proxy_entry *ret = NULL;
610 cache_entry *cache = lookup_ctx_proxy_cache(ctx);
613 proxy_entry *pe = MALLOC(proxy_entry*,
sizeof(proxy_entry));
615 pe->jsproxy = jsproxy;
618 for(i=0;i<vectorSize(cache->cache);i++){
619 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
622 vector_set(proxy_entry*,cache->cache,i,pe);
628 stack_push(proxy_entry*,cache->cache,pe);
632 printf(
"cache after add proxy\n");
633 for(i=0;i<vectorSize(cache->cache);i++){
634 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
636 printf(
"%d %p %p\n",i,pe0->node,pe0->jsproxy);
638 printf(
"%d NULL\n",i);
644void remove_ctx_proxycache_entry_by_nodeptr(duk_context *ctx,
struct X3D_Node *node){
647 proxy_entry *ret = NULL;
648 cache_entry *cache = lookup_ctx_proxy_cache(ctx);
651 for(i=0;i<vectorSize(cache->cache);i++){
652 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
653 if(pe0 && pe0->node == node){
654 vector_set(proxy_entry*,cache->cache,i,NULL);
660 printf(
"after cache clean\n");
661 for(i=0;i<vectorSize(cache->cache);i++){
662 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
664 printf(
"%d %p %p\n",i,pe0->node,pe0->jsproxy);
666 printf(
"%d NULL\n",i);
671void remove_ctx_proxycache_entry_by_jsproxy(duk_context *ctx,
void *jsproxy){
673 proxy_entry *ret = NULL;
674 cache_entry *cache = lookup_ctx_proxy_cache(ctx);
677 for(i=0;i<vectorSize(cache->cache);i++){
678 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
679 if(pe0 && pe0->jsproxy == jsproxy){
680 vector_set(proxy_entry*,cache->cache,i,NULL);
689int cfinalizer(duk_context *ctx){
691 void *fwpointer = NULL;
693 rc = duk_get_prop_string(ctx,0,
"fwItype");
694 if(rc == 1) itype = duk_to_int(ctx,-1);
696 rc = duk_get_prop_string(ctx,0,
"fwGC");
697 if(rc == 1) igc = duk_to_boolean(ctx,-1);
699 rc = duk_get_prop_string(ctx,0,
"fwField");
700 if(rc == 1) fwpointer = duk_to_pointer(ctx,-1);
705 if(itype == FIELDTYPE_SFNode && fwpointer){
712 remove_ctx_proxycache_entry_by_nodeptr(ctx, node);
714 if(igc > 0 && itype > -1 && fwpointer){
715 if(itype < AUXTYPE_X3DConstants){
717 freeField(itype,fwpointer);
726static int doingFinalizer = 1;
727void push_typed_proxy(duk_context *ctx,
int itype,
void *fwpointer,
int* valueChanged)
731 proxy_entry *pe = NULL;
732 if(itype == FIELDTYPE_SFNode){
735 pe = lookup_ctx_proxycache_entry_by_nodeptr(ctx, node);
738 duk_push_heapptr(ctx, pe->jsproxy);
741 duk_eval_string(ctx,
"Proxy");
743 duk_push_pointer(ctx,fwpointer);
744 duk_put_prop_string(ctx,-2,
"fwField");
745 duk_push_pointer(ctx,valueChanged);
746 duk_put_prop_string(ctx,-2,
"fwChanged");
747 duk_push_int(ctx,itype);
748 duk_put_prop_string(ctx,-2,
"fwItype");
750 duk_push_boolean(ctx,TRUE);
751 duk_put_prop_string(ctx,-2,
"fwGC");
753 duk_eval_string(ctx,
"handler");
769 if(itype == FIELDTYPE_SFNode){
771 void *jsproxy = duk_get_heapptr(ctx, -1);
772 add_ctx_proxycache_entry(ctx, node, jsproxy);
774 duk_eval_string(ctx,
"Duktape.fin");
776 duk_push_c_function(ctx,cfinalizer,1);
783int push_typed_proxy2(duk_context *ctx,
int itype,
int kind,
void *fwpointer,
int* valueChanged,
char doGC)
789 proxy_entry *pe = NULL;
790 int idogc = doGC ? TRUE : FALSE;
791 if(itype == FIELDTYPE_SFNode){
794 pe = lookup_ctx_proxycache_entry_by_nodeptr(ctx, node);
797 duk_push_heapptr(ctx, pe->jsproxy);
799 duk_eval_string(ctx,
"Proxy");
800 duk_push_object(ctx);
801 duk_push_pointer(ctx,fwpointer);
802 duk_put_prop_string(ctx,-2,
"fwField");
803 duk_push_pointer(ctx,valueChanged);
804 duk_put_prop_string(ctx,-2,
"fwChanged");
805 duk_push_int(ctx,itype);
806 duk_put_prop_string(ctx,-2,
"fwItype");
807 duk_push_int(ctx,kind);
808 duk_put_prop_string(ctx,-2,
"fwKind");
811 duk_push_boolean(ctx,idogc);
812 duk_put_prop_string(ctx,-2,
"fwGC");
815 duk_eval_string(ctx,
"handler");
827 if(itype == FIELDTYPE_SFNode){
829 void *jsproxy = duk_get_heapptr(ctx, -1);
830 add_ctx_proxycache_entry(ctx, node, jsproxy);
833 duk_eval_string(ctx,
"Duktape.fin");
835 duk_push_c_function(ctx,cfinalizer,1);
845void convert_duk_to_fwvals_old(duk_context *ctx,
int nargs,
int istack,
struct ArgListType arglist, FWval *args,
int *argc){
846 int nUsable,nNeeded, i, ii;
849 nUsable = arglist.iVarArgStartsAt > -1 ? nargs : arglist.nfixedArg;
850 nNeeded = max(nUsable,arglist.nfixedArg);
851 pars = malloc(nNeeded*
sizeof(
struct FWVAL));
855 for(i=0;i<nUsable;i++){
860 if(i < arglist.nfixedArg)
861 ctype = arglist.argtypes[i];
863 ctype = arglist.argtypes[arglist.iVarArgStartsAt];
864 pars[i].itype = ctype;
865 if( duk_is_object(ctx, ii)){
868 rc = duk_get_prop_string(ctx,ii,
"fwItype");
870 isPrimitive = rc == 0;
874 duk_to_primitive(ctx,ii,DUK_HINT_NONE);
878 trhs = duk_get_type(ctx, ii);
897 int bb = duk_get_boolean(ctx,ii);
898 pars[i]._boolean = bb;
901 case 'I': pars[i]._integer = duk_to_int(ctx,ii);
break;
902 case 'F': pars[i]._numeric = duk_to_number(ctx,ii);
break;
903 case 'D': pars[i]._numeric = duk_to_number(ctx,ii);
break;
904 case 'S': pars[i]._string = duk_to_string(ctx,ii);
break;
906 if(duk_is_string(ctx,ii)){
907 pars[i]._string = duk_get_string(ctx,ii);
911 if(!duk_is_object(ctx,i))
915 int rc, isOK, itypeRHS = -1;
916 union anyVrml *fieldRHS = NULL;
917 if(trhs == DUK_TYPE_NULL){
919 fieldRHS = malloc(
sizeof(
union anyVrml));
920 fieldRHS->sfnode = NULL;
921 }
else if(trhs == DUK_TYPE_OBJECT){
922 rc = duk_get_prop_string(ctx,ii,
"fwItype");
924 itypeRHS = duk_to_int(ctx,-1);
927 rc = duk_get_prop_string(ctx,ii,
"fwField");
928 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
937 pars[i]._web3dval.native = fieldRHS;
938 pars[i]._web3dval.fieldType = itypeRHS;
946 int rc, isOK, itypeRHS = -1;
947 union anyVrml *fieldRHS = NULL;
948 rc = duk_get_prop_string(ctx,ii,
"fwItype");
951 itypeRHS = duk_to_int(ctx,-1);
954 rc = duk_get_prop_string(ctx,ii,
"fwField");
955 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
959 if(fieldRHS != NULL && itypeRHS >= AUXTYPE_X3DConstants){
961 pars[i]._pointer.native = fieldRHS;
962 pars[i]._pointer.fieldType = itypeRHS;
974 for(i=nUsable;i<nNeeded;i++){
976 char ctype = arglist.argtypes[i];
977 pars[i].itype = ctype;
979 case 'B': pars[i]._boolean = FALSE;
break;
980 case 'I': pars[i]._integer = 0;
break;
981 case 'F': pars[i]._numeric = 0.0;
break;
982 case 'D': pars[i]._numeric = 0.0;
break;
983 case 'S': pars[i]._string = NULL;
break;
984 case 'Z': pars[i]._string = NULL; pars[i].itype =
'S';
break;
986 pars[i]._web3dval.fieldType = FIELDTYPE_SFNode;
987 pars[i]._web3dval.native = NULL;
break;
992 pars[i]._jsobject = NULL;
break;
999void convert_duk_to_fwvals_new(duk_context *ctx,
int nargs,
int istack,
struct ArgListType arglist, FWval *args,
int *argc){
1000 int nUsable,nNeeded, i, ii, jj, k, len;
1007 for(i=0;i<nargs;i++){
1010 if( duk_is_array(ctx, ii)){
1012 len = duk_get_length(ctx, ii);
1019 nUsable = arglist.iVarArgStartsAt > -1 ? nargs : arglist.nfixedArg;
1020 nNeeded = max(nUsable,arglist.nfixedArg);
1021 pars = malloc(nNeeded*
sizeof(
struct FWVAL));
1026 for(i=0;i<nUsable;){
1031 if( duk_is_array(ctx, ii)){
1033 len = duk_get_length(ctx, ii);
1035 for(k=0;k<len;k++,i++){
1036 if(i < arglist.nfixedArg)
1037 ctype = arglist.argtypes[i];
1039 ctype = arglist.argtypes[arglist.iVarArgStartsAt];
1040 pars[i].itype = ctype;
1042 if( duk_is_array(ctx, ii)){
1043 duk_get_prop_index(ctx, ii, k);
1047 if( duk_is_object(ctx,jj) ){
1048 int rc, isPrimitive;
1050 rc = duk_get_prop_string(ctx,jj,
"fwItype");
1052 isPrimitive = rc == 0;
1056 duk_to_primitive(ctx,jj,DUK_HINT_NONE);
1060 trhs = duk_get_type(ctx, jj);
1079 int bb = duk_get_boolean(ctx,jj);
1080 pars[i]._boolean = bb;
1083 case 'I': pars[i]._integer = duk_to_int(ctx,jj);
break;
1084 case 'F': pars[i]._numeric = duk_to_number(ctx,jj);
break;
1085 case 'D': pars[i]._numeric = duk_to_number(ctx,jj);
break;
1086 case 'S': pars[i]._string = duk_to_string(ctx,jj);
break;
1088 if(duk_is_string(ctx,jj)){
1089 pars[i]._string = duk_get_string(ctx,jj);
1090 pars[i].itype =
'S';
1093 if(!duk_is_object(ctx,jj))
1097 int rc, isOK, itypeRHS = -1;
1098 union anyVrml *fieldRHS = NULL;
1099 if(trhs == DUK_TYPE_NULL){
1101 fieldRHS = malloc(
sizeof(
union anyVrml));
1102 fieldRHS->sfnode = NULL;
1103 }
else if(trhs == DUK_TYPE_OBJECT){
1104 rc = duk_get_prop_string(ctx,jj,
"fwItype");
1106 itypeRHS = duk_to_int(ctx,-1);
1109 rc = duk_get_prop_string(ctx,jj,
"fwField");
1110 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
1119 pars[i]._web3dval.native = fieldRHS;
1120 pars[i]._web3dval.fieldType = itypeRHS;
1121 pars[i].itype =
'W';
1128 int rc, isOK, itypeRHS = -1;
1129 union anyVrml *fieldRHS = NULL;
1130 rc = duk_get_prop_string(ctx,jj,
"fwItype");
1133 itypeRHS = duk_to_int(ctx,-1);
1136 rc = duk_get_prop_string(ctx,jj,
"fwField");
1137 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
1141 if(fieldRHS != NULL && itypeRHS >= AUXTYPE_X3DConstants){
1143 pars[i]._pointer.native = fieldRHS;
1144 pars[i]._pointer.fieldType = itypeRHS;
1145 pars[i].itype =
'P';
1159 for(i=nUsable;i<nNeeded;i++){
1161 char ctype = arglist.argtypes[i];
1162 pars[i].itype = ctype;
1164 case 'B': pars[i]._boolean = FALSE;
break;
1165 case 'I': pars[i]._integer = 0;
break;
1166 case 'F': pars[i]._numeric = 0.0;
break;
1167 case 'D': pars[i]._numeric = 0.0;
break;
1168 case 'S': pars[i]._string = NULL;
break;
1169 case 'Z': pars[i]._string = NULL; pars[i].itype =
'S';
break;
1171 pars[i]._web3dval.fieldType = FIELDTYPE_SFNode;
1172 pars[i]._web3dval.native = NULL;
break;
1177 pars[i]._jsobject = NULL;
break;
1179 pars[i].itype =
'0';
1184void convert_duk_to_fwvals(duk_context *ctx,
int nargs,
int istack,
struct ArgListType arglist, FWval *args,
int *argc){
1212 convert_duk_to_fwvals_new(ctx,nargs,istack,arglist,args,argc);
1216int cfwconstructor(duk_context *ctx) {
1217 int i, j, rc, nargs, argc, ifound;
1221 int *valueChanged = NULL;
1223 nargs = duk_get_top(ctx);
1227 duk_push_current_function(ctx);
1228 rc = duk_get_prop_string(ctx,-1,
"fwItype");
1229 if(rc == 1) itype = duk_to_int(ctx,-1);
1235 if(itype < 0)
return 0;
1236 fwt = getFWTYPE(itype);
1237 if(!fwt->Constructor)
return 0;
1242 while(fwt->ConstructorArgs[i].nfixedArg > -1){
1243 int nfixed = fwt->ConstructorArgs[i].nfixedArg;
1244 int ivarsa = fwt->ConstructorArgs[i].iVarArgStartsAt;
1245 char *neededTypes = fwt->ConstructorArgs[i].argtypes;
1246 int fill = fwt->ConstructorArgs[i].fillMissingFixedWithZero ==
'T';
1247 if( nargs == nfixed || (ivarsa > -1 && nargs >= nfixed ) || (ivarsa > -1 && fill)){
1251 for(j=0;j<nargs;j++){
1253 int isOK, RHS_duk_type = duk_get_type(ctx, j);
1255 neededType = j >= nfixed ? neededTypes[ivarsa] : neededTypes[j];
1258 switch(RHS_duk_type){
1259 case DUK_TYPE_NUMBER:
1260 if(neededType ==
'F' || neededType ==
'D' || neededType ==
'I') isOK = TRUE;
1262 case DUK_TYPE_BOOLEAN:
1263 if(neededType ==
'B') isOK = TRUE;
1265 case DUK_TYPE_STRING:
1266 if(neededType ==
'S' || neededType ==
'Z') isOK = TRUE;
1268 case DUK_TYPE_OBJECT:
1269 if(neededType ==
'W' || neededType ==
'P'){
1270 int rc, itypeRHS = -1;
1271 union anyVrml *fieldRHS = NULL;
1272 rc = duk_get_prop_string(ctx,j,
"fwItype");
1275 itypeRHS = duk_to_int(ctx,-1);
1278 rc = duk_get_prop_string(ctx,j,
"fwField");
1279 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
1283 if(fieldRHS != NULL && itypeRHS > -1){
1294 case DUK_TYPE_UNDEFINED:
1297 case DUK_TYPE_POINTER:
1303 allOK = allOK && isOK;
1306 for(j=nargs;j<nfixed;j++){
1329 convert_duk_to_fwvals(ctx, nargs, 0, fwt->ConstructorArgs[i], &args, &argc);
1330 if(fwt->ConstructorArgs[ifound].fillMissingFixedWithZero ==
'T' && nargs < fwt->ConstructorArgs[ifound].nfixedArg){
1331 int nfixed = fwt->ConstructorArgs[ifound].nfixedArg;
1333 char *neededTypes = fwt->ConstructorArgs[ifound].argtypes;
1335 args = realloc(args,nfixed *
sizeof(
struct FWVAL));
1336 for(j=nargs;j<nfixed;j++){
1337 switch(neededTypes[j]){
1339 args[j]._boolean = FALSE;
break;
1341 args[j]._integer = 0;
break;
1343 args[j]._numeric = 0.0;
break;
1345 args[j]._numeric = 0.0;
break;
1347 args[j]._string =
"";
break;
1356 fwpointer = fwt->Constructor(fwt,argc,args);
1358 push_typed_proxy(ctx,itype, fwpointer, valueChanged);
1362int chas(duk_context *ctx) {
1363 int rc, itype, *valueChanged;
1366 char type, readOnly;
1372 rc = duk_get_prop_string(ctx,0,
"fwItype");
1373 if(rc==1) itype = duk_get_int(ctx,-1);
1376 rc = duk_get_prop_string(ctx,0,
"fwField");
1377 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1380 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1381 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1383 key = duk_require_string(ctx,-1);
1387 fwt = getFWTYPE(itype);
1388 if(fwhas_generic(fwt,parent,
key,&index,&type,&readOnly)){
1391 duk_push_false(ctx);
1398int cownKeys(duk_context *ctx) {
1399 int rc, itype, *valueChanged, arr_idx;
1400 void *parent = NULL;
1402 const char *fieldname;
1403 int lastProp, jndex;
1404 char type, readOnly;
1410 rc = duk_get_prop_string(ctx,0,
"fwItype");
1411 if(rc==1) itype = duk_get_int(ctx,-1);
1414 rc = duk_get_prop_string(ctx,0,
"fwField");
1415 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1418 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1419 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1422 arr_idx = duk_push_array(ctx);
1423 if(itype < 0 || (itype < AUXTYPE_X3DConstants && parent == NULL))
1426 fwt = getFWTYPE(itype);
1428 while( (i = fwiterator_generic(i,fwt,parent,&fieldname,&lastProp,&jndex,&type,&readOnly)) > -1 ){
1429 duk_push_string(ctx, fieldname);
1430 duk_put_prop_index(ctx, arr_idx, i);
1435int cenumerate(duk_context *ctx) {
1436 int rc, itype, *valueChanged;
1439 const char *fieldname;
1440 int lastProp, jndex;
1441 char type, readOnly;
1447 rc = duk_get_prop_string(ctx,0,
"fwItype");
1448 if(rc==1) itype = duk_get_int(ctx,-1);
1451 rc = duk_get_prop_string(ctx,0,
"fwField");
1452 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1455 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1456 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1459 arr_idx = duk_push_array(ctx);
1461 fwt = getFWTYPE(itype);
1463 while( (i = fwiterator_generic(i,fwt,parent,&fieldname,&lastProp,&jndex,&type,&readOnly)) > -1 ){
1465 duk_push_string(ctx, fieldname);
1466 duk_put_prop_index(ctx, arr_idx, i);
1472int push_duk_fieldvalueECMA(duk_context *ctx,
int itype,
union anyVrml *fieldvalue)
1484 case FIELDTYPE_SFBool:
1485 duk_push_boolean(ctx,fieldvalue->sfbool);
break;
1486 case FIELDTYPE_SFFloat:
1487 duk_push_number(ctx,fieldvalue->sffloat);
break;
1488 case FIELDTYPE_SFTime:
1489 duk_push_number(ctx,fieldvalue->sftime);
break;
1490 case FIELDTYPE_SFDouble:
1491 duk_push_number(ctx,fieldvalue->sfdouble);
break;
1492 case FIELDTYPE_SFInt32:
1493 duk_push_int(ctx,fieldvalue->sfint32);
break;
1494 case FIELDTYPE_SFString:
1495 duk_push_string(ctx,fieldvalue->sfstring->strptr);
break;
1504static int SCALARS_ARE_PRIMITIVES = TRUE;
1520int fwval_duk_push(duk_context *ctx, FWval fwretval,
int *valueChanged){
1523 switch(fwretval->itype){
1526 duk_push_boolean(ctx,fwretval->_boolean);
break;
1528 duk_push_int(ctx,fwretval->_integer);
break;
1530 duk_push_number(ctx,fwretval->_numeric);
break;
1532 duk_push_number(ctx,fwretval->_numeric);
break;
1534 duk_push_string(ctx,fwretval->_string);
break;
1537 if(SCALARS_ARE_PRIMITIVES){
1539 switch(fwretval->_web3dval.fieldType){
1540 case FIELDTYPE_SFBool:
1541 duk_push_boolean(ctx,fwretval->_web3dval.anyvrml->sfbool);
break;
1542 case FIELDTYPE_SFInt32:
1543 duk_push_int(ctx,fwretval->_web3dval.anyvrml->sfint32);
break;
1544 case FIELDTYPE_SFFloat:
1545 duk_push_number(ctx,(
double)fwretval->_web3dval.anyvrml->sffloat);
break;
1546 case FIELDTYPE_SFDouble:
1547 case FIELDTYPE_SFTime:
1548 duk_push_number(ctx,fwretval->_web3dval.anyvrml->sfdouble);
break;
1549 case FIELDTYPE_SFString:
1550 if(fwretval->_web3dval.anyvrml->sfstring && fwretval->_web3dval.anyvrml->sfstring->strptr)
1551 duk_push_string(ctx,fwretval->_web3dval.anyvrml->sfstring->strptr);
1553 duk_push_string(ctx,
"");
1556 push_typed_proxy2(ctx,fwretval->_web3dval.fieldType,fwretval->_web3dval.kind,fwretval->_web3dval.native,valueChanged,fwretval->_web3dval.gc);
1560 push_typed_proxy2(ctx,fwretval->_web3dval.fieldType,fwretval->_web3dval.kind,fwretval->_web3dval.native,valueChanged,fwretval->_web3dval.gc);
1564 duk_push_pointer(ctx,fwretval->_jsobject);
1568 push_typed_proxy2(ctx,fwretval->_pointer.fieldType,fwretval->_pointer.kind,fwretval->_pointer.native,valueChanged,fwretval->_pointer.gc);
1579int ctypefunction(duk_context *ctx) {
1580 int rc, nr, itype, kind, nargs;
1581 const char *fwFunc = NULL;
1587 nargs = duk_get_top(ctx);
1589 duk_push_current_function(ctx);
1591 rc = duk_get_prop_string(ctx,-1,
"fwItype");
1592 if(rc==1) itype = duk_get_int(ctx,-1);
1595 rc = duk_get_prop_string(ctx,-1,
"fwKind");
1596 if(rc==1) kind = duk_get_int(ctx,-1);
1599 rc = duk_get_prop_string(ctx,-1,
"fwFunc");
1600 if(rc == 1) fwFunc = duk_to_string(ctx,-1);
1604 if(!strcasecmp(fwFunc,
"getType")){
1605 duk_push_int(ctx,itype);
1608 if(!strcmp(fwFunc,
"isReadable")){
1609 int isreadable = TRUE;
1611 isreadable = isreadable && (kind == PKW_inputOutput || kind == PKW_initializeOnly);
1612 if(isreadable) duk_push_true(ctx);
1613 else duk_push_false(ctx);
1616 if(!strcmp(fwFunc,
"isWritable")){
1617 int iswritable = TRUE;
1619 iswritable = iswritable && (kind == PKW_inputOutput || kind == PKW_outputOnly);
1620 if(iswritable) duk_push_true(ctx);
1621 else duk_push_false(ctx);
1626int cfunction(duk_context *ctx) {
1627 int rc, nr, itype, nargs, *valueChanged = NULL;
1628 const char *fwFunc = NULL;
1635 nargs = duk_get_top(ctx);
1637 duk_push_current_function(ctx);
1639 rc = duk_get_prop_string(ctx,-1,
"fwItype");
1640 if(rc==1) itype = duk_get_int(ctx,-1);
1643 rc = duk_get_prop_string(ctx,-1,
"fwField");
1644 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1647 rc = duk_get_prop_string(ctx,-1,
"fwChanged");
1648 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1651 rc = duk_get_prop_string(ctx,-1,
"fwFunc");
1652 if(rc == 1) fwFunc = duk_to_string(ctx,-1);
1658 fwt = getFWTYPE(itype);
1660 fs = getFWFunc(fwt,fwFunc);
1664 struct FWVAL fwretval;
1667 convert_duk_to_fwvals(ctx, nargs, 0, fs->arglist, &pars, &argc);
1671 duk_eval_string(ctx,
"__script");
1672 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
1675 ec = (
void *)scriptnode->_executionContext;
1677 nr = fs->call(fwt,ec,parent,argc,pars,&fwretval);
1679 nr = fwval_duk_push(ctx,&fwretval,valueChanged);
1680 if(nr && !strcasecmp(fwFunc,
"toString")){
1681 if(fwretval.itype ==
'S' && fwretval._string){
1687 if(valueChanged) *valueChanged = TRUE;
1693int cget(duk_context *ctx) {
1694 int rc, nr, itype, kind, *valueChanged = NULL;
1702 rc = duk_get_prop_string(ctx,0,
"fwItype");
1703 if(rc==1) itype = duk_get_int(ctx,-1);
1706 rc = duk_get_prop_string(ctx,0,
"fwKind");
1707 if(rc==1) kind = 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);
1721 switch(duk_get_type(ctx,-2)){
1722 case DUK_TYPE_NUMBER:{
1728 const char *
key = duk_require_string(ctx,-2);
1730 if(!strcmp(
key,
"fwItype")){
1732 duk_push_int(ctx,itype);
1736 if(!strcmp(
key,
"fwGC")){
1739 duk_push_boolean(ctx,FALSE);
1743 if(!strcmp(
key,
"fwField")){
1745 duk_push_pointer(ctx,parent);
1749 if(!strcasecmp(
key,
"getType") || !strcmp(
key,
"isReadable") || !strcmp(
key,
"isWritable")){
1751 duk_push_c_function(ctx,ctypefunction,DUK_VARARGS);
1752 duk_push_int(ctx,itype);
1753 duk_put_prop_string(ctx,-2,
"fwItype");
1754 duk_push_int(ctx,kind);
1755 duk_put_prop_string(ctx,-2,
"fwKind");
1756 duk_push_string(ctx,
key);
1757 duk_put_prop_string(ctx,-2,
"fwFunc");
1768 const char *
key = NULL;
1769 FWType fwt = getFWTYPE(itype);
1771 char type, readOnly;
1775 if(duk_is_number(ctx,-2)){
1777 int index = duk_get_int(ctx,-2);
1778 if(fwt->takesIndexer){
1779 type = fwt->takesIndexer;
1780 readOnly = fwt->indexerReadOnly;
1787 index = fwiterator_generic(index -1,fwt,parent,&name,&lastProp,&jndex,&type,&readOnly);
1788 if(index > -1) found = 1;
1793 key = duk_get_string(ctx,-2);
1794 found = fwhas_generic(fwt,parent,
key,&jndex,&type,&readOnly);
1795 if(!found && strcmp(
key,
"valueOf")){
1797 static int once = 0;
1799 ConsoleMessage(
"type %s has no property or function %s - please check your typing\n",fwt->name,
key);
1803 if(found && type==
'f'){
1807 duk_push_c_function(ctx,cfunction,DUK_VARARGS);
1808 duk_push_pointer(ctx,parent);
1809 duk_put_prop_string(ctx,-2,
"fwField");
1810 duk_push_pointer(ctx,valueChanged);
1811 duk_put_prop_string(ctx,-2,
"fwChanged");
1812 duk_push_int(ctx,itype);
1813 duk_put_prop_string(ctx,-2,
"fwItype");
1814 duk_push_string(ctx,
key);
1815 duk_put_prop_string(ctx,-2,
"fwFunc");
1818 }
else if(found && fwt->Getter){
1819 struct FWVAL fwretval;
1823 duk_eval_string(ctx,
"__script");
1824 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
1827 ec = (
void *)scriptnode->_executionContext;
1830 nr = fwt->Getter(fwt,jndex,ec,parent,&fwretval);
1832 nr = fwval_duk_push(ctx,&fwretval,valueChanged);
1838int cset(duk_context *ctx) {
1839 int rc, itype, *valueChanged = NULL;
1843 rc = duk_get_prop_string(ctx,0,
"fwItype");
1844 if(rc==1) itype = duk_get_int(ctx,-1);
1847 rc = duk_get_prop_string(ctx,0,
"fwField");
1848 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1851 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1852 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1856 switch(duk_get_type(ctx,-3)){
1857 case DUK_TYPE_NUMBER:{
1868 switch(duk_get_type(ctx,-2)){
1869 case DUK_TYPE_NUMBER:{
1870 int ival = duk_get_int(ctx,-2);
1874 case DUK_TYPE_STRING:{
1875 const char *cval = duk_get_string(ctx,-2);
1888 FWType fwt = getFWTYPE(itype);
1890 char type, readOnly;
1892 if(duk_is_number(ctx,-3) && fwt->takesIndexer){
1894 jndex = duk_get_int(ctx,-3);
1895 type = fwt->takesIndexer;
1896 readOnly = fwt->indexerReadOnly;
1901 key = duk_get_string(ctx,-3);
1902 found = fwhas_generic(fwt,parent,
key,&jndex,&type,&readOnly) && (type !=
'f');
1904 if(found && (readOnly !=
'T') && fwt->Setter){
1905 FWval fwsetval = NULL;
1908 arglist.argtypes = &type;
1909 arglist.fillMissingFixedWithZero = 0;
1910 arglist.nfixedArg = 1;
1911 arglist.iVarArgStartsAt = -1;
1912 convert_duk_to_fwvals(ctx, 1, -2, arglist, &fwsetval, &argc);
1917 duk_eval_string(ctx,
"__script");
1918 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
1921 ec = (
void *)scriptnode->_executionContext;
1924 fwt->Setter(fwt,jndex,ec,parent,fwsetval);
1926 (*valueChanged) = 1;
1933int cdel(duk_context *ctx) {
1934 int rc, itype, *valueChanged;
1938 rc = duk_get_prop_string(ctx,0,
"fwItype");
1939 if(rc==1) itype = duk_get_int(ctx,-1);
1943 rc = duk_get_prop_string(ctx,0,
"fwField");
1944 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1947 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1948 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1951 show_stack(ctx,
"in cdel");
1957void addHandler(duk_context *ctx){
1958 int iglobal, ihandler;
1959 iglobal = duk_get_top(ctx) -1;
1961 duk_push_object(ctx);
1962 duk_put_prop_string(ctx, iglobal,
"handler");
1964 duk_get_prop_string(ctx,iglobal,
"handler");
1965 ihandler = duk_get_top(ctx) -1;
1966 duk_push_c_function(ctx,chas,2);
1967 duk_put_prop_string(ctx, ihandler,
"has");
1968 duk_push_c_function(ctx,cownKeys,1);
1969 duk_put_prop_string(ctx, ihandler,
"ownKeys");
1970 duk_push_c_function(ctx,cenumerate,1);
1971 duk_put_prop_string(ctx, ihandler,
"enumerate");
1972 duk_push_c_function(ctx,cget,3);
1973 duk_put_prop_string(ctx, ihandler,
"get");
1974 duk_push_c_function(ctx,cset,4);
1975 duk_put_prop_string(ctx, ihandler,
"set");
1976 duk_push_c_function(ctx,cdel,2);
1977 duk_put_prop_string(ctx, ihandler,
"del");
1981void addCustomProxyType(duk_context *ctx,
int iglobal,
const char *typeName)
1984 duk_push_c_function(ctx,cfwconstructor,DUK_VARARGS);
1986 itype = fwType2itype(typeName);
1987 duk_push_int(ctx,itype);
1988 duk_put_prop_string(ctx,-2,
"fwItype");
1990 duk_put_prop_string(ctx,iglobal,typeName);
1992void add_duk_global_property(duk_context *ctx,
int itype,
const char *fieldname,
int *valueChanged,
struct X3D_Node *node);
1997static char *eval_string_defineAccessor =
"\
1998function defineAccessor(obj, key, set, get) { \
1999 Object.defineProperty(obj, key, { \
2000 enumerable: true, configurable: true, \
2001 set: set, get: get \
2009void duk_JSCreateScriptContext(
int num) {
2020 ScriptControl = getScriptControlIndex(num);
2021 script = ScriptControl->script;
2022 scriptnode = script->ShaderScriptNode;
2024 ctx = duk_create_heap_default();
2027 duk_push_global_object(ctx);
2028 iglobal = duk_get_top(ctx) -1;
2031 ScriptControl->cx = ctx;
2034 ((
int *)&ScriptControl->glob)[0] = iglobal;
2037 duk_push_pointer(ctx,scriptnode);
2038 duk_put_prop_string(ctx,iglobal,
"__script");
2040 duk_push_string(ctx,eval_string_defineAccessor);
2049 for(i=0;i<FWTYPES_COUNT;i++)
2050 if(fwtypesArray[i]->Constructor)
2051 addCustomProxyType(ctx,iglobal,fwtypesArray[i]->name);
2054 add_duk_global_property(ctx, AUXTYPE_X3DBrowser,
"Browser", NULL, NULL);
2055 add_duk_global_property(ctx, AUXTYPE_X3DConstants,
"X3DConstants", NULL, NULL);
2057 duk_eval_string(ctx,DefaultScriptMethodsA);
2059 duk_eval_string(ctx,DefaultScriptMethodsB);
2063 CRoutes_js_new (num, JAVASCRIPT);
2071 duk_eval_string(ctx,
"__script");
2072 scriptnode = duk_to_pointer(ctx,-1);
2074 snode = (
struct X3D_Node *)scriptnode;
2078 duk_eval_string(ctx,
"print(Object.keys(Browser));");
2080 duk_eval_string(ctx,
"print(Object.getOwnPropertyNames(Browser));");
2082 duk_eval_string(ctx,
"for (k in Browser) {print(k);}");
2084 duk_eval_string(ctx,
"if('println' in Browser) print('have println'); else print('no println');");
2086 duk_eval_string(ctx,
"print('X3DConstants.outputOnly='); print(X3DConstants.outputOnly);");
2088 duk_eval_string(ctx,
"print(Object.keys(X3DConstants));");
2092 duk_eval_string(ctx,
"Browser.println('hi from brwsr.println');");
2094 duk_eval_string(ctx,
"Browser.description = 'funny description happened on the way to ..';");
2096 duk_eval_string(ctx,
"Browser.println(Browser.description);");
2098 duk_eval_string(ctx,
"print('hi from print');");
2100 duk_eval_string(ctx,
"print(Browser.version);");
2105 duk_eval_string(ctx,
"print('Browser.supportedComponents.length = ');");duk_pop(ctx);
2106 duk_eval_string(ctx,
"print(Browser.supportedComponents.length);"); duk_pop(ctx);
2107 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);
2110 duk_eval_string(ctx,
"var myvec3 = new SFVec3f(1.0,2.0,3.0);");
2112 duk_eval_string(ctx,
"print(myvec3.x.toString());");
2114 duk_eval_string(ctx,
"myvec3.y = 45.0;");
2116 duk_eval_string(ctx,
"print('sb45='+myvec3.y);");
2130int SFNode_Setter0(FWType fwt,
int index,
void *ec,
void * fwn, FWval fwval,
int isCurrentScriptNode);
2131int fwsetterNS(duk_context *ctx) {
2139 int rc, itype, *valueChanged;
2143 nargs = duk_get_top(ctx);
2149 key = duk_require_string(ctx,1);
2155 duk_push_current_function(ctx);
2157 rc = duk_get_prop_string(ctx,-1,
"fwItype");
2158 if(rc==1) itype = duk_get_int(ctx,-1);
2160 if(itype > -1 && itype < AUXTYPE_X3DConstants){
2162 rc = duk_get_prop_string(ctx,-1,
"fwNode");
2163 if(rc==1) parent = duk_to_pointer(ctx,-1);
2166 rc = duk_get_prop_string(ctx,-1,
"fwChanged");
2167 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
2172 if(itype > -1 && itype < AUXTYPE_X3DConstants){
2175 FWType fwt = getFWTYPE(FIELDTYPE_SFNode);
2177 char type, readOnly;
2181 any.sfnode = parent;
2183 found = fwhas_generic(fwt,&any,
key,&jndex,&type,&readOnly) && (type !=
'f');
2185 FWval fwsetval = NULL;
2188 arglist.argtypes = &type;
2189 arglist.fillMissingFixedWithZero = 0;
2190 arglist.nfixedArg = 1;
2191 arglist.iVarArgStartsAt = -1;
2192 convert_duk_to_fwvals(ctx, 1, -2, arglist, &fwsetval, &argc);
2197 duk_eval_string(ctx,
"__script");
2198 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
2201 ec = (
void *)scriptnode->_executionContext;
2204 SFNode_Setter0(fwt,jndex,ec,&any,fwsetval,TRUE);
2214void push_typed_proxy_fwgetter(duk_context *ctx,
int itype,
int mode,
const char* fieldname,
void *fwpointer,
int* valueChanged)
2221 proxy_entry *pe = NULL;
2222 if(itype == FIELDTYPE_SFNode){
2224 printf(
"pushtyped2 nodetype %d\n",node->_nodeType);
2225 pe = lookup_ctx_proxycache_entry_by_nodeptr(ctx, node);
2228 duk_push_heapptr(ctx,pe->jsproxy);
2231 duk_eval_string(ctx,
"Proxy");
2232 duk_push_object(ctx);
2233 duk_push_pointer(ctx,fwpointer);
2234 duk_put_prop_string(ctx,-2,
"fwField");
2235 duk_push_pointer(ctx,valueChanged);
2236 duk_put_prop_string(ctx,-2,
"fwChanged");
2237 duk_push_int(ctx,itype);
2238 duk_put_prop_string(ctx,-2,
"fwItype");
2239 duk_eval_string(ctx,
"handler");
2243 if(doingFinalizer) {
2253 if(itype == FIELDTYPE_SFNode){
2255 void *jsproxy = duk_get_heapptr(ctx, -1);
2256 add_ctx_proxycache_entry(ctx, node, jsproxy);
2258 duk_eval_string(ctx,
"Duktape.fin");
2260 duk_push_c_function(ctx,cfinalizer,1);
2269int push_duk_fieldvalue(duk_context *ctx,
int itype,
int mode,
const char* fieldname,
union anyVrml *field,
int *valueChanged)
2283 case FIELDTYPE_SFBool:
2284 duk_push_boolean(ctx,field->sfbool);
break;
2285 case FIELDTYPE_SFFloat:
2286 duk_push_number(ctx,field->sffloat);
break;
2287 case FIELDTYPE_SFTime:
2288 duk_push_number(ctx,field->sftime);
break;
2289 case FIELDTYPE_SFDouble:
2290 duk_push_number(ctx,field->sfdouble);
break;
2291 case FIELDTYPE_SFInt32:
2292 duk_push_int(ctx,field->sfint32);
break;
2293 case FIELDTYPE_SFString:
2294 duk_push_string(ctx,field->sfstring->strptr);
break;
2298 if(itype == FIELDTYPE_SFNode){
2307 (memcpy(&anode,field,
sizeof(
void *)));
2308 printf(
"anode._nodeType=%d ",anode->_nodeType);
2309 printf(
"anyvrml.sfnode._nodetype=%d\n",field->sfnode->_nodeType);
2310 anode = field->sfnode;
2311 printf(
"anode = anyvrml.sfnode ._nodetype=%d\n",anode->_nodeType);
2315 push_typed_proxy_fwgetter(ctx, itype, mode, fieldname, field, valueChanged);
2324int fwgetter0(duk_context *ctx,
void *parent,
int itype,
const char *
key,
int *valueChanged){
2326 FWType fwt = getFWTYPE(itype);
2327 int jndex, found, nr;
2328 char type, readOnly;
2331 found = fwhas_generic(fwt,parent,
key,&jndex,&type,&readOnly);
2332 if(found && fwt->Getter){
2333 struct FWVAL fwretval;
2337 duk_eval_string(ctx,
"__script");
2338 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
2341 ec = (
void *)scriptnode->_executionContext;
2344 nr = fwt->Getter(fwt,jndex,ec,parent,&fwretval);
2346 nr = fwval_duk_push(ctx,&fwretval,valueChanged);
2351int fwgetterNS(duk_context *ctx) {
2360 int rc, itype, *valueChanged = NULL;
2362 const char *fieldname;
2363 struct X3D_Node *thisScriptNode = NULL;
2366 nargs = duk_get_top(ctx);
2370 fieldname = duk_require_string(ctx,0);
2374 duk_push_current_function(ctx);
2376 rc = duk_get_prop_string(ctx,-1,
"fwItype");
2377 if(rc==1) itype = duk_get_int(ctx,-1);
2379 if(itype < AUXTYPE_X3DConstants){
2381 rc = duk_get_prop_string(ctx,-1,
"fwNode");
2382 if(rc==1) thisScriptNode = duk_to_pointer(ctx,-1);
2385 rc = duk_get_prop_string(ctx,-1,
"fwChanged");
2386 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
2393 if(itype < AUXTYPE_X3DConstants){
2396 any.sfnode = thisScriptNode;
2397 nr = fwgetter0(ctx,&any,FIELDTYPE_SFNode,fieldname,valueChanged);
2400 push_typed_proxy_fwgetter(ctx, itype, PKW_initializeOnly, fieldname, NULL, NULL);
2406void add_duk_global_property(duk_context *ctx,
int itype,
const char *fieldname,
int *valueChanged,
struct X3D_Node *node ){
2410 duk_eval_string(ctx,
"defineAccessor");
2412 duk_eval_string(ctx,
"this");
2414 duk_push_string(ctx,fieldname);
2416 duk_push_c_function(ctx,fwsetterNS,2);
2417 if(itype < AUXTYPE_X3DConstants){
2418 duk_push_pointer(ctx,valueChanged);
2419 duk_put_prop_string(ctx,-2,
"fwChanged");
2420 duk_push_pointer(ctx,node);
2421 duk_put_prop_string(ctx,-2,
"fwNode");
2423 duk_push_int(ctx,itype);
2424 duk_put_prop_string(ctx,-2,
"fwItype");
2426 duk_push_c_function(ctx,fwgetterNS,1);
2427 if(itype < AUXTYPE_X3DConstants){
2428 duk_push_pointer(ctx,node);
2429 duk_put_prop_string(ctx,-2,
"fwNode");
2430 duk_push_pointer(ctx,valueChanged);
2431 duk_put_prop_string(ctx,-2,
"fwChanged");
2433 duk_push_int(ctx,itype);
2434 duk_put_prop_string(ctx,-2,
"fwItype");
2440void InitScriptField2(
struct CRscriptStruct *scriptcontrol,
int itype,
int kind,
const char* fieldname,
int *valueChanged,
struct X3D_Node* parent)
2460 ctx = scriptcontrol->cx;
2465 if( kind == PKW_inputOutput){
2468 sprintf(strline,
"_rename_function(this,\"%s\",\"set_%s\");",fieldname,fieldname);
2470 duk_push_string(ctx,strline);
2471 if(duk_peval(ctx) != 0) {
2472 printf(
"Script error: %s\n", duk_safe_to_string(ctx, -1));
2473 printf(
"rename didn't work\n");
2479 add_duk_global_property(ctx,itype,fieldname, valueChanged,parent);
2484void duk_JSInitializeScriptAndFields (
int num) {
2491 int i,nfields, kind, itype;
2492 const char *fieldname;
2495 scriptcontrol = getScriptControlIndex(num);
2498 if(1)
if (!jsActualrunScript(num, scriptcontrol->scriptText)) {
2499 ConsoleMessage (
"JSInitializeScriptAndFields, script failure\n");
2500 scriptcontrol->scriptOK = FALSE;
2501 scriptcontrol->_initialized = TRUE;
2507 script = scriptcontrol->script;
2509 nfields = Shader_Script_getScriptFieldCount(script);
2510 for(i=0;i<nfields;i++){
2511 field = Shader_Script_getScriptField(script,i);
2512 fieldname = ScriptFieldDecl_getName(field);
2513 kind = ScriptFieldDecl_getMode(field);
2514 itype = ScriptFieldDecl_getType(field);
2515 if (kind != PKW_inputOnly) {
2517 field->valueChanged = 0;
2518 InitScriptField2(scriptcontrol, itype, kind, fieldname, &field->valueChanged, script->ShaderScriptNode);
2522 if(0)
if (!jsActualrunScript(num, scriptcontrol->scriptText)) {
2523 ConsoleMessage (
"JSInitializeScriptAndFields, script failure\n");
2524 scriptcontrol->scriptOK = FALSE;
2525 scriptcontrol->_initialized = TRUE;
2528 FREE_IF_NZ(scriptcontrol->scriptText);
2529 scriptcontrol->_initialized = TRUE;
2530 scriptcontrol->scriptOK = TRUE;
2535int duk_jsActualrunScript(
int num,
char *script){
2542 ScriptControl = getScriptControlIndex(num);
2544 ctx = (duk_context *)ScriptControl->cx;
2546 iglobal = ((
int *)&ScriptControl->glob)[0];
2550 len = (int) strlen(script);
2555 duk_eval_string(ctx, script);
2557 printf (
"ActualrunScript - JS_EvaluateScript failed for %s", script);
2559 ConsoleMessage (
"ActualrunScript - JS_EvaluateScript failed for %s", script);
2565 duk_push_string(ctx, script);
2566 if (duk_peval(ctx) != 0) {
2567 ConsoleMessage(
"eval failed: %s\n", duk_safe_to_string(ctx, -1));
2570 printf(
"result is: %s\n", duk_safe_to_string(ctx, -1));
2578void duk_SaveScriptField (
int num, indexT kind, indexT type,
const char* field,
union anyVrml value){
2581static int duk_once = 0;
2582void duk_process_eventsProcessed(){
2595 p = (ppJScript_duk)tg->JScript_duk.prv;
2596 for (counter = 0; counter <= tg->CRoutes.max_script_found_and_initialized; counter++) {
2597 scriptcontrol = getScriptControlIndex(counter);
2603 ctx = scriptcontrol->cx;
2604 if(scriptcontrol->thisScriptType != NOSCRIPT && ctx){
2605 duk_eval_string(ctx,
"eventsProcessed");
2607 duk_push_number(ctx,TickTime());
2608 rc = duk_pcall(ctx, 1);
2609 if (rc != DUK_EXEC_SUCCESS) {
2610 printf(
"error: '%s' happened in js function %s called from process_eventsProcessed\n", duk_to_string(ctx, -1),
"eventsProcessed");
2619void duk_js_cleanup_script_context(
int counter){
2623void duk_js_setField_javascriptEventOut_B(
union anyVrml* any,
int fieldType,
unsigned len,
int extraData,
int actualscript){
2631void duk_setField_javascriptEventOut(
struct X3D_Node *tn,
unsigned int tptr,
int fieldType,
unsigned len,
int extraData) {
2638 ttglobal tg = gglobal();
2641 memptr = offsetPointer_deref(
char *, tn, tptr);
2643 fromptr = tg->JScript_duk.JSglobal_return_val;
2645 medium_copy_field0(fieldType,fromptr,memptr);
2648void duk_js_setField_javascriptEventOut(
struct X3D_Node *tn,
unsigned int tptr,
int fieldType,
unsigned len,
int extraData,
int actualscript) {
2651 scriptcontrol = getScriptControlIndex(actualscript);
2652 duk_setField_javascriptEventOut(tn,tptr,fieldType, len, extraData);
2658void duk_set_one_ECMAtype (
int tonode,
int toname,
int dataType,
void *Data,
int datalen) {
2659 char scriptline[100];
2668 #ifdef SETFIELDVERBOSE
2669 printf (
"set_one_ECMAtype, to %d namepointer %d, fieldname %s, datatype %d length %d\n",
2670 tonode,toname,JSparamnames[toname].name,dataType,datalen);
2674 ScriptControl = getScriptControlIndex(tonode);
2675 ctx = (duk_context *)ScriptControl->cx;
2679 obj = ((
int*)&ScriptControl->glob)[0];
2684 if(JSparamnames[toname].kind == PKW_inputOutput)
2685 strcat(scriptline,
"set_");
2686 strcat(scriptline,JSparamnames[toname].name);
2688 duk_push_string(ctx,scriptline);
2689 if(duk_peval(ctx) != 0){
2690 printf(
"Script error: %s\n", duk_safe_to_string(ctx, -1));
2691 printf(
"ouch - no function named %s\n",scriptline);
2701 fwval._web3dval.native = Data;
2702 fwval._web3dval.fieldType = dataType;
2703 fwval._web3dval.gc = 0;
2705 rc = fwval_duk_push(ctx, &fwval, NULL);
2709 duk_push_number(ctx,TickTime());
2711 rc = duk_pcall(ctx, 2);
2712 if (rc != DUK_EXEC_SUCCESS) {
2713 printf(
"Script error: %s\n", duk_safe_to_string(ctx, -1));
2714 printf(
"error: '%s' happened in js function %s called from set_one_ECMAType\n", duk_to_string(ctx, -1),JSparamnames[toname].name);
2732void duk_setScriptECMAtype (
int num) {
2737 CRnodeStruct *to_ptr = NULL;
2738 struct CRStruct *CRoutes = getCRoutes();
2741 fn = offsetPointer_deref(
void *, CRoutes[num].routeFromNode, CRoutes[num].fnptr);
2742 len = CRoutes[num].len;
2744 for (to_counter = 0; to_counter < CRoutes[num].tonode_count; to_counter++) {
2747 to_ptr = &(CRoutes[num].tonodes[to_counter]);
2748 myObj = X3D_SCRIPT(to_ptr->routeToNode)->__scriptObj;
2750 tptr = to_ptr->foffset;
2751 set_one_ECMAtype (myObj->num, tptr, JSparamnames[tptr].type, fn,len);
2755void duk_set_one_MultiElementType (
int tonode,
int tnfield,
void *Data,
int dataLen){
2769 ScriptControl = getScriptControlIndex(tonode);
2771 ctx = (duk_context *)ScriptControl->cx;
2774 obj = ((
int*)&ScriptControl->glob)[0];
2780 char scriptline[100];
2782 if(JSparamnames[tnfield].kind == PKW_inputOutput)
2783 strcat(scriptline,
"set_");
2784 strcat(scriptline,JSparamnames[tnfield].name);
2786 duk_push_string(ctx,scriptline);
2788 if(duk_peval(ctx) != 0){
2789 ConsoleMessage(
"couldn't find eventin function %s\n",scriptline);
2794 isEventin = duk_is_ecmascript_function(ctx, -1);
2798 itype = JSparamnames[tnfield].type;
2801 medium_copy_field(itype,Data,&datacopy);
2802 push_typed_proxy2(ctx,itype,PKW_inputOutput,datacopy,NULL,
'T');
2803 duk_push_number(ctx,TickTime());
2805 rc = duk_pcall(ctx, 2);
2806 if (rc != DUK_EXEC_SUCCESS) {
2807 printf(
"error: '%s' happened in js function %s called from set_one_Multi_ElementType\n", duk_to_string(ctx, -1),JSparamnames[tnfield].name);
2815void duk_set_one_MFElementType(
int tonode,
int toname,
int dataType,
void *Data,
int datalen){
2823 int itype, isEventin;
2825 void *datacopy = NULL;
2832 ScriptControl = getScriptControlIndex(tonode);
2834 ctx = (duk_context *)ScriptControl->cx;
2837 obj = ((
int*)&ScriptControl->glob)[0];
2842 char scriptline[100];
2844 if(JSparamnames[toname].kind == PKW_inputOutput)
2845 strcat(scriptline,
"set_");
2847 strcat(scriptline,JSparamnames[toname].name);
2848 duk_push_string(ctx,scriptline);
2850 if(duk_peval(ctx) != 0){
2851 ConsoleMessage(
"couldn't find eventin function %s\n",scriptline);
2856 isEventin = duk_is_ecmascript_function(ctx, -1);
2862 source = (
char *)&maData;
2863 any = (
void*)source;
2865 medium_copy_field(itype,source,&datacopy);
2867 push_typed_proxy2(ctx,itype,PKW_inputOutput,datacopy,NULL,
'T');
2868 duk_push_number(ctx,TickTime());
2875int duk_jsIsRunning(){
2879void duk_JSDeleteScriptContext(
int num){
2882 ScriptControl = getScriptControlIndex(num);
2883 duk_destroy_heap(ScriptControl->cx);
2886void duk_jsShutdown(){
2890void duk_jsClearScriptControlEntries(
int num){
2955int isScriptControlOK(
int actualscript);
2956int isScriptControlInitialized(
int actualscript);
2957void getField_ToJavascript_B(
int shader_num,
int fieldOffset,
int type,
union anyVrml *any,
int len);
2958int duk_runQueuedDirectOutputs()
2990 ttglobal tg = gglobal();
2993 int i,num,kind, itype;
2994 const char *fieldname;
2995 static int doneOnce = 0;
3002 printf(
"javascript engine duktape version %ld\n", DUK_VERSION);
3006 for(num=0;num< tg->CRoutes.max_script_found_and_initialized;num++){
3007 scriptcontrol = getScriptControlIndex(num);
3010 script = scriptcontrol->script;
3011 if(scriptcontrol->thisScriptType != NOSCRIPT && script){
3012 if(isScriptControlInitialized(script->num) && isScriptControlOK(script->num)){
3013 int nfields = Shader_Script_getScriptFieldCount(script);
3014 for(i=0;i<nfields;i++){
3015 field = Shader_Script_getScriptField(script,i);
3016 fieldname = ScriptFieldDecl_getName(field);
3017 kind = ScriptFieldDecl_getMode(field);
3018 itype = ScriptFieldDecl_getType(field);
3019 if(field->eventInSet){
3020 if( (kind == PKW_inputOnly || kind == PKW_inputOutput)){
3021 int isMF, sftype, len, isize;
3022 int JSparamNameIndex = field->fieldDecl->JSparamNameIndex;
3023 mark_script(script->num);
3026 sftype = itype - isMF;
3028 isize = returnElementLength(sftype) * returnElementRowSize(sftype);
3029 if(isMF) len =
sizeof(int) +
sizeof(
void*);
3032 field->eventInSet = FALSE;
3033 getField_ToJavascript_B(script->num, JSparamNameIndex, itype, &field->value, len);
3038 field->eventInSet = FALSE;