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