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