FreeWRL / FreeX3D 4.3.0
JScript.c
1/*
2
3
4Javascript C language binding.
5
6*/
7
8/****************************************************************************
9 This file is part of the FreeWRL/FreeX3D Distribution.
10
11 Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12
13 FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14 it under the terms of the GNU Lesser Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25****************************************************************************/
26
27
28#include <config.h>
29#if !defined(JS_SMCPP)
30#include <system.h>
31//#if !(defined(JAVASCRIPT_STUB) || defined(JAVASCRIPT_DUK))
32#ifdef JAVASCRIPT_SM
33#include <display.h>
34#include <internal.h>
35
36#include <libFreeWRL.h>
37
38#include "../vrml_parser/Structs.h"
39#include "../main/headers.h"
40#include "../vrml_parser/CParseGeneral.h"
41#include "../vrml_parser/CRoutes.h"
42#include "../main/Snapshot.h"
43#include "../scenegraph/Collision.h"
44#include "../scenegraph/quaternion.h"
45#include "../scenegraph/Viewer.h"
46#include "../input/EAIHelpers.h"
47#include "../input/SensInterps.h"
48#include "../x3d_parser/Bindable.h"
49
50#include "JScript.h"
51#include "CScripts.h"
52#include "jsUtils.h"
53#include "jsNative.h"
54#include "jsVRMLClasses.h"
55#include "jsVRMLBrowser.h"
56
57
58#ifndef JSCLASS_GLOBAL_FLAGS
59//spidermonkey < 1.7 doesn't have so define here
60#define JSCLASS_GLOBAL_FLAGS 0
61#endif
62
63#ifdef JAVASCRIPTVERBOSE
64int ActualrunScript(int num, char *script, jsval *rval, char *fn, int line);
65#else
66int ActualrunScript(int num, char *script, jsval *rval);
67#endif
68
69
70static JSClass staticGlobalClass = {
71 "global", // char *name
72 JSCLASS_GLOBAL_FLAGS, // uint32 flags
73 JS_PropertyStub, // JSPropertyOp addProperty
74 JS_PropertyStub, // JSPropertyOp delProperty
75 JS_PropertyStub, // JSPropertyOp getProperty
76 JS_StrictPropertyStub, // JSStrictPropertyOp setProperty
77 JS_EnumerateStub, // JSEnumerateOp enumerate
78 globalResolve, // JSResolveOp resolve
79 JS_ConvertStub, // JSConvertOp convert
80 // following are optional and can be NULL
81 JS_FinalizeStub, // JSFinalizeOp finalize
82 NULL, // JSClassInternal reserved
83 NULL, // JSCheckAccessOp checkAccess
84 NULL, // JSNative call
85 NULL, // JSNative construct
86 NULL, // JSXDRObjectOp xdrObject
87 NULL, // JSJasInstanceOp hasInstance
88 NULL // JSTraceOp trace
89};
90
91
92
93
94
95typedef struct pJScript{
96
97
98
99 JSRuntime *runtime;// = NULL;
100 JSClass globalClass;
101 jsval JSglobal_return_value;
102 struct Shader_Script *current_script; //when in some js callback, you get cx, obj. But what script? Set in the call stack
103 int ijunk;
104}* ppJScript;
105
106
107void *JScript_constructor(){
108 void *v = MALLOCV(sizeof(struct pJScript));
109 memset(v,0,sizeof(struct pJScript));
110 return v;
111}
112void JScript_init(struct tJScript *t){
113 //public
114 t->JSglobal_return_val = NULL;
115 //private
116 t->prv = JScript_constructor();
117 {
118 ppJScript p = (ppJScript)t->prv;
119
120 p->runtime = NULL;
121 memcpy(&p->globalClass,&staticGlobalClass,sizeof(staticGlobalClass));
122 t->JSglobal_return_val = &p->JSglobal_return_value;
123 p->current_script = NULL;
124
125 }
126}
127// ppJScript p = (ppJScript)gglobal()->JScript.prv;
128
129
130void sm_js_cleanup_script_context(int counter){
131 //CLEANUP_JAVASCRIPT(p->ScriptControl[counter].cx);
132 //CLEANUP_JAVASCRIPT(getScriptControlIndex(counter)->cx);
133 #if JS_VERSION <= 185
134 struct CRscriptStruct *crss = getScriptControlIndex(counter);
135 #define CATCH_JS_GC_THROWS 1
136 #if defined(CATCH_JS_GC_THROWS) && defined(_MSC_VER) && defined(W_DEBUG)
137 CHECK_MEMORY
138 __try {
139 JS_GC(crss->cx);
140 }
141 __except(EXCEPTION_EXECUTE_HANDLER) {
142 printf("bad js_gc for script num %d\n", counter);
143 if(crss->scriptText){
144 struct X3D_Node *scnode = crss->script->ShaderScriptNode;
145 if(scnode){
146 const char* nn = getNodeName(X3D_NODE(scnode));
147 if(nn) printf("DEF %s \n",nn);
148 if(crss->scriptText) printf("%s\n",crss->scriptText);
149
150 }
151 }
152 }
153 #else
154 JS_GC(crss->cx);
155 #endif
156 #else
157 ttglobal tg = gglobal();
158 ppJScript p = (ppJScript)tg->JScript.prv;
159 //JS_GC((JSRuntime*) p->runtime); //this bombs for us. access violation.
160 //JS_GC(getScriptControlIndex(counter)->cx); //this also bombs for us
161 JS_MaybeGC(getScriptControlIndex(counter)->cx); //this doesn't do gcing.
162
163 #endif
164}
165
166/********************************************************************
167
168process_eventsProcessed()
169
170According to the spec, all scripts can have an eventsProcessed
171function - see section C.4.3 of the spec.
172
173********************************************************************/
174/* run the script from within C */
175void sm_process_eventsProcessed() {
176
177 int counter;
178 jsval retval;
179 struct CRscriptStruct *scriptcontrol;
180 ttglobal tg = gglobal();
181 //ppJScript p = (ppJScript)tg->JScript.prv;
182 for (counter = 0; counter <= tg->CRoutes.max_script_found_and_initialized; counter++) {
183 scriptcontrol = getScriptControlIndex(counter);
184 if(scriptcontrol->thisScriptType != NOSCRIPT ){
185 if (scriptcontrol->eventsProcessed == NULL) {
186#if defined(JS_THREADSAFE)
187 JS_BeginRequest(scriptcontrol->cx);
188#endif
189 scriptcontrol->eventsProcessed = (void *)JS_CompileScript(
190 scriptcontrol->cx,
191 scriptcontrol->glob,
192 "eventsProcessed()", strlen ("eventsProcessed()"),
193 "compile eventsProcessed()", 1);
194#if JS_VERSION >= 185
195 if (!JS_AddObjectRoot(scriptcontrol->cx,(JSSCRIPT**)(&scriptcontrol->eventsProcessed))) {
196 printf ("can not add object root for compiled eventsProcessed() for script %d\n",counter);
197 }
198#endif
199#if defined(JS_THREADSAFE)
200 JS_EndRequest(scriptcontrol->cx);
201#endif
202 }
203
204#if defined(JS_THREADSAFE)
205 JS_BeginRequest(scriptcontrol->cx);
206#endif
207 if (!JS_ExecuteScript( scriptcontrol->cx,
208 scriptcontrol->glob,
209 scriptcontrol->eventsProcessed, &retval)) {
210#if defined(_MSC_VER)
211 printf ("can not run eventsProcessed() for script %d thread %u\n",counter,(unsigned int)pthread_self().x);
212#else
213 printf ("can not run eventsProcessed() for script %d thread %p\n",counter,(void *)pthread_self());
214#endif
215 }
216#if defined(JS_THREADSAFE)
217 JS_EndRequest(scriptcontrol->cx);
218#endif
219 }
220
221 }
222
223}
224
225
226
227
228void sm_jsClearScriptControlEntries(int num) //struct CRscriptStruct *ScriptControl)
229{
230 struct CRscriptStruct *ScriptControl;
231 ScriptControl = getScriptControlIndex(num);
232 if (ScriptControl->eventsProcessed != NULL) {
233#if JS_VERSION >= 185
234 if (ScriptControl->cx != NULL) {
235 JS_RemoveObjectRoot(ScriptControl->cx,(JSSCRIPT**)(&ScriptControl->eventsProcessed));
236 }
237#endif
238 ScriptControl->eventsProcessed = NULL;
239 }
240}
241
242
243
244/* MAX_RUNTIME_BYTES controls when garbage collection takes place. */
245//#define MAX_RUNTIME_BYTES 0xB00000L
246//#define MAX_RUNTIME_BYTES 0xC00000L
247//#define MAX_RUNTIME_BYTES 0x1000000L
248#define MAX_RUNTIME_BYTES 0x4000000L
249//#define MAX_RUNTIME_BYTES 0xF000000L
250
251
252
253#define STACK_CHUNK_SIZE 8192
254
255static int JSaddGlobalECMANativeProperty(int num, const char *name);
256static int JSaddGlobalAssignProperty(int num, const char *name, const char *str);
257
258/*
259 * Global JS variables (from Brendan Eichs short embedding tutorial):
260 *
261 * JSRuntime - 1 runtime per process
262 * JSContext - 1 CONTEXT per thread
263 * global JSObject - 1 global object per CONTEXT
264 *
265 * struct JSClass {
266 * char *name;
267 * uint32 flags;
268 * Mandatory non-null function pointer members:
269 * JSPropertyOp addProperty;
270 * JSPropertyOp delProperty;
271 * JSPropertyOp getProperty;
272 * JSPropertyOp setProperty;
273 * JSEnumerateOp enumerate;
274 * JSResolveOp resolve;
275 * JSConvertOp convert;
276 * JSFinalizeOp finalize;
277 * Optionally non-null members start here:
278 * JSGetObjectOps getObjectOps;
279 * JSCheckAccessOp checkAccess;
280 * JSNative call;
281 * JSNative construct;
282 * JSXDRObjectOp xdrObject;
283 * JSHasInstanceOp hasInstance;
284 * prword spare[2];
285 * };
286 *
287 * global JSClass - populated by stubs
288 *
289 */
290
291static char *DefaultScriptMethods = "function initialize() {}; " \
292 " function shutdown() {}; " \
293 " function eventsProcessed() {}; " \
294 " TRUE=true; FALSE=false; " \
295 " function print(x) {Browser.print(x)}; " \
296 " function println(x) {Browser.println(x)}; " \
297 " function getName() {return Browser.getName()}; "\
298 " function getVersion() {return Browser.getVersion()}; "\
299 " function getCurrentSpeed() {return Browser.getCurrentSpeed()}; "\
300 " function getCurrentFrameRate() {return Browser.getCurrentFrameRate()}; "\
301 " function getWorldURL() {return Browser.getWorldURL()}; "\
302 " function replaceWorld(x) {Browser.replaceWorld(x)}; "\
303 " function loadURL(x,y) {Browser.loadURL(x,y)}; "\
304 " function setDescription(x) {Browser.setDescription(x)}; "\
305 " function createVrmlFromString(x) {Browser.createVrmlFromString(x)}; "\
306 " function createVrmlFromURL(x,y,z) {Browser.createVrmlFromURL(x,y,z)}; "\
307 " function createX3DFromString(x) {Browser.createX3DFromString(x)}; "\
308 " function createX3DFromURL(x,y,z) {Browser.createX3DFromURL(x,y,z)}; "\
309 " function addRoute(a,b,c,d) {Browser.addRoute(a,b,c,d)}; "\
310 " function deleteRoute(a,b,c,d) {Browser.deleteRoute(a,b,c,d)}; "\
311 " function _rename_function(obj,oldf,newf) {if(typeof obj[oldf] === 'function') {obj[newf]=obj[oldf]; delete obj[oldf];}}; "\
312 "";
313
314 //" function _rename_function(obj,oldf,newf) {obj[newf]=obj[oldf]; delete obj[oldf]}; "
315
316/* housekeeping routines */
317int sm_jsIsRunning(){
318 ppJScript p = (ppJScript)gglobal()->JScript.prv;
319 return p->runtime ? 1 : 0;
320}
321void sm_JSDeleteScriptContext(int num){
322 struct CRscriptStruct *ScriptControl;
323 //ppJScript p = (ppJScript)gglobal()->JScript.prv;
324 /* printf ("kill_javascript, context is %p\n",ScriptControl[i].cx); */
325 ScriptControl = getScriptControlIndex(num);
326#if JS_VERSION >= 185
327 if (ScriptControl->eventsProcessed != NULL) {
328 JS_RemoveObjectRoot(ScriptControl->cx,(JSSCRIPT **)(&ScriptControl->eventsProcessed));
329 }
330#endif
331#if JS_VERSION < 186
332 JS_DestroyContextMaybeGC(ScriptControl->cx);
333#else
334 //JS_DestroyContext(ScriptControl->cx);
335#endif
336}
337void sm_jsShutdown(){
338 ttglobal tg = gglobal();
339 ppJScript p = (ppJScript)tg->JScript.prv;
340 if(p->runtime)
341 JS_DestroyRuntime(p->runtime);
342 p->runtime = NULL;
343}
344//========================
345
346#if JS_VERSION >= 186
347static struct keyname {
348 int key;
349 char *name;
350} gcparamname [] = {
351{JSGC_MAX_BYTES,"JSGC_MAX_BYTES"},
352{JSGC_MAX_MALLOC_BYTES, "JSGC_MAX_MALLOC_BYTES"},
353{JSGC_BYTES,"JSGC_BYTES"},
354{JSGC_NUMBER,"JSGC_NUMBER"},
355{JSGC_MAX_CODE_CACHE_BYTES,"JSGC_MAX_CODE_CACHE_BYTES"},
356{JSGC_MODE,"JSGC_MODE"},
357{JSGC_UNUSED_CHUNKS,"JSGC_UNUSED_CHUNKS"},
358{JSGC_TOTAL_CHUNKS,"JSGC_TOTAL_CHUNKS"},
359{JSGC_SLICE_TIME_BUDGET,"JSGC_SLICE_TIME_BUDGET"},
360{JSGC_MARK_STACK_LIMIT,"JSGC_MARK_STACK_LIMIT"},
361{JSGC_HIGH_FREQUENCY_TIME_LIMIT,"JSGC_HIGH_FREQUENCY_TIME_LIMIT"},
362{JSGC_HIGH_FREQUENCY_LOW_LIMIT,"JSGC_HIGH_FREQUENCY_LOW_LIMIT"},
363{JSGC_HIGH_FREQUENCY_HIGH_LIMIT,"JSGC_HIGH_FREQUENCY_HIGH_LIMIT"},
364{JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX,"JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX"},
365{JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN,"JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN"},
366{JSGC_LOW_FREQUENCY_HEAP_GROWTH,"JSGC_LOW_FREQUENCY_HEAP_GROWTH"},
367{JSGC_DYNAMIC_HEAP_GROWTH,"JSGC_DYNAMIC_HEAP_GROWTH"},
368{JSGC_DYNAMIC_MARK_SLICE,"JSGC_DYNAMIC_MARK_SLICE"},
369{JSGC_ANALYSIS_PURGE_TRIGGER,"JSGC_ANALYSIS_PURGE_TRIGGER"},
370{-1,NULL},
371};
372#else //186
373//<= 185
374static struct keyname {
375 int key;
376 char *name;
377} gcparamname [] = {
378{JSGC_MAX_BYTES,"JSGC_MAX_BYTES"},
379{JSGC_MAX_MALLOC_BYTES, "JSGC_MAX_MALLOC_BYTES"},
380{JSGC_STACKPOOL_LIFESPAN,"JSGC_STACKPOOL_LIFESPAN"},
381{JSGC_TRIGGER_FACTOR,"JSGC_TRIGGER_FACTOR"},
382{JSGC_BYTES,"JSGC_BYTES"},
383{JSGC_NUMBER,"JSGC_NUMBER"},
384{JSGC_MAX_CODE_CACHE_BYTES,"JSGC_MAX_CODE_CACHE_BYTES"},
385{JSGC_MODE,"JSGC_MODE"},
386{JSGC_UNUSED_CHUNKS,"JSGC_UNUSED_CHUNKS"},
387{-1,NULL},
388};
389#endif //186
390const char *getgcparamname(int key){
391 int i = 0;
392 while(gcparamname[i].name != NULL){
393 if(gcparamname[i].key == key){
394 return gcparamname[i].name;
395 }
396 i++;
397 }
398 return "NULL";
399}
400//void reportError(JSContext *cx, const char *message, JSErrorReport *report) {
401// printf("%s:%u:%s\n",
402// report->filename ? report->filename : "[no filename]",
403// (unsigned int) report->lineno,
404// message);
405//}
406
407
408
409/* create the script context for this script. This is called from the thread
410 that handles script calling in the fwl_RenderSceneUpdateScene */
411void sm_JSCreateScriptContext(int num) {
412 jsval rval;
413 JSContext *_context; /* these are set here */
414 JSObject *_globalObj; /* these are set here */
415 BrowserNative *br; /* these are set here */
416 ppJScript p = (ppJScript)gglobal()->JScript.prv;
417 struct CRscriptStruct *ScriptControl;
418
419 ScriptControl = getScriptControlIndex(num);
420
421 /* is this the first time through? */
422 if (p->runtime == NULL) {
423 p->runtime = JS_NewRuntime(MAX_RUNTIME_BYTES);
424 if (!p->runtime) freewrlDie("JS_NewRuntime failed");
425 #ifdef JAVASCRIPTVERBOSE
426 printf("\tJS runtime created,\n");
427 #endif
428 #ifdef DEBUG
429 // https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_GetGCParameter
430 int iend = JS_VERSION == 185 ? 8 : JS_VERSION == 186 ? 19 : 0;
431 for(unsigned int i=0; i<= iend; i++){
432 unsigned int gcparam = JS_GetGCParameter(p->runtime,i);
433 printf("%s = %u\n",getgcparamname(i),gcparam);
434 }
435 //#if JS_VERSION == 186
436 // JS_SetGCParameter(p->runtime,JSGC_MODE,JSGC_MODE_INCREMENTAL);
437 // JS_SetGCParameter(p->runtime,JSGC_SLICE_TIME_BUDGET,100); //miliseconds
438 //#endif
439 #endif //DEBUG
440 }
441
442
443 _context = JS_NewContext(p->runtime, STACK_CHUNK_SIZE);
444 if (!_context) freewrlDie("JS_NewContext failed");
445 #ifdef DEBUG
446 unsigned int opts = JS_GetOptions(_context);
447 printf("options %x\n",opts);
448 #endif //DEBUG
449 //JS_SetErrorReporter(_context, reportError);
450
451 #ifdef JAVASCRIPTVERBOSE
452 printf("\tJS context created,\n");
453 #endif
454
455#if defined(JS_THREADSAFE)
456 JS_BeginRequest(_context);
457#endif
458 //#if JS_VERSION == 186
459 // JS_SetGCParameterForThread(_context,JSGC_MODE,JSGC_MODE_INCREMENTAL);
460 // JS_SetGCParameterForThread(_context,JSGC_SLICE_TIME_BUDGET,100); //miliseconds
461 //#endif
462
463 #if JS_VERSION >= 185
464 if (num == 0 && JS_VERSION < 186) {
465 #if JS_VERSION < 186
466 _globalObj = JS_NewCompartmentAndGlobalObject(_context, &p->globalClass, NULL);
467 #endif
468 } else {
469 struct CRscriptStruct *cs = getScriptControlIndex(0);
470 JS_SetGlobalObject(_context,cs->glob); //ScriptControl[0].glob);
471 _globalObj = JS_NewGlobalObjectFw(_context,&p->globalClass);
472 JS_SetGlobalObject(_context,_globalObj);
473 }
474 #else
475 _globalObj = JS_NewObject(_context, &p->globalClass, NULL, NULL);
476 #endif
477 //#ifdef JS_GC_ZEAL
478 //JS_SetGCZeal(_context, 2, 100);
479 //#endif
480#if defined(JS_THREADSAFE)
481 JS_EndRequest(_context);
482#endif
483 if (!_globalObj) freewrlDie("JS_NewObject failed");
484
485 #ifdef JAVASCRIPTVERBOSE
486 printf("\tJS global object created,\n");
487 #endif
488
489
490 /* gets JS standard classes */
491#if defined(JS_THREADSAFE)
492 JS_BeginRequest(_context);
493#endif
494 if (!JS_InitStandardClasses(_context, _globalObj))
495#if defined(JS_THREADSAFE)
496 { JS_EndRequest(_context);
497#endif
498 freewrlDie("JS_InitStandardClasses failed");
499#if defined(JS_THREADSAFE)
500 } else {
501 JS_EndRequest(_context);
502 }
503#endif
504 #ifdef JAVASCRIPTVERBOSE
505 printf("\tJS standard classes initialized,\n");
506 #endif
507
508 #ifdef JAVASCRIPTVERBOSE
509 reportWarningsOn();
510 #endif
511
512 JS_SetErrorReporter(_context, errorReporter);
513
514 #ifdef JAVASCRIPTVERBOSE
515 printf("\tJS error reporter set,\n");
516 #endif
517
518 br = (BrowserNative *) JS_malloc(_context, sizeof(BrowserNative));
519
520 /* for this script, here are the necessary data areas */
521 ScriptControl->cx = _context;
522 ScriptControl->glob = _globalObj;
523 if(SM_method()==2){
524 JS_SetPrivateFw(_context,_globalObj,ScriptControl->script); //in get/setECMAtype we need our C script struct
525 }
526
527
528#if defined(JS_THREADSAFE)
529 JS_BeginRequest(_context);
530#endif
531 if (!loadVrmlClasses(_context, _globalObj))
532#if defined(JS_THREADSAFE)
533 { JS_EndRequest(_context);
534#endif
535 freewrlDie("loadVrmlClasses failed");
536#if defined(JS_THREADSAFE)
537 } else {
538 JS_EndRequest(_context);
539 }
540#endif
541
542
543 #ifdef JAVASCRIPTVERBOSE
544 printf("\tVRML classes loaded,\n");
545 #endif
546
547#if defined(JS_THREADSAFE)
548 JS_BeginRequest(_context);
549#endif
550 if (!VrmlBrowserInit(_context, _globalObj, br))
551#if defined(JS_THREADSAFE)
552 { JS_EndRequest(_context);
553#endif
554 freewrlDie("VrmlBrowserInit failed");
555#if defined(JS_THREADSAFE)
556 } else {
557 JS_EndRequest(_context);
558 }
559#endif
560
561 #ifdef JAVASCRIPTVERBOSE
562 printf("\tVRML Browser interface loaded,\n");
563 #endif
564
565
566 if (!ACTUALRUNSCRIPT(num,DefaultScriptMethods,&rval))
567 cleanupDie(num,"runScript failed in VRML::newJS DefaultScriptMethods");
568
569 /* send this data over to the routing table functions. */
570 CRoutes_js_new (num, JAVASCRIPT);
571
572 #ifdef JAVASCRIPTVERBOSE
573 printf("\tVRML browser initialized, thread %u\n",pthread_self());
574 #endif
575}
576int getJsEngineVariant();
577int SM_method(){
578 return getJsEngineVariant() == 2? 2 : 0;
579 //return 2; //new way dec 31, 2017
580 //return 0; //old way before dec 31, 2017
581}
582
583/* run the script from within C */
584#ifdef JAVASCRIPTVERBOSE
585int ActualrunScript(int num, char *script, jsval *rval, char *fn, int line) {
586#else
587int ActualrunScript(int num, char *script, jsval *rval) {
588#endif
589 int len;
590 JSContext *_context;
591 JSObject *_globalObj;
592 struct CRscriptStruct *ScriptControl;
593
594 ScriptControl = getScriptControlIndex(num);
595 /* get context and global object for this script */
596 _context = (JSContext*)ScriptControl->cx;
597 _globalObj = (JSObject*)ScriptControl->glob;
598
599 #ifdef JAVASCRIPTVERBOSE
600 printf("ActualrunScript script called at %s:%d num: %d cx %p \"%s\", \n",
601 fn, line, num, _context, script);
602 #endif
603
604#if defined(JS_THREADSAFE)
605 JS_BeginRequest(_context);
606#endif
607 //CLEANUP_JAVASCRIPT(_context)
608 js_cleanup_script_context(num);
609#if defined(JS_THREADSAFE)
610 JS_EndRequest(_context);
611#endif
612
613 len = (int) strlen(script);
614#if defined(JS_THREADSAFE)
615 JS_BeginRequest(_context);
616#endif
617 if (!JS_EvaluateScript(_context, _globalObj, script, len, FNAME_STUB, LINENO_STUB, rval)) {
618 printf ("ActualrunScript - JS_EvaluateScript failed for %s", script);
619 printf ("\n");
620 ConsoleMessage ("ActualrunScript - JS_EvaluateScript failed for %s", script);
621#if defined(JS_THREADSAFE)
622 JS_EndRequest(_context);
623#endif
624 return JS_FALSE;
625#if defined(JS_THREADSAFE)
626 } else {
627 JS_EndRequest(_context);
628#endif
629 }
630 #ifdef JAVASCRIPTVERBOSE
631 printf ("runscript passed\n");
632 #endif
633
634 return JS_TRUE;
635}
636
637int sm_jsActualrunScript(int num, char *script) {
638 jsval rval; //discard
639 return ACTUALRUNSCRIPT(num,script,&rval);
640}
641
642/* run the script from within Javascript */
643int jsrrunScript(JSContext *_context, JSObject *_globalObj, char *script, jsval *rval) {
644
645 int len;
646
647 #ifdef JAVASCRIPTVERBOSE
648 printf("jsrrunScript script cx %p \"%s\", \n",
649 _context, script);
650 #endif
651
652 len = (int) strlen(script);
653#if defined(JS_THREADSAFE)
654 JS_BeginRequest(_context);
655#endif
656 if (!JS_EvaluateScript(_context, _globalObj, script, len,
657 FNAME_STUB, LINENO_STUB, rval)) {
658 ConsoleMessage ("jsrunScript - JS_EvaluateScript failed for %s", script);
659#if defined(JS_THREADSAFE)
660 JS_EndRequest(_context);
661#endif
662 return JS_FALSE;
663#if defined(JS_THREADSAFE)
664 } else {
665 JS_EndRequest(_context);
666#endif
667 }
668
669 #ifdef JAVASCRIPTVERBOSE
670 printf ("runscript passed\n");
671 #endif
672
673 return JS_TRUE;
674}
675
676//put source = NULL if you want it to malloc
677//if its a script field, send in the pointer to the script field valuechanged, or NULL if new thing()
678int sizeofSForMF(int itype);
679void *AnyNativeNew(int type, union anyVrml* source, int *valueChanged){
680 AnyNative *ptr;
681 ptr = MALLOC(AnyNative *,sizeof(AnyNative));
682 memset(ptr,0,sizeof(AnyNative));
683 ptr->type = type;
684 ptr->valueChanged = valueChanged;
685 ptr->v = source;
686 ptr->gc = 0;
687 if(ptr->v == NULL){
688 ptr->v = MALLOC(void *,sizeofSForMF(type));
689 memset(ptr->v,0,sizeofSForMF(type));
690 ptr->gc = 1;
691 }
692 return ptr;
693}
694void shallow_copy_field(int typeIndex, union anyVrml* source, union anyVrml* dest);
695void AnyNativeAssign(void *top, void *fromp)
696{
697 if(top != fromp){
698 AnyNative *to = (AnyNative *)top;
699 AnyNative *from = (AnyNative *)fromp;
700 if(to->type == from->type){
701 if(to->valueChanged)
702 (*to->valueChanged) ++;
703 //shallow assumes the top has already been malloced (just base part of MF needed)
704 //use this if you need to malloc anyvrml: int sizeofSForMF(int itype)
705 shallow_copy_field(from->type,from->v,to->v);
706 }
707 }
708}
709/* FROM VRMLC.pm */
710void *SFNodeNativeNew()
711{
712 SFNodeNative *ptr;
713 ptr = MALLOC(SFNodeNative *, sizeof(*ptr));
714
715 /* printf ("SFNodeNativeNew; string len %d handle_len %d\n",vrmlstring_len,handle_len);*/
716
717 ptr->handle = 0;
718 ptr->valueChanged = 0;
719 if(SM_method() == 0){
720 ptr->X3DString = NULL;
721 ptr->fieldsExpanded = FALSE;
722 }
723 return ptr;
724}
725
726/* assign this internally to the Javascript engine environment */
727int SFNodeNativeAssign(void *top, void *fromp)
728{
729 SFNodeNative *to = (SFNodeNative *)top;
730 SFNodeNative *from = (SFNodeNative *)fromp;
731
732 /* indicate that this was touched; and copy contents over */
733 to->valueChanged++;
734
735 if (from != NULL) {
736 to->handle = from->handle;
737 if(SM_method() == 0)
738 to->X3DString = STRDUP(from->X3DString);
739
740 #ifdef JAVASCRIPTVERBOSE
741 printf ("SFNodeNativeAssign, copied %p to %p, handle %p, string %s\n", from, to, to->handle, to->X3DString);
742 #endif
743 } else {
744 to->handle = 0;
745 if(SM_method() == 0)
746 to->X3DString = STRDUP("from a NULL assignment");
747 }
748
749 return JS_TRUE;
750}
751/* assign this internally to the Javascript engine environment */
752int SFNodeNativeEquals(void *top, void *fromp)
753{
754 int equal;
755 SFNodeNative *to = (SFNodeNative *)top;
756 SFNodeNative *from = (SFNodeNative *)fromp;
757
758 equal = 0;
759
760 if (from != NULL) {
761 if(to->handle == from->handle)
762 equal=1;
763 }
764
765 return equal;// ? JS_TRUE : JS_FALSE;
766}
767
768void *SFColorRGBANativeNew()
769{
771 ptr = MALLOC(SFColorRGBANative *, sizeof(*ptr));
772 ptr->valueChanged = 0;
773 return ptr;
774}
775
776void SFColorRGBANativeAssign(void *top, void *fromp)
777{
779 SFColorRGBANative *from = (SFColorRGBANative *)fromp;
780 to->valueChanged ++;
781 (to->v) = (from->v);
782}
783
784void *SFColorNativeNew()
785{
786 SFColorNative *ptr;
787 ptr = MALLOC(SFColorNative *, sizeof(*ptr));
788 ptr->valueChanged = 0;
789 return ptr;
790}
791
792void SFColorNativeAssign(void *top, void *fromp)
793{
794 SFColorNative *to = (SFColorNative *)top;
795 SFColorNative *from = (SFColorNative *)fromp;
796 to->valueChanged++;
797 (to->v) = (from->v);
798}
799
800void *SFImageNativeNew()
801{
802 SFImageNative *ptr;
803 ptr =MALLOC(SFImageNative *, sizeof(*ptr));
804 ptr->valueChanged = 0;
805 return ptr;
806}
807
808void SFImageNativeAssign(void *top, void *fromp)
809{
810 SFImageNative *to = (SFImageNative *)top;
811 /* SFImageNative *from = fromp; */
812 UNUSED(fromp);
813
814 to->valueChanged++;
815/* (to->v) = (from->v); */
816}
817
818void *SFRotationNativeNew()
819{
820 SFRotationNative *ptr;
821 ptr = MALLOC(SFRotationNative *, sizeof(*ptr));
822 ptr->valueChanged = 0;
823 return ptr;
824}
825
826void SFRotationNativeAssign(void *top, void *fromp)
827{
829 SFRotationNative *from = (SFRotationNative *)fromp;
830 to->valueChanged++;
831 (to->v) = (from->v);
832}
833
834void *SFVec2fNativeNew()
835{
836 SFVec2fNative *ptr;
837 ptr = MALLOC(SFVec2fNative *, sizeof(*ptr));
838 ptr->valueChanged = 0;
839 return ptr;
840}
841
842void SFVec2fNativeAssign(void *top, void *fromp)
843{
844 SFVec2fNative *to = (SFVec2fNative *)top;
845 SFVec2fNative *from = (SFVec2fNative *)fromp;
846 to->valueChanged++;
847 (to->v) = (from->v);
848}
849
850void *SFVec3fNativeNew() {
851 SFVec3fNative *ptr;
852 ptr = MALLOC(SFVec3fNative *, sizeof(*ptr));
853 ptr->valueChanged = 0;
854 return ptr;
855}
856
857void SFVec3fNativeAssign(void *top, void *fromp) {
858 SFVec3fNative *to = (SFVec3fNative *)top;
859 SFVec3fNative *from = (SFVec3fNative *)fromp;
860 to->valueChanged++;
861 (to->v) = (from->v);
862}
863
864void *SFVec3dNativeNew() {
865 SFVec3dNative *ptr;
866 ptr = MALLOC(SFVec3dNative *, sizeof(*ptr));
867 ptr->valueChanged = 0;
868 return ptr;
869}
870
871void SFVec3dNativeAssign(void *top, void *fromp) {
872 SFVec3dNative *to = (SFVec3dNative *)top;
873 SFVec3dNative *from = (SFVec3dNative *)fromp;
874 to->valueChanged++;
875 (to->v) = (from->v);
876}
877
878void *SFVec4fNativeNew() {
879 SFVec4fNative *ptr;
880 ptr = MALLOC(SFVec4fNative *, sizeof(*ptr));
881 ptr->valueChanged = 0;
882 return ptr;
883}
884
885void SFVec4fNativeAssign(void *top, void *fromp) {
886 SFVec4fNative *to = (SFVec4fNative *)top;
887 SFVec4fNative *from = (SFVec4fNative *)fromp;
888 to->valueChanged++;
889 (to->v) = (from->v);
890}
891
892void *SFVec4dNativeNew() {
893 SFVec4dNative *ptr;
894 ptr = MALLOC(SFVec4dNative *, sizeof(*ptr));
895 ptr->valueChanged = 0;
896 return ptr;
897}
898
899void SFVec4dNativeAssign(void *top, void *fromp) {
900 SFVec4dNative *to = (SFVec4dNative *)top;
901 SFVec4dNative *from = (SFVec4dNative *)fromp;
902 to->valueChanged++;
903 (to->v) = (from->v);
904}
905
906
907
908static char* re_strcat(char *_Dest, char *_Source, int *destLen, int *destDim)
909{
910 /* strcats, but first checks strlen on source and destination
911 and reallocs if necessary - good when you are doing a lot of strcatting of un-pre-known elements
912 (Q. is there something for this already?)
913 _Dest, _Source - as with strcat(_Dest,_Source)
914 destLen - current cumulative strlen(_Dest)
915 destDim - current malloc/realloc dimension
916 Usage example:
917 dstdim = (rows+1)*(elements*15) + 100; //a guess
918 dstlen = 0;
919 smallfield = MALLOC (char *, dstdim+1); //rows+1)*(elements*15) + 100);
920 smallfield[0] = '\0';
921 ...
922 for(;;)
923 {
924 ...
925 smallfield = re_strcat(smallfield, "new ",&dstlen,&dstdim);
926 ...
927 FREE_IF_NZ(smallfield)
928 */
929 int srclen = (int) strlen(_Source);
930 *destLen = *destLen + srclen;
931 if(*destLen > *destDim -1)
932 {
933 *destDim = *destDim + srclen + 1 + 100;
934 _Dest = REALLOC(_Dest,*destDim);
935 }
936 _Dest = strcat(_Dest,_Source);
937 return _Dest;
938}
939/* the fwl_RenderSceneUpdateScene is initializing this field now */
940/* A new version of InitScriptField which takes "nicer" arguments; currently a
941 * simple and restricted wrapper, but it could replace it soon? */
942/* Parameters:
943 num: Script number. Starts at 0.
944 kind: One of PKW_initializeOnly PKW_outputOnly PKW_inputOutput PKW_inputOnly
945 type: One of the FIELDTYPE_ defines, eg, FIELDTYPE_MFFloat
946 field: the field name as found in the VRML/X3D file. eg "set_myField"
947
948*/
949void InitScriptField(int num, indexT kind, indexT type, const char* field, union anyVrml value) {
950 jsval rval;
951 char *smallfield = NULL;
952 char mynewname[400];
953 char *thisValue;
954 int rows, elements;
955 char *sftype = NULL;
956
957 int haveMulti;
958 int MFhasECMAtype;
959 int rowCount, eleCount;
960
961 int tlen;
962 float *FloatPtr;
963 struct X3D_Node **VoidPtr;
964 int *IntPtr;
965 double *DoublePtr;
966 struct Uni_String **SVPtr;
967
968 float defaultFloat[] = {0.0f,0.0f,0.0f,0.0f};
969 int defaultInt[] = {0,0,0,0};
970 double defaultDouble[] = {0.0, 0.0, 0.0, 0.0};
971 struct Uni_String *sptr[1];
972 struct X3D_Node *defaultVoid[] = {NULL,NULL};
973 struct CRscriptStruct *ScriptControl; //= getScriptControl();
974
975 #ifdef JAVASCRIPTVERBOSE
976 printf ("calling InitScriptField from thread %u\n",pthread_self());
977 printf ("\nInitScriptField, num %d, kind %s type %s field %s value %d\n", num,PROTOKEYWORDS[kind],FIELDTYPES[type],field,value);
978 #endif
979
980 if ((kind != PKW_inputOnly) && (kind != PKW_outputOnly) && (kind != PKW_initializeOnly) && (kind != PKW_inputOutput)) {
981 ConsoleMessage ("InitScriptField: invalid kind for script: %d\n",kind);
982 return;
983 }
984
985 if (type >= FIELDTYPES_COUNT) {
986 ConsoleMessage ("InitScriptField: invalid type for script: %d\n",type);
987 return;
988 }
989 ScriptControl = getScriptControlIndex(num);
990
991 /* first, make a new name up */
992 //if (kind == PKW_inputOnly ) {
993 // sprintf (mynewname,"__eventIn_Value_%s",field);
994 // //strcpy(mynewname,field);
995 //}else
996 if (kind == PKW_inputOutput) {
997 //check if user added an eventIn function with the same basename,
998 // which is allowed with inputOutput fields
999 JSContext *cx;
1000 JSObject *obj;
1001 jsval retval;
1002 cx = (JSContext*)ScriptControl->cx;
1003 obj = (JSObject*)ScriptControl->glob;
1004
1005 if (JS_GetProperty(cx,obj,field,&retval)){
1006 if (JSVAL_IS_OBJECT(retval)){
1007 //I think functions are objects, doesn't seem to be a JSVAL_IS_FUNC
1008 char runstring[STRING_SIZE];
1009 // rename fieldname to set_fieldname
1010 sprintf(runstring,"_rename_function(this,'%s','set_%s');",field,field);
1011 //printf("%s\n",runstring);
1012 #if defined(JS_THREADSAFE)
1013 JS_BeginRequest(cx);
1014 #endif
1015 if(!JS_EvaluateScript(cx,obj, runstring, (int) strlen(runstring), FNAME_STUB, LINENO_STUB, &retval)){
1016 printf("sorry couldn't rename function: %s",runstring);
1017 }
1018 #if defined(JS_THREADSAFE)
1019 JS_EndRequest(cx);
1020 #endif
1021 }
1022 }
1023 strcpy(mynewname,field); //now this is OK, won't overwrite function
1024 // and if so rename it to set_
1025 }else strcpy(mynewname,field);
1026
1027 /* ok, lets handle the types here */
1028 switch (type) {
1029 /* ECMA types */
1030 case FIELDTYPE_SFBool:
1031 case FIELDTYPE_SFFloat:
1032 case FIELDTYPE_SFTime:
1033 case FIELDTYPE_SFDouble:
1034 case FIELDTYPE_SFInt32:
1035 case FIELDTYPE_SFString: {
1036 /* do not care about eventIns */
1037 if (kind != PKW_inputOnly) {
1038 JSaddGlobalECMANativeProperty(num, field);
1039 if (kind == PKW_initializeOnly || kind == PKW_inputOutput) {
1040 if (type == FIELDTYPE_SFString) {
1041 tlen = (int) strlen(value.sfstring->strptr) + strlen(field) + 20;
1042 } else {
1043 tlen = (int) strlen(field) + 400; /* long, in the case of doubles */
1044 }
1045 smallfield = MALLOC (char *, tlen);
1046 smallfield[0] = '\0';
1047
1048 switch (type) {
1049 case FIELDTYPE_SFFloat: sprintf (smallfield,"%s=%f\n",field,value.sffloat);break;
1050 case FIELDTYPE_SFTime: sprintf (smallfield,"%s=%f\n",field,value.sftime);break;
1051 case FIELDTYPE_SFDouble: sprintf (smallfield,"%s=%f\n",field,value.sftime);break;
1052 case FIELDTYPE_SFInt32: sprintf (smallfield,"%s=%d\n",field,value.sfint32); break;
1053 case FIELDTYPE_SFBool:
1054 if (value.sfbool == 1) sprintf (smallfield,"%s=true",field);
1055 else sprintf (smallfield,"%s=false",field);
1056 break;
1057 case FIELDTYPE_SFString:
1058 sprintf (smallfield,"%s=\"%s\"\n",field,value.sfstring->strptr); break;
1059 }
1060
1061 if (!ACTUALRUNSCRIPT(num,smallfield,&rval))
1062 printf ("huh??? Field initialization script failed %s\n",smallfield);
1063 }
1064 }
1065 break;
1066 }
1067 /* non ECMA types */
1068 default: {
1069 /* get an appropriate pointer - we either point to the initialization value
1070 in the script header, or we point to some data here that are default values */
1071
1072 /* does this MF type have an ECMA type as a single element? */
1073 switch (type) {
1074 case FIELDTYPE_MFString:
1075 case FIELDTYPE_MFTime:
1076 case FIELDTYPE_MFBool:
1077 case FIELDTYPE_MFInt32:
1078 case FIELDTYPE_MFFloat:
1079 JSaddGlobalECMANativeProperty(num, field);
1080 MFhasECMAtype = TRUE;
1081 break;
1082 default: {
1083 MFhasECMAtype = FALSE;
1084 }
1085 }
1086
1087 elements=0;
1088 IntPtr = NULL;
1089 FloatPtr = NULL;
1090 DoublePtr = NULL;
1091 SVPtr = NULL;
1092 VoidPtr = NULL;
1093 if (kind == PKW_initializeOnly || kind == PKW_inputOutput) {
1094 switch (type) {
1095 //case FIELDTYPE_SFImage:
1096 // VoidPtr = (struct X3D_Node **) (&(value.sfimage)); elements = 1;
1097 // break;
1098 case FIELDTYPE_SFNode:
1099 VoidPtr = (struct X3D_Node **) (&(value.sfnode)); elements = 1;
1100 break;
1101 case FIELDTYPE_MFColor:
1102 FloatPtr = (float *) value.mfcolor.p; elements = value.mfcolor.n;
1103 break;
1104 case FIELDTYPE_MFColorRGBA:
1105 FloatPtr = (float *) value.mfcolorrgba.p; elements = value.mfcolorrgba.n;
1106 break;
1107 case FIELDTYPE_MFVec2f:
1108 FloatPtr = (float *) value.mfvec2f.p; elements = value.mfvec2f.n;
1109 break;
1110 case FIELDTYPE_MFVec3f:
1111 FloatPtr = (float *) value.mfvec3f.p; elements = value.mfvec3f.n;
1112 break;
1113 case FIELDTYPE_MFRotation:
1114 FloatPtr = (float *) value.mfrotation.p; elements = value.mfrotation.n;
1115 break;
1116 case FIELDTYPE_SFVec2f:
1117 FloatPtr = (float *) value.sfvec2f.c; elements = 1;
1118 break;
1119 case FIELDTYPE_SFColor:
1120 FloatPtr = value.sfcolor.c; elements = 1;
1121 break;
1122 case FIELDTYPE_SFColorRGBA:
1123 FloatPtr = value.sfcolorrgba.c; elements = 1;
1124 break;
1125 case FIELDTYPE_SFRotation:
1126 FloatPtr = value.sfrotation.c; elements = 1;
1127 break;
1128 case FIELDTYPE_SFVec3f:
1129 FloatPtr = value.sfvec3f.c; elements =1;
1130 break;
1131 case FIELDTYPE_SFVec3d:
1132 DoublePtr = value.sfvec3d.c; elements =1;
1133 break;
1134 case FIELDTYPE_MFString:
1135 SVPtr = value.mfstring.p; elements = value.mfstring.n;
1136 break;
1137 case FIELDTYPE_MFTime:
1138 DoublePtr = value.mftime.p; elements = value.mftime.n;
1139 break;
1140 case FIELDTYPE_MFBool:
1141 IntPtr = value.mfbool.p; elements = value.mfbool.n;
1142 break;
1143 case FIELDTYPE_SFImage:
1144 case FIELDTYPE_MFInt32:
1145 IntPtr = value.mfint32.p; elements = value.mfint32.n;
1146 break;
1147 case FIELDTYPE_MFNode:
1148 VoidPtr = (struct X3D_Node **)(value.mfnode.p); elements = value.mfnode.n;
1149 break;
1150 case FIELDTYPE_MFFloat:
1151 FloatPtr = value.mffloat.p; elements = value.mffloat.n;
1152 break;
1153 case FIELDTYPE_SFVec4f:
1154 FloatPtr = value.sfvec4f.c; elements = 1;
1155 break;
1156 case FIELDTYPE_SFVec4d:
1157 DoublePtr = value.sfvec4d.c; elements = 1;
1158 break;
1159
1160 default: {
1161 printf ("unhandled type, in InitScriptField %d\n",type);
1162 return;
1163 }
1164 }
1165
1166 } else {
1167 /* make up a default pointer */
1168 elements = 1;
1169 switch (type) {
1170 /* Void types */
1171 case FIELDTYPE_SFNode:
1172 case FIELDTYPE_MFNode:
1173 VoidPtr = (struct X3D_Node **) &defaultVoid;
1174 break;
1175
1176 /* Float types */
1177 case FIELDTYPE_MFColor:
1178 case FIELDTYPE_MFColorRGBA:
1179 case FIELDTYPE_MFVec2f:
1180 case FIELDTYPE_MFVec3f:
1181 case FIELDTYPE_MFRotation:
1182 case FIELDTYPE_SFVec2f:
1183 case FIELDTYPE_SFColor:
1184 case FIELDTYPE_SFColorRGBA:
1185 case FIELDTYPE_SFRotation:
1186 case FIELDTYPE_SFVec3f:
1187 case FIELDTYPE_SFVec4f:
1188 case FIELDTYPE_MFFloat:
1189 FloatPtr = defaultFloat;
1190 break;
1191
1192 /* Int types */
1193 case FIELDTYPE_MFBool:
1194 case FIELDTYPE_MFInt32:
1195 IntPtr = defaultInt;
1196 break;
1197
1198 /* String types */
1199 case FIELDTYPE_SFString:
1200 case FIELDTYPE_MFString:
1201 sptr[0] = newASCIIString("");
1202 SVPtr = sptr;
1203 break;
1204
1205 /* SFImage */
1206 case FIELDTYPE_SFImage:
1207 IntPtr = defaultInt;
1208 break;
1209
1210 /* Double types */
1211 case FIELDTYPE_SFVec2d:
1212 case FIELDTYPE_SFVec3d:
1213 case FIELDTYPE_MFTime:
1214 case FIELDTYPE_SFTime:
1215 case FIELDTYPE_SFDouble:
1216 case FIELDTYPE_SFVec4d:
1217 DoublePtr = defaultDouble;
1218 break;
1219
1220 default: {
1221 printf ("unhandled type, in InitScriptField part 2 %d\n",type);
1222 return;
1223 }
1224 }
1225
1226 }
1227
1228 rows = returnElementRowSize (type);
1229
1230 #ifdef JAVASCRIPTVERBOSE
1231 printf ("in fieldSet, we have ElementRowSize %d and individual elements %d\n",rows,elements);
1232 #endif
1233
1234 /* make this at least as large as required, then add some more on to the end... */
1235 /*
1236 Old Approach
1237 step1: compute using guestimate formulas
1238 step2: malloc
1239 step3: loop through strcat() and hope no overrun
1240 Problem: heap corruption from array overrun - the guestimate has been bad
1241 a few times in 2010 with MFVec2fs and MFStrings with 42 and 47 elements, strings of varying length
1242 example for MFVec2f
1243 'new MFVec2f(new SFVec2f(1234.678910,1234.678910),...)'
1244 each SF 2 numbers each 10 digits plus new type(,), 15 chars =35.
1245 3 x 15 = 45 (or (rows+1)x(elements*15)+100)
1246 old formula falls short:
1247 old formula: smallfield = MALLOC (rows*((elements*15) + 100));
1248 example 47 SFVec2fs
1249 actual bytes: 47 x 35 bytes = 1645 + 13 for the MF = 1658
1250 old formula 2 x ((47*15)+100) = 1610 //thats 48 bytes short and I bomb out
1251 better formula 3 x (47*15) + 100 = 2215
1252 New Approach (July 28, 2010)
1253 step1: compute using guestimate formulas
1254 step2: malloc
1255 step3: loop through and realloc before strcat() if short
1256 */
1257 {
1258 int dstlen, dstdim, tdim;
1259 tdim = 200;
1260 thisValue = MALLOC(char *, tdim+1);
1261 dstdim = (rows+1)*(elements*15) + 100; /* a guess */
1262 dstlen = 0;
1263 smallfield = MALLOC (char *, dstdim+1); //rows+1)*(elements*15) + 100);
1264 /* what is the equivalent SF for this MF?? */
1265 if (type != convertToSFType(type)) haveMulti = TRUE;
1266 else haveMulti = FALSE;
1267
1268 /* the sftype is the SF form of either the MF or SF */
1269 sftype = STRDUP((char *)FIELDTYPES[convertToSFType(type)]);
1270
1271 /* SFStrings are Strings */
1272 if (strncmp(sftype,"SFString",8)==0) strcpy (sftype,"String");
1273
1274
1275 /* start the string */
1276 smallfield[0] = '\0';
1277
1278 /* is this an MF variable, with SFs in it? */
1279 if (haveMulti) {
1280 smallfield = re_strcat(smallfield, "new ",&dstlen,&dstdim);
1281 smallfield = re_strcat(smallfield, (char *)FIELDTYPES[type],&dstlen,&dstdim);
1282 smallfield = re_strcat(smallfield, "(",&dstlen,&dstdim);
1283 }
1284
1285 /* loop through, and put values in */
1286 for (eleCount=0; eleCount<elements; eleCount++) {
1287 /* ECMA native types can just be passed in... */
1288 if (!MFhasECMAtype) {
1289 smallfield = re_strcat(smallfield, "new ",&dstlen,&dstdim);
1290 smallfield = re_strcat(smallfield, sftype,&dstlen,&dstdim);
1291 smallfield = re_strcat(smallfield, "(",&dstlen,&dstdim);
1292 }
1293
1294 /* go through the SF type; SFints will have 1; SFVec3f's will have 3, etc */
1295 for (rowCount=0; rowCount<rows; rowCount++ ) {
1296 if (IntPtr != NULL) {
1297 sprintf (thisValue,"%d",*IntPtr); IntPtr++;
1298 } else if (FloatPtr != NULL) {
1299 sprintf (thisValue,"%f",*FloatPtr); FloatPtr++;
1300 } else if (DoublePtr != NULL) {
1301 sprintf (thisValue,"%f",*DoublePtr); DoublePtr++;
1302 } else if (SVPtr != NULL) {
1303 sptr[0] = *SVPtr; SVPtr++;
1304 if((int)strlen(sptr[0]->strptr)+2 > tdim-1)
1305 {
1306 tdim = (int) strlen(sptr[0]->strptr) + 1 + 100;
1307 thisValue = REALLOC(thisValue,tdim);
1308 }
1309 sprintf (thisValue,"\"%s\"",sptr[0]->strptr);
1310 } else { /* must be a Void */
1311 /* printf ("sending in a VoidPtr, it is %p\n",VoidPtr[0]);
1312 if (VoidPtr[0] != NULL) {printf ("it is a %s type\n",stringNodeType(X3D_NODE(VoidPtr[0])->_nodeType));} */
1313 sprintf (thisValue,"\"%p\"", VoidPtr[0]); VoidPtr++;
1314 }
1315 smallfield = re_strcat(smallfield, thisValue,&dstlen,&dstdim);
1316 if (rowCount < (rows-1)) smallfield = re_strcat(smallfield,",",&dstlen,&dstdim);
1317 }
1318
1319 if (!MFhasECMAtype) smallfield = re_strcat(smallfield, ")",&dstlen,&dstdim);
1320 if (eleCount < (elements-1)) smallfield = re_strcat(smallfield,",",&dstlen,&dstdim);
1321
1322 }
1323
1324
1325 if (haveMulti) {
1326 smallfield = re_strcat(smallfield,")",&dstlen,&dstdim);
1327 }
1328 /* printf("dstlen=%d dstdim=%d\n",dstlen,dstdim); */
1329 FREE_IF_NZ (thisValue);
1330 }
1331 /* Warp factor 5, Dr Sulu... */
1332 #ifdef JAVASCRIPTVERBOSE
1333 printf ("JScript, for non-ECMA newname %s, sending :%s:\n",mynewname,smallfield);
1334 #endif
1335
1336 JSaddGlobalAssignProperty (num,mynewname,smallfield);
1337 }
1338 }
1339
1340 /* Fields can generate an event, so we allow the touched flag to remain set. eventOuts have just
1341 been initialized, and as such, should not send events, until after they really have been set.
1342 */
1343 if (kind == PKW_outputOnly) {
1344 int fptr;
1345 int touched;
1346
1347 UNUSED(touched); // compiler warning mitigation
1348
1349 /* get the number representing this type */
1350 fptr = JSparamIndex (field, FIELDTYPES[type],kind);
1351
1352 /* set up global variables so that we can reset the touched flag */
1353 touched = get_valueChanged_flag (fptr, num);
1354
1355 /* and, reset the touched flag, knowing that we have the variables set properly */
1356 resetScriptTouchedFlag(num, fptr);
1357 }
1358 ScriptControl = getScriptControlIndex(num);
1359#if defined(JS_THREADSAFE)
1360 JS_BeginRequest(ScriptControl->cx);
1361#endif
1362 //CLEANUP_JAVASCRIPT(ScriptControl->cx)
1363 js_cleanup_script_context(num);
1364#if defined(JS_THREADSAFE)
1365 JS_EndRequest(ScriptControl->cx);
1366#endif
1367
1368 FREE_IF_NZ (smallfield);
1369 FREE_IF_NZ (sftype);
1370
1371 #ifdef JAVASCRIPTVERBOSE
1372 printf ("finished InitScriptField\n");
1373 #endif
1374}
1375
1376void InitScriptFieldB(int num, indexT kind, indexT type, const char* field, union anyVrml value) {
1377 //Dec 31 2017 this version of initscriptfield for SM treats fields more generically
1378
1379 struct CRscriptStruct *ScriptControl; //= getScriptControl();
1380 //char mynewname[256];
1381 #ifdef JAVASCRIPTVERBOSE
1382 printf ("calling InitScriptField from thread %u\n",pthread_self());
1383 printf ("\nInitScriptField, num %d, kind %s type %s field %s value %d\n", num,PROTOKEYWORDS[kind],FIELDTYPES[type],field,value);
1384 #endif
1385
1386 if ((kind != PKW_inputOnly) && (kind != PKW_outputOnly) && (kind != PKW_initializeOnly) && (kind != PKW_inputOutput)) {
1387 ConsoleMessage ("InitScriptField: invalid kind for script: %d\n",kind);
1388 return;
1389 }
1390
1391 ScriptControl = getScriptControlIndex(num);
1392
1393
1394 // fix eventIn vs field name conflicts. by renameing inputOutput and inputOnly eventIn functions to set_fieldname
1395 //if (kind == PKW_inputOnly ||
1396 //strcpy(mynewname,field);
1397 //if (kind == PKW_inputOnly ) {
1398 // sprintf (mynewname,"__eventIn_Value_%s",field);
1399 // //strcpy(mynewname,field);
1400 //} else
1401 if( kind == PKW_inputOutput) {
1402 JSContext *cx;
1403 JSObject *obj;
1404 jsval retval;
1405 cx = (JSContext*)ScriptControl->cx;
1406 obj = (JSObject*)ScriptControl->glob;
1407
1408 if (JS_GetProperty(cx,obj,field,&retval)){
1409 if (JSVAL_IS_OBJECT(retval)){
1410 //I think functions are objects, doesn't seem to be a JSVAL_IS_FUNC
1411 char runstring[STRING_SIZE];
1412 // rename fieldname to set_fieldname
1413 sprintf(runstring,"_rename_function(this,'%s','set_%s');",field,field);
1414 //printf("%s\n",runstring);
1415 #if defined(JS_THREADSAFE)
1416 JS_BeginRequest(cx);
1417 #endif
1418 if(!JS_EvaluateScript(cx,obj, runstring, (int) strlen(runstring), FNAME_STUB, LINENO_STUB, &retval)){
1419 printf("sorry couldn't rename function: %s",runstring);
1420 }
1421 #if defined(JS_THREADSAFE)
1422 JS_EndRequest(cx);
1423 #endif
1424 }
1425 }
1426 // and if so rename it to set_
1427 }
1428
1429 //unconditionally add the field no matter its type
1430 //contains getter and setter
1431 JSaddGlobalECMANativeProperty(num, field);
1432}
1433
1434
1435
1436static int JSaddGlobalECMANativeProperty(int num, const char *name) {
1437 JSContext *_context;
1438 JSObject *_globalObj;
1439 jsval rval = INT_TO_JSVAL(0);
1440 struct CRscriptStruct *ScriptControl; // = getScriptControl();
1441
1442 ScriptControl = getScriptControlIndex(num);
1443 /* get context and global object for this script */
1444 _context = (JSContext*)ScriptControl->cx;
1445 _globalObj = (JSObject*)ScriptControl->glob;
1446
1447 #ifdef JAVASCRIPTVERBOSE
1448 printf("addGlobalECMANativeProperty: name \"%s\"\n", name);
1449 #endif
1450
1451#if defined(JS_THREADSAFE)
1452 JS_BeginRequest(_context);
1453#endif
1454
1455/* Note, for JS-185+, JSPROP_PERMANENT makes properties non-configurable, which can cause runtime
1456 * errors from the JS engine when said property gets redefined to a function by the script. The
1457 * example file tests/Javascript_tests/MFFloat.wrl had this issue. */
1458
1459 if (!JS_DefineProperty(_context, _globalObj, name, rval, getECMANative, setECMANative,
1460 //if (!JS_DefineProperty(_context, _globalObj, name, rval, getECMANative, setECMANative,
1461#if JS_VERSION < 185
1462 0 | JSPROP_PERMANENT
1463#else
1464 0
1465#endif
1466 )) {
1467 printf("JS_DefineProperty failed for \"%s\" in addGlobalECMANativeProperty.\n", name);
1468#if defined(JS_THREADSAFE)
1469 JS_EndRequest(_context);
1470#endif
1471 return JS_FALSE;
1472#if defined(JS_THREADSAFE)
1473 } else {
1474 JS_EndRequest(_context);
1475#endif
1476 }
1477
1478 return JS_TRUE;
1479}
1480
1481static int JSaddGlobalAssignProperty(int num, const char *name, const char *str) {
1482 jsval _rval = INT_TO_JSVAL(0);
1483 JSContext *_context;
1484 JSObject *_globalObj;
1485 struct CRscriptStruct *ScriptControl;
1486
1487 ScriptControl = getScriptControlIndex(num);
1488
1489 /* get context and global object for this script */
1490 _context = (JSContext*)ScriptControl->cx;
1491 _globalObj = (JSObject*)ScriptControl->glob;
1492
1493 #ifdef JAVASCRIPTVERBOSE
1494 printf("addGlobalAssignProperty: cx: %p obj %p name \"%s\", evaluate script \"%s\"\n",
1495 _context, _globalObj, name, str);
1496 #endif
1497
1498#if defined(JS_THREADSAFE)
1499 JS_BeginRequest(_context);
1500#endif
1501 if (!JS_EvaluateScript(_context, _globalObj, str, (int) strlen(str), FNAME_STUB, LINENO_STUB, &_rval)) {
1502 ConsoleMessage ("JSaddGlobalAssignProperty - JS_EvaluateScript failed for %s", str);
1503#if defined(JS_THREADSAFE)
1504 JS_EndRequest(_context);
1505#endif
1506 return JS_FALSE;
1507#if defined(JS_THREADSAFE)
1508 } else {
1509 JS_EndRequest(_context);
1510#endif
1511 }
1512#if defined(JS_THREADSAFE)
1513 JS_BeginRequest(_context);
1514#endif
1515 if (!JS_DefineProperty(_context, _globalObj, name, _rval, getAssignProperty, setAssignProperty, 0 | JSPROP_PERMANENT)) {
1516 printf("JS_DefineProperty failed for \"%s\" in addGlobalAssignProperty.\n", name);
1517#if defined(JS_THREADSAFE)
1518 JS_EndRequest(_context);
1519#endif
1520 return JS_FALSE;
1521#if defined(JS_THREADSAFE)
1522 } else {
1523 JS_EndRequest(_context);
1524#endif
1525 }
1526 return JS_TRUE;
1527}
1528
1529/* defines for getting touched flags and exact Javascript pointers */
1530
1531/* ... make a #define to handle JS requests that can easily be substituted into these other #defines */
1532#if defined(JS_THREADSAFE)
1533# define JSBEGINREQUEST_SUBSTITUTION(mycx) JS_BeginRequest(mycx);
1534# define JSENDREQUEST_SUBSTITUTION(mycx) JS_EndRequest(mycx);
1535#else
1536# define JSBEGINREQUEST_SUBSTITUTION(mycx) /* */
1537# define JSENDREQUEST_SUBSTITUTION(mycx) /* */
1538#endif
1539
1540/****************************** ECMA types ******************************************/
1541/* where we have a Native structure to go along with it */
1542#define GETJSPTR_TYPE_A(thistype) \
1543 case FIELDTYPE_##thistype: { \
1544 thistype##Native *ptr; \
1545 /* printf ("getting private data in GETJSPTR for %p \n",JSglobal_return_val); */ \
1546 if ((ptr = (thistype##Native *)JS_GetPrivateFw(cx, JSVAL_TO_OBJECT(*(jsval *)(tg->JScript.JSglobal_return_val)))) == NULL) { \
1547 printf( "JS_GetPrivate failed in get_valueChanged_flag\n"); \
1548 JSENDREQUEST_SUBSTITUTION(cx) \
1549 return JS_FALSE; \
1550 } \
1551 /* if (ptr->valueChanged > 0) printf ("private is %d valueChanged %d\n",ptr,ptr->valueChanged); */ \
1552 tg->CRoutes.JSSFpointer = (void *)ptr; /* save this for quick extraction of values */ \
1553 touched = ptr->valueChanged; \
1554 break; \
1555 }
1556
1557#define RESET_TOUCHED_TYPE_A(thistype) \
1558 case FIELDTYPE_##thistype: { \
1559 ((thistype##Native *)tg->CRoutes.JSSFpointer)->valueChanged = 0; \
1560 break; \
1561 }
1562
1563#define GETJSPTR_TYPE_MF_A(thisMFtype,thisSFtype) \
1564 case FIELDTYPE_##thisMFtype: { \
1565 thisSFtype##Native *ptr; \
1566 jsval mainElement; \
1567 int len; \
1568 int i; \
1569 if (!JS_GetProperty(cx, JSVAL_TO_OBJECT(*(jsval *)(tg->JScript.JSglobal_return_val)), "length", &mainElement)) { \
1570 printf ("JS_GetProperty failed for \"length\" in get_valueChanged_flag\n"); \
1571 JSENDREQUEST_SUBSTITUTION(cx) \
1572 return FALSE; \
1573 } \
1574 len = JSVAL_TO_INT(mainElement); \
1575 /* go through each element of the main array. */ \
1576 for (i = 0; i < len; i++) { \
1577 if (!JS_GetElement(cx, JSVAL_TO_OBJECT(*(jsval*)(tg->JScript.JSglobal_return_val)), i, &mainElement)) { \
1578 printf ("JS_GetElement failed for %d in get_valueChanged_flag\n",i); \
1579 JSENDREQUEST_SUBSTITUTION(cx) \
1580 return FALSE; \
1581 } \
1582 if ((ptr = (thisSFtype##Native *)JS_GetPrivateFw(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) { \
1583 printf( "JS_GetPrivate failed for obj in setField_javascriptEventOut.\n"); \
1584 JSENDREQUEST_SUBSTITUTION(cx) \
1585 return FALSE; \
1586 } \
1587 if (ptr->valueChanged > 0) touched = TRUE; /* did this element change? */ \
1588 /* printf ("touched flag for element %d is %d\n",i,ptr->touched); */ \
1589 } \
1590 break; \
1591 }
1592
1593#define RESET_TOUCHED_TYPE_MF_A(thisMFtype,thisSFtype) \
1594 case FIELDTYPE_##thisMFtype: { \
1595 thisSFtype##Native *ptr; \
1596 jsval mainElement; \
1597 int len; \
1598 int i; \
1599 JSContext *cx; \
1600 cx = scriptcontrol->cx; \
1601 JSBEGINREQUEST_SUBSTITUTION(cx) \
1602 if (!JS_GetProperty(cx, JSVAL_TO_OBJECT(*(jsval*)(tg->JScript.JSglobal_return_val)), "length", &mainElement)) { \
1603 printf ("JS_GetProperty failed for \"length\" in get_valueChanged_flag\n"); \
1604 JSENDREQUEST_SUBSTITUTION(cx) \
1605 break; \
1606 } \
1607 len = JSVAL_TO_INT(mainElement); \
1608 /* go through each element of the main array. */ \
1609 for (i = 0; i < len; i++) { \
1610 if (!JS_GetElement(cx, JSVAL_TO_OBJECT(*(jsval*)(tg->JScript.JSglobal_return_val)), i, &mainElement)) { \
1611 printf ("JS_GetElement failed for %d in get_valueChanged_flag\n",i); \
1612 JSENDREQUEST_SUBSTITUTION(cx) \
1613 break; \
1614 } \
1615 if ((ptr = (thisSFtype##Native *)JS_GetPrivateFw(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) { \
1616 printf( "JS_GetPrivate failed for obj in setField_javascriptEventOut.\n"); \
1617 JSENDREQUEST_SUBSTITUTION(cx) \
1618 break; \
1619 } \
1620 ptr->valueChanged = 0; \
1621 } \
1622 JSENDREQUEST_SUBSTITUTION(cx) \
1623 break; \
1624 }
1625
1626/****************************** ECMA types ******************************************/
1627
1628#ifdef OLDCODE
1629OLDCODE /* "Bool" might be already declared - we DO NOT want it to be declared as an "int" */
1630OLDCODE #define savedBool Bool
1631OLDCODE #ifdef Bool
1632OLDCODE #undef Bool
1633OLDCODE #endif
1634#endif //OLDCODE
1635
1636/* NOTE - BeginRequest is already called prior to any GET_* defines */
1637
1638#define GET_ECMA_TOUCHED(thistype) \
1639 case FIELDTYPE_SF##thistype: { \
1640 touched = findNameInECMATable( scriptcontrol->cx,fullname);\
1641 break;\
1642 }
1643
1644#define GET_ECMA_MF_TOUCHED(thistype) \
1645 case FIELDTYPE_MF##thistype: {\
1646 jsval mainElement; \
1647 /* printf ("GET_ECMA_MF_TOUCHED called on %d\n",JSglobal_return_val); */ \
1648 if (!JS_GetProperty(cx, JSVAL_TO_OBJECT(*(jsval*)(tg->JScript.JSglobal_return_val)), "MF_ECMA_has_changed", &mainElement)) { \
1649 printf ("JS_GetProperty failed for \"MF_ECMA_HAS_changed\" in get_valueChanged_flag\n"); \
1650 } /* else printf ("GET_ECMA_MF_TOUCHED MF_ECMA_has_changed is %d for %d %d\n",JSVAL_TO_INT(mainElement),cx,JSglobal_return_val); */ \
1651 touched = JSVAL_TO_INT(mainElement);\
1652 break; \
1653 }
1654
1655#define RESET_ECMA_MF_TOUCHED(thistype) \
1656 case FIELDTYPE_##thistype: {\
1657 jsval myv = INT_TO_JSVAL(0); \
1658 /* printf ("RESET_ECMA_MF_TOUCHED called on %d ",JSglobal_return_val); */ \
1659 JSBEGINREQUEST_SUBSTITUTION(scriptcontrol->cx) \
1660 if (!JS_SetProperty(scriptcontrol->cx, JSVAL_TO_OBJECT(*(jsval*)(tg->JScript.JSglobal_return_val)), "MF_ECMA_has_changed", &myv)) { \
1661 printf( "JS_SetProperty failed for \"MF_ECMA_has_changed\" in RESET_ECMA_MF_TOUCHED.\n"); \
1662 }\
1663 /* if (!JS_GetProperty( p->ScriptControl[actualscript].cx, JSVAL_TO_OBJECT(JSglobal_return_val), "MF_ECMA_has_changed", &mainElement)) { \
1664 printf ("JS_GetProperty failed for \"MF_ECMA_HAS_changed\" in get_valueChanged_flag\n"); \
1665 } \
1666 printf ("and MF_ECMA_has_changed is %d\n",JSVAL_TO_INT(mainElement)); */\
1667 JSENDREQUEST_SUBSTITUTION(scriptcontrol->cx) \
1668 break; \
1669 }
1670
1671#define RESET_TOUCHED_TYPE_ECMA(thistype) \
1672 case FIELDTYPE_##thistype: { \
1673 JSBEGINREQUEST_SUBSTITUTION(scriptcontrol->cx) \
1674 resetNameInECMATable( scriptcontrol->cx,JSparamnames[fptr].name); \
1675 JSENDREQUEST_SUBSTITUTION(scriptcontrol->cx) \
1676 break; \
1677 }
1678
1679#ifdef OLDCODE
1680OLDCODE /* in case Bool was defined above, restore the value */
1681OLDCODE #define Bool savedBool
1682#endif //OLDCODE
1683
1684
1685
1686
1687/********************************************************************************/
1688/* */
1689/* get_valueChanged_flag - see if this variable (can be a sub-field; see tests */
1690/* 8.wrl for the DEF PI PositionInterpolator). return true if variable is */
1691/* touched, and pointer to touched value is in global variable */
1692/* JSglobal_return_val, AND possibly: */
1693/* void *JSSFpointer for SF non-ECMA nodes. */
1694/* */
1695/* the way touched, and, the actual values work is as follows: */
1696/* */
1697/* keep track of the name in a table, and set valueChanged flag. */
1698/* look around the function setECMANative to see how this is done. */
1699/* FIELDTYPE_SFInt32 */
1700/* FIELDTYPE_SFBool */
1701/* FIELDTYPE_SFFloat */
1702/* FIELDTYPE_SFTime */
1703/* FIELDTYPE_SFDouble */
1704/* FIELDTYPE_SFString */
1705/* */
1706/* check the "touched" flag for non-zero in the private area: */
1707/* FIELDTYPE_SFRotation */
1708/* FIELDTYPE_SFNode */
1709/* FIELDTYPE_SFVec2f */
1710/* FIELDTYPE_SFVec3f */
1711/* FIELDTYPE_SFImage */
1712/* FIELDTYPE_SFColor */
1713/* FIELDTYPE_SFColorRGBA */
1714/* */
1715/* go through all elements, and find if at least one SF has been touched: */
1716/* FIELDTYPE_MFRotation */
1717/* FIELDTYPE_MFNode */
1718/* FIELDTYPE_MFVec2f */
1719/* FIELDTYPE_MFVec3f */
1720/* FIELDTYPE_MFColor */
1721/* FIELDTYPE_MFColorRGBA */
1722
1723
1724/* has a flag called "MF_ECMA_has_changed" that is used here */
1725/* FIELDTYPE_MFFloat */
1726/* FIELDTYPE_MFBool */
1727/* FIELDTYPE_MFInt32 */
1728/* FIELDTYPE_MFTime */
1729/* FIELDTYPE_MFString */
1730/* */
1731/****************************************************************************/
1732
1733int sm1_get_valueChanged_flag (int fptr, int actualscript) {
1734
1735
1736 struct CRscriptStruct *scriptcontrol;
1737 JSContext *cx;
1738 JSObject *interpobj;
1739 char *fullname;
1740 int touched;
1741 //ppJScript p;
1742 ttglobal tg = gglobal();
1743 struct CRjsnameStruct *JSparamnames = getJSparamnames();
1744 //p = (ppJScript)tg->JScript.prv;
1745
1746 touched = FALSE;
1747 scriptcontrol = getScriptControlIndex(actualscript);
1748 interpobj = (JSObject*)scriptcontrol->glob;
1749 cx = (JSContext*)scriptcontrol->cx;
1750 fullname = JSparamnames[fptr].name;
1751
1752#if defined(JS_THREADSAFE)
1753 JS_BeginRequest(cx);
1754#endif
1755 #ifdef CRVERBOSE
1756 printf ("\ngetting property for fullname %s, cx %p, interpobj %d script %d, fptr %d (%s:%s)\n",
1757 fullname,cx,interpobj,actualscript, fptr,
1758 JSparamnames[fptr].name, FIELDTYPES[JSparamnames[fptr].type]);
1759 #endif
1760
1761 if (!JS_GetProperty(cx, interpobj ,fullname,tg->JScript.JSglobal_return_val)) {
1762 printf ("cant get property for %s\n",fullname);
1763#if defined(JS_THREADSAFE)
1764 JS_EndRequest(cx);
1765#endif
1766 return FALSE;
1767 } else {
1768 #ifdef CRVERBOSE
1769 printf ("so, property is %d (%p)\n",*(jsval*)tg->JScript.JSglobal_return_val,*(jsval *)tg->JScript.JSglobal_return_val);
1770 printf("get_valueChanged_flag: node type: %s name %s\n",FIELDTYPES[JSparamnames[fptr].type],JSparamnames[fptr].name);
1771 #endif
1772
1773 switch (JSparamnames[fptr].type) {
1774 GETJSPTR_TYPE_A(SFRotation)
1775 GETJSPTR_TYPE_A(SFNode)
1776 GETJSPTR_TYPE_A(SFVec2f)
1777 /* GETJSPTR_TYPE_A(SFVec2d) */
1778 GETJSPTR_TYPE_A(SFVec3f)
1779 GETJSPTR_TYPE_A(SFVec3d)
1780 GETJSPTR_TYPE_A(SFVec4f)
1781 GETJSPTR_TYPE_A(SFVec4d)
1782 GETJSPTR_TYPE_A(SFImage)
1783 GETJSPTR_TYPE_A(SFColor)
1784 GETJSPTR_TYPE_A(SFColorRGBA)
1785
1786 GETJSPTR_TYPE_MF_A(MFRotation,SFRotation)
1787 GETJSPTR_TYPE_MF_A(MFNode,SFNode)
1788 GETJSPTR_TYPE_MF_A(MFVec2f,SFVec2f)
1789 GETJSPTR_TYPE_MF_A(MFVec3f,SFVec3f)
1790 GETJSPTR_TYPE_MF_A(MFVec4f,SFVec4f)
1791 GETJSPTR_TYPE_MF_A(MFVec4d,SFVec4d)
1792 /* GETJSPTR_TYPE_MF_A(MFImage,SFImage) */
1793 GETJSPTR_TYPE_MF_A(MFColor,SFColor)
1794 GETJSPTR_TYPE_MF_A(MFColorRGBA,SFColorRGBA)
1795
1796 GET_ECMA_MF_TOUCHED(Int32)
1797 GET_ECMA_MF_TOUCHED(Bool)
1798 GET_ECMA_MF_TOUCHED(Time)
1799 GET_ECMA_MF_TOUCHED(Double)
1800 GET_ECMA_MF_TOUCHED(Float)
1801 GET_ECMA_MF_TOUCHED(String)
1802
1803 GET_ECMA_TOUCHED(Int32)
1804 GET_ECMA_TOUCHED(Bool)
1805 GET_ECMA_TOUCHED(Float)
1806 GET_ECMA_TOUCHED(Time)
1807 GET_ECMA_TOUCHED(Double)
1808 GET_ECMA_TOUCHED(String)
1809
1810 default: {printf ("not handled yet in get_valueChanged_flag %s\n",FIELDTYPES[JSparamnames[fptr].type]);
1811 }
1812 }
1813#if defined(JS_THREADSAFE)
1814 JS_EndRequest(cx);
1815#endif
1816 }
1817
1818#ifdef CHECKER
1819 if (JSparamnames[fptr].type == FIELDTYPE_MFString) {
1820 int len; int i;
1821 jsval mainElement;
1822 int len;
1823
1824 unsigned CRCCheck = 0;
1825 cx = p->ScriptControl[actualscript].cx;
1826#if defined(JS_THREADSAFE)
1827 JS_BeginRequest(cx);
1828#endif
1829 if (!JS_GetProperty(cx, JSglobal_return_val, "length", &mainElement)) {
1830 printf ("JS_GetProperty failed for length_flag\n");
1831 }
1832 len = JSVAL_TO_INT(mainElement);
1833 /* go through each element of the main array. */
1834 for (i = 0; i < len; i++) {
1835 if (!JS_GetElement(cx, JSglobal_return_val, i, &mainElement)) {
1836 printf ("JS_GetElement failed for %d in get_valueChanged_flag\n",i);
1837 break;
1838 }
1839 CRCCheck += (unsigned) mainElement;
1840
1841/*
1842 if (JSVAL_IS_OBJECT(mainElement)) printf ("sc, element %d is an OBJECT\n",i);
1843 if (JSVAL_IS_STRING(mainElement)) printf ("sc, element %d is an STRING\n",i);
1844 if (JSVAL_IS_NUMBER(mainElement)) printf ("sc, element %d is an NUMBER\n",i);
1845 if (JSVAL_IS_DOUBLE(mainElement)) printf ("sc, element %d is an DOUBLE\n",i);
1846 if (JSVAL_IS_INT(mainElement)) printf ("sc, element %d is an INT\n",i);
1847*/
1848
1849 }
1850 printf ("CRCcheck %u\n",CRCCheck);
1851#if defined(JS_THREADSAFE)
1852 JS_EndRequest(cx);
1853#endif
1854 }
1855#endif
1856
1857
1858
1859 return touched;
1860
1861}
1862
1863
1864/* this script value has been looked at, set the touched flag in it to FALSE. */
1865void sm1_resetScriptTouchedFlag(int actualscript, int fptr) {
1866
1867 struct CRscriptStruct *scriptcontrol;
1868 ttglobal tg = gglobal();
1869 struct CRjsnameStruct *JSparamnames = getJSparamnames();
1870 //ppJScript p = (ppJScript)tg->JScript.prv;
1871 #ifdef CRVERBOSE
1872 printf ("resetScriptTouchedFlag, name %s type %s script %d, fptr %d\n",JSparamnames[fptr].name, stringFieldtypeType(JSparamnames[fptr].type), actualscript, fptr);
1873 #endif
1874 scriptcontrol = getScriptControlIndex(actualscript);
1875 switch (JSparamnames[fptr].type) {
1876 RESET_TOUCHED_TYPE_A(SFRotation)
1877 RESET_TOUCHED_TYPE_A(SFNode)
1878 RESET_TOUCHED_TYPE_A(SFVec2f)
1879 RESET_TOUCHED_TYPE_A(SFVec3f)
1880 RESET_TOUCHED_TYPE_A(SFVec4f)
1881 /* RESET_TOUCHED_TYPE_A(SFVec2d) */
1882 RESET_TOUCHED_TYPE_A(SFVec3d)
1883 RESET_TOUCHED_TYPE_A(SFVec4d)
1884 RESET_TOUCHED_TYPE_A(SFImage)
1885 RESET_TOUCHED_TYPE_A(SFColor)
1886 RESET_TOUCHED_TYPE_A(SFColorRGBA)
1887 RESET_TOUCHED_TYPE_MF_A(MFRotation,SFRotation)
1888 RESET_TOUCHED_TYPE_MF_A(MFNode,SFNode)
1889 RESET_TOUCHED_TYPE_MF_A(MFVec2f,SFVec2f)
1890 RESET_TOUCHED_TYPE_MF_A(MFVec3f,SFVec3f)
1891 RESET_TOUCHED_TYPE_MF_A(MFVec4f,SFVec4f)
1892 RESET_TOUCHED_TYPE_MF_A(MFVec4d,SFVec4d)
1893 /* RESET_TOUCHED_TYPE_MF_A(MFImage,SFImage) */
1894 RESET_TOUCHED_TYPE_MF_A(MFColor,SFColor)
1895 RESET_TOUCHED_TYPE_MF_A(MFColorRGBA,SFColorRGBA)
1896
1897 RESET_TOUCHED_TYPE_ECMA (SFInt32)
1898 RESET_TOUCHED_TYPE_ECMA (SFBool)
1899 RESET_TOUCHED_TYPE_ECMA (SFFloat)
1900 RESET_TOUCHED_TYPE_ECMA (SFTime)
1901 RESET_TOUCHED_TYPE_ECMA (SFDouble)
1902 RESET_TOUCHED_TYPE_ECMA (SFString)
1903 RESET_ECMA_MF_TOUCHED(MFInt32)
1904 RESET_ECMA_MF_TOUCHED(MFBool)
1905 RESET_ECMA_MF_TOUCHED(MFFloat)
1906 RESET_ECMA_MF_TOUCHED(MFTime)
1907 RESET_ECMA_MF_TOUCHED(MFString)
1908
1909
1910 default: {printf ("can not reset touched_flag for %s\n",stringFieldtypeType(JSparamnames[fptr].type));
1911 }
1912 }
1913
1914}
1915
1916int sm2_get_valueChanged_flag (int fptr, int actualscript){
1917 char *fullname;
1918 union anyVrml* value;
1919 int type, kind, ifield, found;
1920 struct X3D_Node *node;
1921 struct Shader_Script *script;
1922 struct ScriptFieldDecl *field;
1923 struct CRscriptStruct *scriptcontrol; //, *ScriptControlArr = getScriptControl();
1924 struct CRjsnameStruct *JSparamnames = getJSparamnames();
1925
1926 scriptcontrol = getScriptControlIndex(actualscript); //&ScriptControlArr[actualscript];
1927 script = scriptcontrol->script;
1928 node = script->ShaderScriptNode;
1929 fullname = JSparamnames[fptr].name;
1930 found = getFieldFromNodeAndName(node,fullname,&type,&kind,&ifield,&value);
1931 if(found){
1932 field = Shader_Script_getScriptField(script, ifield);
1933 gglobal()->JScript.JSglobal_return_val = (void *)&field->value;
1934 return field->valueChanged;
1935 }
1936 gglobal()->JScript.JSglobal_return_val = NULL;
1937 return 0;
1938}
1939void sm2_resetScriptTouchedFlag(int actualscript, int fptr){
1940 char *fullname;
1941 union anyVrml* value;
1942 int type, kind, ifield, found;
1943 struct X3D_Node *node;
1944 struct Shader_Script *script;
1945 struct ScriptFieldDecl *field;
1946 struct CRscriptStruct *scriptcontrol; // *ScriptControlArr = getScriptControl();
1947 struct CRjsnameStruct *JSparamnames = getJSparamnames();
1948
1949 scriptcontrol = getScriptControlIndex(actualscript); //&ScriptControlArr[actualscript];
1950 script = scriptcontrol->script;
1951 node = script->ShaderScriptNode;
1952 fullname = JSparamnames[fptr].name;
1953 found = getFieldFromNodeAndName(node,fullname,&type,&kind,&ifield,&value);
1954 if(found){
1955 field = Shader_Script_getScriptField(script, ifield);
1956 field->valueChanged = 0;
1957 }
1958 //printf("in get_valueChanged_flag\n");
1959 return;
1960}
1961int sm_get_valueChanged_flag (int fptr, int actualscript){
1962 if(SM_method() == 2)
1963 return sm2_get_valueChanged_flag(fptr,actualscript);
1964 else
1965 return sm1_get_valueChanged_flag(fptr,actualscript);
1966}
1967void sm_resetScriptTouchedFlag(int actualscript, int fptr){
1968 if(SM_method() == 2)
1969 sm2_resetScriptTouchedFlag(actualscript,fptr);
1970 else
1971 sm1_resetScriptTouchedFlag(actualscript,fptr);
1972}
1973
1974int jsActualrunScript(int num, char *script);
1975void sm_JSInitializeScriptAndFields (int num) {
1976 //jsval rval;
1977 //ppCRoutes p = (ppCRoutes)gglobal()->CRoutes.prv;
1978 struct CRscriptStruct *ScriptControl; // = getScriptControl();
1979
1980 /* printf ("JSInitializeScriptAndFields script %d, thread %u\n",num,pthread_self()); */
1981 /* run through paramList, and run the script */
1982 /* printf ("JSInitializeScriptAndFields, running through params and main script\n"); */
1983 //if (num >= p->JSMaxScript) {
1984 // ConsoleMessage ("JSInitializeScriptAndFields: warning, script %d initialization out of order",num);
1985 // return;
1986 //}
1987 /* run through fields in order of entry in the X3D file */
1988
1989 int i,nfields,kind,itype;
1990 const char *fieldname;
1991 char longfieldname[256];
1992 struct Shader_Script *script;
1993 struct ScriptFieldDecl *field;
1994
1995 ScriptControl = getScriptControlIndex(num);
1996
1997 //add user code -including eventIn functions- first
1998 if(1) if (!jsActualrunScript(num, ScriptControl->scriptText)) {
1999 ConsoleMessage ("JSInitializeScriptAndFields, script failure\n");
2000 ScriptControl->scriptOK = FALSE;
2001 ScriptControl->_initialized = TRUE;
2002 return;
2003 }
2004
2005 // old way: when adding inputOutput fieldnname, check first if there's a user
2006 // eventin function with the same name, and if so rename it to set_fieldname
2007 // new way dec 2017: rename inputOutput functions with a set_prefix
2008 // may 2018: keep inputOnly function at its normal name and
2009 // prefix inputOnly fieldname with __eventIn_Value_
2010 // (inputOutput function is still dec 2017 renamed to set_, and inputOutput field has normal nae)
2011 script = ScriptControl->script;
2012 //printf("adding fields from script %x\n",script);
2013 nfields = Shader_Script_getScriptFieldCount(script);
2014 for(i=0;i<nfields;i++){
2015 field = Shader_Script_getScriptField(script,i);
2016 fieldname = ScriptFieldDecl_getName(field);
2017 kind = ScriptFieldDecl_getMode(field);
2018 itype = ScriptFieldDecl_getType(field);
2019 longfieldname[0] = 0;
2020 if(kind == PKW_inputOnly)
2021 strcat(longfieldname,"__eventIn_Value_");
2022 strcat(longfieldname,fieldname);
2023 if(SM_method() == 2)
2024 InitScriptFieldB(num, kind, itype, longfieldname, field->value);
2025 else
2026 InitScriptField(num, kind, itype, longfieldname, field->value);
2027 }
2028
2029
2030 if(0) if (!jsActualrunScript(num, ScriptControl->scriptText)) {
2031 ConsoleMessage ("JSInitializeScriptAndFields, script failure\n");
2032 ScriptControl->scriptOK = FALSE;
2033 ScriptControl->_initialized = TRUE;
2034 return;
2035 }
2036
2037 //FREE_IF_NZ(ScriptControl->scriptText);
2038 ScriptControl->_initialized = TRUE;
2039 ScriptControl->scriptOK = TRUE;
2040
2041}
2042
2043
2044
2045/* save this field from the parser; initialize it when the fwl_RenderSceneUpdateScene wants to initialize it */
2046void sm_SaveScriptField (int num, indexT kind, indexT type, const char* field, union anyVrml value) {
2047
2048}
2049
2050
2051
2052
2053/****************************************************************/
2054/* a Jscript is returning a Multi-number type; copy this from */
2055/* the Jscript return string to the data structure within the */
2056/* freewrl C side of things. */
2057/* */
2058/* note - this cheats in that the code assumes that it is */
2059/* a series of Multi_Vec3f's while in reality the structure */
2060/* of the multi structures is the same - so we "fudge" things */
2061/* to make this multi-purpose. */
2062/****************************************************************/
2063void getJSMultiNumType (JSContext *cx, struct Multi_Vec3f *tn, int eletype) {
2064 float *fl;
2065 int *il;
2066 double *dl;
2067 struct X3D_Node * *nl;
2068
2069 double dtmp;
2070 jsval mainElement;
2071 int len;
2072 int i;
2073 char *strp;
2074#if JS_VERSION >= 185
2075 char *strpp; /* we need this to reliably free the results of JS_EncodeString() */
2076#endif
2077 int elesize;
2078 SFVec2fNative *sfvec2f;
2079 SFVec3fNative *sfvec3f;
2080 SFRotationNative *sfrotation;
2081 struct Uni_String * *ms;
2082 jsval *myJSVal;
2083 ttglobal tg = gglobal();
2084
2085 /* get size of each element, used for MALLOCing memory - eg, this will
2086 be sizeof(float) * 3 for a SFColor */
2087 elesize = returnElementLength(eletype) * returnElementRowSize(eletype);
2088
2089 /* rough check of return value */
2090 /* where did this come from? Was it from a script execution, or from an assignment from within a script?? */
2091 #ifdef SETFIELDVERBOSE
2092 printf ("getJSMultiNumType, JSCreate_global_return_val %u, JSglobal_return_val %u\n",
2093 (unsigned int) JSVAL_TO_INT(*(jsval *)tg->jsVRMLBrowser.JSCreate_global_return_val),
2094 (unsigned int) JSVAL_TO_INT(*(jsval *)tg->JScript.JSglobal_return_val));
2095 #endif
2096
2097 if (JSVAL_TO_INT(*(jsval*)(tg->jsVRMLBrowser.JSCreate_global_return_val)) != 0) {
2098 myJSVal = (jsval *)tg->jsVRMLBrowser.JSCreate_global_return_val;
2099 *(jsval *)(tg->jsVRMLBrowser.JSCreate_global_return_val) = INT_TO_JSVAL(0);
2100
2101 #ifdef SETFIELDVERBOSE
2102 printf ("getJSMultiNumType: using JSCreate_global_return_val\n");
2103 #endif
2104 } else {
2105 #ifdef SETFIELDVERBOSE
2106 printf ("getJSMultiNumType: using JSglobal_return_val\n");
2107 #endif
2108
2109 myJSVal = tg->JScript.JSglobal_return_val;
2110 }
2111
2112 if (!JSVAL_IS_OBJECT(*myJSVal)) {
2113 printf ("getJSMultiNumType - did not get an object\n");
2114 return;
2115 }
2116
2117 #ifdef SETFIELDVERBOSE
2118 printf ("getJSMultiNumType, tn %p dest has %s size %d\n",tn,stringFieldtypeType(eletype), elesize);
2119
2120 printf("getJSMulitNumType, node type of myJSVal is :");
2121 printJSNodeType (cx,myJSVal);
2122 #endif
2123
2124 if (!JS_GetProperty(cx, JSVAL_TO_OBJECT(*myJSVal), MF_LENGTH_FIELD, &mainElement)) {
2125 printf ("JS_GetProperty failed for \"%s\" in getJSMultiNumType\n", MF_LENGTH_FIELD);
2126 return;
2127 }
2128 len = JSVAL_TO_INT(mainElement);
2129 #ifdef SETFIELDVERBOSE
2130 printf ("getmuiltie length of grv is %d old len is %d\n",len,tn->n);
2131 #endif
2132
2133 /* do we have to realloc memory? */
2134 if (len != tn->n) {
2135
2136 tn->n = 0;
2137 /* yep... */
2138 /* printf ("old pointer %d\n",tn->p); */
2139 FREE_IF_NZ (tn->p);
2140 tn->p = MALLOC (struct SFVec3f *, (unsigned)(elesize*len));
2141
2142 #ifdef SETFIELDVERBOSE
2143 printf ("MALLOCing memory for elesize %d len %d new pointer now is %p\n",elesize,len,tn->p);
2144 #endif
2145
2146 /* if this is an MFString, we should set each element to a null string */
2147 if (eletype == FIELDTYPE_SFString) {
2148 #ifdef SETFIELDVERBOSE
2149 printf ("getJSMultiNumType, this is a MFString, so making tiny strings for now\n");
2150 #endif
2151
2152 ms = (struct Uni_String * *) tn->p;
2153 for (i=0; i<len; i++) {
2154 *ms = newASCIIString ("(getJSMultiNumType null)");
2155 ms ++;
2156 }
2157 }
2158 }
2159
2160 /* set these three up, but we only use one of them */
2161 fl = (float *) tn->p;
2162 il = (int *) tn->p;
2163 dl = (double *) tn->p;
2164 nl = (struct X3D_Node * *) tn->p;
2165 ms = (struct Uni_String * *) tn->p;
2166
2167 /* go through each element of the main array. */
2168 for (i = 0; i < len; i++) {
2169 if (!JS_GetElement(cx, JSVAL_TO_OBJECT(*myJSVal), i, &mainElement)) {
2170 printf ("WARNING: JS_GetElement failed for %d in getJSMultiNumType\n",i);
2171 switch (eletype) {
2172 case FIELDTYPE_SFNode:
2173 *nl = 0; nl++; break;
2174 case FIELDTYPE_SFInt32:
2175 *il=0; il++; break;
2176 case FIELDTYPE_SFDouble:
2177 case FIELDTYPE_SFTime:
2178 *dl=0.0; dl++; break;
2179 case FIELDTYPE_SFFloat:
2180 *fl = (float) 0.0; fl++; break;
2181 case FIELDTYPE_SFVec2f:
2182 *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++; break;
2183 case FIELDTYPE_SFVec3f:
2184 case FIELDTYPE_SFColor:
2185 *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++; break;
2186 case FIELDTYPE_SFRotation:
2187 *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++; break;
2188 case FIELDTYPE_SFString:
2189 verify_Uni_String (*ms,"(empty value)"); ms++; break;
2190
2191 default : {printf ("getJSMultiNumType unhandled eletype: %d\n",
2192 eletype);
2193 return;
2194 }
2195 }
2196 } else {
2197 #ifdef SETFIELDVERBOSE
2198 JSString *_tmpStr;
2199
2200 _tmpStr = JS_ValueToString(cx, mainElement);
2201#if JS_VERSION < 185
2202 strp = JS_GetStringBytes(_tmpStr);
2203#else
2204 strp = strpp = JS_EncodeString(cx,_tmpStr);
2205#endif
2206 printf ("sub element %d is \"%s\" \n",i,strp);
2207#if JS_VERSION >= 185
2208 JS_free(cx,strpp);
2209#endif
2210
2211 if (JSVAL_IS_OBJECT(mainElement)) printf ("sub element %d is an OBJECT\n",i);
2212 if (JSVAL_IS_PRIMITIVE(mainElement)) printf ("sub element %d is an PRIMITIVE\n",i);
2213 #endif
2214
2215 /* code is pretty much same as SF* values in setField_javascriptEventOut */
2216 switch (eletype) {
2217 case FIELDTYPE_SFNode: {
2218
2219 if (JS_InstanceOf (cx, JSVAL_TO_OBJECT(mainElement), &SFNodeClass, NULL)) {
2220 SFNodeNative *_vec;
2221
2222 /* printf ("yep, this is an SFNode class\n"); */
2223 if ((_vec = (SFNodeNative *)JS_GetPrivateFw(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) {
2224 printf ("error getting native\n");
2225 *nl = NULL;
2226 } else {
2227 /* printf ("have native, handle %p\n",_vec->handle);
2228 printf ("and it is a :%s:\n",stringNodeType(_vec->handle->_nodeType)); */
2229 *nl = _vec->handle;
2230 }
2231 } else {
2232 printf ("hmm - not an SFNode class\n");
2233 *nl = NULL;
2234 }
2235
2236 nl++;
2237 break;
2238 }
2239 case FIELDTYPE_SFInt32: {
2240 if (!JS_ValueToInt32(cx, mainElement ,il)) {
2241 printf ("error\n");
2242 *il=0;
2243 }
2244 il++;
2245 break;
2246 }
2247 case FIELDTYPE_SFDouble:
2248 case FIELDTYPE_SFTime: {
2249 if (!JS_ValueToNumber(cx, mainElement ,dl)) *dl=0.0;
2250 dl++;
2251 break;
2252 }
2253 case FIELDTYPE_SFFloat: {
2254 if (!JS_ValueToNumber(cx, mainElement, &dtmp)) dtmp=0.0;
2255 /* convert double precision to single, for X3D */
2256 *fl = (float) dtmp;
2257 fl++;
2258 break;
2259 }
2260 case FIELDTYPE_SFVec2f: {
2261 if (JSVAL_IS_OBJECT(mainElement)) {
2262 if ((sfvec2f = (SFVec2fNative *)JS_GetPrivateFw(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) {
2263 printf( "JS_GetPrivate failed for obj in setField_javascriptEventOut.\n");
2264 return;
2265 }
2266 memcpy ((void *)fl, (void *)&(sfvec2f->v),2*sizeof(float));
2267 fl += 2;
2268 } else {
2269 /* we are working in a value that kind of exists, but is undefined */
2270 *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++;
2271 }
2272 break;
2273 }
2274 case FIELDTYPE_SFVec3f:
2275 case FIELDTYPE_SFColor: { /* SFColor */
2276 if (JSVAL_IS_OBJECT(mainElement)) {
2277 if ((sfvec3f = (SFVec3fNative *)JS_GetPrivateFw(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) {
2278 printf( "JS_GetPrivate failed for obj in setField_javascriptEventOut.\n");
2279 return;
2280 }
2281 memcpy ((void *)fl, (void *)&(sfvec3f->v),3*sizeof(float));
2282 fl += 3;
2283 } else {
2284 /* we are working in a value that kind of exists, but is undefined */
2285 *fl = (float) 0.0; fl++;
2286 *fl = (float) 0.0; fl++;
2287 *fl = (float) 0.0; fl++;
2288 }
2289 break;
2290 }
2291 case FIELDTYPE_SFRotation: {
2292 if (JSVAL_IS_OBJECT(mainElement)) {
2293 if ((sfrotation = (SFRotationNative *)JS_GetPrivateFw(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) {
2294 printf( "JS_GetPrivate failed for obj in setField_javascriptEventOut.\n");
2295 return;
2296 }
2297 memcpy ((void *)fl, (void *)&(sfrotation->v),4*sizeof(float));
2298 fl += 4;
2299 } else {
2300 /* we are working in a value that kind of exists, but is undefined */
2301 *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++;
2302 *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++;
2303 }
2304 break;
2305 }
2306
2307 case FIELDTYPE_SFString: {
2308 JSString *strval;
2309
2310 strval = JS_ValueToString(cx, mainElement);
2311#if JS_VERSION < 185
2312 strp = JS_GetStringBytes(strval);
2313#else
2314 strp = strpp = JS_EncodeString(cx,strval);
2315#endif
2316
2317
2318 #ifdef SETFIELDVERBOSE
2319 printf ("getJSMultiNumType, got string %s\n",strp);
2320 #endif
2321
2322 /* copy the string over, delete the old one, if need be */
2323 verify_Uni_String (*ms,strp);
2324 ms++;
2325#if JS_VERSION >= 185
2326 JS_free(cx,strpp);
2327#endif
2328 break;
2329 }
2330
2331 default : {printf ("getJSMultiNumType unhandled eletype: %d\n",
2332 eletype);
2333 return;
2334 }
2335 }
2336 }
2337
2338 }
2339 #ifdef SETFIELDVERBOSE
2340 printf ("getJSMultiNumType, setting old length %d to length %d\n",tn->n, len);
2341 #endif
2342
2343 tn->n = len;
2344}
2345
2346/****************************************************************/
2347/* a script is returning a MFString type; add this to the C */
2348/* children field */
2349/****************************************************************/
2350void getMFStringtype (JSContext *cx, jsval *from, struct Multi_String *to) {
2351 int oldlen, newlen;
2352 jsval _v;
2353 JSObject *obj;
2354 int i;
2355 char *valStr, *OldvalStr;
2356 struct Uni_String **svptr;
2357 struct Uni_String **newp, **oldp;
2358 int count;
2359
2360 JSString *strval; /* strings */
2361
2362 oldlen = to->n;
2363 svptr = to->p;
2364 newlen=0;
2365
2366 if (!JS_ValueToObject(cx, *from, &obj))
2367 printf ("JS_ValueToObject failed in getMFStringtype\n");
2368
2369 if (!JS_GetProperty(cx, obj, MF_LENGTH_FIELD, &_v)) {
2370 printf ("JS_GetProperty failed for \"%s\" in getMFStringtype.\n", MF_LENGTH_FIELD);
2371 }
2372
2373 newlen = JSVAL_TO_INT(_v);
2374
2375 /* printf ("getMFStringType, newlen %d oldlen %d\n",newlen,oldlen); */
2376
2377
2378 /* if we have to expand size of SV... */
2379 if (newlen > oldlen) {
2380 oldp = to->p; /* same as svptr, assigned above */
2381 to->n = newlen;
2382 to->p = MALLOC(struct Uni_String **, newlen * sizeof(to->p));
2383 newp = to->p;
2384
2385 /* copy old values over */
2386 for (count = 0; count <oldlen; count ++) {
2387 /*printf ("copying over element %d\n",count); */
2388 *newp = *oldp;
2389 newp++;
2390 oldp++;
2391 }
2392
2393 /* zero new entries */
2394 for (count = oldlen; count < newlen; count ++) {
2395 /* make the new SV */
2396 *newp = MALLOC (struct Uni_String *, sizeof (struct Uni_String));
2397
2398
2399 /* now, make it point to a blank string */
2400 *newp = newASCIIString("");
2401 newp ++;
2402 }
2403 FREE_IF_NZ (svptr);
2404 svptr = to->p;
2405 } else {
2406 /* possibly truncate this, but leave the memory alone. */
2407 to->n = newlen;
2408 }
2409
2410 /* printf ("verifying structure here\n");
2411 for (i=0; i<(to->n); i++) {
2412 printf ("indx %d flag %x string :%s: len1 %d len2 %d\n",i,
2413 (svptr[i])->sv_flags,
2414 }
2415 printf ("done\n");
2416 */
2417
2418
2419 for (i = 0; i < newlen; i++) {
2420 /* get the old string pointer */
2421 OldvalStr = svptr[i]->strptr;
2422 /* printf ("old string at %d is %s len %d\n",i,OldvalStr,strlen(OldvalStr)); */
2423
2424 /* get the new string pointer */
2425 if (!JS_GetElement(cx, obj, i, &_v)) {
2426 fprintf(stderr,
2427 "JS_GetElement failed for %d in getMFStringtype\n",i);
2428 return;
2429 }
2430 strval = JS_ValueToString(cx, _v);
2431#if JS_VERSION < 185
2432 valStr = JS_GetStringBytes(strval);
2433#else
2434 valStr = JS_EncodeString(cx,strval);
2435#endif
2436
2437 /* printf ("new string %d is %s\n",i,valStr); */
2438
2439 /* if the strings are different... */
2440 if (strcmp(valStr,OldvalStr) != 0) {
2441 /* MALLOC a new string, of correct len for terminator */
2442 svptr[i] = newASCIIString(valStr);
2443 }
2444#if JS_VERSION >= 185
2445 JS_free(cx,valStr);
2446#endif
2447 }
2448 /*
2449 printf ("\n new structure: %d %d\n",svptr,newlen);
2450 for (i=0; i<newlen; i++) {
2451 printf ("indx %d string :%s: len1 %d len2 %d\n",i,
2452 mypv->xpv_pv, mypv->xpv_cur,mypv->xpv_len);
2453 }
2454 */
2455
2456}
2457
2458
2459
2460
2461void setField_javascriptEventOut(struct X3D_Node *tn,unsigned int tptr, int fieldType, unsigned len, int extraData, JSContext *scriptContext) {
2462 int ival;
2463 double tval;
2464 float fl[4];
2465 char *memptr;
2466 JSString *strval; /* strings */
2467 char *strp;
2468#if JS_VERSION >= 185
2469 char *strpp; /* strp is modified, so we cannot use it to free JS_EncodeString results */
2470#endif
2471 ttglobal tg = gglobal();
2472
2473 /* NOTE - parent calls BeginRequest so we don't have to */
2474
2475 /* set up a pointer to where to put this stuff */
2476 memptr = offsetPointer_deref(char *, tn, tptr);
2477
2478 #ifdef SETFIELDVERBOSE
2479 strval = JS_ValueToString(scriptContext, *(jsval *)tg->JScript.JSglobal_return_val);
2480#if JS_VERSION < 185
2481 strp = JS_GetStringBytes(strval);
2482#else
2483 strp = strpp = JS_EncodeString(scriptContext,strval);
2484#endif
2485 printf ("start of setField_javascriptEventOut, to %ld:%d = %p, fieldtype %d string %s\n",(long)tn, tptr, memptr, fieldType, strp);
2486#if JS_VERSION >= 185
2487 JS_free(scriptContext,strpp);
2488#endif
2489 #endif
2490
2491#define GETJSVAL_TYPE_A(thistype,field) \
2492 case FIELDTYPE_##thistype: { \
2493 /* printf ("doing TYPEA memcpy to %u, from %u, len %d\n",(void *)memptr, (void *) &(((thistype##Native *)JSSFpointer)->field),len); */ \
2494 memcpy ((void *)memptr, (void *) &(((thistype##Native *)tg->CRoutes.JSSFpointer)->field),len); \
2495 break; \
2496 }
2497
2498#define GETJSVAL_TYPE_MF_A(MFtype,SFtype) \
2499 case FIELDTYPE_##MFtype: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_##SFtype); break;}
2500
2501 switch (fieldType) {
2502 GETJSVAL_TYPE_A(SFRotation,v)
2503 /* GETJSVAL_TYPE_A(SFNode,handle) */
2504 /* not implemented yet? GETJSVAL_TYPE_A(SFVec2d,v) */
2505 GETJSVAL_TYPE_A(SFVec3d,v)
2506 GETJSVAL_TYPE_A(SFVec4d,v)
2507 GETJSVAL_TYPE_A(SFVec2f,v)
2508 GETJSVAL_TYPE_A(SFVec3f,v)
2509 GETJSVAL_TYPE_A(SFVec4f,v)
2510 GETJSVAL_TYPE_A(SFColor,v)
2511 GETJSVAL_TYPE_A(SFColorRGBA,v)
2512
2513 GETJSVAL_TYPE_MF_A(MFRotation,SFRotation)
2514 GETJSVAL_TYPE_MF_A(MFVec2d,SFVec2d)
2515 GETJSVAL_TYPE_MF_A(MFVec3d,SFVec3d)
2516 GETJSVAL_TYPE_MF_A(MFVec4d,SFVec4d)
2517 GETJSVAL_TYPE_MF_A(MFVec2f,SFVec2f)
2518 GETJSVAL_TYPE_MF_A(MFVec3f,SFVec3f)
2519 GETJSVAL_TYPE_MF_A(MFVec4f,SFVec4f)
2520 GETJSVAL_TYPE_MF_A(MFColor,SFColor)
2521 GETJSVAL_TYPE_MF_A(MFColorRGBA,SFColorRGBA)
2522
2523
2524 case FIELDTYPE_SFInt32:
2525 case FIELDTYPE_SFBool: { /* SFBool */
2526 if (!JS_ValueToInt32(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val),&ival)) {
2527 printf ("error\n");
2528 ival=0;
2529 }
2530 memcpy ((void *)memptr, (void *)&ival,len);
2531 break;
2532 }
2533
2534 case FIELDTYPE_SFDouble:
2535 case FIELDTYPE_SFTime: {
2536 if (!JS_ValueToNumber(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val),&tval)) tval=0.0;
2537 memcpy ((void *)memptr, (void *)&tval,len);
2538 break;
2539 }
2540
2541 case FIELDTYPE_SFFloat: {
2542 if (!JS_ValueToNumber(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val),&tval)) tval=0.0;
2543 /* convert double precision to single, for X3D */
2544 fl[0] = (float) tval;
2545 memcpy ((void *)memptr, (void *)fl,len);
2546 break;
2547 }
2548
2549 case FIELDTYPE_SFImage: {
2550 /* the string should be saved as an SFImage */
2551 strval = JS_ValueToString(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val));
2552#if JS_VERSION < 185
2553 strp = JS_GetStringBytes(strval);
2554#else
2555 strp = strpp = JS_EncodeString(scriptContext,strval);
2556#endif
2557
2558 Parser_scanStringValueToMem(tn, tptr, FIELDTYPE_SFImage, strp, FALSE);
2559#if JS_VERSION >= 185
2560 JS_free(scriptContext,strpp);
2561#endif
2562 break;
2563 }
2564
2565 case FIELDTYPE_SFString: {
2566 struct Uni_String *ms;
2567 intptr_t *newptr;
2568
2569 strval = JS_ValueToString(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val));
2570#if JS_VERSION < 185
2571 strp = JS_GetStringBytes(strval);
2572#else
2573 strp = strpp = JS_EncodeString(scriptContext,strval);
2574#endif
2575
2576 /* copy the string over, delete the old one, if need be */
2577 /* printf ("fieldSet SFString, tn %d tptr %d offset from struct %d\n",
2578 tn, tptr, offsetof (struct X3D_TextureCoordinateGenerator, mode)); */
2579 newptr = (intptr_t *)memptr;
2580 ms = (struct Uni_String*) *newptr;
2581 verify_Uni_String (ms,strp);
2582#if JS_VERSION >= 185
2583 JS_free(scriptContext,strpp);
2584#endif
2585 break;
2586 }
2587
2588
2589 /* a series of Floats... */
2590 case FIELDTYPE_MFFloat: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFFloat); break;}
2591 case FIELDTYPE_MFInt32: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFInt32); break;}
2592 case FIELDTYPE_MFTime: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFTime); break;}
2593 case FIELDTYPE_MFDouble: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFDouble); break;}
2594 case FIELDTYPE_MFNode: {
2595 struct X3D_Node *mynode;
2596
2597 strval = JS_ValueToString(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val));
2598#if JS_VERSION < 185
2599 strp = JS_GetStringBytes(strval);
2600#else
2601 strp = strpp = JS_EncodeString(scriptContext,strval);
2602#endif
2603
2604 /* we will have at least one node here, in an ascii string */
2605 while ((*strp > '\0') && (*strp <= ' ')) strp ++;
2606 /* are we at a bracket? */
2607 if (*strp == '[') strp ++;
2608 while ((*strp > '\0') && (*strp <= ' ')) strp ++;
2609
2610 /* printf ("convertingthe following string to a pointer :%s:\n",strp); */
2611
2612 mynode = X3D_NODE(atol(strp));
2613#if JS_VERSION >= 185
2614 JS_free(scriptContext,strpp);
2615#endif
2616
2617 /* printf ("mynode is %p %d, \n",mynode,mynode);
2618 printf ("mynode is %p %d, type %d\n",mynode,mynode,mynode->_nodeType);
2619 printf ("calling getMFNodeType now\n"); */
2620
2621
2622 getMFNodetype (mynode,(struct Multi_Node *)memptr,X3D_NODE(tn),extraData); break;
2623 }
2624 case FIELDTYPE_MFString: {
2625 getMFStringtype (
2626 scriptContext,
2627 (jsval *)tg->JScript.JSglobal_return_val,
2628 (struct Multi_String *)memptr);
2629 break;
2630 }
2631
2632 case FIELDTYPE_SFNode: {
2633 //unsigned int valuecopied;
2634 //unsigned int *ptr2value;
2635 /* printf ("doing TYPEA memcpy to %u, from %u, len %d\n",(void *)memptr, (void *) &(((SFNodeNative *)JSSFpointer)->handle),returnElementLength(FIELDTYPE_SFNode));*/
2636 memcpy ((void *)memptr, (void *) &(((SFNodeNative *)tg->CRoutes.JSSFpointer)->handle),returnElementLength(FIELDTYPE_SFNode));
2637 //ptr2value = (unsigned int*)memptr;
2638 //valuecopied = *ptr2value;
2639 //printf("value of memptr %u after memcpy in script route= %u\n",(void*)memptr,valuecopied);
2640 break;
2641 }
2642
2643
2644 default: { printf("WARNING: unhandled from type %s\n", stringFieldtypeType(fieldType));
2645 }
2646 }
2647
2648 #ifdef SETFIELDVERBOSE
2649 printf ("done setField_javascriptEventOut\n");
2650 if (fieldType == FIELDTYPE_MFInt32) {
2651 printf ("setField_javascriptEventOut, checking the pointers...\n");
2652 printf ("node type is %s\n",stringNodeType(X3D_NODE(tn)->_nodeType));
2653 }
2654 if (fieldType == FIELDTYPE_SFNode) {
2655 printf ("setField_javascriptEventOut, checking the pointers...\n");
2656 printf ("node type is %s\n",stringNodeType(X3D_NODE(tn)->_nodeType));
2657 }
2658
2659 #endif
2660}
2661
2662void Parser_scanStringValueToMem_B(union anyVrml* any, indexT ctype, const char *value, int isXML);
2663
2664void setField_javascriptEventOut_B(union anyVrml* any,
2665 int fieldType, unsigned len, int extraData, JSContext *scriptContext)
2666{
2667 //dug9 Feb 2013 for new propagate_events - like setField_javascriptEventout except:
2668 // writes to *anyVrml instead of (toNode,toOffset) combo (which doesn't work for Proto fields)
2669 // and doesn't update parents for SFNode,MFNode - that's done later.
2670 int ival;
2671 double tval;
2672 float fl[4];
2673 char *memptr;
2674 JSString *strval; /* strings */
2675 char *strp;
2676#if JS_VERSION >= 185
2677 char *strpp; /* strp is modified, so we cannot use it to free JS_EncodeString results */
2678#endif
2679 ttglobal tg = gglobal();
2680
2681 /* NOTE - parent calls BeginRequest so we don't have to */
2682
2683 /* set up a pointer to where to put this stuff */
2684 memptr = (char *)any; //offsetPointer_deref(char *, tn, tptr);
2685
2686 #ifdef SETFIELDVERBOSE
2687 strval = JS_ValueToString(scriptContext, *(jsval *)tg->JScript.JSglobal_return_val);
2688#if JS_VERSION < 185
2689 strp = JS_GetStringBytes(strval);
2690#else
2691 strp = strpp = JS_EncodeString(scriptContext,strval);
2692#endif
2693 printf ("start of setField_javascriptEventOut, to %ld:%d = %p, fieldtype %d string %s\n",(long)any, fieldType, memptr, fieldType, strp);
2694#if JS_VERSION >= 185
2695 JS_free(scriptContext,strpp);
2696#endif
2697 #endif
2698
2699#define GETJSVAL_TYPE_A(thistype,field) \
2700 case FIELDTYPE_##thistype: { \
2701 /* printf ("doing TYPEA memcpy to %u, from %u, len %d\n",(void *)memptr, (void *) &(((thistype##Native *)JSSFpointer)->field),len); */ \
2702 memcpy ((void *)memptr, (void *) &(((thistype##Native *)tg->CRoutes.JSSFpointer)->field),len); \
2703 break; \
2704 }
2705
2706#define GETJSVAL_TYPE_MF_A(MFtype,SFtype) \
2707 case FIELDTYPE_##MFtype: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_##SFtype); break;}
2708
2709 switch (fieldType) {
2710 GETJSVAL_TYPE_A(SFRotation,v)
2711 /* GETJSVAL_TYPE_A(SFNode,handle) */
2712 /* not implemented yet? GETJSVAL_TYPE_A(SFVec2d,v) */
2713 GETJSVAL_TYPE_A(SFVec3d,v)
2714 GETJSVAL_TYPE_A(SFVec4d,v)
2715 GETJSVAL_TYPE_A(SFVec2f,v)
2716 GETJSVAL_TYPE_A(SFVec3f,v)
2717 GETJSVAL_TYPE_A(SFVec4f,v)
2718 GETJSVAL_TYPE_A(SFColor,v)
2719 GETJSVAL_TYPE_A(SFColorRGBA,v)
2720
2721 GETJSVAL_TYPE_MF_A(MFRotation,SFRotation)
2722 GETJSVAL_TYPE_MF_A(MFVec2d,SFVec2d)
2723 GETJSVAL_TYPE_MF_A(MFVec3d,SFVec3d)
2724 GETJSVAL_TYPE_MF_A(MFVec4d,SFVec4d)
2725 GETJSVAL_TYPE_MF_A(MFVec2f,SFVec2f)
2726 GETJSVAL_TYPE_MF_A(MFVec3f,SFVec3f)
2727 GETJSVAL_TYPE_MF_A(MFVec4f,SFVec4f)
2728 GETJSVAL_TYPE_MF_A(MFColor,SFColor)
2729 GETJSVAL_TYPE_MF_A(MFColorRGBA,SFColorRGBA)
2730
2731
2732 case FIELDTYPE_SFInt32:
2733 case FIELDTYPE_SFBool: { /* SFBool */
2734 if (!JS_ValueToInt32(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val),&ival)) {
2735 printf ("error\n");
2736 ival=0;
2737 }
2738 memcpy ((void *)memptr, (void *)&ival,len);
2739 break;
2740 }
2741
2742 case FIELDTYPE_SFDouble:
2743 case FIELDTYPE_SFTime: {
2744 if (!JS_ValueToNumber(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val),&tval)) tval=0.0;
2745 memcpy ((void *)memptr, (void *)&tval,len);
2746 break;
2747 }
2748
2749 case FIELDTYPE_SFFloat: {
2750 if (!JS_ValueToNumber(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val),&tval)) tval=0.0;
2751 /* convert double precision to single, for X3D */
2752 fl[0] = (float) tval;
2753 memcpy ((void *)memptr, (void *)fl,len);
2754 break;
2755 }
2756
2757 case FIELDTYPE_SFImage: {
2758 /* the string should be saved as an SFImage */
2759 strval = JS_ValueToString(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val));
2760#if JS_VERSION < 185
2761 strp = JS_GetStringBytes(strval);
2762#else
2763 strp = strpp = JS_EncodeString(scriptContext,strval);
2764#endif
2765
2766 Parser_scanStringValueToMem_B(any, FIELDTYPE_SFImage, strp, FALSE);
2767#if JS_VERSION >= 185
2768 JS_free(scriptContext,strpp);
2769#endif
2770 break;
2771 }
2772
2773 case FIELDTYPE_SFString: {
2774 struct Uni_String *ms;
2775 intptr_t *newptr;
2776
2777 strval = JS_ValueToString(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val));
2778#if JS_VERSION < 185
2779 strp = JS_GetStringBytes(strval);
2780#else
2781 strp = strpp = JS_EncodeString(scriptContext,strval);
2782#endif
2783
2784 /* copy the string over, delete the old one, if need be */
2785 /* printf ("fieldSet SFString, tn %d tptr %d offset from struct %d\n",
2786 tn, tptr, offsetof (struct X3D_TextureCoordinateGenerator, mode)); */
2787 newptr = (intptr_t *)memptr;
2788 ms = (struct Uni_String*) *newptr;
2789 if(!ms) {
2790 ms = malloc(sizeof(struct Uni_String));
2791 *newptr = (intptr_t) ms;
2792 ms->len = 0;
2793 ms->strptr = NULL;
2794 ms->touched = FALSE;
2795 }
2796 verify_Uni_String (ms,strp);
2797#if JS_VERSION >= 185
2798 JS_free(scriptContext,strpp);
2799#endif
2800 break;
2801 }
2802
2803
2804 /* a series of Floats... */
2805 case FIELDTYPE_MFFloat: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFFloat); break;}
2806 case FIELDTYPE_MFInt32: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFInt32); break;}
2807 case FIELDTYPE_MFTime: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFTime); break;}
2808 case FIELDTYPE_MFDouble: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFDouble); break;}
2809 case FIELDTYPE_MFNode: {
2810 struct X3D_Node *mynode;
2811
2812 strval = JS_ValueToString(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val));
2813#if JS_VERSION < 185
2814 strp = JS_GetStringBytes(strval);
2815#else
2816 strp = strpp = JS_EncodeString(scriptContext,strval);
2817#endif
2818
2819 /* we will have at least one node here, in an ascii string */
2820 while ((*strp > '\0') && (*strp <= ' ')) strp ++;
2821 /* are we at a bracket? */
2822 if (*strp == '[') strp ++;
2823 while ((*strp > '\0') && (*strp <= ' ')) strp ++;
2824
2825 /* printf ("convertingthe following string to a pointer :%s:\n",strp); */
2826
2827 mynode = X3D_NODE(atol(strp));
2828#if JS_VERSION >= 185
2829 JS_free(scriptContext,strpp);
2830#endif
2831
2832 /* printf ("mynode is %p %d, \n",mynode,mynode);
2833 printf ("mynode is %p %d, type %d\n",mynode,mynode,mynode->_nodeType);
2834 printf ("calling getMFNodeType now\n"); */
2835
2836
2837 //getMFNodetype (mynode,(struct Multi_Node *)memptr,X3D_NODE(tn),extraData);
2838 any->mfnode.n = 1;
2839 any->mfnode.p = MALLOC(struct X3D_Node **, sizeof(struct X3D_Node *));
2840 any->mfnode.p[0] = mynode;
2841 //Q. can we do add/remove children outside?
2842 break;
2843 }
2844 case FIELDTYPE_MFString: {
2845 getMFStringtype (
2846 scriptContext,
2847 (jsval *)tg->JScript.JSglobal_return_val,
2848 (struct Multi_String *)memptr);
2849 break;
2850 }
2851
2852 case FIELDTYPE_SFNode: {
2853 //unsigned int valuecopied;
2854 //unsigned int *ptr2value;
2855 /* printf ("doing TYPEA memcpy to %u, from %u, len %d\n",(void *)memptr, (void *) &(((SFNodeNative *)JSSFpointer)->handle),returnElementLength(FIELDTYPE_SFNode));*/
2856 memcpy ((void *)memptr, (void *) &(((SFNodeNative *)tg->CRoutes.JSSFpointer)->handle),returnElementLength(FIELDTYPE_SFNode));
2857 //ptr2value = (unsigned int*)memptr;
2858 //valuecopied = *ptr2value;
2859 //printf("value of memptr %u after memcpy in script route= %u\n",(void*)memptr,valuecopied);
2860 break;
2861 }
2862
2863
2864 default: { printf("WARNING: unhandled from type %s\n", stringFieldtypeType(fieldType));
2865 }
2866 }
2867
2868 #ifdef SETFIELDVERBOSE
2869 printf ("done setField_javascriptEventOut\n");
2870 if (fieldType == FIELDTYPE_MFInt32) {
2871 printf ("setField_javascriptEventOut, checking the pointers...\n");
2872 printf ("node type is %s\n",stringNodeType(X3D_NODE(any)->_nodeType));
2873 }
2874 if (fieldType == FIELDTYPE_SFNode) {
2875 printf ("setField_javascriptEventOut, checking the pointers...\n");
2876 printf ("node type is %s\n",stringNodeType(X3D_NODE(any)->_nodeType));
2877 }
2878
2879 #endif
2880}
2881
2882void sm_js_setField_javascriptEventOut(struct X3D_Node *tn,unsigned int tptr, int fieldType, unsigned len, int extraData, int actualscript) {
2883 struct CRscriptStruct *scriptcontrol;
2884
2885 scriptcontrol = getScriptControlIndex(actualscript);
2886#if defined(JS_THREADSAFE)
2887 JS_BeginRequest(scriptcontrol->cx);
2888#endif
2889 setField_javascriptEventOut(tn,tptr,fieldType, len, extraData, scriptcontrol->cx);
2890#if defined(JS_THREADSAFE)
2891 JS_EndRequest(scriptcontrol->cx);
2892#endif
2893}
2894
2895void sm_js_setField_javascriptEventOut_B(union anyVrml* any, int fieldType, unsigned len, int extraData, int actualscript){
2896 struct CRscriptStruct *scriptcontrol;
2897
2898 scriptcontrol = getScriptControlIndex(actualscript);
2899#if defined(JS_THREADSAFE)
2900 JS_BeginRequest(scriptcontrol->cx);
2901#endif
2902 setField_javascriptEventOut_B(any,fieldType, len, extraData, scriptcontrol->cx);
2903
2904#if defined(JS_THREADSAFE)
2905 JS_EndRequest(scriptcontrol->cx);
2906#endif
2907}
2908
2909
2910/******************************************************************************/
2911
2912void sm_set_one_ECMAtype (int tonode, int toname, int dataType, void *Data, int datalen) {
2913 char scriptline[256];
2914 jsval newval;
2915 JSContext *cx;
2916 JSObject *obj;
2917 int kind;
2918 struct CRscriptStruct *ScriptControl; // = getScriptControl();
2919 struct CRjsnameStruct *JSparamnames = getJSparamnames();
2920
2921 #ifdef SETFIELDVERBOSE
2922 printf ("set_one_ECMAtype, to %d namepointer %d, fieldname %s, datatype %d length %d\n",
2923 tonode,toname,JSparamnames[toname].name,dataType,datalen);
2924 #endif
2925 ScriptControl = getScriptControlIndex(tonode);
2926 /* get context and global object for this script */
2927 cx = (JSContext*)ScriptControl->cx;
2928 obj = (JSObject*)ScriptControl->glob;
2929
2930#if defined(JS_THREADSAFE)
2931 JS_BeginRequest(cx);
2932#endif
2933 /* set the time for this script */
2934 SET_JS_TICKTIME
2935
2936 //step 1 set the field value
2937 kind = JSparamnames[toname].kind; //PKW_inputOnly;
2938 if(SM_method() == 2){
2939 int type, iifield, *valueChanged, ifound;
2940 union anyVrml *value;
2941 char *fieldname;
2942 struct Shader_Script *script = ScriptControl->script;
2943 fieldname = JSparamnames[toname].name;
2944 //step 1 update the fieldvalue
2945 ifound = getFieldFromScript(script,fieldname,&type,&kind,&iifield,&value,&valueChanged);
2946 if(ifound && type == dataType && isSFType(type)){
2947 //we have an MF field, and mf coming in, we'll call our field LHS and incoming RHS
2948 union anyVrml *any = (union anyVrml*)Data;
2949 //printf("any float=%f",any->sffloat);
2950 shallow_copy_field(type,any,value);
2951 //if we have an inputOutput field with no eventIn function, we may still be routing
2952 //from the out side
2953 (*valueChanged) = 1;
2954 }else{
2955 ConsoleMessage("sm_set_one_ECMAtype did not find field %s type %d\n",fieldname, dataType);
2956 return;
2957 }
2958
2959 }else{ //SM_method == 2
2960 X3D_ECMA_TO_JS(cx, Data, datalen, dataType, &newval);
2961
2962 /* get the variable name to hold the incoming value */
2963 scriptline[0] = 0;
2964 if(kind == PKW_inputOnly)
2965 strcat(scriptline,"__eventIn_Value_");
2966 //sprintf (scriptline,"__eventIn_Value_%s", JSparamnames[toname].name);
2967 strcat(scriptline,JSparamnames[toname].name);
2968 #ifdef SETFIELDVERBOSE
2969 printf ("set_one_ECMAtype, calling JS_DefineProperty on name %s obj %u, setting setECMANative, 0 \n",scriptline,obj);
2970 #endif
2971
2972 if (!JS_DefineProperty(cx,obj, scriptline, newval, JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_PERMANENT)) {
2973 printf( "JS_DefineProperty failed for \"ECMA in\" at %s:%d.\n",__FILE__,__LINE__);
2974#if defined(JS_THREADSAFE)
2975 JS_EndRequest(cx);
2976#endif
2977 return;
2978 }
2979
2980 } //SM_method == 2
2981
2982 //step 2 run eventin if it exists
2983 /* is the function compiled yet? */
2984 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
2985
2986 /* and run the function */
2987 RUN_FUNCTION (toname)
2988
2989
2990#if defined(JS_THREADSAFE)
2991 JS_EndRequest(cx);
2992#endif
2993}
2994
2995/* setScriptECMAtype called by getField_ToJavascript for
2996 case FIELDTYPE_SFBool:
2997 case FIELDTYPE_SFFloat:
2998 case FIELDTYPE_SFTime:
2999 case FIELDTYPE_SFDouble:
3000 case FIELDTYPE_SFInt32:
3001 case FIELDTYPE_SFString:
3002*/
3003
3004void sm_setScriptECMAtype (int num) {
3005 void *fn;
3006 int tptr;
3007 int len;
3008 int to_counter;
3009 CRnodeStruct *to_ptr = NULL;
3010 struct CRStruct *CRoutes = getCRoutes();
3011 struct CRjsnameStruct *JSparamnames = getJSparamnames();
3012
3013 fn = offsetPointer_deref(void *, CRoutes[num].routeFromNode, CRoutes[num].fnptr);
3014 len = CRoutes[num].len;
3015
3016 for (to_counter = 0; to_counter < CRoutes[num].tonode_count; to_counter++) {
3017 struct Shader_Script *myObj;
3018
3019 to_ptr = &(CRoutes[num].tonodes[to_counter]);
3020 myObj = X3D_SCRIPT(to_ptr->routeToNode)->__scriptObj;
3021 /* printf ("setScriptECMAtype, myScriptNumber is %d\n",myObj->num); */
3022 tptr = to_ptr->foffset;
3023 set_one_ECMAtype (myObj->num, tptr, JSparamnames[tptr].type, fn,len);
3024 }
3025}
3026
3027
3028/* use Javascript to send in one element of an MF. datalen is in number of elements in type. */
3029void sm_set_one_MFElementType(int tonode, int toname, int dataType, void *Data, int datalen) {
3030 JSContext *cx;
3031 JSObject *obj;
3032 int elementlen;
3033 int x;
3034 char scriptline[20000];
3035
3036 /* for PixelTextures we have: */
3037 //struct X3D_PixelTexture *mePix;
3038 //struct Multi_Int32 image;
3039
3040 /* for MFStrings we have: */
3041 char *chptr;
3042 struct Uni_String **uniptr;
3043 int kind;
3044 struct CRscriptStruct *ScriptControl; // = getScriptControl();
3045 struct CRjsnameStruct *JSparamnames = getJSparamnames();
3046
3047 /* get context and global object for this script */
3048 ScriptControl = getScriptControlIndex(tonode);
3049 cx = (JSContext*)ScriptControl->cx;
3050 obj = (JSObject*)ScriptControl->glob;
3051
3052#if defined(JS_THREADSAFE)
3053 JS_BeginRequest(cx);
3054#endif
3055 /* set the TickTime (possibly again) for this context */
3056 kind = JSparamnames[toname].kind; //PKW_inputOnly;
3057 if(SM_method() == 2){
3058 int type, iifield, *valueChanged, ifound;
3059 union anyVrml *value;
3060 char *fieldname;
3061 struct Shader_Script *script = ScriptControl->script;
3062 fieldname = JSparamnames[toname].name;
3063 //step 1 update the fieldvalue
3064 ifound = getFieldFromScript(script,fieldname,&type,&kind,&iifield,&value,&valueChanged);
3065 if(ifound && type == dataType && !isSFType(type)){
3066 //we have an MF field, and mf coming in, we'll call our field LHS and incoming RHS
3067 union anyVrml any;
3068 any.mfbool.n = datalen;
3069 any.mfbool.p = Data;
3070 //printf("address of any.p %x value.p %x",any.mfbool.p,value->mfbool.p);
3071 //printf("any.n=%d \n",any.mffloat.n);
3072 //printf("mfany= %f %f %f",any.mffloat.p[0],any.mffloat.p[1],any.mffloat.p[2]);
3073 //printf("target value.n= %d\n",value->mfbool.n);
3074 shallow_copy_field(type,&any,value);
3075 //printf("after shallow_copy_field:\n");
3076 //printf("target value.n= %d\n",value->mfbool.n);
3077 //printf("mfvalue= %f %f %f",value->mffloat.p[0],value->mffloat.p[1],value->mffloat.p[2]);
3078
3079 //if we have an inputOutput field with no eventIn function, we may still be routing
3080 //from the out side
3081 (*valueChanged) = 1;
3082 }else{
3083 ConsoleMessage("sm_set_one_MFElementType did not find field %s type %d\n",fieldname, dataType);
3084 return;
3085 }
3086 //step 2 run the eventIn if it exists
3087 SET_JS_TICKTIME
3088 //compile also pushes the field val onto call stack
3089 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
3090 RUN_FUNCTION(toname)
3091 return;
3092 }
3093 SET_JS_TICKTIME
3094
3095 /* make up the name */
3096 switch (dataType) {
3097 case FIELDTYPE_MFRotation: {
3098 JSObject *newMFObject;
3099 JSObject *newSFObject;
3100 SFRotationNative *SFRPptr;
3101 float *fp, *fp_in=(float *)Data;
3102
3103 /* create a new MFRotation object... */
3104 newMFObject = JS_ConstructObjectFw(cx, &MFRotationClass, NULL ,JS_GetParentFw(cx, obj));
3105 ADD_ROOT (cx, newMFObject)
3106
3107 /* define the "length" property for this object */
3108 DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3109
3110 /* fill in private pointer area */
3111 elementlen = (int) sizeof (float);
3112 for (x=0; x<datalen; x++) {
3113 /* create a new SFRotation object */
3114 newSFObject = JS_ConstructObjectFw(cx,&SFRotationClass,NULL, newMFObject);
3115 if ((SFRPptr = (SFRotationNative *)JS_GetPrivateFw(cx, newSFObject)) == NULL) {
3116 ConsoleMessage ("failure in getting SF class at %s:%d\n",__FILE__,__LINE__);
3117#if defined(JS_THREADSAFE)
3118 JS_EndRequest(cx);
3119#endif
3120 return;
3121 }
3122
3123 /* fill the private pointer area */
3124 fp = (float *)fp_in; SFRPptr->v.c[0] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3125 fp = (float *)fp_in; SFRPptr->v.c[1] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3126 fp = (float *)fp_in; SFRPptr->v.c[2] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3127 fp = (float *)fp_in; SFRPptr->v.c[3] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3128
3129 /* put this object into the MF class */
3130 if (!JS_DefineElement(cx, newMFObject, (jsint) x, OBJECT_TO_JSVAL(newSFObject),
3131 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3132 printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3133 }
3134 }
3135
3136 /* set the length of this MF */
3137 SET_LENGTH (cx,newMFObject,datalen)
3138
3139 /* set the global variable with this new MF object */
3140 SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3141
3142 /* run the function */
3143 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
3144 RUN_FUNCTION(toname)
3145 break;
3146 }
3147
3148 case FIELDTYPE_MFVec3f: {
3149 JSObject *newMFObject;
3150 JSObject *newSFObject;
3151 SFVec3fNative *SFRPptr;
3152 float *fp, *fp_in=(float *)Data;
3153
3154 /* create a new MFVec3f object... */
3155 newMFObject = JS_ConstructObjectFw(cx, &MFVec3fClass, NULL ,JS_GetParentFw(cx, obj));
3156 ADD_ROOT (cx, newMFObject)
3157
3158 /* define the "length" property for this object */
3159 DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3160
3161 /* fill in private pointer area */
3162 elementlen = (int) sizeof (float);
3163 for (x=0; x<datalen; x++) {
3164 /* create a new SFVec3f object */
3165 newSFObject = JS_ConstructObjectFw(cx,&SFVec3fClass,NULL, newMFObject);
3166 if ((SFRPptr = (SFVec3fNative *)JS_GetPrivateFw(cx, newSFObject)) == NULL) {
3167 ConsoleMessage ("failure in getting SF class at %s:%d\n",__FILE__,__LINE__);
3168#if defined(JS_THREADSAFE)
3169 JS_EndRequest(cx);
3170#endif
3171 return;
3172 }
3173
3174 /* fill the private pointer area */
3175 fp = (float *)fp_in; SFRPptr->v.c[0] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3176 fp = (float *)fp_in; SFRPptr->v.c[1] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3177 fp = (float *)fp_in; SFRPptr->v.c[2] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3178
3179 /* put this object into the MF class */
3180 if (!JS_DefineElement(cx, newMFObject, (jsint) x, OBJECT_TO_JSVAL(newSFObject),
3181 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3182 printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3183 }
3184 }
3185
3186 /* set the length of this MF */
3187 SET_LENGTH (cx,newMFObject,datalen)
3188
3189 /* set the global variable with this new MF object */
3190 SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3191
3192 /* run the function */
3193 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
3194 RUN_FUNCTION(toname)
3195 break;
3196 }
3197
3198 case FIELDTYPE_MFColor: {
3199 JSObject *newMFObject;
3200 JSObject *newSFObject;
3201 SFColorNative *SFRPptr;
3202 float *fp, *fp_in=(float *)Data;
3203
3204 /* create a new MFColor object... */
3205 newMFObject = JS_ConstructObjectFw(cx, &MFColorClass, NULL ,JS_GetParentFw(cx, obj));
3206 ADD_ROOT (cx, newMFObject)
3207
3208 /* define the "length" property for this object */
3209 DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3210
3211 /* fill in private pointer area */
3212 elementlen = (int) sizeof (float);
3213 for (x=0; x<datalen; x++) {
3214 /* create a new SFColor object */
3215 newSFObject = JS_ConstructObjectFw(cx,&SFColorClass,NULL, newMFObject);
3216 if ((SFRPptr = (SFColorNative *)JS_GetPrivateFw(cx, newSFObject)) == NULL) {
3217 ConsoleMessage ("failure in getting SF class at %s:%d\n",__FILE__,__LINE__);
3218#if defined(JS_THREADSAFE)
3219 JS_EndRequest(cx);
3220#endif
3221 return;
3222 }
3223
3224 /* fill the private pointer area */
3225 fp = (float *)fp_in; SFRPptr->v.c[0] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3226 fp = (float *)fp_in; SFRPptr->v.c[1] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3227 fp = (float *)fp_in; SFRPptr->v.c[2] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3228
3229 /* put this object into the MF class */
3230 if (!JS_DefineElement(cx, newMFObject, (jsint) x, OBJECT_TO_JSVAL(newSFObject),
3231 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3232 printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3233 }
3234 }
3235
3236 /* set the length of this MF */
3237 SET_LENGTH (cx,newMFObject,datalen)
3238
3239 /* set the global variable with this new MF object */
3240 SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3241
3242 /* run the function */
3243 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
3244 RUN_FUNCTION(toname)
3245 break;
3246 }
3247
3248 case FIELDTYPE_MFVec2f: {
3249 JSObject *newMFObject;
3250 JSObject *newSFObject;
3251 SFVec2fNative *SFRPptr;
3252 float *fp, *fp_in=(float *)Data;
3253
3254 /* create a new MFVec2f object... */
3255 newMFObject = JS_ConstructObjectFw(cx, &MFVec2fClass, NULL ,JS_GetParentFw(cx, obj));
3256 ADD_ROOT (cx, newMFObject)
3257
3258 /* define the "length" property for this object */
3259 DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3260
3261 /* fill in private pointer area */
3262 elementlen = (int) sizeof (float);
3263 for (x=0; x<datalen; x++) {
3264 /* create a new SFVec2f object */
3265 newSFObject = JS_ConstructObjectFw(cx,&SFVec2fClass,NULL, newMFObject);
3266 if ((SFRPptr = (SFVec2fNative *)JS_GetPrivateFw(cx, newSFObject)) == NULL) {
3267 ConsoleMessage ("failure in getting SF class at %s:%d\n",__FILE__,__LINE__);
3268#if defined(JS_THREADSAFE)
3269 JS_EndRequest(cx);
3270#endif
3271 return;
3272 }
3273
3274 /* fill the private pointer area */
3275 fp = (float *)fp_in; SFRPptr->v.c[0] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3276 fp = (float *)fp_in; SFRPptr->v.c[1] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3277
3278 /* put this object into the MF class */
3279 if (!JS_DefineElement(cx, newMFObject, (jsint) x, OBJECT_TO_JSVAL(newSFObject),
3280 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3281 ConsoleMessage("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3282 }
3283 }
3284
3285 /* set the length of this MF */
3286 SET_LENGTH (cx,newMFObject,datalen)
3287
3288 /* set the global variable with this new MF object */
3289 SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3290
3291 /* run the function */
3292 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
3293 RUN_FUNCTION(toname)
3294 break;
3295 }
3296
3297
3298 case FIELDTYPE_MFFloat: {
3299 JSObject *newMFObject;
3300 jsval newjsval;
3301 float *fp, *fp_in=(float *)Data;
3302 /* create a new MFFloat object... */
3303 newMFObject = JS_ConstructObjectFw(cx, &MFFloatClass, NULL ,JS_GetParentFw(cx, obj));
3304 ADD_ROOT (cx, newMFObject)
3305
3306 /* define the "length" property for this object */
3307 DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3308
3309 /* fill in private pointer area */
3310 elementlen = (int) sizeof (float);
3311 for (x=0; x<datalen; x++) {
3312 /* create a new SFFloat object */
3313
3314 fp = (float *)fp_in;
3315 JS_NewNumberValue(cx,(double)*fp,&newjsval);
3316 fp_in = offsetPointer_deref(float *,fp_in,elementlen);
3317
3318 /* put this object into the MF class */
3319 if (!JS_DefineElement(cx, newMFObject, (jsint) x, newjsval,
3320 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3321 printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3322 }
3323 }
3324
3325 /* set the length of this MF */
3326 SET_LENGTH (cx,newMFObject,datalen)
3327
3328 /* set the global variable with this new MF object */
3329 SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3330
3331 /* run the function */
3332 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
3333 RUN_FUNCTION(toname)
3334 break;
3335 }
3336 case FIELDTYPE_MFTime: {
3337 JSObject *newMFObject;
3338 jsval newjsval;
3339 double *dp, *dp_in=(double *)Data;
3340
3341 /* create a new MFTime object... */
3342 newMFObject = JS_ConstructObjectFw(cx, &MFTimeClass, NULL ,JS_GetParentFw(cx, obj));
3343 ADD_ROOT (cx, newMFObject)
3344
3345 /* define the "length" property for this object */
3346 DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3347
3348 /* fill in private pointer area */
3349 elementlen = (int) sizeof (double);
3350 for (x=0; x<datalen; x++) {
3351 /* create a new SFTime object */
3352
3353 dp = (double *)dp_in;
3354 JS_NewNumberValue(cx,(double)*dp,&newjsval);
3355 dp_in = offsetPointer_deref(double *,dp_in,elementlen);
3356
3357 /* put this object into the MF class */
3358 if (!JS_DefineElement(cx, newMFObject, (jsint) x, newjsval,
3359 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3360 printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3361 }
3362 }
3363
3364 /* set the length of this MF */
3365 SET_LENGTH (cx,newMFObject,datalen)
3366
3367 /* set the global variable with this new MF object */
3368 SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3369
3370 /* run the function */
3371 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
3372 RUN_FUNCTION(toname)
3373 break;
3374 }
3375 case FIELDTYPE_MFInt32: {
3376 JSObject *newMFObject;
3377 jsval newjsval;
3378 int *ip, *ip_in=(int *)Data;
3379
3380 /* create a new MFInt32 object... */
3381 newMFObject = JS_ConstructObjectFw(cx, &MFInt32Class, NULL ,JS_GetParentFw(cx, obj));
3382 ADD_ROOT (cx, newMFObject)
3383
3384 /* define the "length" property for this object */
3385 DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3386
3387 /* fill in private pointer area */
3388 elementlen = (int) sizeof (float);
3389 for (x=0; x<datalen; x++) {
3390 /* create a new SFInt32 object */
3391
3392 ip = (int *)ip_in;
3393 newjsval = INT_TO_JSVAL((int)ip); /* NOTE--this is assigning the pointer itself as an int, not its content */
3394 ip_in = offsetPointer_deref(int *,ip_in,elementlen);
3395
3396 /* put this object into the MF class */
3397 if (!JS_DefineElement(cx, newMFObject, (jsint) x, newjsval,
3398 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3399 printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3400 }
3401 }
3402
3403 /* set the length of this MF */
3404 SET_LENGTH (cx,newMFObject,datalen)
3405
3406 /* set the global variable with this new MF object */
3407 SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3408
3409 /* run the function */
3410 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
3411 RUN_FUNCTION(toname)
3412 break;
3413 }
3414 case FIELDTYPE_MFString: {
3415 JSObject *newMFObject;
3416 jsval newjsval;
3417 struct Uni_String * *ip_in=(struct Uni_String **)Data;
3418
3419 /* create a new MFString object... */
3420 newMFObject = JS_ConstructObjectFw(cx, &MFStringClass, NULL ,JS_GetParentFw(cx, obj));
3421 ADD_ROOT (cx, newMFObject)
3422
3423 /* Data points to a Uni_String */
3424 uniptr = (struct Uni_String **) ip_in;
3425
3426 /* define the "length" property for this object */
3427 DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3428
3429 /* fill in private pointer area */
3430 for (x=0; x<datalen; x++) {
3431 /* create a new SFString object */
3432
3433 chptr = uniptr[x]->strptr;
3434 newjsval = STRING_TO_JSVAL( JS_NewStringCopyZ(cx,chptr));
3435
3436 /* put this object into the MF class */
3437 if (!JS_DefineElement(cx, newMFObject, (jsint) x, newjsval,
3438 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3439 printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3440 }
3441 }
3442
3443 /* set the length of this MF */
3444 SET_LENGTH (cx,newMFObject,datalen)
3445
3446 /* set the global variable with this new MF object */
3447 SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3448
3449 /* run the function */
3450 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
3451 RUN_FUNCTION(toname)
3452 break;
3453 }
3454 case FIELDTYPE_MFNode: {
3455 JSObject *newMFObject;
3456 jsval newjsval;
3457 double *ip, *ip_in=(double *)Data;
3458 /* create a new MFNode object... */
3459 newMFObject = JS_ConstructObjectFw(cx, &MFNodeClass, NULL ,JS_GetParentFw(cx, obj));
3460 ADD_ROOT (cx, newMFObject)
3461
3462 /* define the "length" property for this object */
3463 DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3464
3465 /* fill in private pointer area */
3466 elementlen = (int) sizeof (void *);
3467 for (x=0; x<datalen; x++) {
3468 ip = ip_in;
3469 newjsval = INT_TO_JSVAL((int)ip); /* NOTE--assigning pointer itself as int, not its content */
3470 ip_in = offsetPointer_deref(double *,ip_in,elementlen);
3471
3472 /* put this object into the MF class */
3473 if (!JS_DefineElement(cx, newMFObject, (jsint) x, newjsval,
3474 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3475 printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3476 }
3477 }
3478
3479 /* set the length of this MF */
3480 SET_LENGTH (cx,newMFObject,datalen)
3481
3482 /* set the global variable with this new MF object */
3483 SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3484
3485 /* run the function */
3486 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
3487 RUN_FUNCTION(toname)
3488 break;
3489 }
3490
3491 case FIELDTYPE_SFImage: {
3492 JSObject *newMFObject;
3493 jsval newjsval;
3494 int *ip_in=(int *)Data;
3495
3496 /* create a new MFNode object... */
3497 newMFObject = JS_ConstructObjectFw(cx, &SFImageClass, NULL ,JS_GetParentFw(cx, obj));
3498 ADD_ROOT (cx, newMFObject)
3499
3500 /* define the "length" property for this object */
3501 DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3502
3503 /* fill in private pointer area */
3504 for (x=0; x<datalen; x++) {
3505 newjsval = INT_TO_JSVAL(ip_in[x]);
3506 /* put this object into the MF class */
3507 if (!JS_DefineElement(cx, newMFObject, (jsint) x, newjsval,
3508 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3509 printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3510 }
3511 }
3512
3513 /* set the length of this MF */
3514 SET_LENGTH (cx,newMFObject,datalen)
3515
3516 /* set the global variable with this new MF object */
3517 SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3518
3519 /* run the function */
3520 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
3521 RUN_FUNCTION(toname)
3522
3523 break;
3524 }
3525
3526 default: {
3527 printf ("setMFElement, SHOULD NOT DISPLAY THIS\n");
3528 strcat (scriptline,"(");
3529 }
3530 }
3531#if defined(JS_THREADSAFE)
3532 JS_EndRequest(cx);
3533#endif
3534}
3535
3536/****************************************************************/
3537/* sets a SFVec3f and SFColor and SFVec3d */
3538/* and SFRotation and SFVec2fin a script */
3539/* */
3540/* all *Native types have the same structure of the struct - */
3541/* we are just looking for the pointer, thus we can handle */
3542/* multi types here */
3543/* sets a SFVec3f and SFColor in a script */
3544/****************************************************************/
3545
3546/* get a pointer to the internal data for this object, or return NULL on error */
3547void **getInternalDataPointerForJavascriptObject(JSContext *cx, JSObject *obj, int tnfield, int *iflag) {
3548 char scriptline[256];
3549 void *_privPtr;
3550 JSObject *sfObj;
3551 jsval retval;
3552 struct CRjsnameStruct *JSparamnames = getJSparamnames();
3553
3554 /* NOTE -- this is only called once, and the caller has already defined a JS_BeginRequest() */
3555
3556
3557 /* get the variable name to hold the incoming value */
3558 //sprintf (scriptline,"__eventIn_Value_%s", JSparamnames[tnfield].name);
3559 scriptline[0] = 0;
3560 if(JSparamnames[tnfield].kind == PKW_inputOnly)
3561 strcat(scriptline,"__eventIn_Value_");
3562 strcat(scriptline,JSparamnames[tnfield].name);
3563 #ifdef SETFIELDVERBOSE
3564 printf ("getInternalDataPointerForJavascriptObject: line %s\n",scriptline);
3565 #endif
3566
3567 if (!JS_GetProperty(cx,obj,scriptline,&retval)){
3568 //if you forgot to put both an inputOnly or inputOutput field AND
3569 // you forgot to define a function() with the same name
3570 // then you won't have any objects
3571 // if you didn't have a field then ROUTE would complain, unless directAccess
3572 printf ("JS_GetProperty failed in set_one_MultiElementType.\n");
3573 //return NULL;
3574 }
3575 *iflag = 1;
3576 if (!JSVAL_IS_OBJECT(retval)){
3577 // you don't have an inputOnly static object with this name (but might have a field static object,
3578 //return NULL;
3579 //could be inputOutput which has a norma field name
3580 *iflag = 0;
3581 if (!JS_GetProperty(cx,obj,JSparamnames[tnfield].name,&retval)){
3582 //you may have an inputOutput field, with the plane name
3583 printf ("no field for eventIn function: %s\n",JSparamnames[tnfield].name);
3584 return NULL;
3585 }
3586 if (!JSVAL_IS_OBJECT(retval)){
3587 printf ("no field for eventIn function: %s\n",JSparamnames[tnfield].name);
3588 return NULL;
3589 }
3590 *iflag = 2;
3591 }
3592
3593 sfObj = JSVAL_TO_OBJECT(retval);
3594
3595 if ((_privPtr = JS_GetPrivateFw(cx, sfObj)) == NULL)
3596 printf("JS_GetPrivate failed set_one_MultiElementType.\n");
3597
3598 if (_privPtr == NULL) return NULL;
3599
3600 /* what kind of class of object is this? */
3601
3602 /* we look at EVERY kind of native class found in "jsNative.h" even
3603 if it may not be ever used here */
3604
3605 if (JS_InstanceOf(cx, sfObj, &SFVec3fClass, NULL)) {
3606 SFVec3fNative *me = (SFVec3fNative *)_privPtr;
3607 return (void **) &me->v;
3608
3609 } else if (JS_InstanceOf(cx, sfObj, &SFVec3dClass, NULL)) {
3610 SFVec3dNative *me = (SFVec3dNative *)_privPtr;
3611 return (void **) &me->v;
3612
3613 } else if (JS_InstanceOf(cx, sfObj, &SFRotationClass, NULL)) {
3614 SFRotationNative *me = (SFRotationNative *)_privPtr;
3615 return (void **) &me->v;
3616
3617 } else if (JS_InstanceOf(cx, sfObj, &SFVec2fClass, NULL)) {
3618 SFVec2fNative *me = (SFVec2fNative *)_privPtr;
3619 return (void **) &me->v;
3620
3621 } else if (JS_InstanceOf(cx, sfObj, &SFColorClass, NULL)) {
3622 SFColorNative *me = (SFColorNative *)_privPtr;
3623 return (void **) &me->v;
3624
3625 } else if (JS_InstanceOf(cx, sfObj, &SFColorRGBAClass, NULL)) {
3626 SFColorRGBANative *me = (SFColorRGBANative *)_privPtr;
3627 return (void **) &me->v;
3628
3629 } else if (JS_InstanceOf(cx, sfObj, &SFVec4fClass, NULL)) {
3630 SFVec4fNative *me = (SFVec4fNative *)_privPtr;
3631 return (void **) &me->v;
3632
3633 } else if (JS_InstanceOf(cx, sfObj, &SFVec4dClass, NULL)) {
3634 SFVec4dNative *me = (SFVec4dNative *)_privPtr;
3635 return (void **) &me->v;
3636
3637 } else if (JS_InstanceOf(cx, sfObj, &SFNodeClass, NULL)) {
3638 SFNodeNative *me = (SFNodeNative *)_privPtr;
3639 return (void **) &me->handle;;
3640 //JAS return (void **) &me->v;
3641
3642 } else if (JS_InstanceOf(cx, sfObj, &SFImageClass, NULL)) {
3643 //SFImageNative *me = (SFImageNative *)_privPtr;
3644 //JAS return (void **) &me->v;
3645
3646 }
3647
3648 ConsoleMessage ("getInternalDataPointerForJavascriptObject malfunction");
3649
3650 return NULL;
3651}
3652
3653
3654
3655/* really do the individual set; used by script routing and EAI sending to a script
3656 Dec 2017 - You may have a inpoutOutput field you want to route values to
3657 and not have any inputOnly function() associated with the field
3658 for this scenario you want to check first if there's a function,
3659 and if so do some extra work. If not so be it.
3660 set_one_multielementtype is for SFVecxx, SFColorxxxx, SFNode, SFRotation
3661*/
3662void sm_set_one_MultiElementType (int tonode, int tnfield, void *Data, int dataLen ) {
3663 char scriptline[256];
3664 JSContext *cx;
3665 JSObject *obj;
3666 void **pp;
3667 int iflag, kind, toname;
3668 struct CRscriptStruct *ScriptControl; // = getScriptControl();
3669 struct CRjsnameStruct *JSparamnames = getJSparamnames();
3670
3671 /* get context and global object for this script */
3672 ScriptControl = getScriptControlIndex(tonode);
3673 cx = (JSContext*)ScriptControl->cx;
3674 obj = (JSObject*)ScriptControl->glob;
3675
3676#if defined(JS_THREADSAFE)
3677 JS_BeginRequest(cx);
3678#endif
3679 toname = tnfield;
3680 kind = JSparamnames[toname].kind; // PKW_inputOnly;
3681 if(SM_method() == 2){
3682 int type, iifield, *valueChanged, ifound, datatype;
3683 union anyVrml *value;
3684 char *fieldname;
3685 struct Shader_Script *script = ScriptControl->script;
3686
3687 fieldname = JSparamnames[toname].name;
3688 datatype = JSparamnames[toname].type;
3689
3690 //step 1 update the fieldvalue
3691 ifound = getFieldFromScript(script,fieldname,&type,&kind,&iifield,&value,&valueChanged);
3692 if(ifound && type == datatype && isSFType(type)){
3693 //we have an SF field, and sf coming in, we'll call our field LHS and incoming RHS
3694 shallow_copy_field(type,Data,value);
3695 (*valueChanged) = 1;
3696 }else{
3697 ConsoleMessage("sm_set_one_MultiElementType did not find field %s type %d\n",fieldname, datatype);
3698 return;
3699 }
3700 //step 2 run the eventIn if it exists
3701 SET_JS_TICKTIME
3702 //compile also pushes the field val onto call stack
3703 COMPILE_FUNCTION_IF_NEEDED_SET(toname,kind)
3704 RUN_FUNCTION(toname)
3705 return;
3706 }
3707
3708
3709 /* copy over the data from the VRML side into the script variable. */
3710 iflag = 0;
3711 pp = getInternalDataPointerForJavascriptObject(cx,obj,tnfield,&iflag);
3712 if(pp == NULL){
3713 //no script function with this name - you might be routing to an inputOutput field
3714 printf("function not found\n");
3715 return;
3716 }
3717 memcpy (pp,Data, dataLen);
3718 /* printf ("set_one_MultiElementType, dataLen %d, sizeof(double) %d\n",dataLen, sizeof(double));
3719 printf ("and, sending the data to pointer %p\n",pp); */
3720
3721 //if we added a __eventIn_Value_<fieldname> for inputOnly field
3722 /* set the time for this script */
3723 SET_JS_TICKTIME
3724 /* is the function compiled yet? */
3725 COMPILE_FUNCTION_IF_NEEDED_SET(tnfield,kind)
3726
3727 /* and run the function */
3728 #ifdef SETFIELDVERBOSE
3729 printf ("set_one_MultiElementType: running script %s\n",scriptline);
3730 #endif
3731
3732 RUN_FUNCTION (tnfield)
3733
3734#if defined(JS_THREADSAFE)
3735 JS_EndRequest(cx);
3736#endif
3737}
3738
3739int sm_runQueuedDirectOutputs(){
3740 //stub for SM and STUBS (DUK has it)
3741 static int doneOnce = 0;
3742 if(!doneOnce){
3743 // printf("in runQueuedDirectOutputs\n");
3744 printf("javascript engine spidermonkey version %ld %s\n", (long)JS_VERSION, SM_method() == 2? "SM2" : "SM1");
3745 doneOnce++;
3746 }
3747
3748 return FALSE;
3749}
3750
3751
3752#endif /* !(defined(JAVASCRIPT_STUB) || defined(JAVASCRIPT_DUK) */
3753#endif
Definition Viewer.h:139