FreeWRL / FreeX3D 4.3.0
jsUtils.c
1/*
2
3
4A substantial amount of code has been adapted from js/src/js.c,
5which is the sample application included with the javascript engine.
6
7*/
8
9/****************************************************************************
10 This file is part of the FreeWRL/FreeX3D Distribution.
11
12 Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
13
14 FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
15 it under the terms of the GNU Lesser Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 FreeWRL/FreeX3D is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
26****************************************************************************/
27
28
29#include <config.h>
30#if !defined(JS_SMCPP)
31#include <system.h>
32//#if !(defined(JAVASCRIPT_STUB) || defined(JAVASCRIPT_DUK))
33#ifdef JAVASCRIPT_SM
34#include <display.h>
35#include <internal.h>
36
37#include <libFreeWRL.h>
38
39#include "../vrml_parser/Structs.h"
40#include "../main/headers.h"
41#include "../vrml_parser/CParseGeneral.h"
42#include "../main/Snapshot.h"
43#include "../scenegraph/Collision.h"
44#include "../scenegraph/quaternion.h"
45#include "../scenegraph/Viewer.h"
46#include "../input/EAIHelpers.h"
47#include "../input/SensInterps.h"
48#include "../x3d_parser/Bindable.h"
49
50#include "JScript.h"
51#include "CScripts.h"
52#include "jsUtils.h"
53#include "jsNative.h"
54#include "jsVRMLClasses.h"
55#include "fieldSet.h"
56#ifdef _MSC_VER
57#include <pthread.h> // win32 needs the strtok_r
58#endif
59
60
61#ifdef WANT_OSC
62 #include "../scenegraph/ringbuf.h"
63 #define USE_OSC 1
64 #define TRACK_FIFO_MSG 0
65#else
66 #define USE_OSC 0
67 #define TRACK_FIFO_MSG 0
68#endif
69
70extern void dump_scene (FILE *fp, int level, struct X3D_Node* node); // in GeneratedCode.c
71extern char *parser_getNameFromNode(struct X3D_Node *ptr) ; /* vi +/dump_scene src/lib/scenegraph/GeneratedCode.c */
72
73/********************** Javascript to X3D Scenegraph ****************************/
74
75
76/* a SF value has changed in an MF; eg, xx[10] = new SFVec3f(...); */
77/* These values were created below; new SF values to this MF are not accessed here, but in
78 the MFVec3fSetProperty (or equivalent). Note that we do NOT use something like JS_SetElement
79 on these because it would be a recursive call; thus we set the private data */
80
81
82//static int insetSFStr = FALSE;
83//static JSBool reportWarnings = JS_TRUE;
84typedef struct pjsUtils{
85 int insetSFStr;// = FALSE;
86 JSBool reportWarnings;// = JS_TRUE;
87
88}* ppjsUtils;
89void *jsUtils_constructor(){
90 void *v = MALLOCV(sizeof(struct pjsUtils));
91 memset(v,0,sizeof(struct pjsUtils));
92 return v;
93}
94void jsUtils_init(struct tjsUtils *t){
95 //public
96 //private
97 t->prv = jsUtils_constructor();
98 {
99 ppjsUtils p = (ppjsUtils)t->prv;
100 p->insetSFStr = FALSE;
101 p->reportWarnings = JS_TRUE;
102 }
103}
104
105int JS_SetPrivateFw(JSContext *cx, JSObject* obj, void *data){
106 int iret = TRUE;
107#if JS_VERSION >= 186
108 JS_SetPrivate(obj, data);
109#else
110 iret = JS_SetPrivate(cx,obj,data);
111#endif
112 return iret;
113}
114JSObject* JS_NewGlobalObjectFw(JSContext *cx, JSClass *clasp){
115#if JS_VERSION >= 186
116 return JS_NewGlobalObject(cx, clasp, NULL);
117#else
118 return JS_NewGlobalObject(cx,clasp);
119#endif
120}
121void * JS_GetPrivateFw(JSContext *cx,JSObject* obj){
122#if JS_VERSION >= 186
123 return JS_GetPrivate(obj);
124#else
125 return JS_GetPrivate(cx,obj);
126#endif
127}
128JSObject* JS_GetParentFw(JSContext *cx, JSObject *obj){
129#if JS_VERSION >= 186
130 return JS_GetParent(obj);
131#else
132 return JS_GetParent(cx,obj);
133#endif
134}
135
136#if JS_VERSION > 185
137//https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_NewNumberValue
138JSBool JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval){
139 *rval = JS_NumberValue(d);
140 return JS_TRUE;
141}
142
143#endif
144
145JSObject *
146JS_ConstructObjectWithArgumentsFw(JSContext *cx, JSClass *clasp,
147 JSObject *parent, unsigned argc, jsval *argv)
148{
149 JSObject *global = JS_GetGlobalForScopeChain(cx);
150 jsval v;
151 if (!global || !JS_GetProperty(cx, global, clasp->name, &v))
152 return NULL;
153 if (JSVAL_IS_PRIMITIVE(v)) {
154 JS_ReportError(cx, "cannot construct object: constructor is gone");
155 return NULL;
156 }
157 return JS_New(cx, JSVAL_TO_OBJECT(v), argc, argv);
158}
159
160JSObject *
161JS_ConstructObjectFw(JSContext *cx, JSClass *clasp, void *whatever, JSObject *parent)
162{
163 return JS_ConstructObjectWithArgumentsFw(cx, clasp, parent, 0, NULL);
164}
165JSClass* JS_GetClassFw(JSContext *cx, JSObject *obj){
166 return JS_GetClass(cx,obj);
167}
168JSObject * JS_GetPrototypeFw(JSContext *cx, JSObject * obj){
169#if JS_VERSION >= 186
170 return JS_GetPrototype(obj);
171#else
172 return JS_GetPrototype(cx,obj);
173#endif
174}
175
176
177// ppjsUtils p = (ppjsUtils)gglobal()->jsUtils.prv;
178#if JS_VERSION < 185
179static JSBool setSF_in_MF (JSContext *cx, JSObject *obj, jsval id, jsval *vp) {
180#elif JS_VERSION == 185
181static JSBool setSF_in_MF (JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp) {
182#else
183static JSBool setSF_in_MF (JSContext *cx, JSHandleObject hobj, JSHandleId hiid, JSBool strict, JSMutableHandleValue hvp){
184 JSObject *obj = *hobj._;
185 jsid iid = *hiid._;
186 jsval *vp = hvp._;
187#endif
188 int num;
189 jsval pf;
190 jsval nf;
191 JSObject *me;
192 JSObject *par;
193 jsval ele;
194 ppjsUtils p = (ppjsUtils)gglobal()->jsUtils.prv;
195 jsid oid;
196#if JS_VERSION >= 185
197 char *tmp;
198 jsval id;
199
200 UNUSED(tmp); // compiler warning mitigation
201
202 if (!JS_IdToValue(cx,iid,&id)) {
203 printf("setSF_in_MF: JS_IdToValue failed.\n");
204 return JS_FALSE;
205 }
206#endif
207
208 /* when we save the value, we will be called again, so we make sure that we
209 know if we are being called from within, or from without */
210 if (p->insetSFStr) {
211 #ifdef JSVRMLCLASSESVERBOSE
212 printf ("setSF_in_MF: already caught this value; this is our JS_SetElement call\n");
213 #endif
214 return JS_TRUE;
215 }
216
217 /* ok, we are really called to replace an existing SFNode MF value assignment */
218 p->insetSFStr = TRUE;
219
220 if (JSVAL_IS_INT(id)) {
221 if (!JS_ValueToInt32(cx,id,&num)) {
222 printf ("setSF_in_MF: error converting to number...\n");
223 return JS_FALSE;
224 }
225 /* get a pointer to the object at the index in the parent */
226 if (!JS_GetElement(cx, obj, num, &ele)) {
227 printf ("error getting child %d in setSF_in_MF\n",num);
228 return JS_FALSE;
229 }
230 /* THIS is the touching that will cause us to be called recursively,
231 which is why insetSFStr is TRUE right here */
232 if (!JS_SetElement(cx,obj,num,vp)) {
233 printf ("can not set element %d in MFString\n",num);
234 return JS_FALSE;
235 }
236 } else {
237 printf ("expect an integer id in setSF_in_MF\n");
238 return JS_FALSE;
239 }
240
241
242 /* copy this value out to the X3D scene graph */
243 me = obj;
244 par = JS_GetParentFw(cx, me);
245 while (par != NULL) {
246 #ifdef JSVRMLCLASSESVERBOSE
247 printf ("for obj %u: ",me);
248 printJSNodeType(cx,me);
249 printf ("... parent %u\n",par);
250 printJSNodeType(cx,par);
251 #endif
252
253 if (JS_InstanceOf (cx, par, &SFNodeClass, NULL)) {
254 #ifdef JSVRMLCLASSESVERBOSE
255 printf (" the parent IS AN SFNODE - it is %u\n",par);
256 #endif
257
258
259 if (!JS_GetProperty(cx, obj, "_parentField", &pf)) {
260 printf ("doMFSetProperty, can not get parent field from this object\n");
261 return JS_FALSE;
262 }
263
264 nf = OBJECT_TO_JSVAL(me);
265
266 #ifdef JSVRMLCLASSESVERBOSE
267 #if JS_VERSION < 185
268 printf ("parentField is %u \"%s\"\n", pf, JS_GetStringBytes(JSVAL_TO_STRING(pf)));
269 #else
270 tmp=JS_EncodeString(cx,JSVAL_TO_STRING(pf));
271 printf ("parentField is %u \"%s\"\n", pf, tmp);
272 JS_free(cx,tmp);
273 #endif
274 #endif
275
276 if (!JS_ValueToId(cx,pf,&oid)) {
277 printf("setSF_in_MF: JS_ValueToId failed.\n");
278 return JS_FALSE;
279 }
280 #if JS_VERSION == 186
281 {
282 JSHandleObject hobj;
283 JSHandleId hiid;
284 JSMutableHandleValue hvp;
285 hobj._ = &par;
286 hiid._ = &oid;
287 hvp._ = &nf;
288 setSFNodeField(cx,hobj,hiid,JS_FALSE,hvp);
289 }
290 #else
291 if (!setSFNodeField (cx, par, oid,
292#if JS_VERSION >= 185
293 JS_FALSE,
294#endif
295 &nf)) {
296 printf ("could not set field of SFNode\n");
297 }
298 #endif
299 }
300 me = par;
301 par = JS_GetParentFw(cx, me);
302 }
303 p->insetSFStr = FALSE;
304 return JS_TRUE;
305}
306
307/* take an ECMA value in the X3D Scenegraph, and return a jsval with it in */
308/* This is FAST as w deal just with pointers */
309void JS_ECMA_TO_X3D(JSContext *cx, void *Data, unsigned datalen, int dataType, jsval *newval) {
310 float fl;
311 double dl;
312 int il;
313
314 #ifdef JSVRMLCLASSESVERBOSE
315 printf ("calling JS_ECMA_TO_X3D on type %s\n",FIELDTYPES[dataType]);
316 #endif
317
318 switch (dataType) {
319
320 case FIELDTYPE_SFFloat: {
321 if (!JS_ValueToNumber(cx,*newval,&dl)) {
322 printf ("problems converting Javascript val to number\n");
323 return;
324 }
325 fl = (float) dl;
326 memcpy (Data, (void *) &fl, datalen);
327 break;
328 }
329 case FIELDTYPE_SFDouble:
330 case FIELDTYPE_SFTime: {
331 if (!JS_ValueToNumber(cx,*newval,&dl)) {
332 printf ("problems converting Javascript val to number\n");
333 return;
334 }
335 memcpy (Data, (void *) &dl, datalen);
336 break;
337 }
338 case FIELDTYPE_SFBool: {
339 il = JSVAL_TO_BOOLEAN (*newval);
340 memcpy (Data, (void *) &il, datalen);
341 break;
342 }
343
344 case FIELDTYPE_SFInt32: {
345 il = JSVAL_TO_INT (*newval);
346 memcpy (Data, (void *) &il, datalen);
347 break;
348 }
349
350 case FIELDTYPE_SFString: {
351 struct Uni_String *oldS;
352 JSString *_idStr;
353 char *_id_c;
354
355 _idStr = JS_ValueToString(cx, *newval);
356#if JS_VERSION < 185
357 _id_c = JS_GetStringBytes(_idStr);
358#else
359 _id_c = JS_EncodeString(cx,_idStr);
360#endif
361
362 oldS = (struct Uni_String *) *((intptr_t *)Data);
363 if(oldS == NULL) {
364 *(struct Uni_String **)Data = newASCIIString(_id_c);
365 }else{
366 #ifdef JSVRMLCLASSESVERBOSE
367 printf ("JS_ECMA_TO_X3D, replacing \"%s\" with \"%s\" \n", oldS->strptr, _id_c);
368 #endif
369
370 /* replace the C string if it needs to be replaced. */
371 verify_Uni_String (oldS,_id_c);
372 }
373#if JS_VERSION >= 185
374 JS_free(cx,_id_c);
375#endif
376 break;
377 }
378 default: { printf("WARNING: SHOULD NOT BE HERE in JS_ECMA_TO_X3D! %d\n",dataType); }
379 }
380}
381
382
383/* take a Javascript ECMA value and put it in the X3D Scenegraph. */
384void JS_SF_TO_X3D(JSContext *cx, void *Data, unsigned datalen, int dataType, jsval *newval) {
385 SFColorNative *Cptr;
386 SFVec3fNative *V3ptr;
387 SFVec3dNative *V3dptr;
388 SFVec2fNative *V2ptr;
389 SFRotationNative *VRptr;
390 SFNodeNative *VNptr;
391
392 void *VPtr;
393
394 #ifdef JSVRMLCLASSESVERBOSE
395 printf ("calling JS_SF_TO_X3D on type %s\n",FIELDTYPES[dataType]);
396 #endif
397
398 /* get a pointer to the internal private data */
399 if ((VPtr = JS_GetPrivateFw(cx, JSVAL_TO_OBJECT(*newval))) == NULL) {
400 printf( "JS_GetPrivate failed in JS_SF_TO_X3D.\n");
401 return;
402 }
403
404 /* copy over the data from the X3D node to this new Javascript object */
405 switch (dataType) {
406 case FIELDTYPE_SFColor:
407 Cptr = (SFColorNative *)VPtr;
408 memcpy (Data, (void *)((Cptr->v).c), datalen);
409 break;
410 case FIELDTYPE_SFVec3d:
411 V3dptr = (SFVec3dNative *)VPtr;
412 memcpy (Data, (void *)((V3dptr->v).c), datalen);
413 break;
414 case FIELDTYPE_SFVec3f:
415 V3ptr = (SFVec3fNative *)VPtr;
416 memcpy (Data, (void *)((V3ptr->v).c), datalen);
417 break;
418 case FIELDTYPE_SFVec2f:
419 V2ptr = (SFVec2fNative *)VPtr;
420 memcpy (Data, (void *)((V2ptr->v).c), datalen);
421 break;
422 case FIELDTYPE_SFRotation:
423 VRptr = (SFRotationNative *)VPtr;
424 memcpy (Data,(void *)((VRptr->v).c), datalen);
425 break;
426 case FIELDTYPE_SFNode:
427 VNptr = (SFNodeNative *)VPtr;
428 memcpy (Data, (void *)(VNptr->handle), datalen);
429 break;
430
431 default: { printf("WARNING: SHOULD NOT BE HERE! %d\n",dataType); }
432 }
433}
434
435void JS_SF_TO_X3D_B(JSContext *cx, void *Data, int dataType, int *valueChanged, jsval *newval) {
436 AnyNative *ptr;
437 union anyVrml *anyv;
438
439 /* get a pointer to the internal private data */
440 if ((ptr = JS_GetPrivateFw(cx, JSVAL_TO_OBJECT(*newval))) == NULL) {
441 printf( "JS_GetPrivate failed in JS_SF_TO_X3D_B.\n");
442 return;
443 }
444 if(ptr->type != dataType){
445 printf("JS assigning type %d to %d failed\n",ptr->type,dataType);
446 return;
447 }
448 shallow_copy_field(dataType,ptr->v,Data);
449}
450void JS_SF_TO_X3D_BNode(JSContext *cx, void *Data, int dataType, int *valueChanged, jsval *newval) {
451 AnyNative *ptr;
452 union anyVrml *anyv;
453 if(JSVAL_IS_NULL(*newval)){
454 union anyVrml any;
455 any.sfnode = NULL;
456 shallow_copy_field(dataType,&any,Data);
457 }else{
458 JS_SF_TO_X3D_B(cx, Data, dataType, valueChanged, newval);
459 }
460
461 /* get a pointer to the internal private data */
462}
463
464void getJSMultiNumType(JSContext *, struct Multi_Vec3f *, int);
465
466/* make an MF type from the X3D node. This can be fairly slow... */
467void JS_MF_TO_X3D(JSContext *cx, JSObject * obj, void *Data, int dataType, jsval *newval) {
468 ttglobal tg = gglobal();
469 #ifdef JSVRMLCLASSESVERBOSE
470 printf ("calling JS_MF_TO_X3D on type %s\n",FIELDTYPES[dataType]);
471 printf ("JS_MF_TO_X3D, we have object %u, newval %u\n",obj,*newval);
472 printf ("JS_MF_TO_X3D, obj is an:\n");
473 if (JSVAL_IS_OBJECT(OBJECT_TO_JSVAL(obj))) { printf ("JS_MF_TO_X3D - obj is an OBJECT\n"); }
474 if (JSVAL_IS_PRIMITIVE(OBJECT_TO_JSVAL(obj))) { printf ("JS_MF_TO_X3D - obj is an PRIMITIVE\n"); }
475 printf ("JS_MF_TO_X3D, obj is a "); printJSNodeType(cx,obj);
476 printf ("JS_MF_TO_X3D, vp is an:\n");
477 if (JSVAL_IS_OBJECT(*newval)) { printf ("JS_MF_TO_X3D - vp is an OBJECT\n"); }
478 if (JSVAL_IS_PRIMITIVE(*newval)) { printf ("JS_MF_TO_X3D - vp is an PRIMITIVE\n"); }
479 printf ("JS_MF_TO_X3D, vp is a "); printJSNodeType(cx,JSVAL_TO_OBJECT(*newval));
480 #endif
481
482 *(jsval *)tg->JScript.JSglobal_return_val = *newval;
483 getJSMultiNumType (cx, (struct Multi_Vec3f*) Data, convertToSFType(dataType));
484
485}
486
487/********************** X3D Scenegraph to Javascript ****************************/
488
489/* take an ECMA value in the X3D Scenegraph, and return a jsval with it in */
490/* This is FAST as w deal just with pointers */
491void X3D_ECMA_TO_JS(JSContext *cx, void *Data, int datalen, int dataType, jsval *newval) {
492 float fl;
493 double dl;
494 int il;
495
496 /* NOTE - caller of this function has already defined a BeginRequest */
497
498 #ifdef JSVRMLCLASSESVERBOSE
499 printf ("calling X3D_ECMA_TO_JS on type %s\n",FIELDTYPES[dataType]);
500 #endif
501
502 switch (dataType) {
503
504 case FIELDTYPE_SFFloat: {
505 memcpy ((void *) &fl, Data, datalen);
506 JS_NewNumberValue(cx,(double)fl,newval);
507 break;
508 }
509 case FIELDTYPE_SFDouble:
510 case FIELDTYPE_SFTime: {
511 memcpy ((void *) &dl, Data, datalen);
512 JS_NewNumberValue(cx,dl,newval);
513 break;
514 }
515 case FIELDTYPE_SFBool:
516 case FIELDTYPE_SFInt32: {
517 memcpy ((void *) &il,Data, datalen);
518 *newval = INT_TO_JSVAL(il);
519 break;
520 }
521
522 case FIELDTYPE_SFString: {
523 struct Uni_String *ms;
524
525 /* datalen will be ROUTING_SFSTRING here; or at least should be! We
526 copy over the data, which is a UniString pointer, and use the pointer
527 value here */
528 memcpy((void *) &ms,Data, sizeof(void *));
529 *newval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,ms->strptr));
530 break;
531 }
532 default: { printf("WARNING: SHOULD NOT BE HERE in X3D_ECMA_TO_JS! %d\n",dataType); }
533 }
534}
535
536/* take an ECMA value in the X3D Scenegraph, and return a jsval with it in */
537/* this is not so fast; we call a script to make a default type, then we fill it in */
538void X3D_SF_TO_JS(JSContext *cx, JSObject *obj, void *Data, unsigned datalen, int dataType, jsval *newval) {
539 SFColorNative *Cptr;
540 SFVec3fNative *V3ptr;
541 SFVec3dNative *V3dptr;
542 SFVec2fNative *V2ptr;
543 SFRotationNative *VRptr;
544 SFNodeNative *VNptr;
545
546 void *VPtr;
547 jsval rval;
548 char *script = NULL;
549
550 /* NOTE - caller is (eventually) a class constructor, no need to BeginRequest */
551
552 #ifdef JSVRMLCLASSESVERBOSE
553 printf ("calling X3D_SF_TO_JS on type %s, newval %u\n",FIELDTYPES[dataType],*newval);
554 #endif
555
556 if (!JSVAL_IS_OBJECT(*newval)) {
557 /* find a script to create the correct object */
558 switch (dataType) {
559 case FIELDTYPE_SFVec3f: script = "new SFVec3f()"; break;
560 case FIELDTYPE_SFVec3d: script = "new SFVec3d()"; break;
561 case FIELDTYPE_SFColor: script = "new SFColor()"; break;
562 case FIELDTYPE_SFNode: script = "new SFNode()"; break;
563 case FIELDTYPE_SFVec2f: script = "new SFVec2f()"; break;
564 case FIELDTYPE_SFRotation: script = "new SFRotation()"; break;
565 default: printf ("invalid type in X3D_SF_TO_JS\n"); return;
566 }
567
568 /* create the object */
569
570
571 #ifdef JSVRMLCLASSESVERBOSE
572 printf ("X3D_SF_TO_JS, have to run script to make new object: \"%s\"\n",script);
573 #endif
574
575 if (!JS_EvaluateScript(cx, obj, script, (int) strlen(script), FNAME_STUB, LINENO_STUB, &rval)) {
576 printf ("error creating the new object in X3D_SF_TO_JS, script :%s:\n",script);
577 return;
578 }
579
580 /* this is the return pointer, lets save it right now */
581 *newval = rval;
582
583 #ifdef JSVRMLCLASSESVERBOSE
584 printf ("X3D_SF_TO_JS, so, newval now is %u\n",*newval);
585 #endif
586
587 }
588 /* get a pointer to the internal private data */
589 if ((VPtr = JS_GetPrivateFw(cx, JSVAL_TO_OBJECT(*newval))) == NULL) {
590 printf( "JS_GetPrivate failed in X3D_SF_TO_JS.\n");
591 return;
592 }
593
594
595 /* copy over the data from the X3D node to this new Javascript object */
596 switch (dataType) {
597 case FIELDTYPE_SFColor:
598 Cptr = (SFColorNative *)VPtr;
599 memcpy ((void *)((Cptr->v).c), Data, datalen);
600 Cptr->valueChanged = 1;
601 break;
602 case FIELDTYPE_SFVec3f:
603 V3ptr = (SFVec3fNative *)VPtr;
604 memcpy ((void *)((V3ptr->v).c), Data, datalen);
605 V3ptr->valueChanged = 1;
606 break;
607 case FIELDTYPE_SFVec3d:
608 V3dptr = (SFVec3dNative *)VPtr;
609 memcpy ((void *)((V3dptr->v).c), Data, datalen);
610 V3dptr->valueChanged = 1;
611 break;
612 case FIELDTYPE_SFVec2f:
613 V2ptr = (SFVec2fNative *)VPtr;
614 memcpy ((void *)((V2ptr->v).c), Data, datalen);
615 V2ptr->valueChanged = 1;
616 break;
617 case FIELDTYPE_SFRotation:
618 VRptr = (SFRotationNative *)VPtr;
619 memcpy ((void *)((VRptr->v).c), Data, datalen);
620 VRptr->valueChanged = 1;
621 break;
622 case FIELDTYPE_SFNode:
623 VNptr = (SFNodeNative *)VPtr;
624 memcpy ((void *)(&(VNptr->handle)), Data, datalen);
625 VNptr->valueChanged = 1;
626 break;
627
628 default: { printf("WARNING: SHOULD NOT BE HERE! %d\n",dataType); }
629 }
630}
631
632void X3D_SF_TO_JS_B(JSContext *cx, void *Data, unsigned datalen, int dataType, int *valueChanged, jsval *newval)
633{
634 //for SM_method() == 2
635 // this copies pointers rather than deep copying values
636 jsval rval;
637
638 /* NOTE - caller is (eventually) a class constructor, no need to BeginRequest */
639
640 #ifdef JSVRMLCLASSESVERBOSE
641 printf ("calling X3D_SF_TO_JS on type %s, newval %u\n",FIELDTYPES[dataType],*newval);
642 #endif
643
644 //if (!JSVAL_IS_OBJECT(*newval)) {
645 /* find a script to create the correct object */
646 JSObject *newobj;
647 AnyNative *ptr;
648 switch (dataType) {
649 case FIELDTYPE_SFVec3f:
650 newobj = JS_NewObject(cx,&SFVec3fClass,NULL,NULL); break;
651 case FIELDTYPE_SFVec3d:
652 newobj = JS_NewObject(cx,&SFVec3dClass,NULL,NULL); break;
653 case FIELDTYPE_SFColor:
654 newobj = JS_NewObject(cx,&SFColorClass,NULL,NULL); break;
655 case FIELDTYPE_SFNode:
656 newobj = JS_NewObject(cx,&SFNodeClass,NULL,NULL); break;
657 case FIELDTYPE_SFVec2f:
658 newobj = JS_NewObject(cx,&SFVec2fClass,NULL,NULL); break;
659 case FIELDTYPE_SFRotation:
660 newobj = JS_NewObject(cx,&SFRotationClass,NULL,NULL); break;
661 default: printf ("invalid type in X3D_SF_TO_JS\n"); return;
662 }
663
664 /* create the object */
665 //set private
666 if ((ptr = (AnyNative *) AnyNativeNew(dataType,Data,valueChanged)) == NULL) {
667 printf( "AnyNativeNew failed in X3D_MF_TO_SF_B.\n");
668 return;
669 }
670
671 if (!JS_SetPrivateFw(cx, newobj, ptr)) {
672 printf( "JS_SetPrivate failed in X3D_MF_TO_SF_B.\n");
673 return;
674 }
675
676 /* this is the return pointer, lets save it right now */
677 *newval = OBJECT_TO_JSVAL(newobj);
678 #ifdef JSVRMLCLASSESVERBOSE
679 printf ("X3D_SF_TO_JS_B, so, newval now is %u\n",*newval);
680 #endif
681
682 //}
683}
684void X3D_SF_TO_JS_BNode(JSContext *cx, void *Data, unsigned datalen, int dataType, int *valueChanged, jsval *newval)
685{
686 union anyVrml *any = (union anyVrml *)Data;
687 if(any->sfnode == NULL){
688 *newval = JSVAL_NULL;
689 }else{
690 X3D_SF_TO_JS_B(cx, Data, datalen, dataType, valueChanged, newval);
691 }
692
693}
694/* make an MF type from the X3D node. This can be fairly slow... */
695void X3D_MF_TO_JS(JSContext *cx, JSObject *obj, void *Data, int dataType, jsval *newval, char *fieldName) {
696 int i;
697 jsval rval;
698 char *script = NULL;
699 struct Multi_Int32 *MIptr;
700 struct Multi_Float *MFptr;
701 struct Multi_Time *MTptr;
702 jsval fieldNameAsJSVAL;
703
704 /* NOTE - caller is (eventually) a JS class constructor, no need to BeginRequest */
705
706 /* so, obj should be an __SFNode_proto, and newval should be a __MFString_proto (or whatever) */
707
708 #ifdef JSVRMLCLASSESVERBOSE
709 printf ("calling X3D_MF_TO_JS on type %s\n",FIELDTYPES[dataType]);
710 printf ("X3D_MF_TO_JS, we have object %u, newval %u\n",obj,*newval);
711 printf ("X3D_MF_TO_JS, obj is an:\n");
712 if (JSVAL_IS_OBJECT(OBJECT_TO_JSVAL(obj))) { printf ("X3D_MF_TO_JS - obj is an OBJECT\n");
713 printf ("X3D_MF_TO_JS, obj is a "); printJSNodeType(cx,obj);
714 }
715 if (JSVAL_IS_PRIMITIVE(OBJECT_TO_JSVAL(obj))) { printf ("X3D_MF_TO_JS - obj is an PRIMITIVE\n"); }
716 printf ("X3D_MF_TO_JS, vp is an:\n");
717 if (JSVAL_IS_OBJECT(*newval)) { printf ("X3D_MF_TO_JS - newval is an OBJECT\n");
718 printf ("X3D_MF_TO_JS, newval is a "); printJSNodeType(cx,JSVAL_TO_OBJECT(*newval));
719 }
720 if (JSVAL_IS_PRIMITIVE(*newval)) { printf ("X3D_MF_TO_JS - newval is an PRIMITIVE\n"); }
721 #endif
722
723
724#ifdef JSVRMLCLASSESVERBOSE
725 printf ("X3D_MF_TO_JS - is this already expanded? \n");
726 {
727 SFNodeNative *VNptr;
728
729 /* get a pointer to the internal private data */
730 if ((VNptr = JS_GetPrivate(cx, obj)) == NULL) {
731 printf( "JS_GetPrivate failed in X3D_MF_TO_JS.\n");
732 return;
733 }
734 if (VNptr->fieldsExpanded) printf ("FIELDS EXPANDED\n");
735 else printf ("FIELDS NOT EXPANDED\n");
736 }
737#endif
738
739
740 if (!JSVAL_IS_OBJECT(*newval)) {
741 #ifdef JSVRMLCLASSESVERBOSE
742 printf ("X3D_MF_TO_JS - have to create empty MF type \n");
743 #endif
744
745 /* find a script to create the correct object */
746 switch (dataType) {
747 case FIELDTYPE_MFString: script = "new MFString()"; break;
748 case FIELDTYPE_MFFloat: script = "new MFFloat()"; break;
749 case FIELDTYPE_MFTime: script = "new MFTime()"; break;
750 case FIELDTYPE_MFInt32: script = "new MFInt32()"; break;
751 case FIELDTYPE_SFImage: script = "new SFImage()"; break;
752 case FIELDTYPE_MFVec3f: script = "new MFVec3f()"; break;
753 case FIELDTYPE_MFColor: script = "new MFColor()"; break;
754 case FIELDTYPE_MFNode: script = "new MFNode()"; break;
755 case FIELDTYPE_MFVec2f: script = "new MFVec2f()"; break;
756 case FIELDTYPE_MFRotation: script = "new MFRotation()"; break;
757 default: printf ("invalid type in X3D_MF_TO_JS\n"); return;
758 }
759
760 if (!JS_EvaluateScript(cx, obj, script, (int) strlen(script), FNAME_STUB, LINENO_STUB, &rval)) {
761 printf ("error creating the new object in X3D_MF_TO_JS\n");
762 return;
763 }
764
765 /* this is the return pointer, lets save it right now */
766 *newval = rval;
767 }
768
769 #ifdef JSVRMLCLASSESVERBOSE
770 printf ("setting parent for %u to %u\n", *newval, obj);
771 #endif
772
773 /* ok - if we are setting an MF* field by a thing like myField[10] = new String(); the
774 set method does not really get called. So, we go up the parental chain until we get
775 either no parent, or a SFNode. If we get a SFNode, we call the "save this" function
776 so that the X3D scene graph gets the updated array value. To make a long story short,
777 here's the call to set the parent for the above. */
778 if (!JS_SetParent (cx, JSVAL_TO_OBJECT(*newval), obj)) {
779 printf ("X3D_MF_TO_JS - can not set parent!\n");
780 }
781
782 #ifdef JSVRMLCLASSESVERBOSE
783 printf ("telling %u that it is a child \"%s\" of parent %u\n",*newval, fieldName, obj);
784 #endif
785
786 fieldNameAsJSVAL = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,fieldName));
787
788 if (!JS_DefineProperty(cx, JSVAL_TO_OBJECT(*newval), "_parentField", fieldNameAsJSVAL,
789 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB5, JSPROP_READONLY)) {
790 printf("JS_DefineProperty failed for \"%s\" in X3D_MF_TO_JS.\n", fieldName);
791 return;
792 }
793
794
795 #ifdef JSVRMLCLASSESVERBOSE
796 printf ("X3D_MF_TO_JS - object is %u, copying over data\n",*newval);
797 #endif
798
799
800 /* copy over the data from the X3D node to this new Javascript object */
801 switch (dataType) {
802 case FIELDTYPE_MFInt32:
803 MIptr = (struct Multi_Int32*) Data;
804 for (i=0; i<MIptr->n; i++) {
805 if (!JS_DefineElement(cx, JSVAL_TO_OBJECT(*newval), (jsint) i, INT_TO_JSVAL(MIptr->p[i]),
806 JS_GET_PROPERTY_STUB, setSF_in_MF, JSPROP_ENUMERATE)) {
807 printf( "JS_DefineElement failed for arg %u in MFInt32Constr.\n", i);
808 return;
809 }
810 }
811 break;
812 case FIELDTYPE_MFFloat:
813 MFptr = (struct Multi_Float*) Data;
814 for (i=0; i<MFptr->n; i++) {
815 if (!JS_DefineElement(cx, JSVAL_TO_OBJECT(*newval), (jsint) i, INT_TO_JSVAL(MFptr->p[i]),
816 JS_GET_PROPERTY_STUB, setSF_in_MF, JSPROP_ENUMERATE)) {
817 printf( "JS_DefineElement failed for arg %u in MFFloatConstr.\n", i);
818 return;
819 }
820 }
821 break;
822 case FIELDTYPE_MFTime:
823 MTptr = (struct Multi_Time*) Data;
824 for (i=0; i<MTptr->n; i++) {
825 if (!JS_DefineElement(cx, JSVAL_TO_OBJECT(*newval), (jsint) i, INT_TO_JSVAL(MTptr->p[i]),
826 JS_GET_PROPERTY_STUB, setSF_in_MF, JSPROP_ENUMERATE)) {
827 printf( "JS_DefineElement failed for arg %u in MFTimeConstr.\n", i);
828 return;
829 }
830 }
831 break;
832 case FIELDTYPE_MFColor:
833 case FIELDTYPE_MFVec3f: {
834 struct Multi_Vec3f* MCptr;
835 char newline[100];
836 jsval xf;
837
838 MCptr = (struct Multi_Vec3f *) Data;
839 for (i=0; i<MCptr->n; i++) {
840 if (dataType == FIELDTYPE_MFColor)
841 sprintf (newline,"new SFColor(%f, %f, %f)", MCptr->p[i].c[0], MCptr->p[i].c[1], MCptr->p[i].c[2]);
842 else
843 sprintf (newline,"new SFColor(%f, %f, %f)", MCptr->p[i].c[0], MCptr->p[i].c[1], MCptr->p[i].c[2]);
844 if (!JS_EvaluateScript(cx, JSVAL_TO_OBJECT(*newval), newline, (int) strlen(newline), FNAME_STUB, LINENO_STUB, &xf)) {
845 printf ("error creating the new object in X3D_MF_TO_JS string :%s:\n",newline);
846 return;
847 }
848 if (!JS_DefineElement(cx, JSVAL_TO_OBJECT(*newval), (jsint) i, xf,
849 JS_GET_PROPERTY_STUB, setSF_in_MF, JSPROP_ENUMERATE)) {
850 printf( "JS_DefineElement failed for arg %u .\n", i);
851 return;
852 }
853 }
854 } break;
855
856 case FIELDTYPE_MFVec2f: {
857 struct Multi_Vec2f* MCptr;
858 char newline[100];
859 jsval xf;
860
861 MCptr = (struct Multi_Vec2f *) Data;
862 for (i=0; i<MCptr->n; i++) {
863 sprintf (newline,"new SFVec2f(%f, %f)", MCptr->p[i].c[0], MCptr->p[i].c[1]);
864 if (!JS_EvaluateScript(cx, JSVAL_TO_OBJECT(*newval), newline, (int) strlen(newline), FNAME_STUB, LINENO_STUB, &xf)) {
865 printf ("error creating the new object in X3D_MF_TO_JS string :%s:\n",newline);
866 return;
867 }
868 if (!JS_DefineElement(cx, JSVAL_TO_OBJECT(*newval), (jsint) i, xf,
869 JS_GET_PROPERTY_STUB, setSF_in_MF, JSPROP_ENUMERATE)) {
870 printf( "JS_DefineElement failed for arg %u .\n", i);
871 return;
872 }
873 }
874 } break;
875 case FIELDTYPE_MFRotation: {
876 struct Multi_Rotation* MCptr;
877 char newline[100];
878 jsval xf;
879
880 MCptr = (struct Multi_Rotation*) Data;
881 for (i=0; i<MCptr->n; i++) {
882 sprintf (newline,"new SFRotation(%f, %f, %f, %f)", MCptr->p[i].c[0], MCptr->p[i].c[1], MCptr->p[i].c[2], MCptr->p[i].c[3]);
883 if (!JS_EvaluateScript(cx, JSVAL_TO_OBJECT(*newval), newline, (int) strlen(newline), FNAME_STUB, LINENO_STUB, &xf)) {
884 printf ("error creating the new object in X3D_MF_TO_JS string :%s:\n",newline);
885 return;
886 }
887 if (!JS_DefineElement(cx, JSVAL_TO_OBJECT(*newval), (jsint) i, xf,
888 JS_GET_PROPERTY_STUB, setSF_in_MF, JSPROP_ENUMERATE)) {
889 printf( "JS_DefineElement failed for arg %u .\n", i);
890 return;
891 }
892 }
893 } break;
894
895 case FIELDTYPE_MFNode: {
896 struct Multi_Node* MCptr;
897 char newline[100];
898 jsval xf;
899
900 MCptr = (struct Multi_Node *) Data;
901
902 for (i=0; i<MCptr->n; i++) {
903 /* purge out null nodes */
904 if (MCptr->p[i] != NULL) {
905 sprintf (newline,"new SFNode(\"%p\")", MCptr->p[i]);
906
907 if (!JS_EvaluateScript(cx, JSVAL_TO_OBJECT(*newval), newline, (int) strlen(newline), FNAME_STUB, LINENO_STUB, &xf)) {
908 printf ("error creating the new object in X3D_MF_TO_JS string :%s:\n",newline);
909 return;
910 }
911 if (!JS_DefineElement(cx, JSVAL_TO_OBJECT(*newval), (jsint) i, xf,
912 JS_GET_PROPERTY_STUB, setSF_in_MF, JSPROP_ENUMERATE)) {
913 printf( "JS_DefineElement failed for arg %u .\n", i);
914 return;
915 }
916 } else {
917 /* printf ("X3DMF, ignoring NULL node here \n"); */
918 }
919 }
920 } break;
921
922
923 case FIELDTYPE_MFString: {
924 struct Multi_String* MCptr;
925 char newline[100];
926 jsval xf;
927
928 MCptr = (struct Multi_String *) Data;
929 for (i=0; i<MCptr->n; i++) {
930 #ifdef JSVRMLCLASSESVERBOSE
931 printf ("X3D_MF_TO_JS, working on %d of %d, p %u\n",i, MCptr->n, MCptr->p[i]);
932 #endif
933
934 if (((struct Uni_String *)MCptr->p[i])->strptr != NULL)
935 sprintf (newline,"new String('%s')", ((struct Uni_String *)MCptr->p[i])->strptr);
936 else sprintf (newline,"new String('(NULL)')");
937
938 #ifdef JSVRMLCLASSESVERBOSE
939 printf ("X3D_MF_TO_JS, we have a new script to evaluate: \"%s\"\n",newline);
940 #endif
941
942 if (!JS_EvaluateScript(cx, JSVAL_TO_OBJECT(*newval), newline, (int) strlen(newline), FNAME_STUB, LINENO_STUB, &xf)) {
943 printf ("error creating the new object in X3D_MF_TO_JS string :%s:\n",newline);
944 return;
945 }
946 if (!JS_DefineElement(cx, JSVAL_TO_OBJECT(*newval), (jsint) i, xf,
947 JS_GET_PROPERTY_STUB, setSF_in_MF, JSPROP_ENUMERATE)) {
948 printf( "JS_DefineElement failed for arg %u .\n", i);
949 return;
950 }
951 }
952 } break;
953
954 case FIELDTYPE_SFImage: {
955 struct Multi_Int32* MCptr;
956 char newline[10000];
957 jsval xf;
958
959 /* look at the PixelTexture internals, an image is just a bunch of Int32s */
960 MCptr = (struct Multi_Int32 *) Data;
961 sprintf (newline, "new SFImage(");
962
963 for (i=0; i<MCptr->n; i++) {
964 char sl[20];
965 sprintf (sl,"0x%x ", MCptr->p[i]);
966 strcat (newline,sl);
967
968 if (i != ((MCptr->n)-1)) strcat (newline,",");
969 if (i == 2) strcat (newline, " new MFInt32(");
970
971 }
972 strcat (newline, "))");
973
974 if (!JS_EvaluateScript(cx, JSVAL_TO_OBJECT(*newval), newline, (int) strlen(newline), FNAME_STUB, LINENO_STUB, &xf)) {
975 printf ("error creating the new object in X3D_MF_TO_JS string :%s:\n",newline);
976 return;
977 }
978 *newval = xf; /* save this version */
979 } break;
980 default: { printf("WARNING: SHOULD NOT BE HERE! %d\n",dataType); }
981 }
982
983 #ifdef JSVRMLCLASSESVERBOSE
984 printf ("returning from X3D_MF_TO_JS\n");
985 #endif
986}
987
988
989void X3D_MF_TO_JS_B(JSContext *cx, union anyVrml* Data, int dataType, int *valueChanged, jsval *newval) {
990 // for SM_method == 2, simplifies MF handling
991 //1. create object, with MF getter/setter that looks for [i] or ["length"]
992 //2. add the AnyNative (pass in more details please)
993 //3. set as return value
994
995 jsval rval;
996 char *script = NULL;
997 AnyNative *ptr;
998 JSObject *newobj = NULL;
999
1000
1001// if (!JSVAL_IS_OBJECT(*newval)) { //don't know what this guards against
1002 switch (dataType) {
1003 case FIELDTYPE_MFString:
1004 newobj = JS_NewObject(cx,&MFStringClass,NULL,NULL); break;
1005 case FIELDTYPE_MFFloat:
1006 newobj = JS_NewObject(cx,&MFFloatClass,NULL,NULL); break;
1007 case FIELDTYPE_MFTime:
1008 newobj = JS_NewObject(cx,&MFTimeClass,NULL,NULL); break;
1009 case FIELDTYPE_MFInt32:
1010 newobj = JS_NewObject(cx,&MFInt32Class,NULL,NULL); break;
1011 case FIELDTYPE_SFImage:
1012 newobj = JS_NewObject(cx,&SFImageClass,NULL,NULL); break;
1013 case FIELDTYPE_MFVec3f:
1014 newobj = JS_NewObject(cx,&MFVec3fClass,NULL,NULL); break;
1015 case FIELDTYPE_MFColor:
1016 newobj = JS_NewObject(cx,&MFColorClass,NULL,NULL); break;
1017 case FIELDTYPE_MFNode:
1018 newobj = JS_NewObject(cx,&MFNodeClass,NULL,NULL); break;
1019 case FIELDTYPE_MFVec2f:
1020 newobj = JS_NewObject(cx,&MFVec2fClass,NULL,NULL); break;
1021 case FIELDTYPE_MFRotation:
1022 newobj = JS_NewObject(cx,&MFRotationClass,NULL,NULL); break;
1023 default: printf ("invalid type in X3D_MF_TO_JS\n"); return;
1024 }
1025 //set private
1026 if ((ptr = (AnyNative *) AnyNativeNew(dataType,Data,valueChanged)) == NULL) {
1027 printf( "AnyNativeNew failed in X3D_MF_TO_SF_B.\n");
1028 return;
1029 }
1030
1031 if (!JS_SetPrivateFw(cx, newobj, ptr)) {
1032 printf( "JS_SetPrivate failed in X3D_MF_TO_SF_B.\n");
1033 return;
1034 }
1035
1036 /* this is the return pointer, lets save it right now */
1037 *newval = OBJECT_TO_JSVAL(newobj);
1038 if(0){
1039 //check if ptr is on object constructed from newval, or is it just on the object?
1040 AnyNative *ptr2;
1041 JSObject *obj2 = JSVAL_TO_OBJECT(*newval);
1042 if( (ptr2 = (AnyNative*)JS_GetPrivateFw(cx,obj2)) == NULL){
1043 printf("native pointer doesn't survive reduction to jsval\n");
1044 }else{
1045 printf("OK native pointer survives reduction to jsval");
1046 printf("ptr->v->mf.n=%d\n",ptr2->v->mfbool.n);
1047 }
1048 }
1049 return;
1050
1051}
1052
1053
1054
1055void
1056reportWarningsOn() {
1057 ppjsUtils p = (ppjsUtils)gglobal()->jsUtils.prv;
1058 p->reportWarnings = JS_TRUE;
1059}
1060
1061
1062void
1063reportWarningsOff() {
1064 ppjsUtils p = (ppjsUtils)gglobal()->jsUtils.prv;
1065 p->reportWarnings = JS_FALSE;
1066}
1067
1068
1069void
1070errorReporter(JSContext *context, const char *message, JSErrorReport *report)
1071{
1072 char *errorReport = 0;
1073 int len = 0, charPtrSize = (int) sizeof(char *);
1074 ppjsUtils p = (ppjsUtils)gglobal()->jsUtils.prv;
1075
1076//printf ("*** errorReporter ***\n");
1077
1078 if (!report) {
1079 fprintf(stderr, "%s\n", message);
1080 return;
1081 }
1082
1083 /* Conditionally ignore reported warnings. */
1084 if (JSREPORT_IS_WARNING(report->flags) && !p->reportWarnings) {
1085 return;
1086 }
1087
1088 if (report->filename == NULL) {
1089 len = (int) (strlen(message) + 1);
1090 } else {
1091 len = (int) ((strlen(report->filename) + 1) + (strlen(message) + 1));
1092 }
1093
1094 errorReport = (char *) JS_malloc(context, (len + STRING) * charPtrSize);
1095 if (!errorReport) {
1096 return;
1097 }
1098
1099
1100 if (JSREPORT_IS_WARNING(report->flags)) {
1101 sprintf(errorReport,
1102 "%swarning in %s at line %u:\n\t%s\n",
1103 JSREPORT_IS_STRICT(report->flags) ? "strict " : "",
1104 report->filename ? report->filename : "",
1105 report->lineno ? report->lineno : 0,
1106 message ? message : "No message.");
1107 } else {
1108 sprintf(errorReport,
1109 "error in %s at line %u:\n\t%s\n",
1110 report->filename ? report->filename : "",
1111 report->lineno ? report->lineno : 0,
1112 message ? message : "No message.");
1113 }
1114
1115 fprintf(stderr, "Javascript -- %s", errorReport);
1116
1117 JS_free(context, errorReport);
1118}
1119
1120
1121/* SFNode - find the fieldOffset pointer for this field within this node */
1122static int *getFOP (struct X3D_Node *node, const char *str) {
1123 int *fieldOffsetsPtr;
1124
1125
1126 if (node != NULL) {
1127 #ifdef JSVRMLCLASSESVERBOSE
1128 printf ("...getFOP... it is a %s\n",stringNodeType(node->_nodeType));
1129 #endif
1130
1131 fieldOffsetsPtr = (int *) NODE_OFFSETS[node->_nodeType];
1132 /*go thru all field*/
1133 /* what we have is a list of 4 numbers, representing:
1134 FIELDNAMES__parentResource, offsetof (struct X3D_Anchor, __parenturl), FIELDTYPE_SFString, KW_initializeOnly,
1135 */
1136
1137 while (*fieldOffsetsPtr != -1) {
1138 #ifdef JSVRMLCLASSESVERBOSE
1139 printf ("getFOP, looking at field %s type %s to match %s\n",FIELDNAMES[*fieldOffsetsPtr],FIELDTYPES[*(fieldOffsetsPtr+2)],str);
1140 #endif
1141
1142 /* skip any fieldNames starting with an underscore, as these are "internal" ones */
1143 /* There is in fact nothing in this function that actually enforces this, which is good!! */
1144 if (strcmp(str,FIELDNAMES[*fieldOffsetsPtr]) == 0) {
1145 #ifdef JSVRMLCLASSESVERBOSE
1146 printf ("getFOP, found entry for %s, it is %u (%p)\n",str,fieldOffsetsPtr,fieldOffsetsPtr);
1147 #endif
1148 return fieldOffsetsPtr;
1149 }
1150 fieldOffsetsPtr += FIELDOFFSET_LENGTH;
1151 }
1152
1153 /* failed to find field?? */
1154 #if TRACK_FIFO_MSG
1155 printf ("getFOP, could not find field \"%s\" in nodeType \"%s\"\n", str, stringNodeType(node->_nodeType));
1156 #endif
1157 } else {
1158 printf ("getFOP, passed in X3D node was NULL!\n");
1159 }
1160 return NULL;
1161}
1162
1163
1164/* getter for SFNode accesses */
1165#if JS_VERSION <= 185
1166static JSBool getSFNodeField(JSContext *cx, JSObject *obj, jsid id, jsval *vp){
1167#else
1168static JSBool getSFNodeField(JSContext *cx, JSHandleObject hobj, JSHandleId hiid, JSMutableHandleValue hvp){
1169 JSObject *obj = *hobj._;
1170 jsid id = *hiid._;
1171 jsval *vp = hvp._;
1172#endif
1173 //JSString *_idStr;
1174 char *_id_c;
1175 SFNodeNative *ptr;
1176 int *fieldOffsetsPtr;
1177 struct X3D_Node *node;
1178
1179 /* NOTE - caller is (eventually) a JS class constructor, no need to BeginRequest */
1180
1181 /* _idStr = JS_ValueToString(cx, id); */
1182/* #if JS_VERSION < 185 */
1183 /* _id_c = JS_GetStringBytes(_idStr); */
1184/* #else */
1185 /* _id_c = JS_EncodeString(cx,_idStr); */
1186/* #endif */
1187#if JS_VERSION < 185
1188 _id_c = JS_GetStringBytes(JSVAL_TO_STRING(id));
1189#else
1190 _id_c = JS_EncodeString(cx,JSID_TO_STRING(id));
1191#endif
1192
1193
1194 #ifdef JSVRMLCLASSESVERBOSE
1195 printf ("\ngetSFNodeField called on name %s object %u\n",_id_c, obj);
1196 #endif
1197
1198 if ((ptr = (SFNodeNative *)JS_GetPrivateFw(cx, obj)) == NULL) {
1199 printf( "JS_GetPrivate failed in getSFNodeField.\n");
1200#if JS_VERSION >= 185
1201 JS_free(cx,_id_c);
1202#endif
1203 return JS_FALSE;
1204 }
1205 node = X3D_NODE(ptr->handle);
1206
1207 #ifdef JSVRMLCLASSESVERBOSE
1208 printf ("getSFNodeField, got node %u for field %s object %u\n",node,_id_c, obj);
1209 printf ("getSFNodeField, got node %p for field %s object %p\n",node,_id_c, obj);
1210 #endif
1211
1212 if (node == NULL) {
1213 printf ("getSFNodeField, can not set field \"%s\", NODE is NULL!\n",_id_c);
1214#if JS_VERSION >= 185
1215 JS_free(cx,_id_c);
1216#endif
1217 return JS_FALSE;
1218 }
1219#if USE_OSC
1220 /* Is this a ring buffer item? */
1221 fieldOffsetsPtr = getFOP(ptr->handle,"FIFOsize");
1222 if (fieldOffsetsPtr == NULL) {
1223 #if TRACK_FIFO_MSG
1224 printf("getSFNodeField : This is not a ringBuffer type\n");
1225 #endif
1226 } else {
1227 struct X3D_OSC_Sensor *OSCnode ;
1228 OSCnode = (struct X3D_OSC_Sensor *) X3D_NODE(ptr->handle);
1229 char *_id_buffer_c = NULL ;
1230 RingBuffer * buffer ;
1231
1232 int iVal ;
1233 float fVal ;
1234 char * strPtr ;
1235
1236 #if TRACK_FIFO_MSG
1237 printf("getSFNodeField : This could be a ringBuffer type (found FIFOsize)\n");
1238 #endif
1239
1240 if (0 == strcmp(_id_c,"int32Inp")) {
1241 #if TRACK_FIFO_MSG
1242 printf("getSFNodeField %d : ptr->handle=%p (which corresponds to realnode in scenegraph/Component_Networking.c,314) node=%p see X3D_NODE(ptr->handle)\n",__LINE__,ptr->handle , node);
1243 #endif
1244 /* fieldOffsetsPtr = getFOP(ptr->handle,_id_buffer_c); */
1245 buffer = (RingBuffer *) OSCnode->_int32InpFIFO ;
1246 #if TRACK_FIFO_MSG
1247 printf("getSFNodeField %d : buffer=%p\n",__LINE__,buffer) ;
1248 #endif
1249
1250 if (!RingBuffer_testEmpty(buffer)) {
1251 _id_buffer_c = "_int32InpFIFO" ;
1252 iVal = RingBuffer_pullUnion(buffer)->i ;
1253 #if TRACK_FIFO_MSG
1254 printf("getSFNodeField %d : iVal=%d\n",__LINE__,iVal);
1255 #endif
1256
1257 *vp = INT_TO_JSVAL(iVal) ;
1258 return JS_TRUE;
1259 } else {
1260 #if TRACK_FIFO_MSG
1261 printf("but the buffer is empty\n") ;
1262 #endif
1263 }
1264 } else if (0 == strcmp(_id_c,"floatInp")) {
1265 #if TRACK_FIFO_MSG
1266 printf("getSFNodeField %d : ptr->handle=%p (which corresponds to realnode in scenegraph/Component_Networking.c,314) node=%p see X3D_NODE(ptr->handle)\n",__LINE__,ptr->handle , node);
1267 #endif
1268 buffer = (RingBuffer *) OSCnode->_floatInpFIFO ;
1269 #if TRACK_FIFO_MSG
1270 printf("getSFNodeField %d : buffer=%p\n",__LINE__,buffer) ;
1271 #endif
1272
1273 if (!RingBuffer_testEmpty(buffer)) {
1274 _id_buffer_c = "_floatInpFIFO" ;
1275 fVal = RingBuffer_pullUnion(buffer)->f ;
1276 #if TRACK_FIFO_MSG
1277 printf("getSFNodeField %d : fVal=%d\n",__LINE__,fVal);
1278 #endif
1279
1280 JS_NewNumberValue(cx,(double)fVal,vp);
1281 return JS_TRUE;
1282 } else {
1283 #if TRACK_FIFO_MSG
1284 printf("but the buffer is empty\n") ;
1285 #endif
1286 }
1287 } else if (0 == strcmp(_id_c,"stringInp")) {
1288 #if TRACK_FIFO_MSG
1289 printf("getSFNodeField %d : ptr->handle=%p (which corresponds to realnode in scenegraph/Component_Networking.c,314) node=%p see X3D_NODE(ptr->handle)\n",__LINE__,ptr->handle , node);
1290 #endif
1291 buffer = (RingBuffer *) OSCnode->_stringInpFIFO ;
1292 #if TRACK_FIFO_MSG
1293 printf("getSFNodeField %d : buffer=%p\n",__LINE__,buffer) ;
1294 #endif
1295
1296 if (!RingBuffer_testEmpty(buffer)) {
1297 _id_buffer_c = "_stringInpFIFO" ;
1298 strPtr = (char *) RingBuffer_pullUnion(buffer)->p ;
1299 #if TRACK_FIFO_MSG
1300 printf("getSFNodeField %d : strPtr=%s\n",__LINE__,strPtr);
1301 #endif
1302
1303 *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,strPtr));
1304 return JS_TRUE;
1305 } else {
1306 #if TRACK_FIFO_MSG
1307 printf("but the buffer is empty\n") ;
1308 #endif
1309 }
1310 } else {
1311 #if TRACK_FIFO_MSG
1312 printf("but this variable itself (%s) is not a ring buffer item\n",_id_c) ;
1313 #endif
1314 }
1315 }
1316#endif
1317
1318 /* get the table entry giving the type, offset, etc. of this field in this node */
1319 fieldOffsetsPtr = getFOP(ptr->handle,_id_c);
1320 if (fieldOffsetsPtr == NULL) {
1321#if JS_VERSION >= 185
1322 JS_free(cx,_id_c);
1323#endif
1324 return JS_FALSE;
1325 }
1326 #ifdef JSVRMLCLASSESVERBOSE
1327 printf ("ptr=%p _id_c=%s node=%p node->_nodeType=%d stringNodeType=%s\n",ptr,_id_c,node,node->_nodeType,stringNodeType(node->_nodeType)) ;
1328 printf ("getSFNodeField, fieldOffsetsPtr is %d for node %u, field %s\n",fieldOffsetsPtr, ptr->handle, _id_c);
1329 #endif
1330#if JS_VERSION >= 185
1331 JS_free(cx,_id_c); /* _id_c is not used beyond this point in this fn */
1332#endif
1333
1334
1335 /* now, we have an X3D node, offset, type, etc. Just get the value from memory, and move
1336 it to javascript. Kind of like: void getField_ToJavascript (int num, int fromoffset)
1337 for Routing. */
1338
1339 /* fieldOffsetsPtr points to a 4-number line like:
1340 FIELDNAMES__parentResource, offsetof (struct X3D_Anchor, __parenturl), FIELDTYPE_SFString, KW_initializeOnly */
1341 switch (*(fieldOffsetsPtr+2)) {
1342 case FIELDTYPE_SFBool:
1343 case FIELDTYPE_SFFloat:
1344 case FIELDTYPE_SFTime:
1345 case FIELDTYPE_SFDouble:
1346 case FIELDTYPE_SFInt32:
1347 case FIELDTYPE_SFString:
1348 X3D_ECMA_TO_JS(cx, offsetPointer_deref (void *, node, *(fieldOffsetsPtr+1)),
1349 returnElementLength(*(fieldOffsetsPtr+2)), *(fieldOffsetsPtr+2), vp);
1350 break;
1351 case FIELDTYPE_SFColor:
1352 case FIELDTYPE_SFNode:
1353 case FIELDTYPE_SFVec2f:
1354 case FIELDTYPE_SFVec3f:
1355 case FIELDTYPE_SFVec3d:
1356 case FIELDTYPE_SFRotation:
1357 X3D_SF_TO_JS(cx, obj, offsetPointer_deref (void *, node, *(fieldOffsetsPtr+1)),
1358 returnElementLength(*(fieldOffsetsPtr+2)) * returnElementRowSize(*(fieldOffsetsPtr+2)) , *(fieldOffsetsPtr+2), vp);
1359 break;
1360 case FIELDTYPE_MFColor:
1361 case FIELDTYPE_MFVec3f:
1362 case FIELDTYPE_MFVec2f:
1363 case FIELDTYPE_MFFloat:
1364 case FIELDTYPE_MFTime:
1365 case FIELDTYPE_MFInt32:
1366 case FIELDTYPE_MFString:
1367 case FIELDTYPE_MFNode:
1368 case FIELDTYPE_MFRotation:
1369 case FIELDTYPE_SFImage:
1370 X3D_MF_TO_JS(cx, obj, offsetPointer_deref (void *, node, *(fieldOffsetsPtr+1)), *(fieldOffsetsPtr+2), vp,
1371 (char *)FIELDNAMES[*(fieldOffsetsPtr+0)]);
1372 break;
1373 default: printf ("unhandled type FIELDTYPE_ %d in getSFNodeField\n", *(fieldOffsetsPtr+2)) ;
1374 return JS_FALSE;
1375 }
1376
1377 #ifdef JSVRMLCLASSESVERBOSE
1378 printf ("end of getSFNodeField\n");
1379 #endif
1380
1381 return JS_TRUE;
1382}
1383
1384/* setter for SFNode accesses */
1385#if JS_VERSION < 185
1386JSBool setSFNodeField (JSContext *cx, JSObject *obj, jsid id, jsval *vp) {
1387#elif JS_VERSION == 185
1388JSBool setSFNodeField (JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp){
1389#else
1390JSBool setSFNodeField (JSContext *cx, JSHandleObject hobj, JSHandleId hiid, JSBool strict, JSMutableHandleValue hvp){
1391 JSObject *obj = *hobj._;
1392 jsid id = *hiid._;
1393 jsval *vp = hvp._;
1394#endif
1395 char *_id_c;
1396 SFNodeNative *ptr;
1397 int *fieldOffsetsPtr;
1398 struct X3D_Node *node;
1399
1400 /* get the id field... */
1401
1402#if JS_VERSION < 185
1403 _id_c = JS_GetStringBytes(JSVAL_TO_STRING(id));
1404#else
1405 _id_c = JS_EncodeString(cx,JSID_TO_STRING(id));
1406#endif
1407
1408 #ifdef JSVRMLCLASSESVERBOSE
1409 printf ("\nsetSFNodeField called on name %s object %u, jsval %u\n",_id_c, obj, *vp);
1410 #endif
1411
1412 /* get the private data. This will contain a pointer into the FreeWRL scenegraph */
1413 if ((ptr = (SFNodeNative *)JS_GetPrivateFw(cx, obj)) == NULL) {
1414 printf( "JS_GetPrivate failed in setSFNodeField.\n");
1415#if JS_VERSION >= 185
1416 JS_free(cx,_id_c);
1417#endif
1418 return JS_FALSE;
1419 }
1420
1421 /* get the X3D Scenegraph node pointer from this Javascript SFNode node */
1422 node = (struct X3D_Node *) ptr->handle;
1423
1424 if (node == NULL) {
1425 printf ("setSFNodeField, can not set field \"%s\", NODE is NULL!\n",_id_c);
1426#if JS_VERSION >= 185
1427 JS_free(cx,_id_c);
1428#endif
1429 return JS_FALSE;
1430 }
1431
1432 #ifdef JSVRMLCLASSESVERBOSE
1433 printf ("so then, we have a node of type %s\n",stringNodeType(node->_nodeType));
1434 #endif
1435
1436 #if USE_OSC
1437 #ifdef JSVRMLCLASSESVERBOSE
1438 /* Is this a ring buffer item? */
1439 fieldOffsetsPtr = getFOP(ptr->handle,"FIFOsize");
1440 #if TRACK_FIFO_MSG
1441 if (fieldOffsetsPtr == NULL) {
1442 printf("setSFNodeField : This is not a ringBuffer type\n");
1443 } else {
1444 printf("setSFNodeField : This is a ringBuffer type\n");
1445 }
1446 #endif
1447 #endif
1448 #endif
1449
1450 /* get the table entry giving the type, offset, etc. of this field in this node */
1451 fieldOffsetsPtr = getFOP(ptr->handle,_id_c);
1452#if JS_VERSION >= 185
1453 JS_free(cx,_id_c); /* _id_c is not used beyond this point in this fn */
1454#endif
1455 if (fieldOffsetsPtr == NULL) {
1456 return JS_FALSE;
1457 }
1458
1459 /* now, we have an X3D node, offset, type, etc. Just get the value from Javascript, and move
1460 it to the X3D Scenegraph. */
1461
1462 /* fieldOffsetsPtr points to a 4-number line like:
1463 FIELDNAMES__parentResource, offsetof (struct X3D_Anchor, __parenturl), FIELDTYPE_SFString, KW_initializeOnly */
1464 #ifdef JSVRMLCLASSESVERBOSE
1465 printf ("and a field type of %s\n",FIELDTYPES[*(fieldOffsetsPtr+2)]);
1466 #endif
1467
1468 switch (*(fieldOffsetsPtr+2)) {
1469 case FIELDTYPE_SFBool:
1470 case FIELDTYPE_SFFloat:
1471 case FIELDTYPE_SFTime:
1472 case FIELDTYPE_SFDouble:
1473 case FIELDTYPE_SFInt32:
1474 case FIELDTYPE_SFString:
1475 JS_ECMA_TO_X3D(cx, ((void *)( ((unsigned char *) node) + *(fieldOffsetsPtr+1))),
1476 returnElementLength(*(fieldOffsetsPtr+2)), *(fieldOffsetsPtr+2), vp);
1477 break;
1478 case FIELDTYPE_SFColor:
1479 case FIELDTYPE_SFNode:
1480 case FIELDTYPE_SFVec2f:
1481 case FIELDTYPE_SFVec3f:
1482 case FIELDTYPE_SFVec3d:
1483 case FIELDTYPE_SFRotation:
1484 JS_SF_TO_X3D(cx, ((void *)( ((unsigned char *) node) + *(fieldOffsetsPtr+1))),
1485 returnElementLength(*(fieldOffsetsPtr+2)) * returnElementRowSize(*(fieldOffsetsPtr+2)) , *(fieldOffsetsPtr+2), vp);
1486 break;
1487 case FIELDTYPE_MFColor:
1488 case FIELDTYPE_MFVec3f:
1489 case FIELDTYPE_MFVec2f:
1490 case FIELDTYPE_MFFloat:
1491 case FIELDTYPE_MFTime:
1492 case FIELDTYPE_MFInt32:
1493 case FIELDTYPE_MFString:
1494 case FIELDTYPE_MFNode:
1495 case FIELDTYPE_MFRotation:
1496 case FIELDTYPE_SFImage:
1497 JS_MF_TO_X3D(cx, obj, ((void *)( ((unsigned char *) node) + *(fieldOffsetsPtr+1))), *(fieldOffsetsPtr+2), vp);
1498 break;
1499 default: printf ("unhandled type in setSFNodeField\n");
1500 return JS_FALSE;
1501 }
1502
1503 /* tell the X3D Scenegraph that something has changed in Kansas */
1504 update_node(node);
1505
1506 #ifdef JSVRMLCLASSESVERBOSE
1507 printf ("end of setSFNodeField\n");
1508 #endif
1509
1510
1511 return JS_TRUE;
1512}
1513#define UNHIDE_DEFINE_SFNODESPECIFIC 1
1514#ifdef UNHIDE_DEFINE_SFNODESPECIFIC
1515/* for SFNodes, go through and insure that all properties are defined for the specific node type */
1516int JS_DefineSFNodeSpecificProperties (JSContext *context, JSObject *object, struct X3D_Node * ptr) {
1517 int *fieldOffsetsPtr;
1518 jsval rval = INT_TO_JSVAL(0);
1519 uintN attrs = JSPROP_PERMANENT
1520 | JSPROP_ENUMERATE
1521#ifdef JSPROP_EXPORTED
1522 | JSPROP_EXPORTED
1523#endif
1524 /* | JSPROP_INDEX */
1525 ;
1526 char *name;
1527 SFNodeNative *nodeNative;
1528 #ifdef JSVRMLCLASSESVERBOSE
1529 char *nodeName;
1530 struct X3D_Node *confirmNode;
1531 #endif
1532
1533 /* NOTE - caller of this function is a class constructor, no need to worry about Requests */
1534
1535
1536 #ifdef JSVRMLCLASSESVERBOSE
1537 nodeName = parser_getNameFromNode(ptr) ; /* vi +/dump_scene src/lib/scenegraph/GeneratedCode.c */
1538 if (nodeName == NULL) {
1539 printf ("\nStart of JS_DefineSFNodeSpecificProperties for '---' ... working on node %u object %u (%p,%p)\n",ptr,object,ptr,object);
1540 } else {
1541 printf ("\nStart of JS_DefineSFNodeSpecificProperties for '%s' ... working on node %u object %u (%p,%p)\n",nodeName,ptr,object,ptr,object);
1542 confirmNode = parser_getNodeFromName(nodeName);
1543 if (confirmNode == NULL) {
1544 printf("RoundTrip failed : ptr (%p) -> nodeName (%s) -----\n",ptr,nodeName) ;
1545 } else {
1546 printf("RoundTrip OK : ptr (%p) -> nodeName (%s) -> confirmNode (%p)\n",ptr,nodeName,confirmNode) ;
1547 }
1548 }
1549 #endif
1550
1551 if (ptr != NULL) {
1552 #ifdef JSVRMLCLASSESVERBOSE
1553 printf ("...JS_DefineSFNodeSpecificProperties... it is a %s\n",stringNodeType(ptr->_nodeType));
1554 #endif
1555
1556 /* have we already done this for this node? We really do not want to do this again */
1557 if ((nodeNative = (SFNodeNative *)JS_GetPrivateFw(context,object)) == NULL) {
1558 printf ("JS_DefineSFNodeSpecificProperties, can not get private for a SFNode!\n");
1559 return JS_FALSE;
1560 }
1561 if(SM_method() == 0)
1562 if (nodeNative->fieldsExpanded) {
1563 #ifdef JSVRMLCLASSESVERBOSE
1564 printf ("JS_DefineSFNodeSpecificProperties, already done for node\n");
1565 #endif
1566
1567 return JS_TRUE;
1568 }
1569
1570 fieldOffsetsPtr = (int *) NODE_OFFSETS[ptr->_nodeType];
1571 /*go thru all field*/
1572 /* what we have is a list of 4 numbers, representing:
1573 FIELDNAMES__parentResource, offsetof (struct X3D_Anchor, __parenturl), FIELDTYPE_SFString, KW_initializeOnly,
1574 */
1575
1576 while (*fieldOffsetsPtr != -1) {
1577 /* fieldPtr=(char*)structptr+(*(fieldOffsetsPtr+1)); */
1578 #ifdef JSVRMLCLASSESVERBOSE
1579 printf ("looking at field %s type %s\n",FIELDNAMES[*fieldOffsetsPtr],FIELDTYPES[*(fieldOffsetsPtr+2)]);
1580 #endif
1581
1582#if USE_OSC
1583 if( 0 == strcmp("FreeWRL_PROTOInterfaceNodes",FIELDNAMES[*fieldOffsetsPtr])) {
1584
1585 #ifdef JSVRMLCLASSESVERBOSE
1586 printf ("%s:%d Mangle %s before calling JS_DefineProperty ....\n",__FILE__,__LINE__,FIELDNAMES[*fieldOffsetsPtr]);
1587 #endif
1588 int i ;
1589 char *str1, *token;
1590 char *saveptr1 = NULL;
1591
1592 UNUSED(token); // compiler warning mitigation
1593
1594 for (i=0; i < X3D_GROUP(ptr)->FreeWRL_PROTOInterfaceNodes.n; i++) {
1595 rval = INT_TO_JSVAL(*fieldOffsetsPtr);
1596 name = parser_getNameFromNode(X3D_GROUP(ptr)->FreeWRL_PROTOInterfaceNodes.p[i]);
1597
1598 #ifdef JSVRMLCLASSESVERBOSE
1599 dump_scene(stdout,0,X3D_GROUP(ptr)->FreeWRL_PROTOInterfaceNodes.p[i]);
1600 printf ("%s:%d dummy name=%s\n",__FILE__,__LINE__,name);
1601 #endif
1602
1603 str1 = MALLOC(void *, 1+strlen(name));
1604 strcpy(str1,name) ;
1605 /* discard Proto_0xnnnnn_*/
1606 token = strtok_r(str1, "_", &saveptr1);
1607 str1 = NULL;
1608 token = strtok_r(str1, "_", &saveptr1);
1609 name = saveptr1 ;
1610
1611 #ifdef JSVRMLCLASSESVERBOSE
1612 printf ("%s:%d would call JS_DefineProperty on (context=%p, object=%p, name=%s, rval=%p), setting getSFNodeField, setSFNodeField\n",__FILE__,__LINE__,context,object,name,rval);
1613 #endif
1614 if (!JS_DefineProperty(context, object, name, rval, getSFNodeField, setSFNodeField, attrs)) {
1615 printf("JS_DefineProperty failed for \"%s\" in JS_DefineSFNodeSpecificProperties.\n", name);
1616 return JS_FALSE;
1617 }
1618 }
1619 } else if (FIELDNAMES[*fieldOffsetsPtr][0] != '_') {
1620#else
1621 if (FIELDNAMES[*fieldOffsetsPtr][0] != '_') {
1622#endif
1623 /* skip any fieldNames starting with an underscore, as these are "internal" ones */
1624 name = (char *)FIELDNAMES[*fieldOffsetsPtr];
1625 rval = INT_TO_JSVAL(*fieldOffsetsPtr);
1626
1627 /* is this an initializeOnly property? */
1628 /* lets not do this, ok?
1629 if ((*(fieldOffsetsPtr+3)) == KW_initializeOnly) attrs |= JSPROP_READONLY;
1630 */
1631
1632 #ifdef JSVRMLCLASSESVERBOSE
1633 printf ("calling JS_DefineProperty on (context=%p, object=%p, name=%s, rval=%p), setting getSFNodeField, setSFNodeField\n",context,object,name,rval);
1634 #endif
1635
1636 if (!JS_DefineProperty(context, object, name, rval, getSFNodeField, setSFNodeField, attrs)) {
1637 printf("JS_DefineProperty failed for \"%s\" in JS_DefineSFNodeSpecificProperties.\n", name);
1638 return JS_FALSE;
1639 }
1640 }
1641 fieldOffsetsPtr += FIELDOFFSET_LENGTH;
1642 }
1643
1644 /* set a flag indicating that we have been here already */
1645 if(SM_method() == 0)
1646 nodeNative->fieldsExpanded = TRUE;
1647 }
1648 #ifdef JSVRMLCLASSESVERBOSE
1649 printf ("JS_DefineSFNodeSpecificProperties, returning TRUE\n");
1650 #endif
1651
1652 return TRUE;
1653}
1654#endif // UNHIDE_DEFINE_SFNODESPECIFIC
1655
1656/********************************************************************************************/
1657/* new addition April 2009. It was noted that the following code would not send an event to
1658 FreeWRL:
1659#VRML V2.0 utf8
1660 DEF DisplayScript Script {
1661 eventOut MFString display_string
1662
1663 url [ "javascript:
1664 function eventsProcessed () {
1665 display_string[7] = ' ';
1666 }
1667 "]
1668 }
1669
1670
1671Shape {geometry DEF Display Text {}}
1672 ROUTE DisplayScript.display_string TO Display.set_string
1673
1674(it would if the assignment was display_string = new MFString(...) )
1675
1676But, this property check gets called on the equals. Lets figure out how to indicate that the
1677holding object needs to route to FreeWRL... */
1678
1679
1680#define SET_TOUCHED_TYPE_MF_A(thisMFtype,thisSFtype) \
1681 else if (JS_InstanceOf (cx, obj, &thisMFtype##Class, NULL)) {\
1682 jsval mainElement;\
1683 thisSFtype##Native *ptr; \
1684\
1685 if (!JS_GetElement(cx, obj, num, &mainElement)) { \
1686 printf ("JS_GetElement failed for %d in get_valueChanged_flag\n",num); \
1687 return JS_FALSE; \
1688 } \
1689\
1690 if ((ptr = (thisSFtype##Native *)JS_GetPrivateFw(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) {\
1691 printf( "JS_GetPrivate failed in assignCheck.\n"); \
1692 return JS_FALSE; \
1693 } else { \
1694 /* printf ("got private for MFVec3f, doing it...\n"); */ \
1695 ptr->valueChanged++; \
1696 } \
1697 return JS_TRUE; \
1698 }
1699
1700
1701#if JS_VERSION < 185
1702JSBool js_SetPropertyCheck (JSContext *cx, JSObject *obj, jsval id, jsval *vp) {
1703#elif JS_VERSION == 185
1704JSBool js_SetPropertyCheck(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp) {
1705#else
1706JSBool js_SetPropertyCheck(JSContext *cx, JSHandleObject hobj, JSHandleId hiid, JSBool strict, JSMutableHandleValue hvp){
1707 JSObject *obj = *hobj._;
1708 jsid iid = *hiid._;
1709 jsval *vp = hvp._;
1710#endif
1711 int num=0;
1712#if JS_VERSION >= 185
1713 jsval id;
1714 if (!JS_IdToValue(cx,iid,&id)) {
1715 printf("js_SetPropertyCheck: JS_IdToValue failed.\n");
1716 return JS_FALSE;
1717 }
1718#endif
1719
1720#ifdef JAVASCRIPTVERBOSE
1721 char *_id_c = "(no value in string)";
1722 /* get the id field... */
1723 if (JSVAL_IS_STRING(id)) {
1724/*
1725#if JS_VERSION < 185
1726 _id_c = JS_GetStringBytes(JSVAL_TO_STRING(id));
1727#else
1728 _id_c = JS_EncodeString(cx,JSVAL_TO_STRING(id));
1729#endif
1730 printf ("hmmm...js_SetPropertyCheck called on string \"%s\" object %u, jsval %u\n",_id_c, obj, *vp); */
1731 } else if (JSVAL_IS_DOUBLE(id)) {
1732#if JS_VERSION < 185
1733 _id_c = JS_GetStringBytes(JSVAL_TO_STRING(id));
1734#else
1735 _id_c = JS_EncodeString(cx,JSVAL_TO_STRING(id));
1736#endif
1737 printf ("\n...js_SetPropertyCheck called on double %s object %u, jsval %u\n",_id_c, obj, *vp);
1738#if JS_VERSION >= 185
1739 JS_free(cx,_id_c);
1740#endif
1741 } else if (JSVAL_IS_INT(id)) {
1742 num = JSVAL_TO_INT(id);
1743 printf ("\n...js_SetPropertyCheck called on number %d object %u, jsval %u\n",num, obj, *vp);
1744 } else {
1745 printf ("hmmm...js_SetPropertyCheck called on unknown type of object %u, jsval %u\n", obj, *vp);
1746 }
1747#endif
1748
1749 /* lets worry about the MFs containing ECMAs here - MFFloat MFInt32 MFTime MFString MFBool */
1750
1751 if (JS_InstanceOf (cx, obj, &MFStringClass, NULL)) {
1752 SET_MF_ECMA_HAS_CHANGED;
1753 return JS_TRUE;
1754 }
1755 else if (JS_InstanceOf (cx, obj, &MFFloatClass, NULL)) {
1756 SET_MF_ECMA_HAS_CHANGED;
1757 return JS_TRUE;
1758 }
1759 else if (JS_InstanceOf (cx, obj, &MFInt32Class, NULL)) {
1760 SET_MF_ECMA_HAS_CHANGED;
1761 return JS_TRUE;
1762 }
1763
1764#ifdef NEWCLASSES
1765 else if (JS_InstanceOf (cx, obj, &MFBoolClass, NULL)) {
1766 SET_MF_ECMA_HAS_CHANGED;
1767 return JS_TRUE;
1768 }
1769#endif
1770
1771 SET_TOUCHED_TYPE_MF_A(MFRotation,SFRotation)
1772 SET_TOUCHED_TYPE_MF_A(MFNode,SFNode)
1773 SET_TOUCHED_TYPE_MF_A(MFVec2f,SFVec2f)
1774 SET_TOUCHED_TYPE_MF_A(MFVec3f,SFVec3f)
1775 /* SET_TOUCHED_TYPE_MF_A(MFImage,SFImage) */
1776 SET_TOUCHED_TYPE_MF_A(MFColor,SFColor)
1777 /* SET_TOUCHED_TYPE_MF_A(MFColorRGBA,SFColorRGBA) */
1778
1779
1780 #ifdef JSVRMLCLASSESVERBOSE
1781 printf ("this is a class of "); printJSNodeType (cx,obj);
1782 #endif
1783
1784 return JS_TRUE;
1785
1786}
1787
1788/****************************************************************************/
1789
1790#if JS_VERSION < 185
1791JSBool js_GetPropertyDebug (JSContext *context, JSObject *obj, jsval id, jsval *vp) {
1792#else
1793JSBool js_GetPropertyDebug (JSContext *context, JSObject *obj, jsid iid, jsval *vp) {
1794#endif
1795 #ifdef JSVRMLCLASSESVERBOSE
1796 char *_id_c = "(no value in string)";
1797 int num;
1798 /* get the id field... */
1799#if JS_VERSION >= 185
1800 jsval id;
1801 if (!JS_IdToValue(context,iid,&id)) {
1802 printf("js_GetPropertyDebug: JS_IdToValue failed -- NOT returning false\n");
1803 }
1804#endif
1805
1806 if (JSVAL_IS_STRING(id)) {
1807#if JS_VERSION < 185
1808 _id_c = JS_GetStringBytes(JSVAL_TO_STRING(id));
1809#else
1810 _id_c = JS_EncodeString(context,JSVAL_TO_STRING(id));
1811#endif
1812 printf ("\n...js_GetPropertyDebug called on string \"%s\" object %u, jsval %lu\n",_id_c, (unsigned int) obj, *vp);
1813#if JS_VERSION >= 185
1814 JS_free(context,_id_c);
1815#endif
1816 } else if (JSVAL_IS_INT(id)) {
1817 num = JSVAL_TO_INT(id);
1818 printf ("\n...js_GetPropertyDebug called on number %d object %u, jsval %lu\n",num, (unsigned int) obj, *vp);
1819 } else {
1820 printf ("\n...js_GetPropertyDebug called on unknown type of object %u, jsval %lu\n", (unsigned int) obj, *vp);
1821 }
1822 #endif
1823 return JS_TRUE;
1824}
1825
1826#ifdef JSVRMLCLASSESVERBOSE
1827#if JS_VERSION < 185
1828void js_SetPropertyDebugWrapped (JSContext *context, JSObject *obj, jsval id, jsval *vp,char *debugString) {
1829#else
1830void js_SetPropertyDebugWrapped (JSContext *context, JSObject *obj, jsid iid, jsval *vp,char *debugString) {
1831#endif
1832 char *_id_c = "(no value in string)";
1833 int num;
1834#if JS_VERSION >= 185
1835 jsval id;
1836 if (!JS_IdToValue(context,iid,&id)) {
1837 printf("js_GetPropertyDebug: JS_IdToValue failed\n");
1838 }
1839#endif
1840
1841 /* get the id field... */
1842 if (JSVAL_IS_STRING(id)) {
1843#if JS_VERSION < 185
1844 _id_c = JS_GetStringBytes(JSVAL_TO_STRING(id));
1845#else
1846 _id_c = JS_EncodeString(context,JSVAL_TO_STRING(id));
1847#endif
1848 printf ("\n...js_SetPropertyDebug%s called on string \"%s\" object %p, jsval %lu\n",debugString,_id_c, obj, *vp);
1849#if JS_VERSION >= 185
1850 JS_free(context,_id_c);
1851#endif
1852 } else if (JSVAL_IS_INT(id)) {
1853 num = JSVAL_TO_INT(id);
1854 printf ("\n...js_SetPropertyDebug%s called on number %d object %p, jsval %lu\n",debugString,num, obj, *vp);
1855 } else {
1856 printf ("\n...js_SetPropertyDebug%s called on unknown type of object %p, jsval %lu\n",debugString, obj, *vp);
1857 }
1858}
1859#endif
1860
1861#if JS_VERSION < 185
1862JSBool js_SetPropertyDebug (JSContext *context, JSObject *obj, jsval id, jsval *vp) {
1863#else
1864JSBool js_SetPropertyDebug (JSContext *context, JSObject *obj, jsid id, JSBool strict, jsval *vp) {
1865#endif
1866 #ifdef JSVRMLCLASSESVERBOSE
1867 js_SetPropertyDebugWrapped(context,obj,id,vp,"");
1868 #endif
1869 return JS_TRUE;
1870}
1871
1872#if JS_VERSION < 185
1873JSBool js_SetPropertyDebug1 (JSContext *context, JSObject *obj, jsval id, jsval *vp) {
1874#else
1875JSBool js_SetPropertyDebug1 (JSContext *context, JSObject *obj, jsid id, JSBool strict, jsval *vp) {
1876#endif
1877 #ifdef JSVRMLCLASSESVERBOSE
1878 js_SetPropertyDebugWrapped(context,obj,id,vp,"1");
1879 #endif
1880 return JS_TRUE;
1881}
1882#if JS_VERSION < 185
1883JSBool js_SetPropertyDebug2 (JSContext *context, JSObject *obj, jsval id, jsval *vp) {
1884#else
1885JSBool js_SetPropertyDebug2 (JSContext *context, JSObject *obj, jsid id, JSBool strict, jsval *vp) {
1886#endif
1887 #ifdef JSVRMLCLASSESVERBOSE
1888 js_SetPropertyDebugWrapped(context,obj,id,vp,"2");
1889 #endif
1890 return JS_TRUE;
1891}
1892#if JS_VERSION < 185
1893JSBool js_SetPropertyDebug3 (JSContext *cx, JSObject *obj, jsval id, jsval *vp) {
1894#elif JS_VERSION == 185
1895JSBool js_SetPropertyDebug3 (JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp) {
1896#else
1897JSBool js_SetPropertyDebug3 (JSContext *cx, JSHandleObject hobj, JSHandleId hiid, JSBool strict, JSMutableHandleValue hvp){
1898 JSObject *obj = *hobj._;
1899 jsid id = *hiid._;
1900 jsval *vp = hvp._;
1901#endif
1902 #ifdef JSVRMLCLASSESVERBOSE
1903 js_SetPropertyDebugWrapped(cx,obj,id,vp,"3");
1904 #endif
1905 return JS_TRUE;
1906}
1907#if JS_VERSION < 185
1908JSBool js_SetPropertyDebug4 (JSContext *context, JSObject *obj, jsval id, jsval *vp) {
1909#else
1910JSBool js_SetPropertyDebug4 (JSContext *context, JSObject *obj, jsid id, JSBool strict, jsval *vp) {
1911#endif
1912 #ifdef JSVRMLCLASSESVERBOSE
1913 js_SetPropertyDebugWrapped(context,obj,id,vp,"4");
1914 #endif
1915 return JS_TRUE;
1916}
1917#if JS_VERSION < 185
1918JSBool js_SetPropertyDebug5 (JSContext *context, JSObject *obj, jsval id, jsval *vp) {
1919#elif JS_VERSION == 185
1920JSBool js_SetPropertyDebug5(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp){
1921#else
1922JSBool js_SetPropertyDebug5(JSContext *cx, JSHandleObject hobj, JSHandleId hiid, JSBool strict, JSMutableHandleValue hvp){
1923 JSObject *obj = *hobj._;
1924 jsid id = *hiid._;
1925 jsval *vp = hvp._;
1926#endif
1927 #ifdef JSVRMLCLASSESVERBOSE
1928 js_SetPropertyDebugWrapped(context,obj,id,vp,"5");
1929 #endif
1930 return JS_TRUE;
1931}
1932#if JS_VERSION < 185
1933JSBool js_SetPropertyDebug6 (JSContext *cx, JSObject *obj, jsval id, jsval *vp) {
1934#elif JS_VERSION == 185
1935JSBool js_SetPropertyDebug6 (JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp) {
1936#else
1937JSBool js_SetPropertyDebug6 (JSContext *cx, JSHandleObject hobj, JSHandleId hiid, JSBool strict, JSMutableHandleValue hvp){
1938 JSObject *obj = *hobj._;
1939 jsid id = *hiid._;
1940 jsval *vp = hvp._;
1941#endif
1942 #ifdef JSVRMLCLASSESVERBOSE
1943 js_SetPropertyDebugWrapped(context,obj,id,vp,"6");
1944 #endif
1945 return JS_TRUE;
1946}
1947#if JS_VERSION < 185
1948JSBool js_SetPropertyDebug7 (JSContext *context, JSObject *obj, jsval id, jsval *vp) {
1949#else
1950JSBool js_SetPropertyDebug7 (JSContext *context, JSObject *obj, jsid id, JSBool strict, jsval *vp) {
1951#endif
1952 #ifdef JSVRMLCLASSESVERBOSE
1953 js_SetPropertyDebugWrapped(context,obj,id,vp,"7");
1954 #endif
1955 return JS_TRUE;
1956}
1957#if JS_VERSION < 185
1958JSBool js_SetPropertyDebug8 (JSContext *cx, JSObject *obj, jsval id, jsval *vp) {
1959#elif JS_VERSION == 185
1960JSBool js_SetPropertyDebug8 (JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp) {
1961#else
1962JSBool js_SetPropertyDebug8 (JSContext *cx, JSHandleObject hobj, JSHandleId hiid, JSBool strict, JSMutableHandleValue hvp){
1963 JSObject *obj = *hobj._;
1964 jsid id = *hiid._;
1965 jsval *vp = hvp._;
1966#endif
1967 #ifdef JSVRMLCLASSESVERBOSE
1968 js_SetPropertyDebugWrapped(cx,obj,id,vp,"8");
1969 #endif
1970 return JS_TRUE;
1971}
1972#if JS_VERSION < 185
1973JSBool js_SetPropertyDebug9 (JSContext *context, JSObject *obj, jsval id, jsval *vp) {
1974#else
1975JSBool js_SetPropertyDebug9 (JSContext *context, JSObject *obj, jsid id, JSBool strict, jsval *vp) {
1976#endif
1977 #ifdef JSVRMLCLASSESVERBOSE
1978 js_SetPropertyDebugWrapped(context,obj,id,vp,"9");
1979 #endif
1980 return JS_TRUE;
1981}
1982
1983#endif /* !(defined(JAVASCRIPT_STUB) || defined(JAVASCRIPT_DUK) */
1984#endif
Definition ringbuf.h:8