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)
62void initVRMLBrowser(
FWType* typeArray,
int *n);
63void initVRMLFields(
FWType* typeArray,
int *n);
65 initVRMLBrowser(fwtypesArray, &FWTYPES_COUNT);
66 initVRMLFields(fwtypesArray, &FWTYPES_COUNT);
68FWType 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++;
118int 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;
160int 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 const char* key2 = &
key[4];
177 while( (index = fwiterator_generic(index,fwt,pointer,&name, &lastProp, jndex, type, readOnly)) > -1){
178 if(!strcasecmp(name,key2)){
189typedef struct pJScript_duk{
194void *JScript_duk_constructor(){
195 void *v = MALLOCV(
sizeof(
struct pJScript_duk));
196 memset(v,0,
sizeof(
struct pJScript_duk));
199void JScript_duk_init(
struct tJScript_duk *t){
201 t->JSglobal_return_val = NULL;
203 t->prv = JScript_duk_constructor();
207 if(!FWTYPES_COUNT) initFWTYPEs();
223int 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:
244struct 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},
268char * itype2string(
int itype){
270 while(lookup_fieldType[i].c){
271 if(lookup_fieldType[i].i == itype)
return lookup_fieldType[i].c;
277int getFieldFromNodeAndName(
struct X3D_Node* node,
const char *fieldname,
int *type,
int *kind,
int *iifield,
union anyVrml **value);
280int duk_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_duk.JSglobal_return_val = (
void *)&field->value;
298 return field->valueChanged;
300 gglobal()->JScript_duk.JSglobal_return_val = NULL;
303void duk_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;
328int 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;
351void freeField(
int itype,
void* any){
352 if(isSForMFType(itype) == 0){
359 }
else if(isSForMFType(itype) == 1){
377unsigned long upper_power_of_two(
unsigned long v);
378void deleteMallocedFieldValue(
int type,
union anyVrml *fieldPtr);
379void 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);
425void 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));
435static char *DefaultScriptMethodsA =
"function initialize() {}; " \
436 " function shutdown() {}; " \
437 " function eventsProcessed() {}; " \
438 " TRUE=true; FALSE=false; " \
442static 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)}; "\
458 " function _rename_function(obj,oldf,newf) {if(typeof obj[oldf] === 'function') {obj[newf]=obj[oldf]; delete obj[oldf];}}; "\
470#include "duktape/duktape.h"
472const char *duk_type_to_string(
int duktype){
473 const char* r = NULL;
475 case DUK_TYPE_NUMBER: r =
"DUK_TYPE_NUMBER";
break;
476 case DUK_TYPE_BOOLEAN: r =
"DUK_TYPE_BOOLEAN";
break;
477 case DUK_TYPE_STRING: r =
"DUK_TYPE_STRING";
break;
478 case DUK_TYPE_OBJECT: r =
"DUK_TYPE_OBJECT";
break;
479 case DUK_TYPE_NONE: r =
"DUK_TYPE_NONE";
break;
480 case DUK_TYPE_UNDEFINED: r =
"DUK_TYPE_UNDEFINED";
break;
481 case DUK_TYPE_NULL: r =
"DUK_TYPE_NULL";
break;
482 case DUK_TYPE_POINTER: r =
"DUK_TYPE_POINTER";
break;
492 int i, itop = duk_get_top(ctx);
493 if(comment) printf(
"%s top=%d\n",comment,itop);
495 printf(
"%10s%10s\n",
"position",
"type");
498 int t = duk_get_type(ctx, ipos);
500 const char * amore =
"";
502 case DUK_TYPE_NUMBER: stype =
"number";
break;
503 case DUK_TYPE_STRING: stype =
"string";
break;
505 case DUK_TYPE_OBJECT: stype =
"object";
break;
506 case DUK_TYPE_NONE: stype =
"none";
break;
507 case DUK_TYPE_UNDEFINED: stype =
"undefined";
break;
508 case DUK_TYPE_BOOLEAN: stype =
"boolean";
break;
509 case DUK_TYPE_NULL: stype =
"null";
break;
510 case DUK_TYPE_POINTER: stype =
"pointer";
break;
514 if(duk_is_function(ctx,ipos)){
516 afunc = duk_is_c_function(ctx,ipos) ?
"Cfunc" : afunc;
517 afunc = duk_is_ecmascript_function(ctx,ipos) ?
"jsfunc" : afunc;
518 afunc = duk_is_bound_function(ctx,ipos) ?
"boundfunc" : afunc;
521 if(duk_is_nan(ctx,ipos)){
524 if(duk_is_object(ctx,ipos)){
527 printf(
"%10d%10s %s\n",ipos,stype,amore);
552static Stack * proxycaches = NULL;
553typedef struct cache_table_entry {
557typedef struct proxy_cache_entry {
564cache_entry * lookup_ctx_proxy_cache(
duk_context *ctx){
566 cache_entry *ret = NULL;
567 if(proxycaches == NULL){
568 proxycaches = newStack(cache_entry *);
570 for(i=0;i<vectorSize(proxycaches);i++){
571 cache_entry * ce = vector_get(cache_entry*,proxycaches,i);
578 cache_entry *ce = MALLOC(cache_entry*,
sizeof(cache_entry));
579 stack_push(cache_entry*,proxycaches,ce);
581 ce->cache = newStack(proxy_entry*);
586proxy_entry *lookup_ctx_proxycache_entry_by_nodeptr(
duk_context *ctx,
struct X3D_Node *node){
587 proxy_entry *ret = NULL;
588 cache_entry* cache = lookup_ctx_proxy_cache(ctx);
591 for(i=0;i<vectorSize(cache->cache);i++){
592 proxy_entry *pe = vector_get(proxy_entry*,cache->cache,i);
593 if(pe && pe->node == node){
600proxy_entry *add_ctx_proxycache_entry(
duk_context *ctx,
struct X3D_Node *node,
void *jsproxy){
603 proxy_entry *ret = NULL;
604 cache_entry *cache = lookup_ctx_proxy_cache(ctx);
607 proxy_entry *pe = MALLOC(proxy_entry*,
sizeof(proxy_entry));
609 pe->jsproxy = jsproxy;
612 for(i=0;i<vectorSize(cache->cache);i++){
613 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
616 vector_set(proxy_entry*,cache->cache,i,pe);
622 stack_push(proxy_entry*,cache->cache,pe);
626 printf(
"cache after add proxy\n");
627 for(i=0;i<vectorSize(cache->cache);i++){
628 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
630 printf(
"%d %p %p\n",i,pe0->node,pe0->jsproxy);
632 printf(
"%d NULL\n",i);
641 proxy_entry *ret = NULL;
642 cache_entry *cache = lookup_ctx_proxy_cache(ctx);
645 for(i=0;i<vectorSize(cache->cache);i++){
646 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
647 if(pe0 && pe0->node == node){
648 vector_set(proxy_entry*,cache->cache,i,NULL);
654 printf(
"after cache clean\n");
655 for(i=0;i<vectorSize(cache->cache);i++){
656 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
658 printf(
"%d %p %p\n",i,pe0->node,pe0->jsproxy);
660 printf(
"%d NULL\n",i);
665void remove_ctx_proxycache_entry_by_jsproxy(
duk_context *ctx,
void *jsproxy){
667 proxy_entry *ret = NULL;
668 cache_entry *cache = lookup_ctx_proxy_cache(ctx);
671 for(i=0;i<vectorSize(cache->cache);i++){
672 proxy_entry *pe0 = vector_get(proxy_entry*,cache->cache,i);
673 if(pe0 && pe0->jsproxy == jsproxy){
674 vector_set(proxy_entry*,cache->cache,i,NULL);
685 void *fwpointer = NULL;
687 rc = duk_get_prop_string(ctx,0,
"fwItype");
688 if(rc == 1) itype = duk_to_int(ctx,-1);
690 rc = duk_get_prop_string(ctx,0,
"fwGC");
691 if(rc == 1) igc = duk_to_boolean(ctx,-1);
693 rc = duk_get_prop_string(ctx,0,
"fwField");
694 if(rc == 1) fwpointer = duk_to_pointer(ctx,-1);
699 if(itype == FIELDTYPE_SFNode && fwpointer){
706 remove_ctx_proxycache_entry_by_nodeptr(ctx, node);
708 if(igc > 0 && itype > -1 && fwpointer){
709 if(itype < AUXTYPE_X3DConstants){
711 freeField(itype,fwpointer);
720static int doingFinalizer = 1;
721void push_typed_proxy(
duk_context *ctx,
int itype,
void *fwpointer,
int* valueChanged)
725 proxy_entry *pe = NULL;
726 if(itype == FIELDTYPE_SFNode){
729 pe = lookup_ctx_proxycache_entry_by_nodeptr(ctx, node);
732 duk_push_heapptr(ctx, pe->jsproxy);
735 duk_eval_string(ctx,
"Proxy");
737 duk_push_pointer(ctx,fwpointer);
738 duk_put_prop_string(ctx,-2,
"fwField");
739 duk_push_pointer(ctx,valueChanged);
740 duk_put_prop_string(ctx,-2,
"fwChanged");
741 duk_push_int(ctx,itype);
742 duk_put_prop_string(ctx,-2,
"fwItype");
744 duk_push_boolean(ctx,TRUE);
745 duk_put_prop_string(ctx,-2,
"fwGC");
747 duk_eval_string(ctx,
"handler");
763 if(itype == FIELDTYPE_SFNode){
765 void *jsproxy = duk_get_heapptr(ctx, -1);
766 add_ctx_proxycache_entry(ctx, node, jsproxy);
768 duk_eval_string(ctx,
"Duktape.fin");
770 duk_push_c_function(ctx,cfinalizer,1);
777int push_typed_proxy2(
duk_context *ctx,
int itype,
int kind,
void *fwpointer,
int* valueChanged,
char doGC)
783 proxy_entry *pe = NULL;
784 int idogc = doGC ? TRUE : FALSE;
785 if(itype == FIELDTYPE_SFNode){
788 pe = lookup_ctx_proxycache_entry_by_nodeptr(ctx, node);
791 duk_push_heapptr(ctx, pe->jsproxy);
793 duk_eval_string(ctx,
"Proxy");
794 duk_push_object(ctx);
795 duk_push_pointer(ctx,fwpointer);
796 duk_put_prop_string(ctx,-2,
"fwField");
797 duk_push_pointer(ctx,valueChanged);
798 duk_put_prop_string(ctx,-2,
"fwChanged");
799 duk_push_int(ctx,itype);
800 duk_put_prop_string(ctx,-2,
"fwItype");
801 duk_push_int(ctx,kind);
802 duk_put_prop_string(ctx,-2,
"fwKind");
805 duk_push_boolean(ctx,idogc);
806 duk_put_prop_string(ctx,-2,
"fwGC");
809 duk_eval_string(ctx,
"handler");
821 if(itype == FIELDTYPE_SFNode){
823 void *jsproxy = duk_get_heapptr(ctx, -1);
824 add_ctx_proxycache_entry(ctx, node, jsproxy);
827 duk_eval_string(ctx,
"Duktape.fin");
829 duk_push_c_function(ctx,cfinalizer,1);
840 int nUsable,nNeeded, i, ii;
843 nUsable = arglist.iVarArgStartsAt > -1 ? nargs : arglist.nfixedArg;
844 nNeeded = max(nUsable,arglist.nfixedArg);
845 pars = malloc(nNeeded*
sizeof(
struct FWVAL));
849 for(i=0;i<nUsable;i++){
854 if(i < arglist.nfixedArg)
855 ctype = arglist.argtypes[i];
857 ctype = arglist.argtypes[arglist.iVarArgStartsAt];
858 pars[i].itype = ctype;
859 if( duk_is_object(ctx, ii)){
862 rc = duk_get_prop_string(ctx,ii,
"fwItype");
864 isPrimitive = rc == 0;
868 duk_to_primitive(ctx,ii,DUK_HINT_NONE);
872 trhs = duk_get_type(ctx, ii);
891 int bb = duk_get_boolean(ctx,ii);
892 pars[i]._boolean = bb;
895 case 'I': pars[i]._integer = duk_to_int(ctx,ii);
break;
896 case 'F': pars[i]._numeric = duk_to_number(ctx,ii);
break;
897 case 'D': pars[i]._numeric = duk_to_number(ctx,ii);
break;
898 case 'S': pars[i]._string = duk_to_string(ctx,ii);
break;
900 if(duk_is_string(ctx,ii)){
901 pars[i]._string = duk_get_string(ctx,ii);
905 if(!duk_is_object(ctx,i))
909 int rc, isOK, itypeRHS = -1;
910 union anyVrml *fieldRHS = NULL;
911 if(trhs == DUK_TYPE_NULL){
913 fieldRHS = malloc(
sizeof(
union anyVrml));
914 fieldRHS->sfnode = NULL;
915 }
else if(trhs == DUK_TYPE_OBJECT){
916 rc = duk_get_prop_string(ctx,ii,
"fwItype");
918 itypeRHS = duk_to_int(ctx,-1);
921 rc = duk_get_prop_string(ctx,ii,
"fwField");
922 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
931 pars[i]._web3dval.native = fieldRHS;
932 pars[i]._web3dval.fieldType = itypeRHS;
940 int rc, isOK, itypeRHS = -1;
941 union anyVrml *fieldRHS = NULL;
942 rc = duk_get_prop_string(ctx,ii,
"fwItype");
945 itypeRHS = duk_to_int(ctx,-1);
948 rc = duk_get_prop_string(ctx,ii,
"fwField");
949 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
953 if(fieldRHS != NULL && itypeRHS >= AUXTYPE_X3DConstants){
955 pars[i]._pointer.native = fieldRHS;
956 pars[i]._pointer.fieldType = itypeRHS;
968 for(i=nUsable;i<nNeeded;i++){
970 char ctype = arglist.argtypes[i];
971 pars[i].itype = ctype;
973 case 'B': pars[i]._boolean = FALSE;
break;
974 case 'I': pars[i]._integer = 0;
break;
975 case 'F': pars[i]._numeric = 0.0;
break;
976 case 'D': pars[i]._numeric = 0.0;
break;
977 case 'S': pars[i]._string = NULL;
break;
978 case 'Z': pars[i]._string = NULL; pars[i].itype =
'S';
break;
980 pars[i]._web3dval.fieldType = FIELDTYPE_SFNode;
981 pars[i]._web3dval.native = NULL;
break;
986 pars[i]._jsobject = NULL;
break;
994 int nUsable,nNeeded, i, ii, jj, k, len;
1001 for(i=0;i<nargs;i++){
1004 if( duk_is_array(ctx, ii)){
1006 len = duk_get_length(ctx, ii);
1013 nUsable = arglist.iVarArgStartsAt > -1 ? nargs : arglist.nfixedArg;
1014 nNeeded = max(nUsable,arglist.nfixedArg);
1015 pars = malloc(nNeeded*
sizeof(
struct FWVAL));
1020 for(i=0;i<nUsable;){
1025 if( duk_is_array(ctx, ii)){
1027 len = duk_get_length(ctx, ii);
1029 for(k=0;k<len;k++,i++){
1030 if(i < arglist.nfixedArg)
1031 ctype = arglist.argtypes[i];
1033 ctype = arglist.argtypes[arglist.iVarArgStartsAt];
1034 pars[i].itype = ctype;
1036 if( duk_is_array(ctx, ii)){
1037 duk_get_prop_index(ctx, ii, k);
1041 if( duk_is_object(ctx,jj) ){
1042 int rc, isPrimitive;
1044 rc = duk_get_prop_string(ctx,jj,
"fwItype");
1046 isPrimitive = rc == 0;
1050 duk_to_primitive(ctx,jj,DUK_HINT_NONE);
1054 trhs = duk_get_type(ctx, jj);
1073 int bb = duk_get_boolean(ctx,jj);
1074 pars[i]._boolean = bb;
1077 case 'I': pars[i]._integer = duk_to_int(ctx,jj);
break;
1078 case 'F': pars[i]._numeric = duk_to_number(ctx,jj);
break;
1079 case 'D': pars[i]._numeric = duk_to_number(ctx,jj);
break;
1080 case 'S': pars[i]._string = duk_to_string(ctx,jj);
break;
1082 if(duk_is_string(ctx,jj)){
1083 pars[i]._string = duk_get_string(ctx,jj);
1084 pars[i].itype =
'S';
1087 if(!duk_is_object(ctx,jj))
1091 int rc, isOK, itypeRHS = -1;
1092 union anyVrml *fieldRHS = NULL;
1093 if(trhs == DUK_TYPE_NULL){
1095 fieldRHS = malloc(
sizeof(
union anyVrml));
1096 fieldRHS->sfnode = NULL;
1097 }
else if(trhs == DUK_TYPE_OBJECT){
1098 rc = duk_get_prop_string(ctx,jj,
"fwItype");
1100 itypeRHS = duk_to_int(ctx,-1);
1103 rc = duk_get_prop_string(ctx,jj,
"fwField");
1104 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
1113 pars[i]._web3dval.native = fieldRHS;
1114 pars[i]._web3dval.fieldType = itypeRHS;
1115 pars[i].itype =
'W';
1122 int rc, isOK, itypeRHS = -1;
1123 union anyVrml *fieldRHS = NULL;
1124 rc = duk_get_prop_string(ctx,jj,
"fwItype");
1127 itypeRHS = duk_to_int(ctx,-1);
1130 rc = duk_get_prop_string(ctx,jj,
"fwField");
1131 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
1135 if(fieldRHS != NULL && itypeRHS >= AUXTYPE_X3DConstants){
1137 pars[i]._pointer.native = fieldRHS;
1138 pars[i]._pointer.fieldType = itypeRHS;
1139 pars[i].itype =
'P';
1153 for(i=nUsable;i<nNeeded;i++){
1155 char ctype = arglist.argtypes[i];
1156 pars[i].itype = ctype;
1158 case 'B': pars[i]._boolean = FALSE;
break;
1159 case 'I': pars[i]._integer = 0;
break;
1160 case 'F': pars[i]._numeric = 0.0;
break;
1161 case 'D': pars[i]._numeric = 0.0;
break;
1162 case 'S': pars[i]._string = NULL;
break;
1163 case 'Z': pars[i]._string = NULL; pars[i].itype =
'S';
break;
1165 pars[i]._web3dval.fieldType = FIELDTYPE_SFNode;
1166 pars[i]._web3dval.native = NULL;
break;
1171 pars[i]._jsobject = NULL;
break;
1173 pars[i].itype =
'0';
1206 convert_duk_to_fwvals_new(ctx,nargs,istack,arglist,args,argc);
1211 int i, j, rc, nargs, argc, ifound;
1215 int *valueChanged = NULL;
1217 nargs = duk_get_top(ctx);
1221 duk_push_current_function(ctx);
1222 rc = duk_get_prop_string(ctx,-1,
"fwItype");
1223 if(rc == 1) itype = duk_to_int(ctx,-1);
1229 if(itype < 0)
return 0;
1230 fwt = getFWTYPE(itype);
1231 if(!fwt->Constructor)
return 0;
1236 while(fwt->ConstructorArgs[i].nfixedArg > -1){
1237 int nfixed = fwt->ConstructorArgs[i].nfixedArg;
1238 int ivarsa = fwt->ConstructorArgs[i].iVarArgStartsAt;
1239 char *neededTypes = fwt->ConstructorArgs[i].argtypes;
1240 int fill = fwt->ConstructorArgs[i].fillMissingFixedWithZero ==
'T';
1241 if( nargs == nfixed || (ivarsa > -1 && nargs >= nfixed ) || (ivarsa > -1 && fill)){
1245 for(j=0;j<nargs;j++){
1247 int isOK, RHS_duk_type = duk_get_type(ctx, j);
1249 neededType = j >= nfixed ? neededTypes[ivarsa] : neededTypes[j];
1252 switch(RHS_duk_type){
1253 case DUK_TYPE_NUMBER:
1254 if(neededType ==
'F' || neededType ==
'D' || neededType ==
'I') isOK = TRUE;
1256 case DUK_TYPE_BOOLEAN:
1257 if(neededType ==
'B') isOK = TRUE;
1259 case DUK_TYPE_STRING:
1260 if(neededType ==
'S' || neededType ==
'Z') isOK = TRUE;
1262 case DUK_TYPE_OBJECT:
1263 if(neededType ==
'W' || neededType ==
'P'){
1264 int rc, itypeRHS = -1;
1265 union anyVrml *fieldRHS = NULL;
1266 rc = duk_get_prop_string(ctx,j,
"fwItype");
1269 itypeRHS = duk_to_int(ctx,-1);
1272 rc = duk_get_prop_string(ctx,j,
"fwField");
1273 if(rc == 1) fieldRHS = duk_to_pointer(ctx,-1);
1277 if(fieldRHS != NULL && itypeRHS > -1){
1288 case DUK_TYPE_UNDEFINED:
1291 case DUK_TYPE_POINTER:
1297 allOK = allOK && isOK;
1300 for(j=nargs;j<nfixed;j++){
1323 convert_duk_to_fwvals(ctx, nargs, 0, fwt->ConstructorArgs[i], &args, &argc);
1324 if(fwt->ConstructorArgs[ifound].fillMissingFixedWithZero ==
'T' && nargs < fwt->ConstructorArgs[ifound].nfixedArg){
1325 int nfixed = fwt->ConstructorArgs[ifound].nfixedArg;
1327 char *neededTypes = fwt->ConstructorArgs[ifound].argtypes;
1329 args = realloc(args,nfixed *
sizeof(
struct FWVAL));
1330 for(j=nargs;j<nfixed;j++){
1331 switch(neededTypes[j]){
1333 args[j]._boolean = FALSE;
break;
1335 args[j]._integer = 0;
break;
1337 args[j]._numeric = 0.0;
break;
1339 args[j]._numeric = 0.0;
break;
1341 args[j]._string =
"";
break;
1350 fwpointer = fwt->Constructor(fwt,argc,args);
1352 push_typed_proxy(ctx,itype, fwpointer, valueChanged);
1357 int rc, itype, *valueChanged;
1360 char type, readOnly;
1366 rc = duk_get_prop_string(ctx,0,
"fwItype");
1367 if(rc==1) itype = duk_get_int(ctx,-1);
1370 rc = duk_get_prop_string(ctx,0,
"fwField");
1371 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1374 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1375 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1377 key = duk_require_string(ctx,-1);
1381 fwt = getFWTYPE(itype);
1382 if(fwhas_generic(fwt,parent,
key,&index,&type,&readOnly)){
1385 duk_push_false(ctx);
1393 int rc, itype, *valueChanged, arr_idx;
1394 void *parent = NULL;
1396 const char *fieldname;
1397 int lastProp, jndex;
1398 char type, readOnly;
1404 rc = duk_get_prop_string(ctx,0,
"fwItype");
1405 if(rc==1) itype = duk_get_int(ctx,-1);
1408 rc = duk_get_prop_string(ctx,0,
"fwField");
1409 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1412 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1413 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1416 arr_idx = duk_push_array(ctx);
1417 if(itype < 0 || (itype < AUXTYPE_X3DConstants && parent == NULL))
1420 fwt = getFWTYPE(itype);
1422 while( (i = fwiterator_generic(i,fwt,parent,&fieldname,&lastProp,&jndex,&type,&readOnly)) > -1 ){
1423 duk_push_string(ctx, fieldname);
1424 duk_put_prop_index(ctx, arr_idx, i);
1430 int rc, itype, *valueChanged;
1433 const char *fieldname;
1434 int lastProp, jndex;
1435 char type, readOnly;
1441 rc = duk_get_prop_string(ctx,0,
"fwItype");
1442 if(rc==1) itype = duk_get_int(ctx,-1);
1445 rc = duk_get_prop_string(ctx,0,
"fwField");
1446 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1449 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1450 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1453 arr_idx = duk_push_array(ctx);
1455 fwt = getFWTYPE(itype);
1457 while( (i = fwiterator_generic(i,fwt,parent,&fieldname,&lastProp,&jndex,&type,&readOnly)) > -1 ){
1459 duk_push_string(ctx, fieldname);
1460 duk_put_prop_index(ctx, arr_idx, i);
1478 case FIELDTYPE_SFBool:
1479 duk_push_boolean(ctx,fieldvalue->sfbool);
break;
1480 case FIELDTYPE_SFFloat:
1481 duk_push_number(ctx,fieldvalue->sffloat);
break;
1482 case FIELDTYPE_SFTime:
1483 duk_push_number(ctx,fieldvalue->sftime);
break;
1484 case FIELDTYPE_SFDouble:
1485 duk_push_number(ctx,fieldvalue->sfdouble);
break;
1486 case FIELDTYPE_SFInt32:
1487 duk_push_int(ctx,fieldvalue->sfint32);
break;
1488 case FIELDTYPE_SFString:
1489 duk_push_string(ctx,fieldvalue->sfstring->strptr);
break;
1498static int SCALARS_ARE_PRIMITIVES = TRUE;
1517 switch(fwretval->itype){
1520 duk_push_boolean(ctx,fwretval->_boolean);
break;
1522 duk_push_int(ctx,fwretval->_integer);
break;
1524 duk_push_number(ctx,fwretval->_numeric);
break;
1526 duk_push_number(ctx,fwretval->_numeric);
break;
1528 duk_push_string(ctx,fwretval->_string);
break;
1531 if(SCALARS_ARE_PRIMITIVES){
1533 switch(fwretval->_web3dval.fieldType){
1534 case FIELDTYPE_SFBool:
1535 duk_push_boolean(ctx,fwretval->_web3dval.anyvrml->sfbool);
break;
1536 case FIELDTYPE_SFInt32:
1537 duk_push_int(ctx,fwretval->_web3dval.anyvrml->sfint32);
break;
1538 case FIELDTYPE_SFFloat:
1539 duk_push_number(ctx,(
double)fwretval->_web3dval.anyvrml->sffloat);
break;
1540 case FIELDTYPE_SFDouble:
1541 case FIELDTYPE_SFTime:
1542 duk_push_number(ctx,fwretval->_web3dval.anyvrml->sfdouble);
break;
1543 case FIELDTYPE_SFString:
1544 if(fwretval->_web3dval.anyvrml->sfstring->strptr)
1545 duk_push_string(ctx,fwretval->_web3dval.anyvrml->sfstring->strptr);
1547 duk_push_string(ctx,
"");
1550 push_typed_proxy2(ctx,fwretval->_web3dval.fieldType,fwretval->_web3dval.kind,fwretval->_web3dval.native,valueChanged,fwretval->_web3dval.gc);
1554 push_typed_proxy2(ctx,fwretval->_web3dval.fieldType,fwretval->_web3dval.kind,fwretval->_web3dval.native,valueChanged,fwretval->_web3dval.gc);
1558 duk_push_pointer(ctx,fwretval->_jsobject);
1562 push_typed_proxy2(ctx,fwretval->_pointer.fieldType,fwretval->_pointer.kind,fwretval->_pointer.native,valueChanged,fwretval->_pointer.gc);
1574 int rc, nr, itype, kind, nargs;
1575 const char *fwFunc = NULL;
1581 nargs = duk_get_top(ctx);
1583 duk_push_current_function(ctx);
1585 rc = duk_get_prop_string(ctx,-1,
"fwItype");
1586 if(rc==1) itype = duk_get_int(ctx,-1);
1589 rc = duk_get_prop_string(ctx,-1,
"fwKind");
1590 if(rc==1) kind = duk_get_int(ctx,-1);
1593 rc = duk_get_prop_string(ctx,-1,
"fwFunc");
1594 if(rc == 1) fwFunc = duk_to_string(ctx,-1);
1598 if(!strcasecmp(fwFunc,
"getType")){
1599 duk_push_int(ctx,itype);
1602 if(!strcmp(fwFunc,
"isReadable")){
1603 int isreadable = TRUE;
1605 isreadable = isreadable && (kind == PKW_inputOutput || kind == PKW_initializeOnly);
1606 if(isreadable) duk_push_true(ctx);
1607 else duk_push_false(ctx);
1610 if(!strcmp(fwFunc,
"isWritable")){
1611 int iswritable = TRUE;
1613 iswritable = iswritable && (kind == PKW_inputOutput || kind == PKW_outputOnly);
1614 if(iswritable) duk_push_true(ctx);
1615 else duk_push_false(ctx);
1621 int rc, nr, itype, nargs, *valueChanged = NULL;
1622 const char *fwFunc = NULL;
1629 nargs = duk_get_top(ctx);
1631 duk_push_current_function(ctx);
1633 rc = duk_get_prop_string(ctx,-1,
"fwItype");
1634 if(rc==1) itype = duk_get_int(ctx,-1);
1637 rc = duk_get_prop_string(ctx,-1,
"fwField");
1638 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1641 rc = duk_get_prop_string(ctx,-1,
"fwChanged");
1642 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1645 rc = duk_get_prop_string(ctx,-1,
"fwFunc");
1646 if(rc == 1) fwFunc = duk_to_string(ctx,-1);
1652 fwt = getFWTYPE(itype);
1654 fs = getFWFunc(fwt,fwFunc);
1658 struct FWVAL fwretval;
1661 convert_duk_to_fwvals(ctx, nargs, 0, fs->arglist, &pars, &argc);
1665 duk_eval_string(ctx,
"__script");
1666 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
1669 ec = (
void *)scriptnode->_executionContext;
1671 nr = fs->call(fwt,ec,parent,argc,pars,&fwretval);
1673 nr = fwval_duk_push(ctx,&fwretval,valueChanged);
1674 if(nr && !strcasecmp(fwFunc,
"toString")){
1675 if(fwretval.itype ==
'S' && fwretval._string){
1681 if(valueChanged) *valueChanged = TRUE;
1688 int rc, nr, itype, kind, *valueChanged = NULL;
1696 rc = duk_get_prop_string(ctx,0,
"fwItype");
1697 if(rc==1) itype = duk_get_int(ctx,-1);
1700 rc = duk_get_prop_string(ctx,0,
"fwKind");
1701 if(rc==1) kind = duk_get_int(ctx,-1);
1704 rc = duk_get_prop_string(ctx,0,
"fwField");
1705 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1708 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1709 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1715 switch(duk_get_type(ctx,-2)){
1716 case DUK_TYPE_NUMBER:{
1722 const char *
key = duk_require_string(ctx,-2);
1724 if(!strcmp(
key,
"fwItype")){
1726 duk_push_int(ctx,itype);
1730 if(!strcmp(
key,
"fwGC")){
1733 duk_push_boolean(ctx,FALSE);
1737 if(!strcmp(
key,
"fwField")){
1739 duk_push_pointer(ctx,parent);
1743 if(!strcasecmp(
key,
"getType") || !strcmp(
key,
"isReadable") || !strcmp(
key,
"isWritable")){
1745 duk_push_c_function(ctx,ctypefunction,DUK_VARARGS);
1746 duk_push_int(ctx,itype);
1747 duk_put_prop_string(ctx,-2,
"fwItype");
1748 duk_push_int(ctx,kind);
1749 duk_put_prop_string(ctx,-2,
"fwKind");
1750 duk_push_string(ctx,
key);
1751 duk_put_prop_string(ctx,-2,
"fwFunc");
1762 const char *
key = NULL;
1763 FWType fwt = getFWTYPE(itype);
1765 char type, readOnly;
1769 if(duk_is_number(ctx,-2)){
1771 int index = duk_get_int(ctx,-2);
1772 if(fwt->takesIndexer){
1773 type = fwt->takesIndexer;
1774 readOnly = fwt->indexerReadOnly;
1781 index = fwiterator_generic(index -1,fwt,parent,&name,&lastProp,&jndex,&type,&readOnly);
1782 if(index > -1) found = 1;
1787 key = duk_get_string(ctx,-2);
1788 found = fwhas_generic(fwt,parent,
key,&jndex,&type,&readOnly);
1789 if(!found && strcmp(
key,
"valueOf")){
1791 static int once = 0;
1793 ConsoleMessage(
"type %s has no property or function %s - please check your typing\n",fwt->name,
key);
1797 if(found && type==
'f'){
1801 duk_push_c_function(ctx,cfunction,DUK_VARARGS);
1802 duk_push_pointer(ctx,parent);
1803 duk_put_prop_string(ctx,-2,
"fwField");
1804 duk_push_pointer(ctx,valueChanged);
1805 duk_put_prop_string(ctx,-2,
"fwChanged");
1806 duk_push_int(ctx,itype);
1807 duk_put_prop_string(ctx,-2,
"fwItype");
1808 duk_push_string(ctx,
key);
1809 duk_put_prop_string(ctx,-2,
"fwFunc");
1812 }
else if(found && fwt->Getter){
1813 struct FWVAL fwretval;
1817 duk_eval_string(ctx,
"__script");
1818 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
1821 ec = (
void *)scriptnode->_executionContext;
1824 nr = fwt->Getter(fwt,jndex,ec,parent,&fwretval);
1826 nr = fwval_duk_push(ctx,&fwretval,valueChanged);
1833 int rc, itype, *valueChanged = NULL;
1837 rc = duk_get_prop_string(ctx,0,
"fwItype");
1838 if(rc==1) itype = duk_get_int(ctx,-1);
1841 rc = duk_get_prop_string(ctx,0,
"fwField");
1842 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1845 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1846 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1850 switch(duk_get_type(ctx,-3)){
1851 case DUK_TYPE_NUMBER:{
1862 switch(duk_get_type(ctx,-2)){
1863 case DUK_TYPE_NUMBER:{
1864 int ival = duk_get_int(ctx,-2);
1868 case DUK_TYPE_STRING:{
1869 const char *cval = duk_get_string(ctx,-2);
1882 FWType fwt = getFWTYPE(itype);
1884 char type, readOnly;
1886 if(duk_is_number(ctx,-3) && fwt->takesIndexer){
1888 jndex = duk_get_int(ctx,-3);
1889 type = fwt->takesIndexer;
1890 readOnly = fwt->indexerReadOnly;
1895 key = duk_get_string(ctx,-3);
1896 found = fwhas_generic(fwt,parent,
key,&jndex,&type,&readOnly) && (type !=
'f');
1898 if(found && (readOnly !=
'T') && fwt->Setter){
1899 FWval fwsetval = NULL;
1902 arglist.argtypes = &type;
1903 arglist.fillMissingFixedWithZero = 0;
1904 arglist.nfixedArg = 1;
1905 arglist.iVarArgStartsAt = -1;
1906 convert_duk_to_fwvals(ctx, 1, -2, arglist, &fwsetval, &argc);
1911 duk_eval_string(ctx,
"__script");
1912 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
1915 ec = (
void *)scriptnode->_executionContext;
1918 fwt->Setter(fwt,jndex,ec,parent,fwsetval);
1920 (*valueChanged) = 1;
1928 int rc, itype, *valueChanged;
1932 rc = duk_get_prop_string(ctx,0,
"fwItype");
1933 if(rc==1) itype = duk_get_int(ctx,-1);
1937 rc = duk_get_prop_string(ctx,0,
"fwField");
1938 if(rc == 1) parent = duk_to_pointer(ctx,-1);
1941 rc = duk_get_prop_string(ctx,0,
"fwChanged");
1942 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
1945 show_stack(ctx,
"in cdel");
1952 int iglobal, ihandler;
1953 iglobal = duk_get_top(ctx) -1;
1955 duk_push_object(ctx);
1956 duk_put_prop_string(ctx, iglobal,
"handler");
1958 duk_get_prop_string(ctx,iglobal,
"handler");
1959 ihandler = duk_get_top(ctx) -1;
1960 duk_push_c_function(ctx,chas,2);
1961 duk_put_prop_string(ctx, ihandler,
"has");
1962 duk_push_c_function(ctx,cownKeys,1);
1963 duk_put_prop_string(ctx, ihandler,
"ownKeys");
1964 duk_push_c_function(ctx,cenumerate,1);
1965 duk_put_prop_string(ctx, ihandler,
"enumerate");
1966 duk_push_c_function(ctx,cget,3);
1967 duk_put_prop_string(ctx, ihandler,
"get");
1968 duk_push_c_function(ctx,cset,4);
1969 duk_put_prop_string(ctx, ihandler,
"set");
1970 duk_push_c_function(ctx,cdel,2);
1971 duk_put_prop_string(ctx, ihandler,
"del");
1975void addCustomProxyType(
duk_context *ctx,
int iglobal,
const char *typeName)
1978 duk_push_c_function(ctx,cfwconstructor,DUK_VARARGS);
1980 itype = fwType2itype(typeName);
1981 duk_push_int(ctx,itype);
1982 duk_put_prop_string(ctx,-2,
"fwItype");
1984 duk_put_prop_string(ctx,iglobal,typeName);
1986void add_duk_global_property(
duk_context *ctx,
int itype,
const char *fieldname,
int *valueChanged,
struct X3D_Node *node);
1991static char *eval_string_defineAccessor =
"\
1992function defineAccessor(obj, key, set, get) { \
1993 Object.defineProperty(obj, key, { \
1994 enumerable: true, configurable: true, \
1995 set: set, get: get \
2003void duk_JSCreateScriptContext(
int num) {
2014 ScriptControl = getScriptControlIndex(num);
2015 script = ScriptControl->script;
2016 scriptnode = script->ShaderScriptNode;
2018 ctx = duk_create_heap_default();
2021 duk_push_global_object(ctx);
2022 iglobal = duk_get_top(ctx) -1;
2025 ScriptControl->cx = ctx;
2028 ((
int *)&ScriptControl->glob)[0] = iglobal;
2031 duk_push_pointer(ctx,scriptnode);
2032 duk_put_prop_string(ctx,iglobal,
"__script");
2034 duk_push_string(ctx,eval_string_defineAccessor);
2043 for(i=0;i<FWTYPES_COUNT;i++)
2044 if(fwtypesArray[i]->Constructor)
2045 addCustomProxyType(ctx,iglobal,fwtypesArray[i]->name);
2048 add_duk_global_property(ctx, AUXTYPE_X3DBrowser,
"Browser", NULL, NULL);
2049 add_duk_global_property(ctx, AUXTYPE_X3DConstants,
"X3DConstants", NULL, NULL);
2051 duk_eval_string(ctx,DefaultScriptMethodsA);
2053 duk_eval_string(ctx,DefaultScriptMethodsB);
2057 CRoutes_js_new (num, JAVASCRIPT);
2065 duk_eval_string(ctx,
"__script");
2066 scriptnode = duk_to_pointer(ctx,-1);
2068 snode = (
struct X3D_Node *)scriptnode;
2072 duk_eval_string(ctx,
"print(Object.keys(Browser));");
2074 duk_eval_string(ctx,
"print(Object.getOwnPropertyNames(Browser));");
2076 duk_eval_string(ctx,
"for (k in Browser) {print(k);}");
2078 duk_eval_string(ctx,
"if('println' in Browser) print('have println'); else print('no println');");
2080 duk_eval_string(ctx,
"print('X3DConstants.outputOnly='); print(X3DConstants.outputOnly);");
2082 duk_eval_string(ctx,
"print(Object.keys(X3DConstants));");
2086 duk_eval_string(ctx,
"Browser.println('hi from brwsr.println');");
2088 duk_eval_string(ctx,
"Browser.description = 'funny description happened on the way to ..';");
2090 duk_eval_string(ctx,
"Browser.println(Browser.description);");
2092 duk_eval_string(ctx,
"print('hi from print');");
2094 duk_eval_string(ctx,
"print(Browser.version);");
2099 duk_eval_string(ctx,
"print('Browser.supportedComponents.length = ');");duk_pop(ctx);
2100 duk_eval_string(ctx,
"print(Browser.supportedComponents.length);"); duk_pop(ctx);
2101 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);
2104 duk_eval_string(ctx,
"var myvec3 = new SFVec3f(1.0,2.0,3.0);");
2106 duk_eval_string(ctx,
"print(myvec3.x.toString());");
2108 duk_eval_string(ctx,
"myvec3.y = 45.0;");
2110 duk_eval_string(ctx,
"print('sb45='+myvec3.y);");
2124int SFNode_Setter0(
FWType fwt,
int index,
void *ec,
void * fwn,
FWval fwval,
int isCurrentScriptNode);
2133 int rc, itype, *valueChanged;
2137 nargs = duk_get_top(ctx);
2143 key = duk_require_string(ctx,1);
2149 duk_push_current_function(ctx);
2151 rc = duk_get_prop_string(ctx,-1,
"fwItype");
2152 if(rc==1) itype = duk_get_int(ctx,-1);
2154 if(itype > -1 && itype < AUXTYPE_X3DConstants){
2156 rc = duk_get_prop_string(ctx,-1,
"fwNode");
2157 if(rc==1) parent = duk_to_pointer(ctx,-1);
2160 rc = duk_get_prop_string(ctx,-1,
"fwChanged");
2161 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
2166 if(itype > -1 && itype < AUXTYPE_X3DConstants){
2169 FWType fwt = getFWTYPE(FIELDTYPE_SFNode);
2171 char type, readOnly;
2175 any.sfnode = parent;
2177 found = fwhas_generic(fwt,&any,
key,&jndex,&type,&readOnly) && (type !=
'f');
2179 FWval fwsetval = NULL;
2182 arglist.argtypes = &type;
2183 arglist.fillMissingFixedWithZero = 0;
2184 arglist.nfixedArg = 1;
2185 arglist.iVarArgStartsAt = -1;
2186 convert_duk_to_fwvals(ctx, 1, -2, arglist, &fwsetval, &argc);
2191 duk_eval_string(ctx,
"__script");
2192 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
2195 ec = (
void *)scriptnode->_executionContext;
2198 SFNode_Setter0(fwt,jndex,ec,&any,fwsetval,TRUE);
2208void push_typed_proxy_fwgetter(
duk_context *ctx,
int itype,
int mode,
const char* fieldname,
void *fwpointer,
int* valueChanged)
2215 proxy_entry *pe = NULL;
2216 if(itype == FIELDTYPE_SFNode){
2218 printf(
"pushtyped2 nodetype %d\n",node->_nodeType);
2219 pe = lookup_ctx_proxycache_entry_by_nodeptr(ctx, node);
2222 duk_push_heapptr(ctx,pe->jsproxy);
2225 duk_eval_string(ctx,
"Proxy");
2226 duk_push_object(ctx);
2227 duk_push_pointer(ctx,fwpointer);
2228 duk_put_prop_string(ctx,-2,
"fwField");
2229 duk_push_pointer(ctx,valueChanged);
2230 duk_put_prop_string(ctx,-2,
"fwChanged");
2231 duk_push_int(ctx,itype);
2232 duk_put_prop_string(ctx,-2,
"fwItype");
2233 duk_eval_string(ctx,
"handler");
2237 if(doingFinalizer) {
2247 if(itype == FIELDTYPE_SFNode){
2249 void *jsproxy = duk_get_heapptr(ctx, -1);
2250 add_ctx_proxycache_entry(ctx, node, jsproxy);
2252 duk_eval_string(ctx,
"Duktape.fin");
2254 duk_push_c_function(ctx,cfinalizer,1);
2263int push_duk_fieldvalue(
duk_context *ctx,
int itype,
int mode,
const char* fieldname,
union anyVrml *field,
int *valueChanged)
2277 case FIELDTYPE_SFBool:
2278 duk_push_boolean(ctx,field->sfbool);
break;
2279 case FIELDTYPE_SFFloat:
2280 duk_push_number(ctx,field->sffloat);
break;
2281 case FIELDTYPE_SFTime:
2282 duk_push_number(ctx,field->sftime);
break;
2283 case FIELDTYPE_SFDouble:
2284 duk_push_number(ctx,field->sfdouble);
break;
2285 case FIELDTYPE_SFInt32:
2286 duk_push_int(ctx,field->sfint32);
break;
2287 case FIELDTYPE_SFString:
2288 duk_push_string(ctx,field->sfstring->strptr);
break;
2292 if(itype == FIELDTYPE_SFNode){
2301 (memcpy(&anode,field,
sizeof(
void *)));
2302 printf(
"anode._nodeType=%d ",anode->_nodeType);
2303 printf(
"anyvrml.sfnode._nodetype=%d\n",field->sfnode->_nodeType);
2304 anode = field->sfnode;
2305 printf(
"anode = anyvrml.sfnode ._nodetype=%d\n",anode->_nodeType);
2309 push_typed_proxy_fwgetter(ctx, itype, mode, fieldname, field, valueChanged);
2318int fwgetter0(
duk_context *ctx,
void *parent,
int itype,
const char *
key,
int *valueChanged){
2320 FWType fwt = getFWTYPE(itype);
2321 int jndex, found, nr;
2322 char type, readOnly;
2325 found = fwhas_generic(fwt,parent,
key,&jndex,&type,&readOnly);
2326 if(found && fwt->Getter){
2327 struct FWVAL fwretval;
2331 duk_eval_string(ctx,
"__script");
2332 scriptnode = (
struct X3D_Node*) duk_to_pointer(ctx,-1);
2335 ec = (
void *)scriptnode->_executionContext;
2338 nr = fwt->Getter(fwt,jndex,ec,parent,&fwretval);
2340 nr = fwval_duk_push(ctx,&fwretval,valueChanged);
2354 int rc, itype, *valueChanged = NULL;
2356 const char *fieldname;
2357 struct X3D_Node *thisScriptNode = NULL;
2360 nargs = duk_get_top(ctx);
2364 fieldname = duk_require_string(ctx,0);
2368 duk_push_current_function(ctx);
2370 rc = duk_get_prop_string(ctx,-1,
"fwItype");
2371 if(rc==1) itype = duk_get_int(ctx,-1);
2373 if(itype < AUXTYPE_X3DConstants){
2375 rc = duk_get_prop_string(ctx,-1,
"fwNode");
2376 if(rc==1) thisScriptNode = duk_to_pointer(ctx,-1);
2379 rc = duk_get_prop_string(ctx,-1,
"fwChanged");
2380 if(rc == 1) valueChanged = duk_to_pointer(ctx,-1);
2387 if(itype < AUXTYPE_X3DConstants){
2390 any.sfnode = thisScriptNode;
2391 nr = fwgetter0(ctx,&any,FIELDTYPE_SFNode,fieldname,valueChanged);
2394 push_typed_proxy_fwgetter(ctx, itype, PKW_initializeOnly, fieldname, NULL, NULL);
2400void add_duk_global_property(
duk_context *ctx,
int itype,
const char *fieldname,
int *valueChanged,
struct X3D_Node *node ){
2404 duk_eval_string(ctx,
"defineAccessor");
2406 duk_eval_string(ctx,
"this");
2408 duk_push_string(ctx,fieldname);
2410 duk_push_c_function(ctx,fwsetterNS,2);
2411 if(itype < AUXTYPE_X3DConstants){
2412 duk_push_pointer(ctx,valueChanged);
2413 duk_put_prop_string(ctx,-2,
"fwChanged");
2414 duk_push_pointer(ctx,node);
2415 duk_put_prop_string(ctx,-2,
"fwNode");
2417 duk_push_int(ctx,itype);
2418 duk_put_prop_string(ctx,-2,
"fwItype");
2420 duk_push_c_function(ctx,fwgetterNS,1);
2421 if(itype < AUXTYPE_X3DConstants){
2422 duk_push_pointer(ctx,node);
2423 duk_put_prop_string(ctx,-2,
"fwNode");
2424 duk_push_pointer(ctx,valueChanged);
2425 duk_put_prop_string(ctx,-2,
"fwChanged");
2427 duk_push_int(ctx,itype);
2428 duk_put_prop_string(ctx,-2,
"fwItype");
2434void InitScriptField2(
struct CRscriptStruct *scriptcontrol,
int itype,
int kind,
const char* fieldname,
int *valueChanged,
struct X3D_Node* parent)
2454 ctx = scriptcontrol->cx;
2459 if( kind == PKW_inputOutput){
2462 sprintf(strline,
"_rename_function(this,\"%s\",\"set_%s\");",fieldname,fieldname);
2464 duk_push_string(ctx,strline);
2465 if(duk_peval(ctx) != 0) {
2466 printf(
"Script error: %s\n", duk_safe_to_string(ctx, -1));
2467 printf(
"rename didn't work\n");
2473 add_duk_global_property(ctx,itype,fieldname, valueChanged,parent);
2478void duk_JSInitializeScriptAndFields (
int num) {
2485 int i,nfields, kind, itype;
2486 const char *fieldname;
2489 scriptcontrol = getScriptControlIndex(num);
2492 if(1)
if (!jsActualrunScript(num, scriptcontrol->scriptText)) {
2493 ConsoleMessage (
"JSInitializeScriptAndFields, script failure\n");
2494 scriptcontrol->scriptOK = FALSE;
2495 scriptcontrol->_initialized = TRUE;
2501 script = scriptcontrol->script;
2503 nfields = Shader_Script_getScriptFieldCount(script);
2504 for(i=0;i<nfields;i++){
2505 field = Shader_Script_getScriptField(script,i);
2506 fieldname = ScriptFieldDecl_getName(field);
2507 kind = ScriptFieldDecl_getMode(field);
2508 itype = ScriptFieldDecl_getType(field);
2509 if (kind != PKW_inputOnly) {
2511 field->valueChanged = 0;
2512 InitScriptField2(scriptcontrol, itype, kind, fieldname, &field->valueChanged, script->ShaderScriptNode);
2516 if(0)
if (!jsActualrunScript(num, scriptcontrol->scriptText)) {
2517 ConsoleMessage (
"JSInitializeScriptAndFields, script failure\n");
2518 scriptcontrol->scriptOK = FALSE;
2519 scriptcontrol->_initialized = TRUE;
2522 FREE_IF_NZ(scriptcontrol->scriptText);
2523 scriptcontrol->_initialized = TRUE;
2524 scriptcontrol->scriptOK = TRUE;
2529int duk_jsActualrunScript(
int num,
char *script){
2536 ScriptControl = getScriptControlIndex(num);
2540 iglobal = ((
int *)&ScriptControl->glob)[0];
2544 len = (int) strlen(script);
2549 duk_eval_string(ctx, script);
2551 printf (
"ActualrunScript - JS_EvaluateScript failed for %s", script);
2553 ConsoleMessage (
"ActualrunScript - JS_EvaluateScript failed for %s", script);
2559 duk_push_string(ctx, script);
2560 if (duk_peval(ctx) != 0) {
2561 ConsoleMessage(
"eval failed: %s\n", duk_safe_to_string(ctx, -1));
2564 printf(
"result is: %s\n", duk_safe_to_string(ctx, -1));
2572void duk_SaveScriptField (
int num, indexT kind, indexT type,
const char* field,
union anyVrml value){
2575static int duk_once = 0;
2576void duk_process_eventsProcessed(){
2589 p = (ppJScript_duk)tg->JScript_duk.prv;
2590 for (counter = 0; counter <= tg->CRoutes.max_script_found_and_initialized; counter++) {
2591 scriptcontrol = getScriptControlIndex(counter);
2597 ctx = scriptcontrol->cx;
2598 if(scriptcontrol->thisScriptType != NOSCRIPT && ctx){
2599 duk_eval_string(ctx,
"eventsProcessed");
2601 duk_push_number(ctx,TickTime());
2602 rc = duk_pcall(ctx, 1);
2603 if (rc != DUK_EXEC_SUCCESS) {
2604 printf(
"error: '%s' happened in js function %s called from process_eventsProcessed\n", duk_to_string(ctx, -1),
"eventsProcessed");
2613void duk_js_cleanup_script_context(
int counter){
2617void duk_js_setField_javascriptEventOut_B(
union anyVrml* any,
int fieldType,
unsigned len,
int extraData,
int actualscript){
2625void duk_setField_javascriptEventOut(
struct X3D_Node *tn,
unsigned int tptr,
int fieldType,
unsigned len,
int extraData) {
2635 memptr = offsetPointer_deref(
char *, tn, tptr);
2637 fromptr = tg->JScript_duk.JSglobal_return_val;
2639 medium_copy_field0(fieldType,fromptr,memptr);
2642void duk_js_setField_javascriptEventOut(
struct X3D_Node *tn,
unsigned int tptr,
int fieldType,
unsigned len,
int extraData,
int actualscript) {
2645 scriptcontrol = getScriptControlIndex(actualscript);
2646 duk_setField_javascriptEventOut(tn,tptr,fieldType, len, extraData);
2652void duk_set_one_ECMAtype (
int tonode,
int toname,
int dataType,
void *Data,
int datalen) {
2653 char scriptline[100];
2662 #ifdef SETFIELDVERBOSE
2663 printf (
"set_one_ECMAtype, to %d namepointer %d, fieldname %s, datatype %d length %d\n",
2664 tonode,toname,JSparamnames[toname].name,dataType,datalen);
2668 ScriptControl = getScriptControlIndex(tonode);
2673 obj = ((
int*)&ScriptControl->glob)[0];
2678 if(JSparamnames[toname].kind == PKW_inputOutput)
2679 strcat(scriptline,
"set_");
2680 strcat(scriptline,JSparamnames[toname].name);
2682 duk_push_string(ctx,scriptline);
2683 if(duk_peval(ctx) != 0){
2684 printf(
"Script error: %s\n", duk_safe_to_string(ctx, -1));
2685 printf(
"ouch - no function named %s\n",scriptline);
2695 fwval._web3dval.native = Data;
2696 fwval._web3dval.fieldType = dataType;
2697 fwval._web3dval.gc = 0;
2699 rc = fwval_duk_push(ctx, &fwval, NULL);
2703 duk_push_number(ctx,TickTime());
2705 rc = duk_pcall(ctx, 2);
2706 if (rc != DUK_EXEC_SUCCESS) {
2707 printf(
"Script error: %s\n", duk_safe_to_string(ctx, -1));
2708 printf(
"error: '%s' happened in js function %s called from set_one_ECMAType\n", duk_to_string(ctx, -1),JSparamnames[toname].name);
2726void duk_setScriptECMAtype (
int num) {
2732 struct CRStruct *CRoutes = getCRoutes();
2735 fn = offsetPointer_deref(
void *, CRoutes[num].routeFromNode, CRoutes[num].fnptr);
2736 len = CRoutes[num].len;
2738 for (to_counter = 0; to_counter < CRoutes[num].tonode_count; to_counter++) {
2741 to_ptr = &(CRoutes[num].tonodes[to_counter]);
2742 myObj = X3D_SCRIPT(to_ptr->routeToNode)->__scriptObj;
2744 tptr = to_ptr->foffset;
2745 set_one_ECMAtype (myObj->num, tptr, JSparamnames[tptr].type, fn,len);
2749void duk_set_one_MultiElementType (
int tonode,
int tnfield,
void *Data,
int dataLen){
2763 ScriptControl = getScriptControlIndex(tonode);
2768 obj = ((
int*)&ScriptControl->glob)[0];
2774 char scriptline[100];
2776 if(JSparamnames[tnfield].kind == PKW_inputOutput)
2777 strcat(scriptline,
"set_");
2778 strcat(scriptline,JSparamnames[tnfield].name);
2780 duk_push_string(ctx,scriptline);
2782 if(duk_peval(ctx) != 0){
2783 ConsoleMessage(
"couldn't find eventin function %s\n",scriptline);
2788 isEventin = duk_is_ecmascript_function(ctx, -1);
2792 itype = JSparamnames[tnfield].type;
2795 medium_copy_field(itype,Data,&datacopy);
2796 push_typed_proxy2(ctx,itype,PKW_inputOutput,datacopy,NULL,
'T');
2797 duk_push_number(ctx,TickTime());
2799 rc = duk_pcall(ctx, 2);
2800 if (rc != DUK_EXEC_SUCCESS) {
2801 printf(
"error: '%s' happened in js function %s called from set_one_Multi_ElementType\n", duk_to_string(ctx, -1),JSparamnames[tnfield].name);
2809void duk_set_one_MFElementType(
int tonode,
int toname,
int dataType,
void *Data,
int datalen){
2817 int itype, isEventin;
2819 void *datacopy = NULL;
2826 ScriptControl = getScriptControlIndex(tonode);
2831 obj = ((
int*)&ScriptControl->glob)[0];
2836 char scriptline[100];
2838 if(JSparamnames[toname].kind == PKW_inputOutput)
2839 strcat(scriptline,
"set_");
2841 strcat(scriptline,JSparamnames[toname].name);
2842 duk_push_string(ctx,scriptline);
2844 if(duk_peval(ctx) != 0){
2845 ConsoleMessage(
"couldn't find eventin function %s\n",scriptline);
2850 isEventin = duk_is_ecmascript_function(ctx, -1);
2856 source = (
char *)&maData;
2857 any = (
void*)source;
2859 medium_copy_field(itype,source,&datacopy);
2861 push_typed_proxy2(ctx,itype,PKW_inputOutput,datacopy,NULL,
'T');
2862 duk_push_number(ctx,TickTime());
2869int duk_jsIsRunning(){
2873void duk_JSDeleteScriptContext(
int num){
2876 ScriptControl = getScriptControlIndex(num);
2877 duk_destroy_heap(ScriptControl->cx);
2880void duk_jsShutdown(){
2884void duk_jsClearScriptControlEntries(
int num){
2949int isScriptControlOK(
int actualscript);
2950int isScriptControlInitialized(
int actualscript);
2951void getField_ToJavascript_B(
int shader_num,
int fieldOffset,
int type,
union anyVrml *any,
int len);
2952int duk_runQueuedDirectOutputs()
2987 int i,num,kind, itype;
2988 const char *fieldname;
2989 static int doneOnce = 0;
2996 printf(
"javascript engine duktape version %ld\n", DUK_VERSION);
3000 for(num=0;num< tg->CRoutes.max_script_found_and_initialized;num++){
3001 scriptcontrol = getScriptControlIndex(num);
3004 script = scriptcontrol->script;
3005 if(scriptcontrol->thisScriptType != NOSCRIPT && script){
3006 if(isScriptControlInitialized(script->num) && isScriptControlOK(script->num)){
3007 int nfields = Shader_Script_getScriptFieldCount(script);
3008 for(i=0;i<nfields;i++){
3009 field = Shader_Script_getScriptField(script,i);
3010 fieldname = ScriptFieldDecl_getName(field);
3011 kind = ScriptFieldDecl_getMode(field);
3012 itype = ScriptFieldDecl_getType(field);
3013 if(field->eventInSet){
3014 if( (kind == PKW_inputOnly || kind == PKW_inputOutput)){
3015 int isMF, sftype, len, isize;
3016 int JSparamNameIndex = field->fieldDecl->JSparamNameIndex;
3017 mark_script(script->num);
3020 sftype = itype - isMF;
3022 isize = returnElementLength(sftype) * returnElementRowSize(sftype);
3023 if(isMF) len =
sizeof(int) +
sizeof(
void*);
3026 field->eventInSet = FALSE;
3027 getField_ToJavascript_B(script->num, JSparamNameIndex, itype, &field->value, len);
3032 field->eventInSet = FALSE;