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