FreeWRL / FreeX3D 4.3.0
jsVRMLBrowser_sm.cpp
1/*
2
3
4Javascript C language binding.
5
6*/
7
8/****************************************************************************
9 This file is part of the FreeWRL/FreeX3D Distribution.
10
11 Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12
13 FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14 it under the terms of the GNU Lesser Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25****************************************************************************/
26
27
28#include <config.h>
29#if defined(JS_SMCPP)
30#ifdef JAVASCRIPT_SM
31#undef DEBUG
32//#define DEBUG 1 //challenge it with lots of ASSERTS, just for cleaning up code correctness, not production
33# include <jsapi.h> /* JS compiler */
34//# include <jsdbgapi.h> /* JS debugger */
35
36#ifndef JS_VERSION
37#define JS_VERSION 187
38#endif
39//#define JS_THREADSAFE 1 //by default in 186+
40int JS_SetPrivateFw(JSContext *cx, JSObject* obj, void *data);
41JSObject* JS_NewGlobalObjectFw(JSContext *cx, JSClass *clasp); //, JSPrincipals *princ);
42void * JS_GetPrivateFw(JSContext *cx,JSObject*_obj);
43JSObject* JS_GetParentFw(JSContext *cx, JSObject *me);
44JSObject * JS_ConstructObjectWithArgumentsFw(JSContext *cx, JSClass *clasp, JSObject *parent, unsigned argc, jsval *argv);
45JSObject * JS_ConstructObjectFw(JSContext *cx, JSClass *clasp, void *whatever, JSObject *parent);
46JSObject * JS_GetPrototypeFw(JSContext *cx, JSObject * obj);
47JSClass * JS_GetClassFw(JSContext *cx, JSObject * obj);
48#define STRING_SIZE 256
49#define uintN unsigned
50#define intN int
51#define jsint int32_t
52#define jsuint uint32_t
53#define int32 int32_t
54#define jsdouble double
55
56#define JS_FinalizeStub NULL
57#define JSSCRIPT2 JSScript
58#define JS_GET_CLASS JS_GetClassFw
59JSBool JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval);
60//#define JSVAL_IS_OBJECT(retval) JSVAL_IS_OBJECT_OR_NULL_IMPL(retval)
61#ifndef IBOOL
62typedef int IBOOL;
63#endif
64typedef IBOOL _Bool;
65//typedef _Bool bool;
66
67
68
69extern "C" {
70#include <system.h>
71
72#include <display.h>
73#include <internal.h>
74
75//#include <libFreeWRL.h>
76//#include <list.h>
77//
78//#include "../vrml_parser/Structs.h"
79#include "../vrml_parser/CRoutes.h"
80#include "../opengl/OpenGL_Utils.h"
81//#include "../main/headers.h"
82#include "../main/ProdCon.h"
83#include "../scenegraph/RenderFuncs.h"
84//#include "../vrml_parser/CParseGeneral.h"
85//#include "../scenegraph/Vector.h"
86//#include "../vrml_parser/CFieldDecls.h"
87//#include "../vrml_parser/CParseParser.h"
88//#include "../vrml_parser/CParseLexer.h"
89//#include "../vrml_parser/CParse.h"
90//#include "../main/Snapshot.h"
91//#include "../scenegraph/Collision.h"
92//#include "../scenegraph/quaternion.h"
93//#include "../scenegraph/Viewer.h"
94void getCurrentSpeed();
95//#include "../x3d_parser/Bindable.h"
96//#include "../input/EAIHeaders.h" /* for implicit declarations */
97#include "../ui/common.h"
98
99
100#include "JScript.h"
101#include "CScripts.h"
102#include "fieldSet.h"
103#include "jsNative.h"
104
105struct X3D_Anchor* get_EAIEventsIn_AnchorNode();
106
107//ComonentInfo{
108//String name;
109//Numeric level;
110//String Title;
111//String providerUrl;
112//}
113int capabilitiesHandler_getTableLength(int* table);
114int capabilitiesHandler_getComponentLevel(int *table, int comp);
115int capabilitiesHandler_getProfileLevel(int prof);
116const int *capabilitiesHandler_getProfileComponent(int prof);
117const int *capabilitiesHandler_getCapabilitiesTable();
118typedef struct intTableIndex{
119 int* table;
120 int index;
121} *IntTableIndex;
122
123//X3DRoute{
124//SFNode sourceNode;
125//String sourceField;
126//SFNode destinationNode;
127//String destinationField;
128//}
129struct CRStruct *getCRoutes();
130int getCRouteCount();
131
132struct X3D_Node* broto_search_DEFname(struct X3D_Proto* context, const char* name);
133struct X3D_Node* broto_search_ALLnames(struct X3D_Proto* context, const char* name, int* source);
134void remove_node_from_parents_children(struct X3D_Node* node);
135int remove_broto_node(struct X3D_Proto* context, struct X3D_Node* node);
136void remove_node_from_def_list(struct X3D_Proto* ec, struct X3D_Node* node, char* defname) {
137 if (ec->__DEFnames) {
138 struct brotoDefpair* bd;
139 for (int i = 0; i < vectorSize((Vector*)ec->__DEFnames); i++) {
140 bd = vector_get_ptr(struct brotoDefpair, (Vector*)ec->__DEFnames, i);
141 if (!strcmp(bd->name, defname)) {
142 node = bd->node;
143 //remove DEF name mapping:
144 vector_remove_elem(struct brotoDefpair, (Vector*)ec->__DEFnames, i);
145 break;
146 }
147 }
148 }
149
150}
151void* addDeleteRoute0(void* ec, const char* callingFunc, struct X3D_Node* fromNode, const char* sfromField, struct X3D_Node* toNode, const char* stoField);
152void update_weakRoutes(struct X3D_Proto* context);
153
154} //extern "C"
155
156#include "jsUtils_sm.h"
157#include "jsVRMLClasses_sm.h"
158#include "jsVRMLBrowser_sm.h"
159
160// the JSVAL_IS_INT wasn't giving me the tinyid for switch-casing on property like it used to
161// this function will take the string field name and get the tinyid, so old switch-case can continue
162int lookup_tinyid(char* fieldname, JSPropertySpec* properties) {
163 JSPropertySpec* p = &properties[0];
164 int i = 0;
165 int index = -1;
166 while (p->name) {
167 if (!strcmp(p->name, fieldname)) {
168 index = p->tinyid;
169 break;
170 }
171 i++;
172 p = &properties[i];
173 }
174 return index;
175}
176
177#define X3DBROWSER 1
178
179
180
181#ifndef X3DBROWSER
182#define SetPropertyStub JS_StrictPropertyStub
183#endif // ndef X3DBROWSER
184
185#ifdef X3DBROWSER
186JSBool
187BrowserGetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp);
188
189JSBool
190BrowserSetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp);
191#endif
192int jsrrunScript(JSContext *_context, JSObject *_globalObj, char *script, jsval *rval);
193/*
194//js 17 aka 186
195struct JSClass {
196 const char *name;
197 uint32_t flags;
198
199 // Mandatory non-null function pointer members.
200 JSPropertyOp addProperty;
201 JSPropertyOp delProperty;
202 JSPropertyOp getProperty;
203 JSStrictPropertyOp setProperty;
204 JSEnumerateOp enumerate;
205 JSResolveOp resolve;
206 JSConvertOp convert;
207 JSFinalizeOp finalize;
208
209 // Optionally non-null members start here.
210 JSCheckAccessOp checkAccess;
211 JSNative call;
212 JSHasInstanceOp hasInstance; // +
213 JSNative construct;
214 JSTraceOp trace;
215
216 void *reserved[40];
217};
218//js 185
219struct JSClass {
220 const char *name;
221 uint32 flags;
222
223 // Mandatory non-null function pointer members.
224 JSPropertyOp addProperty;
225 JSPropertyOp delProperty;
226 JSPropertyOp getProperty;
227 JSStrictPropertyOp setProperty;
228 JSEnumerateOp enumerate;
229 JSResolveOp resolve;
230 JSConvertOp convert;
231 JSFinalizeOp finalize;
232
233 // Optionally non-null members start here.
234 JSClassInternal reserved0; // -
235 JSCheckAccessOp checkAccess;
236 JSNative call;
237 JSNative construct;
238 JSXDRObjectOp xdrObject; //-
239 JSHasInstanceOp hasInstance; //changed place with construct
240 JSMarkOp mark; //changed from JSTraceOp
241
242 JSClassInternal reserved1;
243 void *reserved[19]; //-
244};
245*/
246
247#if JS_VERSION < 187
248#define JS_DeletePropertyStub JS_PropertyStub
249#endif
250
251
252//X3DConstants
253struct string_int {
254 char* c;
255 int i;
256};
257
258struct string_int lookup_X3DConstants[] = {
259 {"INITIALIZED_EVENT",1},
260 {"SHUTDOWN_EVENT",1},
261 {"CONNECTION_ERROR",1},
262 {"INITIALIZED_ERROR",1},
263 {"NOT_STARTED_STATE",1},
264 {"IN_PROGRESS_STATE",1},
265 {"COMPLETE_STATE",1},
266 {"FAILED_STATE",0},
267 {"SFBool",FIELDTYPE_SFBool},
268 {"MFBool",FIELDTYPE_MFBool},
269 {"MFInt32",FIELDTYPE_MFInt32},
270 {"SFInt32",FIELDTYPE_SFInt32},
271 {"SFFloat",FIELDTYPE_SFFloat},
272 {"MFFloat",FIELDTYPE_MFFloat},
273 {"SFDouble",FIELDTYPE_SFDouble},
274 {"MFDouble",FIELDTYPE_MFDouble},
275 {"SFTime",FIELDTYPE_SFTime},
276 {"MFTime",FIELDTYPE_MFTime},
277 {"SFNode",FIELDTYPE_SFNode},
278 {"MFNode",FIELDTYPE_MFNode},
279 {"SFVec2f",FIELDTYPE_SFVec2f},
280 {"MFVec2f",FIELDTYPE_MFVec2f},
281 {"SFVec3f",FIELDTYPE_SFVec3f},
282 {"MFVec3f",FIELDTYPE_MFVec3f},
283 {"SFVec3d",FIELDTYPE_SFVec3d},
284 {"MFVec3d",FIELDTYPE_MFVec3d},
285 {"SFRotation",FIELDTYPE_SFRotation},
286 {"MFRotation",FIELDTYPE_MFRotation},
287 {"SFColor",FIELDTYPE_SFColor},
288 {"MFColor",FIELDTYPE_MFColor},
289 {"SFImage",FIELDTYPE_SFImage},
290 // {"MFImage",FIELDTYPE_MFImage},
291 {"SFColorRGBA",FIELDTYPE_SFColorRGBA},
292 {"MFColorRGBA",FIELDTYPE_MFColorRGBA},
293 {"SFString",FIELDTYPE_SFString},
294 {"MFString",FIELDTYPE_MFString},
295 /*
296 {"X3DBoundedObject",},
297 {"X3DMetadataObject",},
298 {"X3DUrlObject",},
299 {"X3DTriggerNode",},
300 {"X3DInfoNode",},
301 {"X3DAppearanceNode",},
302 {"X3DAppearanceChildNode",},
303 {"X3DMaterialNode",},
304 {"X3DTextureNode",},
305 {"X3DTexture2DNode",},
306 {"X3DTexture3DNode",},
307 {"X3DTextureTransformNode",},
308 {"X3DGeometryNode",},
309 {"X3DGeometry3DNode",},
310 {"X3DCoordinateNode",},
311 {"X3DParametricGeometryNode",},
312 {"X3DGeometricPropertyNode",},
313 {"X3DColorNode",},
314 {"X3DProtoInstance",},
315 {"X3DNormalNode",},
316 {"X3DTextureCoordinateNode",},
317 {"X3DFontStyleNode",},
318 {"X3DGroupingNode ",},
319 {"X3DChildNode",},
320 {"X3DBindableNode",},
321 {"X3DBackgroundNode",},
322 {"X3DInterpolatorNode",},
323 {"X3DShapeNode",},
324 {"X3DScriptNode",},
325 {"X3DSensorNode",},
326 {"X3DEnvironmentalSensorNode",},
327 {"X3DLightNode",},
328 {"X3DNetworkSensorNode",},
329 {"X3DPointingDeviceSensorNode",},
330 {"X3DDragSensorNode",},
331 {"X3DKeyDeviceSensorNode",},
332 {"X3DSequencerNode",},
333 {"X3DTimeDependentNode",},
334 {"X3DSoundNode",},
335 {"X3DSoundSourceNode",},
336 {"X3DTouchSensorNode",},
337 */
338 {"inputOnly",PKW_inputOnly},
339 {"outputOnly",PKW_outputOnly},
340 {"inputOutput",PKW_inputOutput},
341 {"initializeOnly",PKW_initializeOnly},
342 {NULL,0}
343};
344
345struct string_int* lookup_string_int(struct string_int* table, const char* searchkey, int* index) {
346 int i;
347 //struct string_int *retval = NULL;
348 *index = -1;
349 if (!table) return NULL;
350 i = 0;
351 while (table[i].c) {
352 if (!strcmp(table[i].c, searchkey)) {
353 //found it
354 (*index) = i;
355 return &table[i];
356 }
357 i++;
358 }
359 return NULL;
360}
361JSBool
362X3DConstantsGetProperty(JSContext* cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp) {
363 JSObject* obj = *hobj.address();
364 jsid iid = *hiid.address();
365 jsval* vp = hvp.address();
366
367 int index;
368 JSString* _str;
369 char* str;
370 jsval rval;
371 jsval id;
372
373 if (!JS_IdToValue(cx, iid, &id)) {
374 printf("JS_IdToValue failed in X3DRouteGetProperty.\n");
375 return JS_FALSE;
376 }
377 if (JSVAL_IS_STRING(id)) {
378 str = (char*)JS_EncodeString(cx, JSVAL_TO_STRING(id));;
379 string_int* iret = lookup_string_int(lookup_X3DConstants, str, &index);
380 rval = INT_TO_JSVAL(iret->i);
381 JS_SET_RVAL(cx, vp, rval);
382 return JS_TRUE;
383 }
384 return JS_FALSE;
385}
386
387
388int len_constants() {
389 int len = (sizeof(lookup_X3DConstants) / sizeof(struct string_int)) - 1;
390 return len;
391}
392
393static JSClass X3DConstantsClass = {
394 "X3DConstants",
395 JSCLASS_HAS_PRIVATE,
396 JS_PropertyStub,
397 JS_DeletePropertyStub,
398 X3DConstantsGetProperty,
399 JS_StrictPropertyStub,
400 JS_EnumerateStub,
401 JS_ResolveStub,
402 JS_ConvertStub,
403 JS_FinalizeStub
404};
405
406//fieldDefinition
407
408static JSPropertySpec(FieldDefinitionProperties)[] = {
409 {"name", 0, JSPROP_ENUMERATE}, //string
410 {"accessType", 1, JSPROP_ENUMERATE}, //numeric / enumerated inputOnly..
411 {"dataType", 2, JSPROP_ENUMERATE}, //numeric / enumerated SFBool etc
412 {0}
413};
414
415JSBool
416FieldDefinitionGetProperty(JSContext* cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp) {
417 JSObject* obj = *hobj.address();
418 jsid iid = *hiid.address();
419 jsval* vp = hvp.address();
420
421 struct ProtoFieldDecl* ptr;
422 int _index;
423 JSString* _str;
424 jsval rval;
425 jsval id;
426
427 UNUSED(rval); // compiler warning mitigation
428
429
430 if (!JS_IdToValue(cx, iid, &id)) {
431 printf("JS_IdToValue failed in X3DRouteGetProperty.\n");
432 return JS_FALSE;
433 }
434
435 if ((ptr = (struct ProtoFieldDecl*)JS_GetPrivateFw(cx, obj)) == NULL) {
436 printf("JS_GetPrivate failed in FieldDefinitionGetProperty.\n");
437 return JS_FALSE;
438 }
439 struct X3D_Proto* ec = (struct X3D_Proto*)JS_GetContextPrivate(cx);
440
441
442 int index = -1;
443 if (JSVAL_IS_INT(id))
444 index = JSVAL_TO_INT(id);
445 else
446 index = lookup_tinyid(JS_EncodeString(cx, JSVAL_TO_STRING(id)), FieldDefinitionProperties);
447 switch (index) {
448 case 0://name (string)
449 {
450 JSString* _str;
451 _str = JS_NewStringCopyZ(cx,ptr->cname);
452 rval = STRING_TO_JSVAL(_str);
453
454 JS_SET_RVAL(cx, vp, rval);
455 break;
456 }
457 case 1://accessType enumerant ie inputOnly
458 {
459
460 rval = INT_TO_JSVAL(ptr->mode);
461 JS_SET_RVAL(cx, vp, rval);
462
463 break;
464 }
465 case 2://dataType enumerant ie SFBool
466 {
467 rval = INT_TO_JSVAL(ptr->type);
468 JS_SET_RVAL(cx, vp, rval);
469 break;
470 }
471 }
472
473 return JS_TRUE;
474}
475JSBool
476FieldDefinitionSetProperty(JSContext* cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp) {
477 JSObject* obj = *hobj.address();
478 jsid iid = *hiid.address();
479 jsval* vp = hvp.address();
480 //can I, should I force it to read-only this way?
481 return JS_FALSE;
482}
483
484static JSClass FieldDefinitionClass = {
485 "FieldDefinition",
486 JSCLASS_HAS_PRIVATE,
487 JS_PropertyStub,
488 JS_DeletePropertyStub,
489 FieldDefinitionGetProperty,
490 FieldDefinitionSetProperty,
491 JS_EnumerateStub,
492 JS_ResolveStub,
493 JS_ConvertStub,
494 JS_FinalizeStub
495};
496
497//fieldDefinitionArray
498
499static JSPropertySpec(FieldDefinitionArrayProperties)[] = {
500 {"length", -1, JSPROP_READONLY | JSPROP_SHARED | JSPROP_PERMANENT}, //JSPROP_ENUMERATE},
501 {0}
502};
503
504JSBool
505FieldDefinitionArrayGetProperty(JSContext* cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp) {
506 JSObject* obj = *hobj.address();
507 jsid iid = *hiid.address();
508 jsval* vp = hvp.address();
509
510 struct ProtoDefinition* pd;
511 jsval rval;
512 jsval id;
513
514 UNUSED(rval); // compiler warning mitigation
515
516
517 if (!JS_IdToValue(cx, iid, &id)) {
518 printf("JS_IdToValue failed in FieldDefinitionArrayGetProperty.\n");
519 return JS_FALSE;
520 }
521
522 if ((pd = (struct ProtoDefinition*)JS_GetPrivateFw(cx, obj)) == NULL) {
523 printf("JS_GetPrivate failed in ProtoDeclarationArrayGetProperty.\n");
524 return JS_FALSE;
525 }
526 struct X3D_Proto* ec = (struct X3D_Proto*)JS_GetContextPrivate(cx);
527
528 int index = -1;
529 if (JSVAL_IS_INT(id))
530 index = JSVAL_TO_INT(id);
531 else
532 index = lookup_tinyid(JS_EncodeString(cx, JSVAL_TO_STRING(id)), FieldDefinitionArrayProperties);
533 if (index == -1) {
534 int _length = vectorSize(pd->iface);
535 JS_SET_RVAL(cx, vp, INT_TO_JSVAL(_length));
536 }
537 else if (index > -1 && index < vectorSize(pd->iface))
538 {
539 JSObject* _obj;
540 struct ProtoFieldDecl* pfield = vector_get(struct ProtoFieldDecl*, pd->iface, index);
541
542 _obj = JS_NewObject(cx, &FieldDefinitionClass, NULL, obj);
543 if (0) if (!JS_DefineProperties(cx, _obj, FieldDefinitionProperties)) {
544 printf("JS_DefineProperties failed in FieldDefinitionProperties.\n");
545 return JS_FALSE;
546 }
547
548 if (!JS_SetPrivateFw(cx, _obj, (void*)pfield)) {
549 printf("JS_SetPrivate failed in FieldDefinitionArray.\n");
550 return JS_FALSE;
551 }
552
553 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(_obj));
554
555 }
556
557 return JS_TRUE;
558}
559JSBool
560FieldDefinitionArraySetProperty(JSContext* cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp) {
561 JSObject* obj = *hobj.address();
562 jsid iid = *hiid.address();
563 jsval* vp = hvp.address();
564 //can I, should I force it to read-only this way?
565 return JS_FALSE;
566}
567
568
569static JSClass FieldDefinitionArrayClass = {
570 "FieldDefinitionArray",
571 JSCLASS_HAS_PRIVATE,
572 JS_PropertyStub,
573 JS_DeletePropertyStub,
574 FieldDefinitionArrayGetProperty,
575 FieldDefinitionArraySetProperty,
576 JS_EnumerateStub,
577 JS_ResolveStub,
578 JS_ConvertStub,
579 JS_FinalizeStub
580};
581
582
583//ProtoDeclaration
584JSBool
585ProtoDeclaration_newInstance(JSContext* cx, uintN argc, jsval* vp) {
586 JSObject* obj = JS_THIS_OBJECT(cx, vp);
587 jsval* argv = JS_ARGV(cx, vp);
588 jsval rval;
589
590 UNUSED(argc);
591 UNUSED(argv);
592
593
594 struct X3D_Proto* ptr;
595 char str[200];
596 JSString* _str;
597 if ((ptr = (struct X3D_Proto*)JS_GetPrivateFw(cx, obj)) == NULL) {
598 printf("in ProtoDeclaration_newInstance() - not a Native\n");
599 return JS_FALSE;
600 }
601 struct X3D_Proto* ec = (struct X3D_Proto*)JS_GetContextPrivate(cx);
602 struct X3D_Proto* proto = ptr;
603
604 struct ProtoDefinition* pd;
605 pd = (struct ProtoDefinition*)proto->__protoDef;
606
607 struct X3D_Node* dest = X3D_NODE(brotoInstance(X3D_PROTO(X3D_PROTO(proto)->__prototype), ciflag_get(ec->__protoFlags, 0)));
608
609 AnyNative* nany = MALLOC(AnyNative*, sizeof(AnyNative));
610 memset(nany, 0, sizeof(AnyNative));
611 nany->type = FIELDTYPE_SFNode;
612 nany->v = MALLOC(union anyVrml*, sizeof(union anyVrml));
613 memset(nany->v, 0, sizeof(union anyVrml));
614
615 nany->v->sfnode = dest;
616
617 JSObject* _obj = JS_NewObject(cx, &SFNodeClass, NULL, obj);
618 if (0) if (!JS_DefineProperties(cx, _obj, SFNodeProperties)) {
619 printf("JS_DefineProperties failed in Route sourceNode.\n");
620 return JS_FALSE;
621 }
622 if (0) if (!JS_DefineFunctions(cx, _obj, SFNodeFunctions)) {
623 printf("JS_DefineFunctions failed in Route sourceNode.\n");
624 return JS_FALSE;
625 }
626
627 if (!JS_SetPrivateFw(cx, _obj, (void*)nany)) {
628 printf("JS_SetPrivate failed in Route sourceNode.\n");
629 return JS_FALSE;
630 }
631
632 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(_obj));
633
634 return JS_TRUE;
635
636}
637JSFunctionSpec(ProtoDeclarationFunctions)[] = {
638 {"newInstance", ProtoDeclaration_newInstance, 0},
639 {0}
640};
641
642static JSPropertySpec(ProtoDeclarationProperties)[] = {
643 {"name", 0, JSPROP_ENUMERATE}, //string
644 {"fields", 1, JSPROP_ENUMERATE}, //FieldDefinitionArray
645 {"isExternProto", 2, JSPROP_ENUMERATE}, //boolea
646 {0}
647};
648
649JSBool
650ProtoDeclarationGetProperty(JSContext* cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp) {
651 JSObject* obj = *hobj.address();
652 jsid iid = *hiid.address();
653 jsval* vp = hvp.address();
654
655 struct X3D_Proto* ptr;
656 int _index;
657 JSString* _str;
658 jsval rval;
659 jsval id;
660
661 UNUSED(rval); // compiler warning mitigation
662
663
664 if (!JS_IdToValue(cx, iid, &id)) {
665 printf("JS_IdToValue failed in ProtoDeclarationGetProperty.\n");
666 return JS_FALSE;
667 }
668
669 if ((ptr = (struct X3D_Proto*)JS_GetPrivateFw(cx, obj)) == NULL) {
670 printf("JS_GetPrivate failed in ProtoDeclarationGetProperty.\n");
671 return JS_FALSE;
672 }
673 struct X3D_Proto* ec = (struct X3D_Proto*)JS_GetContextPrivate(cx);
674 struct X3D_Proto* proto = ptr;
675 struct ProtoDefinition* pd;
676 pd = (struct ProtoDefinition*)proto->__protoDef;
677
678 int index = -1;
679 if (JSVAL_IS_INT(id))
680 index = JSVAL_TO_INT(id);
681 else
682 index = lookup_tinyid(JS_EncodeString(cx, JSVAL_TO_STRING(id)), ProtoDeclarationProperties);
683 switch (index) {
684 case 0://name (string)
685 {
686 //Q. where do we hide the name of the proto type?
687 //see BOOL isAvailableBroto(const char *pname, struct X3D_Proto* currentContext, struct X3D_Proto **proto)
688
689 JSString* _str;
690 _str = JS_NewStringCopyZ(cx, pd->protoName);
691 rval = STRING_TO_JSVAL(_str);
692
693 JS_SET_RVAL(cx, vp, rval);
694 break;
695 }
696 case 1://fields (FieldDefinitionArray)
697 {
698 JSObject* _obj;
699 _obj = JS_NewObject(cx, &FieldDefinitionArrayClass, NULL, obj);
700 if (0) if (!JS_DefineProperties(cx, _obj, FieldDefinitionArrayProperties)) {
701 printf("JS_DefineProperties failed in FieldDefinitionArrayProperties.\n");
702 return JS_FALSE;
703 }
704
705 if (!JS_SetPrivateFw(cx, _obj, (void*)pd)) {
706 printf("JS_SetPrivate failed in ProtoDeclarationArray.\n");
707 return JS_FALSE;
708 }
709
710 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(_obj));
711
712 break;
713 }
714 case 2://isExternProto (boolean)
715 {
716 char flagInstance, flagExtern;
717 flagInstance = ciflag_get(proto->__protoFlags, 2);
718 flagExtern = ciflag_get(proto->__protoFlags, 3);
719
720 JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(flagExtern == 0 ? false : true));
721 break;
722 }
723 }
724
725 return JS_TRUE;
726}
727JSBool
728ProtoDeclarationSetProperty(JSContext* cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp) {
729 JSObject* obj = *hobj.address();
730 jsid iid = *hiid.address();
731 jsval* vp = hvp.address();
732 //can I, should I force it to read-only this way?
733 return JS_FALSE;
734}
735
736static JSClass ProtoDeclarationClass = {
737 "ProtoDeclaration",
738 JSCLASS_HAS_PRIVATE,
739 JS_PropertyStub,
740 JS_DeletePropertyStub,
741 ProtoDeclarationGetProperty,
742 ProtoDeclarationSetProperty,
743 JS_EnumerateStub,
744 JS_ResolveStub,
745 JS_ConvertStub,
746 JS_FinalizeStub
747};
748
749//ProtoDeclarationArray{
750
751static JSPropertySpec(ProtoDeclarationArrayProperties)[] = {
752 {"length", -1, JSPROP_READONLY | JSPROP_SHARED | JSPROP_PERMANENT}, //JSPROP_ENUMERATE},
753 {0}
754};
755
756JSBool
757ProtoDeclarationArrayGetProperty(JSContext* cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp) {
758 JSObject* obj = *hobj.address();
759 jsid iid = *hiid.address();
760 jsval* vp = hvp.address();
761
762 Stack *protos;
763 jsval rval;
764 jsval id;
765
766 UNUSED(rval); // compiler warning mitigation
767
768
769 if (!JS_IdToValue(cx, iid, &id)) {
770 printf("JS_IdToValue failed in ProtoDeclarationArrayGetProperty.\n");
771 return JS_FALSE;
772 }
773
774 if ((protos = (Stack*)JS_GetPrivateFw(cx, obj)) == NULL) {
775 printf("JS_GetPrivate failed in ProtoDeclarationArrayGetProperty.\n");
776 return JS_FALSE;
777 }
778 struct X3D_Proto* ec = (struct X3D_Proto*)JS_GetContextPrivate(cx);
779
780 int index = -1;
781 if (JSVAL_IS_INT(id))
782 index = JSVAL_TO_INT(id);
783 else
784 index = lookup_tinyid(JS_EncodeString(cx, JSVAL_TO_STRING(id)), ProtoDeclarationArrayProperties);
785 if (index == -1) {
786 int _length = vectorSize(protos);
787 JS_SET_RVAL(cx, vp, INT_TO_JSVAL(_length));
788 }
789 else if (index > -1 && index < vectorSize(protos))
790 {
791 JSObject* _obj;
792 _obj = JS_NewObject(cx, &ProtoDeclarationClass, NULL, obj);
793 if (0) if (!JS_DefineProperties(cx, _obj, ProtoDeclarationProperties)) {
794 printf("JS_DefineProperties failed in ProtoDeclarationProperties.\n");
795 return JS_FALSE;
796 }
797 struct X3D_Proto* proto = vector_get(struct X3D_Proto*,protos,index);
798 if (!JS_SetPrivateFw(cx, _obj, (void*)proto)) {
799 printf("JS_SetPrivate failed in ProtoDeclarationArray.\n");
800 return JS_FALSE;
801 }
802
803 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(_obj));
804
805 }
806
807 return JS_TRUE;
808}
809JSBool
810ProtoDeclarationArraySetProperty(JSContext* cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp) {
811 JSObject* obj = *hobj.address();
812 jsid iid = *hiid.address();
813 jsval* vp = hvp.address();
814 //can I, should I force it to read-only this way?
815 return JS_FALSE;
816}
817
818
819static JSClass ProtoDeclarationArrayClass = {
820 "ProtoDeclarationArray",
821 JSCLASS_HAS_PRIVATE,
822 JS_PropertyStub,
823 JS_DeletePropertyStub,
824 ProtoDeclarationArrayGetProperty,
825 ProtoDeclarationArraySetProperty,
826 JS_EnumerateStub,
827 JS_ResolveStub,
828 JS_ConvertStub,
829 JS_FinalizeStub
830};
831
832
833
834
835//Q. is this a true sharable static?
836static JSClass BrowserClass = {
837 "Browser",
838 JSCLASS_HAS_PRIVATE,
839 JS_PropertyStub,
840 JS_DeletePropertyStub,
841#ifdef X3DBROWSER
842 BrowserGetProperty, //JS_PropertyStub,
843 BrowserSetProperty, //JS_StrictPropertyStub,
844#else
845 JS_PropertyStub,
846 SetPropertyStub,
847#endif
848
849 JS_EnumerateStub,
850 JS_ResolveStub,
851 JS_ConvertStub,
852 JS_FinalizeStub
853};
854
855static JSBool doVRMLRoute(JSContext *context, JSObject *obj, uintN argc, jsval *argv, const char *browserFunc);
856
857static JSFunctionSpec (BrowserFunctions)[] = {
858 {"getName", VrmlBrowserGetName, 0},
859 {"getVersion", VrmlBrowserGetVersion, 0},
860 {"getCurrentSpeed", VrmlBrowserGetCurrentSpeed, 0},
861 {"getCurrentFrameRate", VrmlBrowserGetCurrentFrameRate, 0},
862 {"getWorldURL", VrmlBrowserGetWorldURL, 0},
863 {"replaceWorld", VrmlBrowserReplaceWorld, 0},
864 {"loadURL", VrmlBrowserLoadURL, 0},
865 {"setDescription", VrmlBrowserSetDescription, 0},
866 {"createVrmlFromString", VrmlBrowserCreateVrmlFromString, 0},
867 {"createVrmlFromURL", VrmlBrowserCreateVrmlFromURL, 0},
868 {"createX3DFromString", VrmlBrowserCreateX3DFromString, 0},
869 {"createX3DFromURL", VrmlBrowserCreateVrmlFromURL, 0},
870 {"addRoute", VrmlBrowserAddRoute, 0},
871 {"deleteRoute", VrmlBrowserDeleteRoute, 0},
872 {"print", VrmlBrowserPrint, 0},
873 {"println", VrmlBrowserPrintln, 0},
874#ifdef X3DBROWSER
875 //{"replaceWorld", X3dBrowserReplaceWorld, 0}, //conflicts - X3DScene vs MFNode parameter - could detect?
876 //{"createX3DFromString", X3dBrowserCreateX3DFromString, 0}, //conflicts but above verion shouldn't be above, or could detect?
877 //{"createX3DFromURL", X3dBrowserCreateVrmlFromURL, 0}, //conflicts but above version shouldn't be above, or could detect?
878 //{importDocument, X3dBrowserImportDocument, 0), //not sure we need/want this, what does it do?
879 //{getRenderingProperty, X3dGetRenderingProperty, 0},
880 //{addBrowserListener, X3dAddBrowserListener, 0},
881 //{removeBrowserListener, X3dRemoveBrowserListener, 0},
882#endif
883 {0}
884};
885#ifdef X3DBROWSER
886
887/* ProfileInfo, ProfileInfoArray, ComponentInfo, ComponentInfoArray
888 I decided to do these as thin getter wrappers on the bits and pieces defined
889 in Structs.h, GeneratedCode.c and capabilitiesHandler.c
890 The Array types return the info type wrapper with private native member == index into
891 the native array.
892*/
893
894
895JSBool
896ComponentInfoGetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp){
897 JSObject *obj = *hobj.address();
898 jsid iid = *hiid.address();
899 jsval *vp = hvp.address();
900
901
902 IntTableIndex ptr;
903 int _index, *_table, _nameIndex;
904 jsval rval;
905 jsval id;
906
907 UNUSED(rval); // compiler warning mitigation
908
909
910 if (!JS_IdToValue(cx,iid,&id)) {
911 printf("JS_IdToValue failed in ComponentInfoGetProperty.\n");
912 return JS_FALSE;
913 }
914
915 if ((ptr = (IntTableIndex)JS_GetPrivateFw(cx, obj)) == NULL) {
916 printf( "JS_GetPrivate failed in ExecutionContextGetProperty.\n");
917 return JS_FALSE;
918 }
919 _index = ptr->index;
920 _table = ptr->table;
921//extern const char *COMPONENTS[];
922//extern const int COMPONENTS_COUNT;
923
924 if (JSVAL_IS_INT(id))
925 {
926 int index = JSVAL_TO_INT(id);
927 switch(index){
928 case 0://name
929 case 1://Title
930 _nameIndex = _table[2*_index];
931 JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,COMPONENTS[_nameIndex])));
932 break;
933 case 2://level
934 {
935 int level = capabilitiesHandler_getComponentLevel(_table,_index);
936 JS_SET_RVAL(cx,vp,INT_TO_JSVAL(level));
937 }
938 break;
939 case 3://providerUrl
940 JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,"freewrl.sourceforge.net")));
941 break;
942 }
943 }
944 return JS_TRUE;
945}
946JSBool
947ComponentInfoSetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp){
948 JSObject *obj = *hobj.address();
949 jsid iid = *hiid.address();
950 jsval *vp = hvp.address();
951 //can I, should I force it to read-only this way?
952 return JS_FALSE;
953}
954void
955ComponentInfoFinalize(JSContext *cx, JSObject *obj)
956{
957 IntTableIndex ptr;
958 if ((ptr = (IntTableIndex)JS_GetPrivateFw(cx, obj)) == NULL) {
959 return;
960 } else {
961 FREE_IF_NZ (ptr);
962 }
963}
964
965
966static JSClass ComponentInfoClass = {
967 "ComponentInfo",
968 JSCLASS_HAS_PRIVATE,
969 JS_PropertyStub,
970 JS_DeletePropertyStub,
971 ComponentInfoGetProperty,
972 ComponentInfoSetProperty,
973 JS_EnumerateStub,
974 JS_ResolveStub,
975 JS_ConvertStub,
976 JS_FinalizeStub, //ComponentInfoFinalize //JS_FinalizeStub
977};
978
979static JSPropertySpec (ComponentInfoProperties)[] = {
980 //executionContext
981 {"name", 0, JSPROP_ENUMERATE}, //"Core"
982 {"title", 1, JSPROP_ENUMERATE}, //"Core"
983 {"level", 2, JSPROP_ENUMERATE}, //4
984 {"providerUrl", 3, JSPROP_ENUMERATE}, //"freewrl.sourceforge.net"
985 {0}
986};
987
988
989//ComponentInfoArray{
990//numeric length;
991//ComponentInfo [integer index];
992//}
993static JSPropertySpec(ComponentInfoArrayProperties)[] = {
994 {"length", -1, JSPROP_READONLY | JSPROP_SHARED | JSPROP_PERMANENT}, //JSPROP_ENUMERATE},
995 {0}
996};
997
998JSBool
999ComponentInfoArrayGetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp){
1000 JSObject *obj = *hobj.address();
1001 jsid iid = *hiid.address();
1002 jsval *vp = hvp.address();
1003
1004 int *_table;
1005 jsval rval;
1006 jsval id;
1007
1008 UNUSED(rval); // compiler warning mitigation
1009
1010
1011 if (!JS_IdToValue(cx,iid,&id)) {
1012 printf("JS_IdToValue failed in ComponentInfoArrayGetProperty.\n");
1013 return JS_FALSE;
1014 }
1015
1016 if ((_table = (int *)JS_GetPrivateFw(cx, obj)) == NULL) {
1017 printf( "JS_GetPrivate failed in ComponentInfoGetProperty.\n");
1018 return JS_FALSE;
1019 }
1020
1021 int index = -1;
1022 if (JSVAL_IS_INT(id))
1023 index = JSVAL_TO_INT(id);
1024 else
1025 index = lookup_tinyid(JS_EncodeString(cx, JSVAL_TO_STRING(id)), ComponentInfoArrayProperties);
1026 if(index == -1){
1027//extern const char *COMPONENTS[];
1028//extern const int COMPONENTS_COUNT;
1029
1030 int _length = capabilitiesHandler_getTableLength(_table); //COMPONENTS_COUNT;
1031 JS_SET_RVAL(cx,vp,INT_TO_JSVAL(_length));
1032 }else if(index > -1 && index < COMPONENTS_COUNT )
1033 {
1034 JSObject *_obj;
1035 IntTableIndex tableindex = (IntTableIndex)MALLOC(void *, sizeof(struct intTableIndex));
1036 //int* _index = MALLOC(void *, sizeof(int));
1037 _obj = JS_NewObject(cx,&ComponentInfoClass,NULL,obj);
1038 tableindex->index = index;
1039 tableindex->table = _table;
1040 if(0) if (!JS_DefineProperties(cx, _obj, ComponentInfoProperties)) {
1041 printf( "JS_DefineProperties failed in ComponentInfoProperties.\n");
1042 return JS_FALSE;
1043 }
1044
1045 if (!JS_SetPrivateFw(cx, _obj, (void*)tableindex)) {
1046 printf( "JS_SetPrivate failed in ComponentInfoArray.\n");
1047 return JS_FALSE;
1048 }
1049
1050 JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
1051
1052 }
1053
1054 return JS_TRUE;
1055}
1056JSBool
1057ComponentInfoArraySetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp){
1058 JSObject *obj = *hobj.address();
1059 jsid iid = *hiid.address();
1060 jsval *vp = hvp.address();
1061 //can I, should I force it to read-only this way?
1062 return JS_FALSE;
1063}
1064
1065
1066static JSClass ComponentInfoArrayClass = {
1067 "ComponentInfoArray",
1068 JSCLASS_HAS_PRIVATE,
1069 JS_PropertyStub,
1070 JS_DeletePropertyStub,
1071 ComponentInfoArrayGetProperty,
1072 ComponentInfoArraySetProperty,
1073 JS_EnumerateStub,
1074 JS_ResolveStub,
1075 JS_ConvertStub,
1076 JS_FinalizeStub
1077};
1078
1079
1080//ProfileInfo{
1081//String name;
1082//Numeric level;
1083//String Title;
1084//String providerUrl;
1085//ComonentInfoArray components;
1086//}
1087
1088JSBool
1089ProfileInfoGetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp){
1090 JSObject *obj = *hobj.address();
1091 jsid iid = *hiid.address();
1092 jsval *vp = hvp.address();
1093
1094 int *ptr;
1095 int _index;
1096 jsval rval;
1097 jsval id;
1098
1099 UNUSED(rval); // compiler warning mitigation
1100
1101 if (!JS_IdToValue(cx,iid,&id)) {
1102 printf("JS_IdToValue failed in ProfileInfoGetProperty.\n");
1103 return JS_FALSE;
1104 }
1105
1106 if ((ptr = (int *)JS_GetPrivateFw(cx, obj)) == NULL) {
1107 printf( "JS_GetPrivate failed in ProfileInfoGetProperty.\n");
1108 return JS_FALSE;
1109 }
1110 _index = *ptr;
1111//extern const char *PROFILES[];
1112//extern const int PROFILES_COUNT;
1113
1114 if (JSVAL_IS_INT(id))
1115 {
1116 int index = JSVAL_TO_INT(id);
1117 switch(index){
1118 case 0://name
1119 case 1://Title
1120 JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,PROFILES[_index])));
1121 break;
1122 case 2://level
1123 {
1124 int level = capabilitiesHandler_getProfileLevel(_index);
1125 JS_SET_RVAL(cx,vp,INT_TO_JSVAL(level));
1126
1127 }
1128 break;
1129 case 3://providerUrl
1130 JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,"freewrl.sourceforge.net")));
1131 break;
1132 case 4://components ComponentInfoArray
1133 {
1134 const int *_table = capabilitiesHandler_getProfileComponent(_index);
1135 JSObject *_obj;
1136 //malloc private not needed
1137 _obj = JS_NewObject(cx,&ComponentInfoArrayClass,NULL,obj);
1138 if(0)if (!JS_DefineProperties(cx, _obj, ComponentInfoArrayProperties)) {
1139 printf( "JS_DefineProperties failed in ComponentInfoArrayProperties.\n");
1140 return JS_FALSE;
1141 }
1142
1143 if (!JS_SetPrivateFw(cx, _obj, (void*)_table)) {
1144 printf( "JS_SetPrivate failed in ComponentInfoArray.\n");
1145 return JS_FALSE;
1146 }
1147 JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
1148 }
1149 break;
1150 }
1151 }
1152 return JS_TRUE;
1153}
1154JSBool
1155ProfileInfoSetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp){
1156 JSObject *obj = *hobj.address();
1157 jsid iid = *hiid.address();
1158 jsval *vp = hvp.address();
1159
1160 //can I, should I force it to read-only this way?
1161 return JS_FALSE;
1162}
1163
1164static JSClass ProfileInfoClass = {
1165 "ProfileInfo",
1166 JSCLASS_HAS_PRIVATE,
1167 JS_PropertyStub,
1168 JS_DeletePropertyStub,
1169 ProfileInfoGetProperty,
1170 ProfileInfoSetProperty,
1171 JS_EnumerateStub,
1172 JS_ResolveStub,
1173 JS_ConvertStub,
1174 JS_FinalizeStub
1175};
1176
1177static JSPropertySpec (ProfileInfoProperties)[] = {
1178 //executionContext
1179 {"name", 0, JSPROP_ENUMERATE},
1180 {"Title", 1, JSPROP_ENUMERATE},
1181 {"level", 2, JSPROP_ENUMERATE},
1182 {"providerUrl", 3, JSPROP_ENUMERATE},
1183 {"components", 4, JSPROP_ENUMERATE},
1184 {0}
1185};
1186
1187//ProfileInfoArray{
1188//numeric length;
1189//ProfileInfo [integer index];
1190//}
1191static JSPropertySpec(ProfileInfoArrayProperties)[] = {
1192 {"length", -1, JSPROP_READONLY | JSPROP_SHARED | JSPROP_PERMANENT}, //JSPROP_ENUMERATE},
1193 {0}
1194};
1195
1196JSBool
1197ProfileInfoArrayGetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp){
1198 JSObject *obj = *hobj.address();
1199 jsid iid = *hiid.address();
1200 jsval *vp = hvp.address();
1201
1202 jsval rval;
1203 jsval id;
1204
1205 UNUSED(rval); // compiler warning mitigation
1206
1207
1208 if (!JS_IdToValue(cx,iid,&id)) {
1209 printf("JS_IdToValue failed in ProfileInfoArrayGetProperty.\n");
1210 return JS_FALSE;
1211 }
1212
1213 int index = -1;
1214 if (JSVAL_IS_INT(id))
1215 index = JSVAL_TO_INT(id);
1216 else
1217 index = lookup_tinyid(JS_EncodeString(cx, JSVAL_TO_STRING(id)), ProfileInfoArrayProperties);
1218 if (index == -1) {
1219 int _length = PROFILES_COUNT;
1220 JS_SET_RVAL(cx,vp,INT_TO_JSVAL(_length));
1221 }else
1222 //if(index < getNumberOfProfiles() )
1223 {
1224 JSObject *_obj;
1225 int* _index = (int*)MALLOC(void *, sizeof(int));
1226 _obj = JS_NewObject(cx,&ProfileInfoClass,NULL,obj);
1227 *_index = index;
1228 if (!JS_DefineProperties(cx, _obj, ProfileInfoProperties)) {
1229 printf( "JS_DefineProperties failed in ProfileInfoArray.\n");
1230 return JS_FALSE;
1231 }
1232
1233 if (!JS_SetPrivateFw(cx, _obj, (void*)_index)) {
1234 printf( "JS_SetPrivate failed in ProfileInfoArray.\n");
1235 return JS_FALSE;
1236 }
1237
1238 JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
1239 }
1240
1241 return JS_TRUE;
1242}
1243JSBool
1244ProfileInfoArraySetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp){
1245 JSObject *obj = *hobj.address();
1246 jsid iid = *hiid.address();
1247 jsval *vp = hvp.address();
1248
1249 //can I, should I force it to read-only this way?
1250 return JS_FALSE;
1251}
1252
1253
1254static JSClass ProfileInfoArrayClass = {
1255 "ProfileInfo",
1256 JSCLASS_HAS_PRIVATE,
1257 JS_PropertyStub,
1258 JS_DeletePropertyStub,
1259 ProfileInfoArrayGetProperty,
1260 ProfileInfoArraySetProperty,
1261 JS_EnumerateStub,
1262 JS_ResolveStub,
1263 JS_ConvertStub,
1264 JS_FinalizeStub
1265};
1266
1267char* lookup_brotoDefname(struct X3D_Proto* ec, struct X3D_Node* node);
1268JSBool
1269X3DRouteToString(JSContext* cx, uintN argc, jsval* vp) {
1270 JSObject* obj = JS_THIS_OBJECT(cx, vp);
1271 jsval* argv = JS_ARGV(cx, vp);
1272 jsval rval;
1273
1274 UNUSED(argc);
1275 UNUSED(argv);
1276
1277
1278 long long ptr;
1279 char str[200];
1280 JSString* _str;
1281 if ((ptr = (long long)JS_GetPrivateFw(cx, obj)) == NULL) {
1282 printf("in route.toString() - not a Native\n");
1283 return JS_FALSE;
1284 }
1285 int _index = ptr - 1;
1286 struct X3D_Proto *ec = (struct X3D_Proto*)JS_GetContextPrivate(cx);
1287 struct brotoRoute* route = vector_get(struct brotoRoute*, ec->__ROUTES, _index);
1288
1289 //getSpecificRoute(_index, &fromNode, &fromOffset, &toNode, &toOffset);
1290 char* fromName = lookup_brotoDefname(ec,route->from.node); // parser_getNameFromNode(route->from.node);
1291 char* toName = lookup_brotoDefname(ec,route->from.node); // parser_getNameFromNode(route->to.node);
1292 char *fromfield = findFIELDNAMESfromNodeOffset0(route->from.node, route->from.ifield);
1293 char *tofield = findFIELDNAMESfromNodeOffset0(route->to.node, route->to.ifield);
1294
1295 sprintf(str,"[ROUTE %s.%s TO %s.%s]", fromName, fromfield, toName, tofield);
1296 _str = JS_NewStringCopyZ(cx, str);
1297 rval = STRING_TO_JSVAL(_str);
1298
1299 JS_SET_RVAL(cx, vp, rval);
1300 return JS_TRUE;
1301
1302}
1303
1304JSFunctionSpec(X3DRouteFunctions)[] = {
1305 {"toString", X3DRouteToString, 0},
1306 {0}
1307};
1308
1309static JSPropertySpec(X3DRouteProperties)[] = {
1310 //executionContext
1311 {"sourceNode", 0, JSPROP_ENUMERATE},
1312 {"sourceField", 1, JSPROP_ENUMERATE},
1313 {"destinationNode", 2, JSPROP_ENUMERATE},
1314 {"destinationField", 3, JSPROP_ENUMERATE},
1315 {0}
1316};
1317
1318JSBool
1319X3DRouteGetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp){
1320 JSObject *obj = *hobj.address();
1321 jsid iid = *hiid.address();
1322 jsval *vp = hvp.address();
1323
1324 long long ptr;
1325 int _index;
1326 JSString *_str;
1327 jsval rval;
1328 struct X3D_Node *fromNode, *toNode;
1329 int fromOffset, toOffset;
1330 const char *fieldname;
1331 jsval id;
1332
1333 UNUSED(rval); // compiler warning mitigation
1334
1335
1336 if (!JS_IdToValue(cx,iid,&id)) {
1337 printf("JS_IdToValue failed in X3DRouteGetProperty.\n");
1338 return JS_FALSE;
1339 }
1340
1341 if ((ptr = (long long)JS_GetPrivateFw(cx, obj)) == NULL) {
1342 printf( "JS_GetPrivate failed in X3DRouteGetProperty.\n");
1343 return JS_FALSE;
1344 }
1345 _index = ptr - 1;
1346 struct X3D_Proto* ec = (struct X3D_Proto*)JS_GetContextPrivate(cx);
1347 struct brotoRoute* route = vector_get(struct brotoRoute*, ec->__ROUTES, _index);
1348
1349 //routes = getCRoutes();
1350 //route = routes[_index];
1351 //getSpecificRoute (_index,&fromNode, &fromOffset, &toNode, &toOffset);
1352 char* fromName = lookup_brotoDefname(ec,route->from.node); // parser_getNameFromNode(route->from.node);
1353 char* toName = lookup_brotoDefname(ec,route->to.node); // parser_getNameFromNode(route->to.node);
1354
1355 int index = -1;
1356 if (JSVAL_IS_INT(id))
1357 index = JSVAL_TO_INT(id);
1358 else
1359 index = lookup_tinyid(JS_EncodeString(cx, JSVAL_TO_STRING(id)), X3DRouteProperties);
1360 switch(index){
1361 case 0://sourceNode
1362 case 2://destinationNode
1363 //route.routeFromNode
1364 {
1365 JSObject *_obj;
1366 //SFNodeNative *sfnn = (SFNodeNative *)MALLOC(void *, sizeof(SFNodeNative));
1367 //memset(sfnn,0,sizeof(SFNodeNative)); //I don't know if I'm supposed to set something else dug9 aug5,2013
1368 AnyNative* nany = MALLOC(AnyNative*, sizeof(AnyNative));
1369 memset(nany, 0, sizeof(AnyNative));
1370 nany->type = FIELDTYPE_SFNode;
1371 nany->v = MALLOC(union anyVrml*, sizeof(union anyVrml));
1372 memset(nany->v, 0, sizeof(union anyVrml));
1373 if (index == 0)
1374 nany->v->sfnode = route->from.node; // fromNode;
1375 if (index == 2)
1376 nany->v->sfnode = route->to.node; // toNode;
1377
1378 _obj = JS_NewObject(cx,&SFNodeClass,NULL,obj);
1379 if(0) if (!JS_DefineProperties(cx, _obj, SFNodeProperties)) {
1380 printf( "JS_DefineProperties failed in Route sourceNode.\n");
1381 return JS_FALSE;
1382 }
1383 if(0) if (!JS_DefineFunctions(cx, _obj, SFNodeFunctions)) {
1384 printf( "JS_DefineFunctions failed in Route sourceNode.\n");
1385 return JS_FALSE;
1386 }
1387
1388 if (!JS_SetPrivateFw(cx, _obj, (void*)nany)) {
1389 printf( "JS_SetPrivate failed in Route sourceNode.\n");
1390 return JS_FALSE;
1391 }
1392
1393 JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
1394 }
1395 break;
1396
1397 case 1://sourceField
1398 fieldname = findFIELDNAMESfromNodeOffset0(route->from.node, route->from.ifield);
1399 _str = JS_NewStringCopyZ(cx,fieldname);
1400 JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(_str));
1401 break;
1402 case 3://destinationField
1403 fieldname = findFIELDNAMESfromNodeOffset0(route->to.node, route->to.ifield);
1404 _str = JS_NewStringCopyZ(cx,fieldname);
1405 JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(_str));
1406
1407 break;
1408 }
1409
1410 return JS_TRUE;
1411}
1412JSBool
1413X3DRouteSetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp){
1414 JSObject *obj = *hobj.address();
1415 jsid iid = *hiid.address();
1416 jsval *vp = hvp.address();
1417 //can I, should I force it to read-only this way?
1418 return JS_FALSE;
1419}
1420
1421static JSClass X3DRouteClass = {
1422 "X3DRoute",
1423 JSCLASS_HAS_PRIVATE,
1424 JS_PropertyStub,
1425 JS_DeletePropertyStub,
1426 X3DRouteGetProperty,
1427 X3DRouteSetProperty,
1428 JS_EnumerateStub,
1429 JS_ResolveStub,
1430 JS_ConvertStub,
1431 JS_FinalizeStub
1432};
1433
1434
1435
1436//ProfileInfoArray{
1437//numeric length;
1438//ProfileInfo [integer index];
1439//}
1440static JSPropertySpec(RouteArrayProperties)[] = {
1441 {"length", -1, JSPROP_READONLY | JSPROP_SHARED | JSPROP_PERMANENT}, //JSPROP_ENUMERATE},
1442 {0}
1443};
1444
1445JSBool
1446RouteArrayGetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp){
1447 JSObject *obj = *hobj.address();
1448 jsid iid = *hiid.address();
1449 jsval *vp = hvp.address();
1450
1451
1452 jsval rval;
1453 jsval id;
1454
1455 UNUSED(rval); //compiler warning mitigation
1456
1457
1458 if (!JS_IdToValue(cx,iid,&id)) {
1459 printf("JS_IdToValue failed in RouteArrayGetProperty.\n");
1460 return JS_FALSE;
1461 }
1462 struct X3D_Proto* ec;
1463 //ec = getExecutionContextFromCx(cx);
1464 ec = (struct X3D_Proto*)JS_GetContextPrivate(cx);
1465
1466 int index = -1;
1467 if (JSVAL_IS_STRING(id)) {
1468 char* field = (char*)JS_EncodeString(cx, JSVAL_TO_STRING(id));
1469 index = lookup_tinyid(field, RouteArrayProperties);
1470 //printf("ExecutionContextGetProperty %s %d\n", field, index);
1471 if (index == -1) {
1472 int _length = vectorSize(ec->__ROUTES); //getCRouteCount();
1473 JS_SET_RVAL(cx, vp, INT_TO_JSVAL(_length));
1474 }
1475 }
1476 else if (JSVAL_IS_INT(id)) {
1477 index = JSVAL_TO_INT(id);
1478 {
1479 JSObject *_obj;
1480 //int* _index = (int*) MALLOC(void *, sizeof(int));
1481 _obj = JS_NewObject(cx,&X3DRouteClass,NULL,obj);
1482 //*_index = index;
1483 if(0) if (!JS_DefineProperties(cx, _obj, X3DRouteProperties)) {
1484 printf( "JS_DefineProperties failed in RouteArray.\n");
1485 return JS_FALSE;
1486 }
1487 long long iindex = index+1; //instead of malloc and free wrapper for long, just send a longlong on x64
1488 if (!JS_SetPrivateFw(cx, _obj, (void*)iindex)) {
1489 printf( "JS_SetPrivate failed in RouteArray.\n");
1490 return JS_FALSE;
1491 }
1492
1493 JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
1494
1495 }
1496 }
1497 return JS_TRUE;
1498}
1499JSBool
1500RouteArraySetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp){
1501 JSObject *obj = *hobj.address();
1502 jsid iid = *hiid.address();
1503 jsval *vp = hvp.address();
1504 //can I, should I force it to read-only this way?
1505 return JS_FALSE;
1506}
1507
1508
1509static JSClass RouteArrayClass = {
1510 "RouteArray",
1511 JSCLASS_HAS_PRIVATE,
1512 JS_PropertyStub,
1513 JS_DeletePropertyStub,
1514 RouteArrayGetProperty,
1515 RouteArraySetProperty,
1516 JS_EnumerateStub,
1517 JS_ResolveStub,
1518 JS_ConvertStub,
1519 JS_FinalizeStub
1520};
1521
1522
1523static JSBool
1524X3DExecutionContext_createNode(JSContext* context, uintN argc, jsval* vp) {
1525 JSObject* obj = JS_NewObject(context, &SFNodeClass, NULL, NULL);
1526 ADD_ROOT(cx, obj)
1527
1528 jsval* argv = JS_ARGV(context, vp);
1529 const char* _c_format = "S";
1530 JSString* js_c;
1531
1532 char* _c;
1533
1534 /* for the return of the nodes */
1535 struct X3D_Group* retGroup;
1536 struct Multi_Node* newHandle = NULL;
1537
1538 if (argc == 1 &&
1539 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
1540 _c = JS_EncodeString(context, js_c);
1541#ifdef JSVERBOSE
1542 printf("X3DExecutionContext_createNode: obj = %u, str = \"%s\"\n",
1543 obj, _c);
1544#endif
1545 {
1546 int ctype;
1547 //check builtins
1548 ctype = findFieldInNODES(_c);
1549 struct X3D_Node* node = NULL;
1550 struct X3D_Proto* ec;
1551 //ec = getExecutionContextFromCx(cx);
1552 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
1553
1554 if (ctype > -1) {
1555 node = (struct X3D_Node*)createNewX3DNode(ctype);
1556 add_node_to_broto_context(ec, node);
1557
1558 AnyNative* lhs;
1559 if ((lhs = (AnyNative*)AnyNativeNew(FIELDTYPE_SFNode, NULL, NULL)) == NULL) {
1560 printf("AnyNativeNew failed in SFNodeConstr.\n");
1561 return JS_FALSE;
1562 }
1563 if (!JS_SetPrivateFw(context, obj, lhs)) {
1564 printf("JS_SetPrivate failed in SFNodeConstr.\n");
1565 return JS_FALSE;
1566 }
1567 //lhs->valueChanged = NULL;
1568 lhs->v->sfnode = node;
1569 }
1570 else {
1571 printf("\nIncorrect argument format for createNode('nodetype').\n");
1572 JS_free(context, _c);
1573 return JS_FALSE;
1574 }
1575 }
1576 JS_free(context, _c);
1577 }
1578 else {
1579 printf("\nIncorrect argument format for createNode('nodetype').\n");
1580 return JS_FALSE;
1581 }
1582
1583 JS_SET_RVAL(context, vp, OBJECT_TO_JSVAL(obj));
1584 return JS_TRUE;
1585}
1586
1587static JSBool
1588X3DExecutionContext_createProto(JSContext* context, uintN argc, jsval* vp) {
1589 JSObject* obj = JS_NewObject(context, &SFNodeClass, NULL, NULL);
1590 ADD_ROOT(cx, obj)
1591 jsval* argv = JS_ARGV(context, vp);
1592 const char* _c_format = "S";
1593 JSString* js_c;
1594 struct X3D_Node* node = NULL;
1595 struct X3D_Proto* ec;
1596 struct X3D_Proto* proto;
1597 proto = NULL;
1598
1599 char* _c;
1600
1601 if (argc == 1 &&
1602 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
1603 _c = JS_EncodeString(context, js_c);
1604#ifdef JSVERBOSE
1605 printf("X3DExecutionContext_createProto: obj = %u, str = \"%s\"\n", obj, _c);
1606#endif
1607 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
1608 if (isAvailableBroto(_c, ec, &proto))
1609 {
1610 struct X3D_Proto* source, * dest;
1611 node = X3D_NODE(brotoInstance(proto, 1));
1612 node->_executionContext = X3D_NODE(ec); //me->ptr;
1613 add_node_to_broto_context(ec, node);
1614 //during parsing, setting of fields would occur between instance and body,
1615 //so field values perculate down.
1616 //here we elect default field values
1617 source = X3D_PROTO(X3D_PROTO(node)->__prototype);
1618 dest = X3D_PROTO(node);
1619 deep_copy_broto_body2(&source, &dest);
1620
1621 AnyNative* lhs;
1622 if ((lhs = (AnyNative*)AnyNativeNew(FIELDTYPE_SFNode, NULL, NULL)) == NULL) {
1623 printf("AnyNativeNew failed in SFNodeConstr.\n");
1624 return JS_FALSE;
1625 }
1626 if (!JS_SetPrivateFw(context, obj, lhs)) {
1627 printf("JS_SetPrivate failed in SFNodeConstr.\n");
1628 return JS_FALSE;
1629 }
1630 //lhs->valueChanged = NULL;
1631 lhs->v->sfnode = node;
1632 }
1633 else {
1634 printf("\nIncorrect argument for createProto('prototype').\n");
1635 JS_free(context, _c);
1636 return JS_FALSE;
1637 }
1638 JS_free(context, _c);
1639 }
1640 else {
1641 printf("\nIncorrect argument format for createNode('nodetype').\n");
1642 return JS_FALSE;
1643 }
1644 JS_SET_RVAL(context, vp, OBJECT_TO_JSVAL(obj));
1645 return JS_TRUE;
1646}
1647/*
1648struct X3D_Node *broto_search_DEFname(struct X3D_Proto *context, const char *name);
1649struct X3D_Node * broto_search_ALLnames(struct X3D_Proto *context, const char *name, int *source);
1650int X3DExecutionContext_getNamedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1651 int nr = 0;
1652 struct X3D_Node* node = NULL;
1653 //broto warning - DEF name list should be per-executionContext
1654 //struct X3D_Proto *ec = (struct X3D_Proto *)fwn; //we want the script node's parent context for imported nodes, I think
1655 node = broto_search_DEFname(ec, fwpars[0]._string);
1656
1657 if(node){
1658 //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1659 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1660 fwretval->_web3dval.anyvrml->sfnode = node;
1661 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1662 fwretval->_web3dval.gc = 1;
1663 fwretval->itype = 'W';
1664 nr = 1;
1665 }
1666 return nr;
1667}
1668*/
1669
1670static JSBool
1671X3DExecutionContext_getNamedNode(JSContext* context, uintN argc, jsval* vp) {
1672 JSObject* obj = JS_NewObject(context, &SFNodeClass, NULL, NULL);
1673 ADD_ROOT(cx, obj)
1674 jsval* argv = JS_ARGV(context, vp);
1675 const char* _c_format = "S";
1676 JSString* js_c;
1677 char* _c;
1678
1679 if (argc == 1 &&
1680 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
1681 _c = JS_EncodeString(context, js_c);
1682#ifdef JSVERBOSE
1683 printf("X3DExecutionContext_getNamedNode: obj = %u, str = \"%s\"\n",
1684 obj, _c);
1685#endif
1686 {
1687 struct X3D_Node* node = NULL;
1688 struct X3D_Proto* ec;
1689 //ec = getExecutionContextFromCx(cx);
1690 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
1691 node = broto_search_DEFname(ec, _c);
1692
1693 if (node != NULL) {
1694 AnyNative* lhs;
1695 if ((lhs = (AnyNative*)AnyNativeNew(FIELDTYPE_SFNode, NULL, NULL)) == NULL) {
1696 printf("AnyNativeNew failed in SFNodeConstr.\n");
1697 return JS_FALSE;
1698 }
1699 if (!JS_SetPrivateFw(context, obj, lhs)) {
1700 printf("JS_SetPrivate failed in SFNodeConstr.\n");
1701 return JS_FALSE;
1702 }
1703 //lhs->valueChanged = NULL;
1704 lhs->v->sfnode = node;
1705 }
1706 else {
1707 printf("\nIncorrect argument for getNamedNode('DEFname').\n");
1708 JS_free(context, _c);
1709 return JS_FALSE;
1710 }
1711 }
1712 JS_free(context, _c);
1713 }
1714 else {
1715 printf("\nIncorrect argument format for getNamedNode('DEFname').\n");
1716 return JS_FALSE;
1717 }
1718
1719 JS_SET_RVAL(context, vp, OBJECT_TO_JSVAL(obj));
1720 return JS_TRUE;
1721}
1722
1723static JSBool
1724X3DExecutionContext_removeNamedNode(JSContext* context, uintN argc, jsval* vp) {
1725 jsval* argv = JS_ARGV(context, vp);
1726 const char* _c_format = "S";
1727 JSString* js_c;
1728 char* _c;
1729
1730 if (argc == 1 &&
1731 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
1732 _c = JS_EncodeString(context, js_c);
1733#ifdef JSVERBOSE
1734 printf("X3DExecutionContext_removeNamedNode: obj = %u, str = \"%s\"\n",
1735 obj, _c);
1736#endif
1737 {
1738 struct X3D_Node* node = NULL;
1739 struct X3D_Proto* ec;
1740 //ec = getExecutionContextFromCx(cx);
1741 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
1742 node = broto_search_DEFname(ec, _c);
1743
1744 if (node != NULL) {
1745 remove_node_from_parents_children(node);
1746 remove_broto_node(ec, node);
1747 remove_node_from_def_list(ec, node, _c);
1748 }
1749 else {
1750 printf("\nIncorrect argument for removeNamedNode('DEFname').\n");
1751 JS_free(context, _c);
1752 return JS_FALSE;
1753 }
1754 }
1755 JS_free(context, _c);
1756 }
1757 else {
1758 printf("\nIncorrect argument format for removeNamedNode('DEFname').\n");
1759 return JS_FALSE;
1760 }
1761
1762 return JS_TRUE;
1763}
1764static JSBool
1765X3DExecutionContext_updateNamedNode(JSContext* context, uintN argc, jsval* vp) {
1766 jsval* argv = JS_ARGV(context, vp);
1767 const char* _c_format = "S";
1768 JSString* js_c;
1769 JSObject* _ob2;
1770 struct X3D_Node* node = NULL;
1771 struct brotoDefpair* bd;
1772 int found = 0;
1773 char* defname;
1774
1775 if (argc == 2 &&
1776 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
1777 defname = JS_EncodeString(context, js_c);
1778 if (argv[1].isObject()) {
1779 _ob2 = JSVAL_TO_OBJECT(argv[1]);
1780 AnyNative* _node = NULL;
1781 if ((_node = (AnyNative*)JS_GetPrivateFw(context, _ob2)) == NULL) {
1782 printf("JS_GetPrivate failed for arg format \"o d\" in SFRotationConstr.\n");
1783 return JS_FALSE;
1784 }
1785 node = _node->v->sfnode;
1786
1787#ifdef JSVERBOSE
1788 printf("X3DExecutionContext_removeNamedNode: obj = %u, str = \"%s\"\n",
1789 obj, _c);
1790#endif
1791
1792 struct X3D_Proto* ec;
1793 //ec = getExecutionContextFromCx(cx);
1794 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
1795 if (ec->__DEFnames) {
1796 struct Vector* defnames = (struct Vector*)ec->__DEFnames;
1797 for (int i = 0; i < vectorSize(defnames); i++) {
1798 bd = vector_get_ptr(struct brotoDefpair, defnames, i);
1799 //Q. is it the DEF we search for, and node we replace, OR
1800 // is it the node we search for, and DEF we replace?
1801 if (!strcmp(bd->name, defname)) {
1802 bd->node = node;
1803 found = 1;
1804 break;
1805 }
1806 if (bd->node == node) {
1807 bd->name = strdup(defname);
1808 found = 2;
1809 break;
1810 }
1811 }
1812 }
1813 if (!found) {
1814 //I guess its an add
1815 if (!ec->__DEFnames)
1816 ec->__DEFnames = newVector(struct brotoDefpair, 4);
1817 struct brotoDefpair bd2;
1818 memset(&bd2, 0, sizeof(struct brotoDefpair));
1819 bd2.node = node;
1820 bd2.name = strdup(defname);
1821 stack_push(struct brotoDefpair, (struct Vector*)ec->__DEFnames, bd2);
1822 }
1823 else {
1824 printf("\nIncorrect argument for updateNamedNode('DEFname').\n");
1825 JS_free(context, defname);
1826 return JS_FALSE;
1827 }
1828 }
1829 JS_free(context, defname);
1830 }
1831 else {
1832 printf("\nIncorrect argument format for updateNamedNode('DEFname').\n");
1833 return JS_FALSE;
1834 }
1835
1836 return JS_TRUE;
1837}
1838
1839static JSBool X3DExecutionContext_addRoute(JSContext* context, uintN argc, jsval* vp) {
1840 JSObject* obj = JS_THIS_OBJECT(context, vp);
1841 jsval* argv = JS_ARGV(context, vp);
1842
1843 JSObject* fromNodeObj, * toNodeObj;
1844 JSClass* _cls[2];
1845 char * fromField, * toField;
1846 const char* _c_args =
1847 "SFNode fromNode, SFString fromEventOut, SFNode toNode, SFString toEventIn",
1848 * _c_format = "oSoS";
1849 JSString* fromFieldStringJS, * toFieldStringJS;
1850 struct X3D_Node* fromNode;
1851 struct X3D_Node* toNode;
1852 int fromOfs, toOfs, len;
1853 int fromtype, totype;
1854 int xxx;
1855 int myField;
1856
1857 /* first, are there 4 arguments? */
1858 if (argc != 4) {
1859 printf("Problem with script - add/delete route command needs 4 parameters\n");
1860 return JS_FALSE;
1861 }
1862
1863 /* get the arguments, and ensure that they are obj, string, obj, string */
1864 if (JS_ConvertArguments(context, argc, argv, _c_format,
1865 &fromNodeObj, &fromFieldStringJS, &toNodeObj, &toFieldStringJS)) {
1866 fromField = JS_EncodeString(context, fromFieldStringJS);
1867 toField = JS_EncodeString(context, toFieldStringJS);
1868
1869 if ((_cls[0] = JS_GET_CLASS(context, fromNodeObj)) == NULL) {
1870 printf("JS_GetClass failed for arg 0 in doVRMLRoute called from %s.\n",
1871 "addRoute");
1872 return JS_FALSE;
1873 }
1874 if ((_cls[1] = JS_GET_CLASS(context, toNodeObj)) == NULL) {
1875 printf("JS_GetClass failed for arg 2 in doVRMLRoute called from %s.\n",
1876 "addRoute");
1877 return JS_FALSE;
1878 }
1879
1880 /* make sure these are both SFNodes */
1881 if (memcmp("SFNode", (_cls[0])->name, strlen((_cls[0])->name)) != 0 &&
1882 memcmp("SFNode", (_cls[1])->name, strlen((_cls[1])->name)) != 0) {
1883 printf("\nArguments 0 and 2 must be SFNode in doVRMLRoute called from %s(%s): %s\n",
1884 "addRoute", _c_args, "addRoute");
1885 return JS_FALSE;
1886 }
1887
1888 /* get the "private" data for these nodes. It will consist of a SFNodeNative structure */
1889 AnyNative* fromNative;
1890 AnyNative* toNative;
1891 if ((fromNative = (AnyNative*)JS_GetPrivateFw(context,fromNodeObj)) == NULL) {
1892 printf("problem getting native props first node\n");
1893 return JS_FALSE;
1894 }
1895 if ((toNative = (AnyNative*)JS_GetPrivateFw(context, toNodeObj)) == NULL) {
1896 printf("problem getting native props second node\n");
1897 return JS_FALSE;
1898 }
1899
1900 /* get the "handle" for the actual memory pointer */
1901 fromNode = X3D_NODE(fromNative->v->sfnode);
1902 toNode = X3D_NODE(toNative->v->sfnode);
1903
1904#ifdef JSVERBOSE
1905 printf("routing from a node of type %s to a node of type %s\n",
1906 stringNodeType(fromNode->_nodeType),
1907 stringNodeType(toNode->_nodeType));
1908#endif
1909 struct X3D_Proto* ec;
1910 //ec = getExecutionContextFromCx(cx);
1911 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
1912
1913 void* xroute;
1914 int nr = 0;
1915 xroute = addDeleteRoute0(ec, "addRoute", fromNode, fromField, toNode, toField);
1916 //find its index
1917 struct Vector* routes = (struct Vector*)ec->__ROUTES;
1918 int index = -1;
1919 for (int j = 0; j < vectorSize(routes); j++) {
1920 struct brotoRoute* route = vector_get(struct brotoRoute*, routes, j);
1921 if ((void*)route == (void*)xroute) {
1922 index = j;
1923 break;
1924 }
1925 }
1926 if (index > -1) {
1927 JSObject* _obj;
1928 //int* _index = (int*) MALLOC(void *, sizeof(int));
1929 _obj = JS_NewObject(context, &X3DRouteClass, NULL, obj); //could parent be context or RouteArray?
1930 ADD_ROOT(context, _obj)
1931
1932 long long iindex = index + 1; //instead of malloc and free wrapper for long, just send a longlong on x64
1933 if (!JS_SetPrivateFw(context, _obj, (void*)iindex)) {
1934 printf("JS_SetPrivate failed in RouteArray.\n");
1935 return JS_FALSE;
1936 }
1937 JS_SET_RVAL(context, vp, OBJECT_TO_JSVAL(_obj));
1938 }
1939 JS_free(context, fromField);
1940 JS_free(context, toField);
1941 }
1942 else {
1943 printf("\nIncorrect argument format for %s(%s).\n",
1944 "addRoute", _c_args);
1945 return JS_FALSE;
1946 }
1947 return JS_TRUE;
1948}
1949static JSBool X3DExecutionContext_deleteRoute(JSContext* context, uintN argc, jsval* vp) {
1950 JSObject* obj = JS_THIS_OBJECT(context, vp);
1951 jsval* argv = JS_ARGV(context, vp);
1952 JSObject* routeObj;
1953 JSClass* _cls[1];
1954 const char* _c_args =
1955 "X3DRoute route",
1956 * _c_format = "o";
1957
1958 /* first, are there 4 arguments? */
1959 if (argc != 1) {
1960 printf("Problem with script - delete route command needs 1 parameter\n");
1961 return JS_FALSE;
1962 }
1963
1964 /* get the arguments, and ensure that they are obj, string, obj, string */
1965 if (JS_ConvertArguments(context, argc, argv, _c_format,
1966 &routeObj)) {
1967
1968 if ((_cls[0] = JS_GET_CLASS(context, routeObj)) == NULL) {
1969 printf("JS_GetClass failed for arg 0 in deleteRoute \n");
1970 return JS_FALSE;
1971 }
1972
1973 /* make sure these are both SFNodes */
1974 if (memcmp("X3DRoute", (_cls[0])->name, strlen((_cls[0])->name)) != 0 ) {
1975 printf("\nArguments 0 must be X3DRoute in deleteRoute \n");
1976 return JS_FALSE;
1977 }
1978 long long iindex;
1979 if ((iindex = (long long)JS_GetPrivateFw(context, routeObj)) == 0) {
1980 printf("problem getting native prop for route\n");
1981 }
1982 struct X3D_Proto* ec;
1983 //ec = getExecutionContextFromCx(cx);
1984 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
1985
1986 void* xroute;
1987 int nr = 0;
1988 struct Vector* routes = (struct Vector*)ec->__ROUTES;
1989 int index = iindex -1;
1990 struct brotoRoute* broute = vector_get(struct brotoRoute*, routes, index);
1991 CRoutes_RemoveSimpleB(broute->from.node, broute->from.ifield, broute->from.builtIn, broute->to.node, broute->to.ifield, broute->to.builtIn, broute->ft);
1992 vector_remove_elem(struct brotoRoute*, routes, index);
1993 }
1994 else {
1995 printf("\nIncorrect argument format for deleteRoute.\n");
1996 return JS_FALSE;
1997 }
1998 return JS_TRUE;
1999}
2000struct X3D_Node* broto_search_DEFname(struct X3D_Proto* context, const char* name);
2001struct IMEXPORT* broto_search_IMPORTname(struct X3D_Proto* context, const char* name);
2002struct IMEXPORT* broto_search_EXPORTname(struct X3D_Proto* context, const char* name);
2003
2004static JSBool
2005X3DExecutionContext_getImportedNode(JSContext* context, uintN argc, jsval* vp) {
2006 //has optional 2nd parameter in specs (importname,exportname)
2007 JSObject* obj = JS_NewObject(context, &SFNodeClass, NULL, NULL);
2008 ADD_ROOT(cx, obj)
2009 jsval* argv = JS_ARGV(context, vp);
2010 const char* _c_format = "S";
2011 JSString* js_c;
2012 char* _c;
2013
2014 if (argc == 1 &&
2015 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
2016 _c = JS_EncodeString(context, js_c);
2017#ifdef JSVERBOSE
2018 printf("X3DExecutionContext_getNamedNode: obj = %u, str = \"%s\"\n",
2019 obj, _c);
2020#endif
2021 {
2022 struct X3D_Node* node = NULL;
2023 struct X3D_Proto* ec;
2024 //ec = getExecutionContextFromCx(cx);
2025 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
2026 //struct IMEXPORT* im = broto_search_IMPORTname(ec, _c);
2027 //if (im) node = im->nodeptr;
2028 //
2029 //imports show up late. The main scene parser never sees the nodeptr in the inline, leaves it null.
2030 //then if you patiently wait for the inline to load, something has to go hunting for
2031 // the imported node in the inline. broto_search_ALLnames has some code for that.
2032 int source;
2033 node = broto_search_ALLnames(ec, _c, &source);
2034 if (source == 0) node = NULL; //import must be source 2
2035 if (node != NULL) {
2036 AnyNative* lhs;
2037 if ((lhs = (AnyNative*)AnyNativeNew(FIELDTYPE_SFNode, NULL, NULL)) == NULL) {
2038 printf("AnyNativeNew failed in SFNodeConstr.\n");
2039 return JS_FALSE;
2040 }
2041 if (!JS_SetPrivateFw(context, obj, lhs)) {
2042 printf("JS_SetPrivate failed in SFNodeConstr.\n");
2043 return JS_FALSE;
2044 }
2045 //lhs->valueChanged = NULL;
2046 lhs->v->sfnode = node;
2047 }
2048 else {
2049 printf("Incorrect argument for getImportedNode('DEFname').\n");
2050 }
2051 }
2052 JS_free(context, _c);
2053 }
2054 else {
2055 printf("\nIncorrect argument format for getImportedNode('DEFname').\n");
2056 return JS_FALSE;
2057 }
2058
2059 JS_SET_RVAL(context, vp, OBJECT_TO_JSVAL(obj));
2060 return JS_TRUE;
2061}
2062static JSBool
2063X3DExecutionContext_removeImportedNode(JSContext* context, uintN argc, jsval* vp) {
2064 jsval* argv = JS_ARGV(context, vp);
2065 const char* _c_format = "S";
2066 JSString* js_c;
2067 char* _c;
2068
2069 if (argc == 1 &&
2070 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
2071 _c = JS_EncodeString(context, js_c);
2072#ifdef JSVERBOSE
2073 printf("X3DExecutionContext_getNamedNode: obj = %u, str = \"%s\"\n",
2074 obj, _c);
2075#endif
2076 {
2077 struct X3D_Node* node = NULL;
2078 struct X3D_Proto* ec;
2079 //ec = getExecutionContextFromCx(cx);
2080 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
2081 struct IMEXPORT* im = broto_search_IMPORTname(ec, _c);
2082
2083 if (im) {
2084 struct IMEXPORT* def;
2085 struct Vector* imports = (struct Vector*)ec->__IMPORTS;
2086 int k = 0;
2087 for (int i = 0; i < vectorSize(imports); i++) {
2088 def = vector_get(struct IMEXPORT*, imports, i);
2089 vector_set(struct IMEXPORT*, imports, i, def);
2090 if (im != def) k++;
2091 }
2092 imports->n = k;
2093 }
2094 }
2095 JS_free(context, _c);
2096 }
2097 else {
2098 printf("\nIncorrect argument format for getImportedNode('DEFname').\n");
2099 return JS_FALSE;
2100 }
2101
2102 return JS_TRUE;
2103}
2104
2105
2106static JSBool
2107X3DExecutionContext_updateImportedNode(JSContext* context, uintN argc, jsval* vp) {
2108 //2023 interpretation of parameters:
2109 // string1 is the main scene local DEF name (the AS name)
2110 // string2 is the inline export name
2111 // no need for 3rd string for inline name:
2112 // - if you want to say which inline, use <inline name>.<export name> in string2
2113 // - otherwise if no "." it assumes that's the export name and will search for that in all inlines
2114 //
2115 jsval* argv = JS_ARGV(context, vp);
2116 const char* _c_format = "SS";
2117 JSString* js_1, * js_2, * js_3;
2118 JSObject* _ob2;
2119 struct X3D_Node* node = NULL;
2120 int found = 0;
2121 const char* as, * mxname, * impname;
2122 char* nline;
2123 struct IMEXPORT* mxp;
2124
2125
2126 if (argc == 2) {
2127 JS_ConvertArguments(context, argc, argv, "SS", &js_1, &js_2);
2128
2129 as = JS_EncodeString(context, js_1);
2130 mxname = JS_EncodeString(context, js_2);
2131 impname = strdup(mxname);
2132 nline = NULL;
2133 const char* dot = strstr(mxname, ".");
2134 if (dot) {
2135 nline = strdup(mxname);
2136 nline[dot - mxname] = 0;
2137 impname = strdup(&dot[1]);
2138 }
2139 printf("as [%s] impname [%s] nline [%s]\n", as, impname, nline);
2140#ifdef JSVERBOSE
2141 printf("X3DExecutionContext_removeNamedNode: obj = %u, str = \"%s\"\n",
2142 obj, _c);
2143#endif
2144
2145 struct X3D_Proto* ec;
2146 //ec = getExecutionContextFromCx(cx);
2147 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
2148 struct Vector* imports = (struct Vector*)ec->__IMPORTS;
2149 if (imports) {
2150 for (int i = 0; i < vectorSize(imports); i++) {
2151 mxp = vector_get(struct IMEXPORT*, imports, i);
2152 //Q. is it the DEF we search for, and node we replace, OR
2153 // is it the node we search for, and DEF we replace?
2154 int inlineOK = !nline || !strcmp(nline, mxp->inlinename);
2155 int asOK = !strcmp(as, mxp->as);
2156 int impOK = !strcmp(impname, mxp->mxname);
2157 if(inlineOK && impOK){
2158 //if (!strcmp(nline, mxp->inlinename) && !strcmp(mxp->mxname, mxname)) {
2159 printf("updating import new as [%s] old import [%s] inline [%s]\n", as, impname, nline);
2160 mxp->as = strdup(as);
2161 found = 1;
2162 break;
2163 }
2164 }
2165 }
2166 if (!found) {
2167 //I guess its an add
2168 if (!ec->__IMPORTS)
2169 ec->__IMPORTS = newVector(struct IMEXPORT*, 4);
2170 mxp = (struct IMEXPORT*)malloc(sizeof(struct IMEXPORT));
2171 mxp->mxname = strdup(impname);
2172 mxp->as = strdup(as);
2173 mxp->inlinename = nline ? strdup(nline) : NULL;
2174 printf("adding import mapping as [%s] import [%s] inline [%s]\n", impname, as, nline);
2175 stack_push(struct IMEXPORT*, (struct Vector *)ec->__IMPORTS, mxp);
2176 }
2177 update_weakRoutes(ec);
2178 //JS_free(context, mxname); //? what's wrong
2179 }
2180 else {
2181 printf("\nIncorrect argument format for updateImportedNode('DEFname').\n");
2182 return JS_FALSE;
2183 }
2184
2185 return JS_TRUE;
2186}
2187JSBool
2188X3DExecutionContext_toString(JSContext* cx, uintN argc, jsval* vp) {
2189 JSObject* obj = JS_THIS_OBJECT(cx, vp);
2190 jsval* argv = JS_ARGV(cx, vp);
2191 jsval rval;
2192 JSString *_str;
2193
2194 UNUSED(argc);
2195 UNUSED(argv);
2196
2197
2198 char str[200];
2199 struct X3D_Proto* ec = (struct X3D_Proto*)JS_GetContextPrivate(cx);
2200
2201 sprintf(str, "%p", (void*)ec);
2202 _str = JS_NewStringCopyZ(cx, str);
2203 rval = STRING_TO_JSVAL(_str);
2204
2205 JS_SET_RVAL(cx, vp, rval);
2206 return JS_TRUE;
2207}
2208
2209static JSBool
2210X3DScene_getExportedNode(JSContext* context, uintN argc, jsval* vp) {
2211 //has optional 2nd parameter in specs (importname,exportname)
2212 JSObject* obj = JS_NewObject(context, &SFNodeClass, NULL, NULL);
2213 ADD_ROOT(cx, obj)
2214 jsval* argv = JS_ARGV(context, vp);
2215 const char* _c_format = "S";
2216 JSString* js_c;
2217 char* _c;
2218
2219 if (argc == 1 &&
2220 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
2221 _c = JS_EncodeString(context, js_c);
2222#ifdef JSVERBOSE
2223 printf("X3DExecutionContext_getNamedNode: obj = %u, str = \"%s\"\n",
2224 obj, _c);
2225#endif
2226 {
2227 struct X3D_Node* node = NULL;
2228 struct X3D_Proto* ec;
2229 //ec = getExecutionContextFromCx(cx);
2230 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
2231 int source = 0;
2232 struct IMEXPORT * ex = broto_search_EXPORTname(ec, _c);
2233 if (ex) node = ex->nodeptr;
2234 if (node != NULL) {
2235 AnyNative* lhs;
2236 if ((lhs = (AnyNative*)AnyNativeNew(FIELDTYPE_SFNode, NULL, NULL)) == NULL) {
2237 printf("AnyNativeNew failed in SFNodeConstr.\n");
2238 return JS_FALSE;
2239 }
2240 if (!JS_SetPrivateFw(context, obj, lhs)) {
2241 printf("JS_SetPrivate failed in SFNodeConstr.\n");
2242 return JS_FALSE;
2243 }
2244 //lhs->valueChanged = NULL;
2245 lhs->v->sfnode = node;
2246 }
2247 else {
2248 printf("Incorrect argument for getExportedNode('DEFname').\n");
2249 }
2250 }
2251 JS_free(context, _c);
2252 }
2253 else {
2254 printf("\nIncorrect argument format for getExportedNode('DEFname').\n");
2255 return JS_FALSE;
2256 }
2257
2258 JS_SET_RVAL(context, vp, OBJECT_TO_JSVAL(obj));
2259 return JS_TRUE;
2260}
2261static JSBool
2262X3DScene_removeExportedNode(JSContext* context, uintN argc, jsval* vp) {
2263 jsval* argv = JS_ARGV(context, vp);
2264 const char* _c_format = "S";
2265 JSString* js_c;
2266 char* _c;
2267
2268 if (argc == 1 &&
2269 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
2270 _c = JS_EncodeString(context, js_c);
2271#ifdef JSVERBOSE
2272 printf("X3DExecutionContext_getNamedNode: obj = %u, str = \"%s\"\n",
2273 obj, _c);
2274#endif
2275 {
2276 struct X3D_Node* node = NULL;
2277 struct X3D_Proto* ec;
2278 //ec = getExecutionContextFromCx(cx);
2279 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
2280 struct IMEXPORT* ex = broto_search_EXPORTname(ec, _c);
2281
2282 if (ex) {
2283 struct IMEXPORT* def;
2284 struct Vector* exports = (struct Vector*)ec->__EXPORTS;
2285 int k = 0;
2286 for (int i = 0; i < vectorSize(exports); i++) {
2287 def = vector_get(struct IMEXPORT*, exports, i);
2288 vector_set(struct IMEXPORT*, exports, i, def);
2289 if (ex != def) k++;
2290 }
2291 exports->n = k;
2292 }
2293 }
2294 JS_free(context, _c);
2295 }
2296 else {
2297 printf("\nIncorrect argument format for removeExportedNode('DEFname').\n");
2298 return JS_FALSE;
2299 }
2300
2301 return JS_TRUE;
2302}
2303
2304
2305static JSBool
2306X3DScene_updateExportedNode(JSContext* context, uintN argc, jsval* vp) {
2307 jsval* argv = JS_ARGV(context, vp);
2308 const char* _c_format = "SS";
2309 JSString* js_1, * js_2, * js_3;
2310 JSObject* _ob2;
2311 struct X3D_Node* node = NULL;
2312 int found = 0;
2313 const char* as, * mxname, * nline;
2314 struct IMEXPORT* mxp;
2315
2316
2317 if (argc >= 2) {
2318 if (argc == 2)
2319 JS_ConvertArguments(context, argc, argv, "SS", &js_1, &js_2);
2320 if (argc == 3)
2321 JS_ConvertArguments(context, argc, argv, "SSS", &js_1, &js_2, &js_3);
2322
2323 nline = JS_EncodeString(context, js_1);
2324 mxname = JS_EncodeString(context, js_2);
2325 as = mxname;
2326 if (argc == 3)
2327 as = JS_EncodeString(context, js_3);
2328
2329
2330#ifdef JSVERBOSE
2331 printf("X3DExecutionContext_removeNamedNode: obj = %u, str = \"%s\"\n",
2332 obj, _c);
2333#endif
2334
2335 struct X3D_Proto* ec;
2336 //ec = getExecutionContextFromCx(cx);
2337 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
2338 struct Vector* exports = (struct Vector*)ec->__EXPORTS;
2339 if (exports) {
2340 for (int i = 0; i < vectorSize(exports); i++) {
2341 mxp = vector_get(struct IMEXPORT*, exports, i);
2342 //Q. is it the DEF we search for, and node we replace, OR
2343 // is it the node we search for, and DEF we replace?
2344 if (!strcmp(nline, mxp->inlinename) && !strcmp(mxp->mxname, mxname)) {
2345 mxp->as = strdup(as);
2346 found = 1;
2347 break;
2348 }
2349 }
2350 }
2351 if (!found) {
2352 //I guess its an add
2353 if (!ec->__EXPORTS)
2354 ec->__EXPORTS = newVector(struct IMEXPORT*, 4);
2355 mxp = (struct IMEXPORT*)malloc(sizeof(struct IMEXPORT));
2356 mxp->mxname = strdup(mxname);
2357 mxp->as = strdup(as);
2358 mxp->inlinename = strdup(nline);
2359 stack_push(struct IMEXPORT*, (struct Vector*)ec->__EXPORTS, mxp);
2360 }
2361 update_weakRoutes(ec);
2362 //JS_free(context, mxname); //? what's wrong
2363 }
2364 else {
2365 printf("\nIncorrect argument format for updateImportedNode('DEFname').\n");
2366 return JS_FALSE;
2367 }
2368
2369 return JS_TRUE;
2370}
2371
2372static JSBool
2373X3DScene_getMetaData(JSContext* context, uintN argc, jsval* vp) {
2374 //has optional 2nd parameter in specs (importname,exportname)
2375 jsval* argv = JS_ARGV(context, vp);
2376 const char* _c_format = "S";
2377 JSString* js_c;
2378 char* name, *content;
2379 content = NULL;
2380 if (argc == 1 &&
2381 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
2382 name = JS_EncodeString(context, js_c);
2383#ifdef JSVERBOSE
2384 printf("X3DScene_getMetaData: obj = %u, str = \"%s\"\n",
2385 obj, _c);
2386#endif
2387 {
2388 struct X3D_Node* node = NULL;
2389 struct X3D_Proto* ec;
2390 //ec = getExecutionContextFromCx(cx);
2391 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
2392 if (ec->__META) {
2393 struct Vector* metalist = (struct Vector*)ec->__META;
2394 struct metarecord* mr;
2395 for (int i = 0; i < vectorSize(metalist); i++) {
2396 mr = vector_get_ptr(struct metarecord, metalist, i);
2397 if (!strcmp(mr->name, name)) {
2398 content = strdup(mr->content);
2399 break;
2400 }
2401 }
2402 }
2403 }
2404 JS_free(context, name);
2405 }
2406 else {
2407 printf("\nIncorrect argument format for Scene.getMetaData('name').\n");
2408 return JS_FALSE;
2409 }
2410
2411 JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(context, content)));
2412 return JS_TRUE;
2413}
2414static JSBool
2415X3DScene_setMetaData(JSContext* context, uintN argc, jsval* vp) {
2416 //has optional 2nd parameter in specs (importname,exportname)
2417 jsval* argv = JS_ARGV(context, vp);
2418 const char* _c_format = "SS";
2419 JSString* js_name, *js_content;
2420 char* name, * content;
2421
2422 if (argc == 2 &&
2423 JS_ConvertArguments(context, argc, argv, _c_format, &js_name, &js_content)) {
2424 name = JS_EncodeString(context, js_name);
2425 content = JS_EncodeString(context, js_content);
2426#ifdef JSVERBOSE
2427 printf("X3DScene_getMetaData: obj = %u, str = \"%s\"\n",
2428 obj, _c);
2429#endif
2430 {
2431 struct X3D_Node* node = NULL;
2432 struct X3D_Proto* ec;
2433 //ec = getExecutionContextFromCx(cx);
2434 ec = (struct X3D_Proto*)JS_GetContextPrivate(context);
2435 if (!ec->__META)
2436 ec->__META = newVector(struct metarecord, 10);
2437
2438 struct Vector* metalist = (struct Vector*)ec->__META;
2439 struct metarecord* mr;
2440 int done = FALSE;
2441 for (int i = 0; i < vectorSize(metalist); i++) {
2442 mr = vector_get_ptr(struct metarecord, metalist, i);
2443 if (!strcmp(mr->name, name)) {
2444 mr->content = strdup(content);
2445 done = TRUE;
2446 break;
2447 }
2448 }
2449 if (!done) {
2450 //add
2451 struct metarecord mr2;
2452 mr2.name = strdup(name);
2453 mr2.content = strdup(content);
2454 vector_pushBack(struct metarecord, metalist, mr2);
2455 }
2456 }
2457 JS_free(context, name);
2458 JS_free(context, content);
2459 }
2460 else {
2461 printf("\nIncorrect argument format for Scene.setMetaData('name','content').\n");
2462 return JS_FALSE;
2463 }
2464
2465 return JS_TRUE;
2466}
2467
2468static JSFunctionSpec (ExecutionContextFunctions)[] = {
2469 //executionContext
2470 {"addRoute", X3DExecutionContext_addRoute, 0},
2471 {"deleteRoute", X3DExecutionContext_deleteRoute, 0},
2472 {"createNode", X3DExecutionContext_createNode, 0},
2473 {"createProto", X3DExecutionContext_createProto, 0},
2474 {"getImportedNode", X3DExecutionContext_getImportedNode, 0},
2475 {"updateImportedNode", X3DExecutionContext_updateImportedNode, 0},
2476 {"removeImportedNode", X3DExecutionContext_removeImportedNode, 0},
2477 {"getNamedNode", X3DExecutionContext_getNamedNode, 0},
2478 {"updateNamedNode", X3DExecutionContext_updateNamedNode, 0},
2479 {"removeNamedNode", X3DExecutionContext_removeNamedNode, 0},
2480 {"toString", X3DExecutionContext_toString, 0},
2481 //scene
2482 {"setMetaData", X3DScene_setMetaData, 0},
2483 {"getMetaData", X3DScene_getMetaData, 0},
2484 {"getExportedNode", X3DScene_getExportedNode, 0},
2485 {"updateExportedNode", X3DScene_updateExportedNode, 0},
2486 {"removeExportedNode", X3DScene_removeExportedNode, 0},
2487 {0}
2488};
2489
2490
2491static JSPropertySpec (ExecutionContextProperties)[] = {
2492 //executionContext
2493 {"specificationVersion", 0, JSPROP_ENUMERATE},
2494 {"encoding", 1, JSPROP_ENUMERATE},
2495 {"profile", 2, JSPROP_ENUMERATE},
2496 {"components", 3, JSPROP_ENUMERATE},
2497 {"worldURL", 4, JSPROP_ENUMERATE},
2498 {"rootNodes", 5, JSPROP_ENUMERATE},
2499 {"protos", 6, JSPROP_ENUMERATE},
2500 {"externprotos", 7, JSPROP_ENUMERATE},
2501 {"routes", 8, JSPROP_ENUMERATE},
2502 //scene
2503 //{"specificationVersion", 9, JSPROP_ENUMERATE}, //already done for executionContext above
2504 {"isScene", 9, JSPROP_ENUMERATE}, //else protoInstance. extra beyond specs - I think flux has it.
2505 {0,0,0}
2506};
2507
2508//typedef struct _ExecutionContextNative {
2509// struct X3D_Node *handle;
2510//} ExecutionContextNative;
2511typedef struct X3D_Node * ExecutionContextNative;
2512
2513JSBool
2514ExecutionContextGetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp){
2515 JSObject *obj = *hobj.address();
2516 jsid iid = *hiid.address();
2517 jsval *vp = hvp.address();
2518
2519 //ExecutionContextNative *ptr;
2520 struct X3D_Proto *ptr, *ec;
2521 JSString *_str;
2522 jsval rval;
2523 jsval id;
2524
2525 UNUSED(rval); //compiler warning mitigation
2526
2527
2528 if (!JS_IdToValue(cx,iid,&id)) {
2529 printf("JS_IdToValue failed in ExecutionContextGetProperty.\n");
2530 return JS_FALSE;
2531 }
2532
2533
2534 //if ((ptr = (ExecutionContextNative *)JS_GetPrivateFw(cx, obj)) == NULL) {
2535 if ((ptr = (struct X3D_Proto*)JS_GetPrivateFw(cx, obj)) == NULL) {
2536 printf( "JS_GetPrivate failed in ExecutionContextGetProperty.\n");
2537 return JS_FALSE;
2538 }
2539 ec = ptr;
2540
2541 int index = -1;
2542 if (JSVAL_IS_STRING(id)) {
2543 char* field = (char*)JS_EncodeString(cx, JSVAL_TO_STRING(id));
2544 index = lookup_tinyid(field, ExecutionContextProperties);
2545 //printf("ExecutionContextGetProperty %s %d\n", field, index);
2546 }
2547 else if (JSVAL_IS_INT(id)) {
2548 index = JSVAL_TO_INT(id);
2549 }
2550 switch(index){
2551 case 0: //specificationVersion string readonly
2552 {
2553 char cs[100];
2554 sprintf(cs,"{%d,%d,%d}",inputFileVersion[0],inputFileVersion[1],inputFileVersion[2]);
2555 _str = JS_NewStringCopyZ(cx,cs);
2556 }
2557 JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(_str));
2558 break;
2559 case 1: //encoding string readonly
2560 //Valid values are "ASCII", "VRML", "XML", "BINARY", "SCRIPTED", "BIFS", "NONE"
2561 _str = JS_NewStringCopyZ(cx, "not filled in yet sb. VRML or XML or ..");
2562 JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(_str));
2563 break;
2564 case 2: //profile ProfileInfo readonly
2565 {
2566 int index = gglobal()->Mainloop.scene_profile;
2567
2568 JSObject *_obj;
2569 int* _index = MALLOC(int *, sizeof(int));
2570 _obj = JS_NewObject(cx,&ProfileInfoClass,NULL,obj);
2571 *_index = index;
2572 if (!JS_DefineProperties(cx, _obj, ProfileInfoProperties)) {
2573 printf( "JS_DefineProperties failed in ExecutionContextProfileInfoProperties.\n");
2574 return JS_FALSE;
2575 }
2576
2577 if (!JS_SetPrivateFw(cx, _obj, (void*)_index)) {
2578 printf( "JS_SetPrivate failed in ExecutionContextProfileInfoArray.\n");
2579 return JS_FALSE;
2580 }
2581
2582 JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
2583 }
2584 break;
2585 case 3: //components ComponentInfoArray readonly
2586 {
2587 JSObject *_obj;
2588 //int ncomp;
2589 const int *_table = gglobal()->Mainloop.scene_components; //capabilitiesHandler_getProfileComponent(_index);
2590 //ncomp = capabilitiesHandler_getTableLength(_table);
2591 //malloc private not needed
2592 _obj = JS_NewObject(cx,&ComponentInfoArrayClass,NULL,obj);
2593 if (!JS_DefineProperties(cx, _obj, ComponentInfoArrayProperties)) {
2594 printf( "JS_DefineProperties failed in ExecutionContext_ComponentInfoArrayProperties.\n");
2595 return JS_FALSE;
2596 }
2597
2598 if (!JS_SetPrivateFw(cx, _obj, (void*)_table)) {
2599 printf( "JS_SetPrivate failed in ExecutionContext_ComponentInfoArray.\n");
2600 return JS_FALSE;
2601 }
2602 JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
2603 }
2604 break;
2605 case 4: //worldURL string readonly
2606 _str = JS_NewStringCopyZ(cx, gglobal()->Mainloop.url);
2607 //printf("mainloop.url= %s \n", gglobal()->Mainloop.url);
2608 JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(_str));
2609 break;
2610 case 5: //rootNodes MFNode (readonly if !isScene, else rw)
2611 {
2612 JSObject *_obj;
2613 //printf("__nodes length %d", vectorSize(ec->__nodes)); //all nodes in context
2614 //printf(" __children.n %d\n", ec->__children.n); //rootnodes in context
2615 AnyNative* nany;
2616
2617 _obj = JS_NewObject(cx,&MFNodeClass,NULL,obj);
2618 //set private
2619 if ((nany = (AnyNative*)AnyNativeNew(FIELDTYPE_MFNode, (anyVrml*) & ec->__children, 0)) == NULL) {
2620 printf("AnyNativeNew failed in ExecutionContext..\n");
2621 return JS_FALSE;
2622 }
2623
2624 if (!JS_SetPrivateFw(cx, _obj, nany)) {
2625 printf("JS_SetPrivate failed in ExecutionContext..\n");
2626 return JS_FALSE;
2627 }
2628
2629 JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
2630 }
2631 break;
2632 case 6: //protos protoDeclarationArray rw
2633 {
2634 JSObject* _obj;
2635 //malloc private not needed
2636 _obj = JS_NewObject(cx, &ProtoDeclarationArrayClass, NULL, obj);
2637 if (0) if (!JS_DefineProperties(cx, _obj, RouteArrayProperties)) {
2638 printf("JS_DefineProperties failed in ExecutionContext_X3DRouteArrayProperties.\n");
2639 return JS_FALSE;
2640 }
2641 if (!JS_SetPrivateFw(cx, _obj, ptr->__protoDeclares)) {
2642 printf( "JS_SetPrivate failed in ExecutionContext_X3DRouteArray.\n");
2643 return JS_FALSE;
2644 }
2645 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(_obj));
2646
2647 }
2648 break;
2649
2650 case 7: //externprotos externProtoDeclarationArray rw
2651 {
2652 JSObject* _obj;
2653 //malloc private not needed
2654 _obj = JS_NewObject(cx, &ProtoDeclarationArrayClass, NULL, obj);
2655 if (!JS_SetPrivateFw(cx, _obj, ptr->__externProtoDeclares)) {
2656 printf("JS_SetPrivate failed in ExecutionContext_X3DRouteArray.\n");
2657 return JS_FALSE;
2658 }
2659 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(_obj));
2660
2661 }
2662 break;
2663 case 8: //routes RouteArray readonly
2664 {
2665 JSObject *_obj;
2666 //malloc private not needed
2667 _obj = JS_NewObject(cx,&RouteArrayClass,NULL,obj);
2668 if(0) if (!JS_DefineProperties(cx, _obj, RouteArrayProperties)) {
2669 printf( "JS_DefineProperties failed in ExecutionContext_X3DRouteArrayProperties.\n");
2670 return JS_FALSE;
2671 }
2672 //if (!JS_SetPrivateFw(cx, _obj, (void*)_table)) {
2673 // printf( "JS_SetPrivate failed in ExecutionContext_X3DRouteArray.\n");
2674 // return JS_FALSE;
2675 //}
2676 JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
2677 }
2678 break;
2679 case 9: //isScene readonly (extra to specs)
2680 //once brotos are working then the main scene broto will need a flag to say it's a scene
2681 JS_SET_RVAL(cx,vp,BOOLEAN_TO_JSVAL(JS_TRUE));
2682 break;
2683 }
2684
2685 return JS_TRUE;
2686}
2687
2688
2689JSBool
2690ExecutionContextSetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp){
2691 JSObject *obj = *hobj.address();
2692 jsid iid = *hiid.address();
2693 jsval *vp = hvp.address();
2694 //can I, should I force it to read-only this way?
2695 return JS_FALSE;
2696}
2697static JSClass ExecutionContextClass = {
2698 "ExecutionContext",
2699 JSCLASS_HAS_PRIVATE,
2700 JS_PropertyStub,
2701 JS_DeletePropertyStub,
2702 ExecutionContextGetProperty,
2703 ExecutionContextSetProperty,
2704 JS_EnumerateStub,
2705 JS_ResolveStub,
2706 JS_ConvertStub,
2707 JS_FinalizeStub
2708};
2709
2710
2711static JSPropertySpec (BrowserProperties)[] = {
2712 {"name", 0, JSPROP_ENUMERATE},
2713 {"version", 1, JSPROP_ENUMERATE},
2714 {"currentSpeed", 2, JSPROP_ENUMERATE},
2715 {"currentFrameRate", 3, JSPROP_ENUMERATE},
2716 {"description", 4, JSPROP_ENUMERATE},
2717 {"supportedComponents", 5, JSPROP_ENUMERATE},
2718 {"supportedProfiles", 6, JSPROP_ENUMERATE},
2719 {"currentScene", 7, JSPROP_ENUMERATE},
2720 {0}
2721};
2722struct X3D_Node* getExecutionContextFromCx(void *cx) {
2723 struct CRscriptStruct* sc;
2724 struct X3D_Node* executionContext = NULL; //its an X3D_Proto struct, which represents Scene, Proto (declare/instance), and Inline
2725 int nscript = getScriptControlCount();
2726 for (int i = 0; i <= nscript; i++) {
2727 sc = getScriptControlIndex(i);
2728 if (sc->cx == cx) {
2729 executionContext = sc->script->ShaderScriptNode->_executionContext;
2730 break;
2731 }
2732 }
2733 return executionContext;
2734}
2735JSBool
2736BrowserGetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JS::MutableHandle<JS::Value> hvp){
2737 JSObject *obj = *hobj.address();
2738 jsid iid = *hiid.address();
2739 jsval *vp = hvp.address();
2740
2741 BrowserNative *ptr;
2742 struct X3D_Proto* ec;
2743
2744 jsdouble d;
2745 JSString *_str;
2746 jsval rval;
2747 jsval id;
2748
2749 UNUSED(rval); // compiler warning mitigation
2750
2751
2752 if (!JS_IdToValue(cx,iid,&id)) {
2753 printf("JS_IdToValue failed in BrowserGetProperty.\n");
2754 return JS_FALSE;
2755 }
2756
2757 //right now we don't need/use the ptr to BrowserNative which is a stub struct,
2758 //because browser is conceptually a global static singleton
2759 //(or more precisely 1:1 with a gglobal[i] 'browser instance' for things like framerate,
2760 // and 1:1 with static for unchanging things like browser version, components and profiles supported),
2761 //and in practice all the bits and pieces are scattered throughout freewrl
2762 //but for fun we'll get it:
2763 if ((ptr = (BrowserNative *)JS_GetPrivateFw(cx, obj)) == NULL) {
2764 printf( "JS_GetPrivate failed in BrowserGetProperty.\n");
2765 return JS_FALSE;
2766 }
2767 ec = (struct X3D_Proto*)JS_GetContextPrivate(cx);
2768
2769 int index = -1;
2770 if (JSVAL_IS_INT(id))
2771 index = JSVAL_TO_INT(id);
2772 else
2773 index = lookup_tinyid(JS_EncodeString(cx, JSVAL_TO_STRING(id)), BrowserProperties);
2774
2775 switch (index) {
2776 case 0: //name
2777 _str = JS_NewStringCopyZ(cx,BrowserName);
2778 JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(_str));
2779 break;
2780 case 1: //version
2781 _str = JS_NewStringCopyZ(cx, libFreeWRL_get_version());
2782 JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
2783 break;
2784 case 2: //currentSpeed
2785 /* get the variable updated */
2786 getCurrentSpeed();
2787 d = gglobal()->Mainloop.BrowserSpeed;
2788 if (JS_NewNumberValue(cx, d, vp) == JS_FALSE) {
2789 printf("JS_NewDouble failed for %f in BrowserGetProperty.\n",d);
2790 return JS_FALSE;
2791 }
2792 break;
2793 case 3: //currentFrameRate
2794 d = gglobal()->Mainloop.BrowserFPS;
2795 if (JS_NewNumberValue(cx, d, vp) == JS_FALSE) {
2796 printf("JS_NewDouble failed for %f in BrowserGetProperty.\n",d);
2797 return JS_FALSE;
2798 }
2799 break;
2800 case 4: //description
2801 _str = JS_NewStringCopyZ(cx, get_status());
2802 JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
2803 break;
2804 case 5: //supportedComponents
2805 {
2806 JSObject *_obj;
2807 //malloc private not needed
2808 _obj = JS_NewObject(cx,&ComponentInfoArrayClass,NULL,obj);
2809 if(0) if (!JS_DefineProperties(cx, _obj, ComponentInfoArrayProperties)) {
2810 printf( "JS_DefineProperties failed in ComponentInfoArrayProperties.\n");
2811 return JS_FALSE;
2812 }
2813 //if (!JS_DefineFunctions(cx, _obj, ProfileInfoArrayFunctions)) {
2814 // printf( "JS_DefineProperties failed in ExecutionContextFunctions.\n");
2815 // return JS_FALSE;
2816 //}
2817 if (!JS_SetPrivateFw(cx, _obj, (void*)capabilitiesHandler_getCapabilitiesTable())) {
2818 printf( "JS_SetPrivate failed in ExecutionContext.\n");
2819 return JS_FALSE;
2820 }
2821
2822 JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
2823 }
2824 break;
2825
2826 case 6: //supportedProfiles
2827 {
2828 JSObject *_obj;
2829 //malloc private not needed
2830 _obj = JS_NewObject(cx,&ProfileInfoArrayClass,NULL,obj);
2831 if (!JS_DefineProperties(cx, _obj, ProfileInfoArrayProperties)) {
2832 printf( "JS_DefineProperties failed in ExecutionContextProperties.\n");
2833 return JS_FALSE;
2834 }
2835 //if (!JS_DefineFunctions(cx, _obj, ProfileInfoArrayFunctions)) {
2836 // printf( "JS_DefineProperties failed in ExecutionContextFunctions.\n");
2837 // return JS_FALSE;
2838 //}
2839 //set private not needed
2840 //if (!JS_SetPrivateFw(cx, _obj, ec)) {
2841 // printf( "JS_SetPrivate failed in ExecutionContext.\n");
2842 // return JS_FALSE;
2843 //}
2844
2845 JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
2846 }
2847 break;
2848 case 7: //currentScene
2849#ifdef sceneIsBroto
2850 //someday soon I hope, the ScriptNode._executionContext might be working,
2851 //and give you the currentScene native pointer to put as PRIVATE in BrowserNative
2852#else
2853 //in theory it's rootNode() in
2854 //struct X3D_Group *rootNode()
2855 //H: I have to return an ExecutionContextNative here with its guts set to our rootNode or ???
2856 {
2857 JSObject *_obj;
2858 _obj = JS_NewObject(cx,&ExecutionContextClass,NULL,obj);
2859 //if(!ec)
2860 // ec = (struct X3D_Node*)rootNode(); //change this to (Script)._executionContext when brotos working fully
2861 if(0) if (!JS_DefineProperties(cx, _obj, ExecutionContextProperties)) {
2862 printf( "JS_DefineProperties failed in ExecutionContextProperties.\n");
2863 return JS_FALSE;
2864 }
2865 if(0) if (!JS_DefineFunctions(cx, _obj, ExecutionContextFunctions)) {
2866 printf( "JS_DefineProperties failed in ExecutionContextFunctions.\n");
2867 return JS_FALSE;
2868 }
2869
2870 if (!JS_SetPrivateFw(cx, _obj, ec)) {
2871 printf( "JS_SetPrivate failed in ExecutionContext.\n");
2872 return JS_FALSE;
2873 }
2874
2875 JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
2876
2877 }
2878
2879#endif
2880 }
2881
2882 return JS_TRUE;
2883}
2884
2885
2886JSBool
2887BrowserSetProperty(JSContext *cx, JS::Handle<JSObject*> hobj, JS::Handle<jsid> hiid, JSBool strict, JS::MutableHandle<JS::Value> hvp){
2888 JSObject *obj = *hobj.address();
2889 jsid iid = *hiid.address();
2890 jsval *vp = hvp.address();
2891
2892 BrowserNative *ptr;
2893 jsval _val;
2894 JSString *ss;
2895 char *cs;
2896
2897 jsval id;
2898 if (!JS_IdToValue(cx,iid,&id)) {
2899 printf("JS_IdToValue failed in BrowserSetProperty.\n");
2900 return JS_FALSE;
2901 }
2902
2903
2904 if ((ptr = (BrowserNative *)JS_GetPrivateFw(cx, obj)) == NULL) {
2905 printf( "JS_GetPrivate failed in BrowserSetProperty.\n");
2906 return JS_FALSE;
2907 }
2908 //ptr->valueChanged++;
2909
2910 if (!JS_ConvertValue(cx, *vp, JSTYPE_STRING, &_val)) {
2911 printf( "JS_ConvertValue failed in BrowserSetProperty.\n");
2912 return JS_FALSE;
2913 }
2914
2915 if (JSVAL_IS_INT(id)) {
2916 switch (JSVAL_TO_INT(id)) {
2917 case 0:
2918 case 1:
2919 case 2:
2920 case 3:
2921 return JS_FALSE;
2922 case 4: //description
2923 ss = JS_ValueToString(cx, _val);
2924 cs = JS_EncodeString(cx, ss);
2925 update_status(cs); //script node setting the statusbar text
2926 break;
2927 case 5:
2928 case 6:
2929 case 7:
2930 return JS_FALSE;
2931
2932 }
2933 }
2934 return JS_TRUE;
2935}
2936
2937
2938
2939#endif
2940
2941extern "C" {
2942
2945//jsval JSCreate_global_return_val;
2946typedef struct pjsVRMLBrowser{
2947 int ijunk;
2948
2949 jsval JSCreate_global_return_val;
2950
2951
2952}* ppjsVRMLBrowser;
2953void *jsVRMLBrowser_constructor(){
2954 void *v = MALLOC(void *, sizeof(struct pjsVRMLBrowser));
2955 memset(v,0,sizeof(struct pjsVRMLBrowser));
2956 return v;
2957}
2958void jsVRMLBrowser_init(struct iiglobal::tjsVRMLBrowser *t){
2959 //public
2960 //private
2961 t->prv = jsVRMLBrowser_constructor();
2962 {
2963 ppjsVRMLBrowser p = (ppjsVRMLBrowser)t->prv;
2964 /* Script name/type table */
2965
2966 t->JSCreate_global_return_val = &p->JSCreate_global_return_val;
2967
2968 }
2969
2970}
2971} //extern "C"
2972
2973// ppjsVRMLBrowser p = (ppjsVRMLBrowser)gglobal()->jsVRMLBrowser.prv;
2974/* we add/remove routes with this call */
2975void jsRegisterRoute(
2976 struct X3D_Node* from, int fromOfs,
2977 struct X3D_Node* to, int toOfs,
2978 int len, const char *adrem) {
2979 int ad;
2980
2981 if (strcmp("addRoute",adrem) == 0)
2982 ad = 1;
2983 else ad = 0;
2984
2985 CRoutes_Register(ad, from, fromOfs, to, toOfs , len,
2986 returnInterpolatorPointer(to->_nodeType), 0, 0);
2987}
2988
2989
2990/* used in loadURL*/
2991void conCat (char *out, char *in) {
2992
2993 while (strlen (in) > 0) {
2994 strcat (out," :loadURLStringBreak:");
2995 while (*out != '\0') out++;
2996
2997 if (*in == '[') in++;
2998 while ((*in != '\0') && (*in == ' ')) in++;
2999 if (*in == '"') {
3000 in++;
3001 /* printf ("have the initial quote string here is %s\n",in); */
3002 while (*in != '"') { *out = *in; out++; in++; }
3003 *out = '\0';
3004 /* printf ("found string is :%s:\n",tfilename); */
3005 }
3006
3007 /* skip along to the start of the next name */
3008 if (*in == '"') in++;
3009 if (*in == ',') in++;
3010 if (*in == ']') in++; /* this allows us to leave */
3011 }
3012}
3013
3014
3015
3016void createLoadUrlString(char *out, int outLen, char *url, char *param) {
3017 int commacount1;
3018 int commacount2;
3019 char *tptr;
3020
3021 /* mimic the EAI loadURL, java code is:
3022 // send along sizes of the Strings
3023 SysString = "" + url.length + " " + parameter.length;
3024
3025 for (count=0; count<url.length; count++) {
3026 SysString = SysString + " :loadURLStringBreak:" + url[count];
3027 }
3028
3029 for (count=0; count<parameter.length; count++) {
3030 SysString = SysString + " :loadURLStringBreak:" + parameter[count];
3031 }
3032 */
3033
3034 /* find out how many elements there are */
3035
3036 commacount1 = 0; commacount2 = 0;
3037 tptr = url; while (*tptr != '\0') { if (*tptr == '"') commacount1 ++; tptr++; }
3038 tptr = param; while (*tptr != '\0') { if (*tptr == '"') commacount2 ++; tptr++; }
3039 commacount1 = commacount1 / 2;
3040 commacount2 = commacount2 / 2;
3041
3042 if ((int)(strlen(url) +
3043 strlen(param) +
3044 (commacount1 * strlen (" :loadURLStringBreak:")) +
3045 (commacount2 * strlen (" :loadURLStringBreak:"))) > (outLen - 20)) {
3046 printf ("createLoadUrlString, string too long\n");
3047 return;
3048 }
3049
3050 sprintf (out,"%d %d",commacount1,commacount2);
3051
3052 /* go to the end of this string */
3053 while (*out != '\0') out++;
3054
3055 /* go through the elements and find which (if any) url exists */
3056 conCat (out,url);
3057 while (*out != '\0') out++;
3058 conCat (out,param);
3059}
3060
3061
3062JSBool
3063VrmlBrowserInit(JSContext *context, JSObject *globalObj, BrowserNative *brow)
3064{
3065 JSObject *obj;
3066 ttglobal tg = gglobal();
3067 *(jsval *)tg->jsVRMLBrowser.JSCreate_global_return_val = INT_TO_JSVAL(0);
3068
3069 #ifdef JSVERBOSE
3070 printf("VrmlBrowserInit\n");
3071 #endif
3072
3073 obj = JS_DefineObject(context, globalObj, "Browser", &BrowserClass, NULL,
3074 JSPROP_ENUMERATE | JSPROP_PERMANENT);
3075 if (!JS_DefineFunctions(context, obj, BrowserFunctions)) {
3076 printf( "JS_DefineFunctions failed in VrmlBrowserInit.\n");
3077 return JS_FALSE;
3078 }
3079#ifdef X3DBROWSER
3080
3081 if (!JS_DefineProperties(context, obj, BrowserProperties)) {
3082 printf( "JS_DefineProperties failed in VrmlBrowserInit.\n");
3083 return JS_FALSE;
3084 }
3085#endif
3086 if (!JS_SetPrivateFw(context, obj, brow)) {
3087 printf( "JS_SetPrivate failed in VrmlBrowserInit.\n");
3088 return JS_FALSE;
3089 }
3090 return JS_TRUE;
3091}
3092
3093
3094JSBool
3095VrmlBrowserGetName(JSContext *context, uintN argc, jsval *vp) {
3096 JSObject *obj = JS_THIS_OBJECT(context,vp);
3097 jsval *argv = JS_ARGV(context,vp);
3098
3099 JSString *_str;
3100
3101 UNUSED(obj);
3102 UNUSED(argc);
3103 UNUSED(argv);
3104
3105 _str = JS_NewStringCopyZ(context,BrowserName);
3106 JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
3107
3108 return JS_TRUE;
3109}
3110
3111
3112/* get the string stored in FWVER into a jsObject */
3113JSBool
3114VrmlBrowserGetVersion(JSContext *context, uintN argc, jsval *vp) {
3115 JSObject *obj = JS_THIS_OBJECT(context,vp);
3116 jsval *argv = JS_ARGV(context,vp);
3117
3118 JSString *_str;
3119
3120 UNUSED(obj);
3121 UNUSED(argc);
3122 UNUSED(argv);
3123
3124 _str = JS_NewStringCopyZ(context, libFreeWRL_get_version());
3125 JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
3126 return JS_TRUE;
3127}
3128
3129
3130JSBool
3131VrmlBrowserGetCurrentSpeed(JSContext *context, uintN argc, jsval *vp) {
3132 JSObject *obj = JS_THIS_OBJECT(context,vp);
3133 jsval *argv = JS_ARGV(context,vp);
3134
3135 JSString *_str;
3136 char string[1000];
3137
3138 UNUSED(obj);
3139 UNUSED(argc);
3140 UNUSED(argv);
3141
3142 /* get the variable updated */
3143 getCurrentSpeed();
3144 sprintf (string,"%f",gglobal()->Mainloop.BrowserSpeed);
3145 _str = JS_NewStringCopyZ(context,string);
3146 JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
3147 return JS_TRUE;
3148}
3149
3150
3151JSBool
3152VrmlBrowserGetCurrentFrameRate(JSContext *context, uintN argc, jsval *vp) {
3153 JSObject *obj = JS_THIS_OBJECT(context,vp);
3154 jsval *argv = JS_ARGV(context,vp);
3155
3156 JSString *_str;
3157 char FPSstring[1000];
3158
3159 UNUSED(obj);
3160 UNUSED(argc);
3161 UNUSED(argv);
3162
3163 sprintf (FPSstring,"%6.2f",gglobal()->Mainloop.BrowserFPS);
3164 _str = JS_NewStringCopyZ(context,FPSstring);
3165 JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
3166 return JS_TRUE;
3167}
3168
3169
3170JSBool
3171VrmlBrowserGetWorldURL(JSContext *context, uintN argc, jsval *vp) {
3172 JSObject *obj = JS_THIS_OBJECT(context,vp);
3173 jsval *argv = JS_ARGV(context,vp);
3174
3175 JSString *_str;
3176
3177 UNUSED(obj);
3178 UNUSED(argc);
3179 UNUSED(argv);
3180
3181 _str = JS_NewStringCopyZ(context,BrowserFullPath);
3182 JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
3183 return JS_TRUE;
3184}
3185
3186
3187JSBool
3188VrmlBrowserReplaceWorld(JSContext *context, uintN argc, jsval *vp) {
3189 jsval *argv = JS_ARGV(context,vp);
3190 JSObject *_obj;
3191 JSString *_str;
3192 JSClass *_cls;
3193 jsval _rval = INT_TO_JSVAL(0);
3194 const char *_c_args = "MFNode nodes",
3195 *_c_format = "o";
3196 char *_costr,*tptr;
3197
3198 if (JS_ConvertArguments(context, argc, argv, _c_format, &_obj)) {
3199 if ((_cls = JS_GET_CLASS(context, _obj)) == NULL) {
3200 printf("JS_GetClass failed in VrmlBrowserReplaceWorld.\n");
3201 return JS_FALSE;
3202 }
3203
3204 if (memcmp("MFNode", _cls->name, strlen(_cls->name)) != 0) {
3205 printf( "\nIncorrect argument in VrmlBrowserReplaceWorld.\n");
3206 return JS_FALSE;
3207 }
3208 _str = JS_ValueToString(context, argv[0]);
3209 _costr = JS_EncodeString(context,_str);
3210
3211 /* sanitize string, for the EAI_RW call (see EAI_RW code) */
3212 tptr = _costr;
3213 while (*tptr != '\0') {
3214 if(*tptr == '[') *tptr = ' ';
3215 if(*tptr == ']') *tptr = ' ';
3216 if(*tptr == ',') *tptr = ' ';
3217 tptr++;
3218 }
3219 EAI_RW(_costr);
3220
3221 JS_free(context,_costr);
3222 } else {
3223 printf( "\nIncorrect argument format for replaceWorld(%s).\n", _c_args);
3224 return JS_FALSE;
3225 }
3226 JS_SET_RVAL(context,vp,_rval);
3227
3228 return JS_TRUE;
3229}
3230
3231JSBool
3232VrmlBrowserLoadURL(JSContext *context, uintN argc, jsval *vp) {
3233 jsval *argv = JS_ARGV(context,vp);
3234 JSObject *_obj[2];
3235 JSString *_str[2];
3236 JSClass *_cls[2];
3237 const char *_c_args = "MFString url, MFString parameter",
3238 *_c_format = "o o";
3239 #define myBufSize 2000
3240 char *_costr[2];
3241 char myBuf[myBufSize];
3242
3243 if (JS_ConvertArguments(context, argc, argv, _c_format, &(_obj[0]), &(_obj[1]))) {
3244 if ((_cls[0] = JS_GET_CLASS(context, _obj[0])) == NULL) {
3245 printf( "JS_GetClass failed for arg 0 in VrmlBrowserLoadURL.\n");
3246 return JS_FALSE;
3247 }
3248 if ((_cls[1] = JS_GET_CLASS(context, _obj[1])) == NULL) {
3249 printf( "JS_GetClass failed for arg 1 in VrmlBrowserLoadURL.\n");
3250 return JS_FALSE;
3251 }
3252 if (memcmp("MFString", (_cls[0])->name, strlen((_cls[0])->name)) != 0 &&
3253 memcmp("MFString", (_cls[1])->name, strlen((_cls[1])->name)) != 0) {
3254 printf( "\nIncorrect arguments in VrmlBrowserLoadURL.\n");
3255 return JS_FALSE;
3256 }
3257 _str[0] = JS_ValueToString(context, argv[0]);
3258 _costr[0] = JS_EncodeString(context,_str[0]);
3259
3260 _str[1] = JS_ValueToString(context, argv[1]);
3261 _costr[1] = JS_EncodeString(context,_str[1]);
3262
3263 /* we use the EAI code for this - so reformat this for the EAI format */
3264 {
3265 //extern struct X3D_Anchor EAI_AnchorNode; /* win32 C doesnt like new declarations in the middle of executables - start a new scope {} and put dec at top */
3266
3267 /* make up the URL from what we currently know */
3268 createLoadUrlString(myBuf,myBufSize,_costr[0], _costr[1]);
3269 createLoadURL(myBuf);
3270
3271 /* now tell the fwl_RenderSceneUpdateScene that BrowserAction is requested... */
3272 setAnchorsAnchor( get_EAIEventsIn_AnchorNode()); //&gglobal()->EAIEventsIn.EAI_AnchorNode;
3273 }
3274 gglobal()->RenderFuncs.BrowserAction = TRUE;
3275
3276 JS_free(context,_costr[0]);
3277 JS_free(context,_costr[1]);
3278 } else {
3279 printf( "\nIncorrect argument format for loadURL(%s).\n", _c_args);
3280 return JS_FALSE;
3281 }
3282 JS_SET_RVAL(context,vp,INT_TO_JSVAL(0)); //JSVAL_ZERO);
3283
3284 return JS_TRUE;
3285}
3286
3287
3288JSBool
3289VrmlBrowserSetDescription(JSContext *context, uintN argc, jsval *vp) {
3290 jsval *argv = JS_ARGV(context,vp);
3291 JSString *js_c;
3292 const char *_c_format = "S", *_c_args = "SFString description";
3293 char *_c;
3294
3295 UNUSED(_c); // compiler warning mitigation
3296
3297 if (argc == 1 &&
3298 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
3299 /* _c = JS_EncodeString(context,js_c);
3300 ...why encode the string when we just have to JS_free it later? */
3301
3302 /* we do not do anything with the description. If we ever wanted to, it is in _c */
3303 JS_SET_RVAL(context,vp,INT_TO_JSVAL(0)); //JSVAL_ZERO);
3304 } else {
3305 printf( "\nIncorrect argument format for setDescription(%s).\n", _c_args);
3306 return JS_FALSE;
3307 }
3308 return JS_TRUE;
3309}
3310
3311//new May 2022 based on jsVRML_SFClasses_sm.cpp SFNodeConstr handling of js new SfNode('Shape{}');
3312
3313JSBool
3314VrmlBrowserCreateVrmlFromString(JSContext* context, uintN argc, jsval* vp) {
3315 //JSObject* obj = JS_THIS_OBJECT(context, vp);
3316 JSObject* obj = JS_NewObject(context, &MFNodeClass, NULL, NULL);
3317 ADD_ROOT(cx, obj)
3318
3319 jsval* argv = JS_ARGV(context, vp);
3320 const char* _c_format = "S", * _c_args = "SFString vrmlSyntax";
3321 JSString* js_c;
3322
3323 char* _c;
3324
3325 /* for the return of the nodes */
3326 struct X3D_Group* retGroup;
3327 struct Multi_Node* newHandle = NULL;
3328
3329 if (argc == 1 &&
3330 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
3331 _c = JS_EncodeString(context, js_c);
3332
3333#ifdef JSVERBOSE
3334 printf("VrmlBrowserCreateVrmlFromString: obj = %u, str = \"%s\"\n",
3335 obj, _c);
3336#endif
3337
3338 {
3339 resource_item_t* res = resource_create_from_string(_c);
3340 struct X3D_Group* myGroup = (struct X3D_Group*)createNewX3DNode(NODE_Group);
3341 res->whereToPlaceData = myGroup;
3342 res->ectx = JS_GetContextPrivate(context); //executionContext the script is in, stored using JS_SetContextPrivate
3343 res->offsetFromWhereToPlaceData = (int)offsetof(struct X3D_Group, children);
3344 res->media_type = resm_vrml;
3345 res->parsed_request = strdup("From the EAI bootcamp of life ");
3346 parser_process_res_VRML_X3D(res);
3347 newHandle = &(myGroup->children);
3348
3349 AnyNative* lhs;
3350 if ((lhs = (AnyNative*)AnyNativeNew(FIELDTYPE_MFNode, NULL, NULL)) == NULL) {
3351 printf("AnyNativeNew failed in SFNodeConstr.\n");
3352 return JS_FALSE;
3353 }
3354 if (!JS_SetPrivateFw(context, obj, lhs)) {
3355 printf("JS_SetPrivate failed in SFNodeConstr.\n");
3356 return JS_FALSE;
3357 }
3358 //lhs->valueChanged = NULL;
3359 lhs->v->mfnode = *newHandle;
3360 }
3361
3362 JS_free(context, _c);
3363 }
3364 else {
3365 printf("\nIncorrect argument format for createVrmlFromString(%s).\n", _c_args);
3366 return JS_FALSE;
3367 }
3368
3369 JS_SET_RVAL(context, vp, OBJECT_TO_JSVAL(obj));
3370 return JS_TRUE;
3371}
3372
3373
3374
3375
3376JSBool
3377VrmlBrowserCreateX3DFromString(JSContext* context, uintN argc, jsval* vp) {
3378 //JSObject* obj = JS_THIS_OBJECT(context, vp);
3379 JSObject* obj = JS_NewObject(context, &MFNodeClass, NULL, NULL);
3380 ADD_ROOT(cx, obj)
3381
3382 jsval* argv = JS_ARGV(context, vp);
3383 const char* _c_format = "S", * _c_args = "SFString x3dSyntax";
3384 JSString* js_c;
3385
3386 char* _c;
3387
3388 /* for the return of the nodes */
3389 struct X3D_Group* retGroup;
3390 struct Multi_Node* newHandle = NULL;
3391
3392 if (argc == 1 &&
3393 JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
3394 _c = JS_EncodeString(context, js_c);
3395
3396#ifdef JSVERBOSE
3397 printf("VrmlBrowserCreateVrmlFromString: obj = %u, str = \"%s\"\n",
3398 obj, _c);
3399#endif
3400
3401 {
3402 resource_item_t* res = resource_create_from_string(_c);
3403 struct X3D_Group* myGroup = (struct X3D_Group*)createNewX3DNode(NODE_Group);
3404 res->whereToPlaceData = myGroup;
3405 res->ectx = JS_GetContextPrivate(context); //executionContext the script is in, stored using JS_SetContextPrivate
3406 res->offsetFromWhereToPlaceData = (int)offsetof(struct X3D_Group, children);
3407 res->media_type = resm_x3d;
3408 res->parsed_request = strdup("From the EAI bootcamp of life ");
3409 parser_process_res_VRML_X3D(res);
3410 newHandle = &(myGroup->children);
3411
3412 AnyNative* lhs;
3413 if ((lhs = (AnyNative*)AnyNativeNew(FIELDTYPE_MFNode, NULL, NULL)) == NULL) {
3414 printf("AnyNativeNew failed in SFNodeConstr.\n");
3415 return JS_FALSE;
3416 }
3417 if (!JS_SetPrivateFw(context, obj, lhs)) {
3418 printf("JS_SetPrivate failed in SFNodeConstr.\n");
3419 return JS_FALSE;
3420 }
3421 //lhs->valueChanged = NULL;
3422 lhs->v->mfnode = *newHandle;
3423 }
3424
3425 JS_free(context, _c);
3426 }
3427 else {
3428 printf("\nIncorrect argument format for createX3dFromString(%s).\n", _c_args);
3429 return JS_FALSE;
3430 }
3431
3432 JS_SET_RVAL(context, vp, OBJECT_TO_JSVAL(obj));
3433 return JS_TRUE;
3434}
3435
3436JSBool
3437VrmlBrowserCreateVrmlFromURL(JSContext *context, uintN argc, jsval *vp) {
3438 jsval *argv = JS_ARGV(context,vp);
3439 jsval _my_rval;
3440 jsval *rval = &_my_rval;
3441
3442 JSString *_str[2];
3443 JSClass *_cls[2];
3444 SFNodeNative *oldPtr;
3445 char *fieldStr,
3446 *_costr0;
3447 struct X3D_Node *myptr;
3448 #define myFileSizeLimit 4000
3449
3450/* DJ Tue May 4 21:25:15 BST 2010 Old stuff, no longer applicable
3451 int count;
3452 int offset;
3453 int fromtype;
3454 int xxx;
3455 int myField;
3456 char *address;
3457 struct X3D_Group *subtree;
3458*/
3459 resource_item_t *res = NULL;
3460 int fieldInt;
3461 int offs;
3462 int type;
3463 int accessType;
3464 struct Multi_String url;
3465
3466
3467 #ifdef JSVERBOSE
3468 printf ("JS start of createVrmlFromURL\n");
3469 #endif
3470
3471 /* rval is always zero, so lets just set it */
3472 *rval = INT_TO_JSVAL(0); //JSVAL_ZERO;
3473
3474 /* first parameter - expect a MFString Object here */
3475 //if (JSVAL_IS_OBJECT(argv[0])) {
3476 if (argv[0].isObject()) {
3477 if ((_cls[0] = JS_GET_CLASS(context, JSVAL_TO_OBJECT(argv[0]))) == NULL) {
3478 printf( "JS_GetClass failed for arg 0 in VrmlBrowserLoadURL.\n");
3479 return JS_FALSE;
3480 }
3481 } else {
3482 printf ("VrmlBrowserCreateVrmlFromURL - expect first parameter to be an object\n");
3483 return JS_FALSE;
3484 }
3485
3486 /* second parameter - expect a SFNode Object here */
3487 //if (JSVAL_IS_OBJECT(argv[1])) {
3488 if (argv[1].isObject()) {
3489 if ((_cls[1] = JS_GET_CLASS(context, JSVAL_TO_OBJECT(argv[1]))) == NULL) {
3490 printf( "JS_GetClass failed for arg 1 in VrmlBrowserLoadURL.\n");
3491 return JS_FALSE;
3492 }
3493 } else {
3494 printf ("VrmlBrowserCreateVrmlFromURL - expect first parameter to be an object\n");
3495 return JS_FALSE;
3496 }
3497
3498 #ifdef JSVERBOSE
3499 printf ("JS createVrml - step 2\n");
3500 printf ("JS create - we should havve a MFString and SFNode, have :%s: :%s:\n",(_cls[0])->name, (_cls[1])->name);
3501 #endif
3502
3503 /* make sure these 2 objects are really MFString and SFNode */
3504 if (memcmp("MFString", (_cls[0])->name, strlen((_cls[0])->name)) != 0 &&
3505 memcmp("SFNode", (_cls[1])->name, strlen((_cls[1])->name)) != 0) {
3506 printf( "Incorrect arguments in VrmlBrowserLoadURL.\n");
3507 return JS_FALSE;
3508 }
3509
3510 /* third parameter should be a string */
3511 if (JSVAL_IS_STRING(argv[2])) {
3512 _str[1] = JSVAL_TO_STRING(argv[2]);
3513 fieldStr = JS_EncodeString(context,_str[1]);
3514
3515 #ifdef JSVERBOSE
3516 printf ("field string is :%s:\n",fieldStr);
3517 #endif
3518 } else {
3519 printf ("Expected a string in createVrmlFromURL\n");
3520 return JS_FALSE;
3521 }
3522
3523 #ifdef JSVERBOSE
3524 printf ("passed object type tests\n");
3525 #endif
3526
3527 /* get the URL listing as a string */
3528 _str[0] = JS_ValueToString(context, argv[0]);
3529 _costr0 = JS_EncodeString(context,_str[0]);
3530
3531 #ifdef JSVERBOSE
3532 printf ("URL string is %s\n",_costr0);
3533 #endif
3534
3535
3536 /* get a pointer to the SFNode structure, in order to properly place the new string */
3537 if ((oldPtr = (SFNodeNative *)JS_GetPrivateFw(context, JSVAL_TO_OBJECT(argv[1]))) == NULL) {
3538 printf( "JS_GetPrivate failed in VrmlBrowserLoadURL for SFNode parameter.\n");
3539
3540 JS_free(context,_costr0);
3541 JS_free(context,fieldStr);
3542
3543 return JS_FALSE;
3544 }
3545 myptr = X3D_NODE(oldPtr->handle);
3546 if (myptr == NULL) {
3547 printf ("CreateVrmlFromURL, internal error - SFNodeNative memory pointer is NULL\n");
3548
3549 JS_free(context,_costr0);
3550 JS_free(context,fieldStr);
3551
3552 return JS_FALSE;
3553 }
3554
3555
3556 #ifdef JSVERBOSE
3557 printf ("SFNode handle %d, old X3DString %s\n",oldPtr->handle, oldPtr->X3DString);
3558 printf ("myptr %d\n",myptr);
3559 printf ("points to a %s\n",stringNodeType(myptr->_nodeType));
3560 #endif
3561
3562
3563 /* bounds checks */
3564 if (sizeof (_costr0) > (myFileSizeLimit-200)) {
3565 printf ("VrmlBrowserCreateVrmlFromURL, url too long...\n");
3566
3567 JS_free(context,_costr0);
3568 JS_free(context,fieldStr);
3569
3570 return JS_FALSE;
3571 }
3572
3573 /* ok - here we have:
3574 _costr0 : the url string array; eg: [ "vrml.wrl" ]
3575 opldPtr : pointer to a SFNode, with oldPtr->handle as C memory location.
3576 fielsStr : the field to send this to, eg: addChildren
3577 */
3578
3579 url.n = 0;
3580 url.p = NULL;
3581
3582 /* parse the string, put it into the "url" struct defined here */
3583 Parser_scanStringValueToMem(X3D_NODE(&url),0,FIELDTYPE_MFString, _costr0, FALSE);
3584
3585 /* find a file name that exists. If not, return JS_FALSE */
3586 res = resource_create_multi(&url);
3587 res->whereToPlaceData = myptr;
3588
3589
3590 /* lets see if this node has a routed field fromTo = 0 = from node, anything else = to node */
3591 fieldInt = findRoutedFieldInFIELDNAMES (myptr, fieldStr, TRUE);
3592
3593 if (fieldInt >=0) {
3594 findFieldInOFFSETS(myptr->_nodeType, fieldInt, &offs, &type, &accessType);
3595 } else {
3596 ConsoleMessage ("Can not find field :%s: in nodeType :%s:",fieldStr,stringNodeType(myptr->_nodeType));
3597
3598 JS_free(context,_costr0);
3599 JS_free(context,fieldStr);
3600
3601 return JS_FALSE;
3602 }
3603
3604 /* printf ("type of field %s, accessType %s\n",stringFieldtypeType(type),stringKeywordType(accessType)); */
3605 res->offsetFromWhereToPlaceData = offs;
3606 parser_process_res_VRML_X3D(res);
3607 //send_resource_to_parser(res);
3608 //resource_wait(res);
3609 //
3610 //if (res->status == ress_parsed) {
3611 // /* Cool :) */
3612 //}
3613
3614 MARK_EVENT(myptr,offs);
3615
3616 JS_SET_RVAL(context,vp,*rval);
3617 JS_free(context,fieldStr);
3618 JS_free(context,_costr0);
3619
3620 return JS_TRUE;
3621}
3622
3623JSBool
3624VrmlBrowserAddRoute(JSContext *context, uintN argc, jsval *vp) {
3625 JSObject *obj = JS_THIS_OBJECT(context,vp);
3626 jsval *argv = JS_ARGV(context,vp);
3627
3628 if (!doVRMLRoute(context, obj, argc, argv, "addRoute")) {
3629 printf( "doVRMLRoute failed in VrmlBrowserAddRoute.\n");
3630 return JS_FALSE;
3631 }
3632 JS_SET_RVAL(context,vp,INT_TO_JSVAL(0)); //JSVAL_ZERO);
3633 return JS_TRUE;
3634}
3635
3636JSBool
3637VrmlBrowserPrint(JSContext *context, uintN argc, jsval *vp) {
3638 JSObject *obj = JS_THIS_OBJECT(context,vp);
3639 jsval *argv = JS_ARGV(context,vp);
3640 unsigned int count;
3641 JSString *_str;
3642 char *_id_c;
3643
3644 UNUSED (context); UNUSED(obj);
3645 /* printf ("FreeWRL:javascript: "); */
3646 for (count=0; count < argc; count++) {
3647 if (JSVAL_IS_STRING(argv[count])) {
3648 _str = JSVAL_TO_STRING(argv[count]);
3649 _id_c = JS_EncodeString(context,_str);
3650 // OLD_IPHONE_AQUA #if defined(AQUA) || defined(_MSC_VER)
3651 #if defined(AQUA) || defined(_MSC_VER)
3652 ConsoleMessage(_id_c); /* statusbar hud */
3653 gglobal()->ConsoleMessage.consMsgCount = 0; /* reset the "Maximum" count */
3654 #else
3655 #ifdef HAVE_NOTOOLKIT
3656 printf ("%s", _id_c);
3657 #else
3658 printf ("%s\n", _id_c);
3659 ConsoleMessage(_id_c); /* statusbar hud */
3660 gglobal()->ConsoleMessage.consMsgCount = 0; /* reset the "Maximum" count */
3661 #endif
3662 #endif
3663 JS_free(context,_id_c);
3664 } else {
3665 /* printf ("unknown arg type %d\n",count); */
3666 }
3667 }
3668 /* the \n should be done with println below, or in javascript print("\n");
3669 except web3d V3 specs don't have Browser.println so print will do \n like the old days*/
3670 JS_SET_RVAL(context,vp,INT_TO_JSVAL(0)); //JSVAL_ZERO);
3671 return JS_TRUE;
3672}
3673
3674JSBool
3675VrmlBrowserPrintln(JSContext *context, uintN argc, jsval *vp) {
3676 /* note, vp holds rval, since it is set in here we should be good */
3677 //VrmlBrowserPrint(context,argc,vp);
3678
3680 //#if defined(AQUA) || defined(_MSC_VER)
3681 // //ConsoleMessage("\n"); /* statusbar hud */
3682 // gglobal()->ConsoleMessage.consMsgCount = 0; /* reset the "Maximum" count */
3683 //#else
3684 // #ifdef HAVE_NOTOOLKIT
3685 // printf ("\n");
3686 // #endif
3687 //#endif
3688
3689 JSObject* obj = JS_THIS_OBJECT(context, vp);
3690 jsval* argv = JS_ARGV(context, vp);
3691 unsigned int count;
3692 JSString* _str;
3693 char* _id_c;
3694
3695 UNUSED(context); UNUSED(obj);
3696 /* printf ("FreeWRL:javascript: "); */
3697 for (count = 0; count < argc; count++) {
3698 if (JSVAL_IS_STRING(argv[count])) {
3699 _str = JSVAL_TO_STRING(argv[count]);
3700 _id_c = JS_EncodeString(context, _str);
3701 // OLD_IPHONE_AQUA #if defined(AQUA) || defined(_MSC_VER)
3702#if defined(AQUA) || defined(_MSC_VER)
3703 ConsoleMessage(_id_c); /* statusbar hud */
3704 gglobal()->ConsoleMessage.consMsgCount = 0; /* reset the "Maximum" count */
3705#else
3706#ifdef HAVE_NOTOOLKIT
3707 printf("%s", _id_c);
3708#else
3709 printf("%s\n", _id_c);
3710 ConsoleMessage(_id_c); /* statusbar hud */
3711 gglobal()->ConsoleMessage.consMsgCount = 0; /* reset the "Maximum" count */
3712#endif
3713#endif
3714 JS_free(context, _id_c);
3715 }
3716 else {
3717 /* printf ("unknown arg type %d\n",count); */
3718 }
3719 }
3720 /* the \n should be done with println below, or in javascript print("\n");
3721 except web3d V3 specs don't have Browser.println so print will do \n like the old days*/
3722 // OLD_IPHONE_AQUA #if defined(AQUA) || defined(_MSC_VER)
3723#if defined(AQUA) || defined(_MSC_VER)
3724 ConsoleMessage("\n"); /* statusbar hud */
3725 gglobal()->ConsoleMessage.consMsgCount = 0; /* reset the "Maximum" count */
3726#elif !defined(_MSC_VER)
3727#ifdef HAVE_NOTOOLKIT
3728 printf("\n");
3729#endif
3730#endif
3731 JS_SET_RVAL(context, vp, INT_TO_JSVAL(0)); //JSVAL_ZERO);
3732 return JS_TRUE;
3733}
3734
3735JSBool
3736VrmlBrowserDeleteRoute(JSContext *context, uintN argc, jsval *vp) {
3737 JSObject *obj = JS_THIS_OBJECT(context,vp);
3738 jsval *argv = JS_ARGV(context,vp);
3739
3740 if (!doVRMLRoute(context, obj, argc, argv, "deleteRoute")) {
3741 printf( "doVRMLRoute failed in VrmlBrowserDeleteRoute.\n");
3742 return JS_FALSE;
3743 }
3744
3745 JS_SET_RVAL(context,vp,INT_TO_JSVAL(0)); //JSVAL_ZERO);
3746 return JS_TRUE;
3747}
3748
3749/****************************************************************************************/
3750
3751
3752/****************************************************************************************************/
3753
3754/* internal to add/remove a ROUTE */
3755static JSBool doVRMLRoute(JSContext *context, JSObject *obj, uintN argc, jsval *argv, const char *callingFunc) {
3756 JSObject *fromNodeObj, *toNodeObj;
3757 SFNodeNative *fromNative, *toNative;
3758 JSClass *_cls[2];
3759 char
3760 *fromFieldString, *toFieldString;
3761 const char *_c_args =
3762 "SFNode fromNode, SFString fromEventOut, SFNode toNode, SFString toEventIn",
3763 *_c_format = "oSoS";
3764 JSString *fromFieldStringJS, *toFieldStringJS;
3765 struct X3D_Node *fromNode;
3766 struct X3D_Node *toNode;
3767 int fromOfs, toOfs, len;
3768 int fromtype, totype;
3769 int xxx;
3770 int myField;
3771
3772 /* first, are there 4 arguments? */
3773 if (argc != 4) {
3774 printf ("Problem with script - add/delete route command needs 4 parameters\n");
3775 return JS_FALSE;
3776 }
3777
3778 /* get the arguments, and ensure that they are obj, string, obj, string */
3779 if (JS_ConvertArguments(context, argc, argv, _c_format,
3780 &fromNodeObj, &fromFieldStringJS, &toNodeObj, &toFieldStringJS)) {
3781 fromFieldString = JS_EncodeString(context,fromFieldStringJS);
3782 toFieldString = JS_EncodeString(context,toFieldStringJS);
3783
3784 if ((_cls[0] = JS_GET_CLASS(context, fromNodeObj)) == NULL) {
3785 printf("JS_GetClass failed for arg 0 in doVRMLRoute called from %s.\n",
3786 callingFunc);
3787 return JS_FALSE;
3788 }
3789 if ((_cls[1] = JS_GET_CLASS(context, toNodeObj)) == NULL) {
3790 printf("JS_GetClass failed for arg 2 in doVRMLRoute called from %s.\n",
3791 callingFunc);
3792 return JS_FALSE;
3793 }
3794
3795 /* make sure these are both SFNodes */
3796 if (memcmp("SFNode", (_cls[0])->name, strlen((_cls[0])->name)) != 0 &&
3797 memcmp("SFNode", (_cls[1])->name, strlen((_cls[1])->name)) != 0) {
3798 printf("\nArguments 0 and 2 must be SFNode in doVRMLRoute called from %s(%s): %s\n",
3799 callingFunc, _c_args, callingFunc);
3800 return JS_FALSE;
3801 }
3802
3803 /* get the "private" data for these nodes. It will consist of a SFNodeNative structure */
3804 if ((fromNative = (SFNodeNative *)JS_GetPrivateFw(context, fromNodeObj)) == NULL) {
3805 printf ("problem getting native props\n");
3806 return JS_FALSE;
3807 }
3808 if ((toNative = (SFNodeNative *)JS_GetPrivateFw(context, toNodeObj)) == NULL) {
3809 printf ("problem getting native props\n");
3810 return JS_FALSE;
3811 }
3812 /* get the "handle" for the actual memory pointer */
3813 fromNode = X3D_NODE(fromNative->handle);
3814 toNode = X3D_NODE(toNative->handle);
3815
3816 #ifdef JSVERBOSE
3817 printf ("routing from a node of type %s to a node of type %s\n",
3818 stringNodeType(fromNode->_nodeType),
3819 stringNodeType(toNode->_nodeType));
3820 #endif
3821
3822 /* From field */
3823 /* try finding it, maybe with a "set_" or "changed" removed */
3824 myField = findRoutedFieldInFIELDNAMES(fromNode,fromFieldString,0);
3825 if (myField == -1)
3826 myField = findRoutedFieldInFIELDNAMES(fromNode,fromFieldString,1);
3827
3828 /* find offsets, etc */
3829 findFieldInOFFSETS(fromNode->_nodeType, myField, &fromOfs, &fromtype, &xxx);
3830
3831 /* To field */
3832 /* try finding it, maybe with a "set_" or "changed" removed */
3833 myField = findRoutedFieldInFIELDNAMES(toNode,toFieldString,0);
3834 if (myField == -1)
3835 myField = findRoutedFieldInFIELDNAMES(toNode,toFieldString,1);
3836
3837 /* find offsets, etc */
3838 findFieldInOFFSETS(toNode->_nodeType, myField, &toOfs, &totype, &xxx);
3839
3840 /* do we have a mismatch here? */
3841 if (fromtype != totype) {
3842 printf ("Javascript routing problem - can not route from %s to %s\n",
3843 stringNodeType(fromNode->_nodeType),
3844 stringNodeType(toNode->_nodeType));
3845 return JS_FALSE;
3846 }
3847
3848 len = returnRoutingElementLength(totype);
3849
3850 jsRegisterRoute(fromNode, fromOfs, toNode, toOfs, len,callingFunc);
3851
3852 JS_free(context,fromFieldString);
3853 JS_free(context,toFieldString);
3854
3855 } else {
3856 printf( "\nIncorrect argument format for %s(%s).\n",
3857 callingFunc, _c_args);
3858 return JS_FALSE;
3859 }
3860
3861 return JS_TRUE;
3862}
3863
3864struct JSLoadPropElement {
3865 JSClass* fwclass;
3866 //void *constr;
3867 JSBool(*constr)(JSContext*, unsigned int, jsval*);
3868 void* Functions;
3869 void* Properties;
3870 const char* id;
3871};
3872struct JSLoadPropElement JSLoadPropsAux[] = {
3873
3874 // done separately { &BrowserClass, NULL, &BrowserFunctions, &BrowserProperties, "BrowserClass"},
3875 { &ExecutionContextClass, NULL, &ExecutionContextFunctions, &ExecutionContextProperties, "ExecutionContextClass"},
3876 { &ComponentInfoClass, NULL, NULL, &ComponentInfoProperties, "ComponentInfoClass"},
3877 { &ComponentInfoArrayClass, NULL, NULL, &ComponentInfoArrayProperties, "ComponentInforArrayClass"},
3878 { &ProfileInfoClass, NULL, NULL, &ProfileInfoProperties, "ProfileInfoClass"},
3879 { &ProfileInfoArrayClass, NULL, NULL, &ProfileInfoArrayProperties, "ProfileInfoArrayClass"},
3880 { &X3DRouteClass, NULL, &X3DRouteFunctions, &X3DRouteProperties, "X3DRouteClass"},
3881 { &RouteArrayClass, NULL, NULL, &RouteArrayProperties, "RouteArrayClass"},
3882 { &ProtoDeclarationArrayClass, NULL, NULL, &ProtoDeclarationArrayProperties, "ProtoDeclarationArrayClass"},
3883 { &ProtoDeclarationClass, NULL, &ProtoDeclarationFunctions, &ProtoDeclarationProperties, "ProtoDeclarationClass"},
3884 { &FieldDefinitionArrayClass, NULL, NULL, &FieldDefinitionArrayProperties, "FieldDefinitionClass"},
3885 { &FieldDefinitionClass, NULL, NULL, &FieldDefinitionProperties, "FieldDefinitionClass"},
3886 { &X3DConstantsClass, NULL, NULL, NULL, "FieldDefinitionClass"},
3887 { NULL, NULL, NULL, NULL, NULL }
3888};
3889
3890/* load the FreeWRL extra classes */
3891JSBool loadAuxiliaryClasses(JSContext* context, JSObject* globalObj) {
3892 jsval v;
3893 int i;
3894
3895 JSObject* myProto;
3896
3897 i = 0;
3898 while (JSLoadPropsAux[i].fwclass != NULL) {
3899#ifdef JSVRMLCLASSESVERBOSE
3900 printf("loading %s\n", JSLoadProps[i].id);
3901#endif
3902
3903 /* v = 0; */
3904 if ((myProto = JS_InitClass(context, globalObj, NULL, JSLoadPropsAux[i].fwclass,
3905 (JSNative)JSLoadPropsAux[i].constr, INIT_ARGC, (JSPropertySpec*)JSLoadPropsAux[i].Properties,
3906 (JSFunctionSpec*)JSLoadPropsAux[i].Functions, NULL, NULL)) == NULL) {
3907 printf("JS_InitClass for %s failed in loadVrmlClasses.\n", JSLoadPropsAux[i].id);
3908 return JS_FALSE;
3909 }
3910 //JS::RootedObject protoObj(context, myProto);
3911 v = OBJECT_TO_JSVAL(myProto);
3912 if (!JS_SetProperty(context, globalObj, JSLoadPropsAux[i].id, &v)) {
3913 printf("JS_SetProperty for %s failed in loadAuxiliaryClasses.\n", JSLoadPropsAux[i].id);
3914 return JS_FALSE;
3915 }
3916
3917 i++;
3918 }
3919 return JS_TRUE;
3920}
3921//dug9 - first look at x3dbrowser and x3dscene/executionContext
3922#ifdef X3DBROWSER
3923/* The Browser's supportedComponents and supportedProfiles are statically defined
3924 in 'bits and pieces' in generatedCode.c and capabilitiesHandler.c and Structs.h.
3925 The Scene/ExecutionContext Profile and Components should be created during parsing
3926 (as of Aug 3, 2013 the parser calls handleProfile() or handleComponent() which
3927 just complains with printfs if freewrl can't handle the scene, and doesn't save them)
3928
3929 For the browser's supportedComponents and supportedProfiles, we'll have
3930 indexable arrays, and on getting an index, we'll construct a throwaway JS object.
3931*/
3932
3933
3934
3935
3936#endif
3937/*
3938ComponentInfo{
3939String name;
3940Numeric level;
3941String Title;
3942String providerUrl;
3943}
3944
3945ComponentInfoArray{
3946numeric length;
3947ComponentInfo [integer index];
3948}
3949
3950
3951ProfileInfo{
3952String name;
3953Numeric level;
3954String Title;
3955String providerUrl;
3956ComonentInfoArray components;
3957}
3958ProfileInfoArray{
3959numeric length;
3960ProfileInfo [integer index];
3961}
3962
3963X3DFieldDefinition{
3964//properties
3965String name;
3966numeric accessType; //e.g.. inputOnly
3967numeric dataType; //e.g. SFBool
3968}
3969
3970FieldDefinitionArray{
3971numeric length;
3972X3DFieldDefinition [integer index];
3973}
3974
3975
3976ProtoDeclaration{
3977//properties
3978String name;
3979FieldDefinitionArray fields;
3980Boolean isExternProto;
3981//functions
3982SFNode newInstance();
3983}
3984
3985ExternProtoDeclaration : ProtoDeclaration {
3986//properties
3987MFString urls;
3988numeric loadState;
3989//functions
3990void loadNow();
3991}
3992
3993ProtoDeclarationArray{
3994numeric length;
3995X3DProtoDeclaration [integer index];
3996}
3997
3998ExternProtoDeclarationArray{
3999numeric length;
4000X3DExternProtoDeclaration [integer index];
4001}
4002
4003Route{
4004}
4005RouteArray{
4006numeric length;
4007Route [integer index];
4008}
4009
4010
4011ExecutionContext{
4012//properties
4013String specificationVersion;
4014String encoding;
4015ProfileInfo profile;
4016ComponentInfoArray components;
4017String worldURL;
4018MFNode rootNodes; //R + writable except in protoInstance
4019ProtoDeclarationArray protos; //RW
4020ExternProtoDeclarationArray externprotos; //RW
4021RouteArray routes;
4022//functions
4023X3DRoute addRoute(SFNode fromNode, String fromReadableField, SFNode toNode, String toWriteableField);
4024void deleteRoute(X3DRoute route);
4025SFNode createNode(String x3dsyntax);
4026SFNode createProto(String x3dsyntax);
4027SFNode getImportedNode(String defname, String);
4028void updateImportedNode(String defname, String);
4029void removeImportedNode(String defname);
4030SFNode getNamedNode(String defname):
4031void updateNamedNode(String defname, SFNode);
4032void removeNamedNode(String defname);
4033}
4034
4035Scene : ExecutionContext{
4036//properties
4037String specificationVersion;
4038//functions
4039void setMetaData(String name, String value);
4040String getMetaData(String name);
4041SFNode getExportedNode(String defname);
4042void updateExportedNode(String defname, SFNode node);
4043void removeExportedNode(String defname);
4044}
4045
4046//just createX3DFromString, createX3DFromURL and replaceWorld differ in signature between VRML and X3D browser classes
4047X3DBrowser{
4048//properties
4049String name;
4050String version;
4051numeric currentSpeed;
4052numeric currentFrameRate;
4053String description; //R/W
4054CompnentInfoArray supportedComponents;
4055ProfileInfoArray supportedProfiles;
4056//functions
4057X3DScene currentScene; //since X3DScene : X3DExecutionContext, use Scene w/flag
4058void replaceWorld(X3DScene);
4059X3DScene createX3DFromString(String x3dsyntax);
4060X3DScene createX3DFromURL(MFString url, String callbackFunctionName, Object cbContextObject);
4061void loadURL(MFString url, MFString parameter);
4062X3DScene importDocument(DOMNode domNodeObject);
4063void getRenderingProperty(String propertyName);
4064void print(Object or String);
4065void println(Object or String);
4066}
4067*/
4068
4069#endif /* !(defined(JAVASCRIPT_STUB) || defined(JAVASCRIPT_DUK) */
4070
4071#endif //defined(JS_SMCPP)