FreeWRL / FreeX3D 4.3.0
jsVRMLBrowser_duk.c
1/*
2
3
4Javascript C language binding.
5
6*/
7
8/****************************************************************************
9 This file is part of the FreeWRL/FreeX3D Distribution.
10
11 Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12
13 FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14 it under the terms of the GNU Lesser Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25****************************************************************************/
26
27/* To do list July 2014
28X3DRoute type is broken
29X3DScene/X3DExecutionContext - functions not implemented relating to protos
30*/
31#include <config.h>
32#include <system.h>
33#if defined(JAVASCRIPT_DUK)
34#include <display.h>
35#include <internal.h>
36
37#include <libFreeWRL.h>
38#include <list.h>
39
40#include "../vrml_parser/Structs.h"
41#include "../vrml_parser/CRoutes.h"
42#include "../opengl/OpenGL_Utils.h"
43#include "../main/headers.h"
44#include "../scenegraph/RenderFuncs.h"
45#include "../vrml_parser/CParseGeneral.h"
46#include "../scenegraph/Vector.h"
47#include "../vrml_parser/CFieldDecls.h"
48#include "../vrml_parser/CParseParser.h"
49#include "../vrml_parser/CParseLexer.h"
50#include "../vrml_parser/CParse.h"
51#include "../main/Snapshot.h"
52#include "../scenegraph/Collision.h"
53#include "../scenegraph/quaternion.h"
54#include "../scenegraph/Viewer.h"
55#include "../x3d_parser/Bindable.h"
56#include "../input/EAIHeaders.h" /* for implicit declarations */
57
58
59#include "JScript.h"
60#include "CScripts.h"
61#include "fieldSet.h"
62#include "FWTYPE.h"
63
64#ifdef DEBUG_MALLOC
65#define malloc(A) MALLOCV(A)
66#define free(A) FREE_IF_NZ(A)
67#define realloc(A,B) REALLOC(A,B)
68#endif
69
70/* The Browser's supportedComponents and supportedProfiles are statically defined
71 in 'bits and pieces' in generatedCode.c and capabilitiesHandler.c and Structs.h.
72 The Scene/ExecutionContext Profile and Components should be created during parsing
73 (as of Aug 3, 2013 the parser calls handleProfile() or handleComponent() which
74 just complains with printfs if freewrl can't handle the scene, and doesn't save them)
75 For the browser's supportedComponents and supportedProfiles, we'll have
76 indexable arrays.
77
78 AUXTYPES are never routed, never assigned to a Script Node's fields. They are never deep copied.
79 But they may have FIELDTYPE properties.
80
81 X3DRoute - as of july 2014 this is 'broken'
82 X3DScene/X3DExecutionContext - not properly implemented
83
84*/
85
86
87
88
89
90/*
91ComonentInfo{
92String name;
93Numeric level;
94String Title;
95String providerUrl;
96}
97
98ComponentInfoArray{
99numeric length;
100ComponentInfo [integer index];
101}
102
103
104ProfileInfo{
105String name;
106Numeric level;
107String Title;
108String providerUrl;
109ComonentInfoArray components;
110}
111ProfileInfoArray{
112numeric length;
113ProfileInfo [integer index];
114}
115
116X3DFieldDefinition{
117//properties
118String name;
119numeric accessType; //e.g.. inputOnly
120numeric dataType; //e.g. SFBool
121}
122
123FieldDefinitionArray{
124numeric length;
125X3DFieldDefinition [integer index];
126}
127
128
129ProtoDeclaration{
130//properties
131String name;
132FieldDefinitionArray fields;
133Boolean isExternProto;
134//functions
135SFNode newInstance();
136}
137
138ExternProtoDeclaration : ProtoDeclaration {
139//properties
140MFString urls;
141numeric loadState;
142//functions
143void loadNow();
144}
145
146ProtoDeclarationArray{
147numeric length;
148X3DProtoDeclaration [integer index];
149}
150
151ExternProtoDeclarationArray{
152numeric length;
153X3DExternProtoDeclaration [integer index];
154}
155
156Route{
157}
158RouteArray{
159numeric length;
160Route [integer index];
161}
162
163
164ExecutionContext{
165//properties
166 String specificationVersion;
167 String encoding;
168 ProfileInfo profile;
169 ComponentInfoArray components;
170 String worldURL;
171 MFNode rootNodes; //R + writable except in protoInstance
172 ProtoDeclarationArray protos; //RW
173 ExternProtoDeclarationArray externprotos; //RW
174 RouteArray routes;
175//functions
176 X3DRoute addRoute(SFNode fromNode, String fromReadableField, SFNode toNode, String toWriteableField);
177 void deleteRoute(X3DRoute route);
178 SFNode createNode(String x3dsyntax);
179 SFNode createProto(String x3dsyntax);
180 SFNode getImportedNode(String defname, String);
181 void updateImportedNode(String defname, String);
182 void removeImportedNode(String defname);
183 SFNode getNamedNode(String defname):
184 void updateNamedNode(String defname, SFNode);
185 void removeNamedNode(String defname);
186}
187
188Scene : ExecutionContext{
189//properties
190 String specificationVersion;
191//functions
192 void setMetaData(String name, String value);
193 String getMetaData(String name);
194 SFNode getExportedNode(String defname);
195 void updateExportedNode(String defname, SFNode node);
196 void removeExportedNode(String defname);
197}
198
199//just createX3DFromString, createX3DFromURL and replaceWorld differ in signature between VRML and X3D browser classes
200X3DBrowser{
201//properties
202 String name;
203 String version;
204 numeric currentSpeed;
205 numeric currentFrameRate;
206 String description; //R/W
207 CompnentInfoArray supportedComponents;
208 ProfileInfoArray supportedProfiles;
209 X3DScene currentScene; //since X3DScene : X3DExecutionContext, use Scene w/flag
210//functions
211 void replaceWorld(X3DScene);
212 X3DScene createX3DFromString(String x3dsyntax);
213 X3DScene createX3DFromURL(MFString url, String callbackFunctionName, Object cbContextObject);
214 void loadURL(MFString url, MFString parameter);
215 X3DScene importDocument(DOMNode domNodeObject);
216 void getRenderingProperty(String propertyName);
217 void print(Object or String);
218 void println(Object or String);
219}
220*/
221
222struct string_int{
223 char *c;
224 int i;
225};
226
227struct string_int lookup_X3DConstants[] = {
228 {"INITIALIZED_EVENT",1},
229 {"SHUTDOWN_EVENT",1},
230 {"CONNECTION_ERROR",1},
231 {"INITIALIZED_ERROR",1},
232 {"NOT_STARTED_STATE",1},
233 {"IN_PROGRESS_STATE",1},
234 {"COMPLETE_STATE",1},
235 {"FAILED_STATE",0},
236 {"SFBool",FIELDTYPE_SFBool},
237 {"MFBool",FIELDTYPE_MFBool},
238 {"MFInt32",FIELDTYPE_MFInt32},
239 {"SFInt32",FIELDTYPE_SFInt32},
240 {"SFFloat",FIELDTYPE_SFFloat},
241 {"MFFloat",FIELDTYPE_MFFloat},
242 {"SFDouble",FIELDTYPE_SFDouble},
243 {"MFDouble",FIELDTYPE_MFDouble},
244 {"SFTime",FIELDTYPE_SFTime},
245 {"MFTime",FIELDTYPE_MFTime},
246 {"SFNode",FIELDTYPE_SFNode},
247 {"MFNode",FIELDTYPE_MFNode},
248 {"SFVec2f",FIELDTYPE_SFVec2f},
249 {"MFVec2f",FIELDTYPE_MFVec2f},
250 {"SFVec3f",FIELDTYPE_SFVec3f},
251 {"MFVec3f",FIELDTYPE_MFVec3f},
252 {"SFVec3d",FIELDTYPE_SFVec3d},
253 {"MFVec3d",FIELDTYPE_MFVec3d},
254 {"SFRotation",FIELDTYPE_SFRotation},
255 {"MFRotation",FIELDTYPE_MFRotation},
256 {"SFColor",FIELDTYPE_SFColor},
257 {"MFColor",FIELDTYPE_MFColor},
258 {"SFImage",FIELDTYPE_SFImage},
259// {"MFImage",FIELDTYPE_MFImage},
260 {"SFColorRGBA",FIELDTYPE_SFColorRGBA},
261 {"MFColorRGBA",FIELDTYPE_MFColorRGBA},
262 {"SFString",FIELDTYPE_SFString},
263 {"MFString",FIELDTYPE_MFString},
264/*
265 {"X3DBoundedObject",},
266 {"X3DMetadataObject",},
267 {"X3DUrlObject",},
268 {"X3DTriggerNode",},
269 {"X3DInfoNode",},
270 {"X3DAppearanceNode",},
271 {"X3DAppearanceChildNode",},
272 {"X3DMaterialNode",},
273 {"X3DTextureNode",},
274 {"X3DTexture2DNode",},
275 {"X3DTexture3DNode",},
276 {"X3DTextureTransformNode",},
277 {"X3DGeometryNode",},
278 {"X3DGeometry3DNode",},
279 {"X3DCoordinateNode",},
280 {"X3DParametricGeometryNode",},
281 {"X3DGeometricPropertyNode",},
282 {"X3DColorNode",},
283 {"X3DProtoInstance",},
284 {"X3DNormalNode",},
285 {"X3DTextureCoordinateNode",},
286 {"X3DFontStyleNode",},
287 {"X3DGroupingNode ",},
288 {"X3DChildNode",},
289 {"X3DBindableNode",},
290 {"X3DBackgroundNode",},
291 {"X3DInterpolatorNode",},
292 {"X3DShapeNode",},
293 {"X3DScriptNode",},
294 {"X3DSensorNode",},
295 {"X3DEnvironmentalSensorNode",},
296 {"X3DLightNode",},
297 {"X3DNetworkSensorNode",},
298 {"X3DPointingDeviceSensorNode",},
299 {"X3DDragSensorNode",},
300 {"X3DKeyDeviceSensorNode",},
301 {"X3DSequencerNode",},
302 {"X3DTimeDependentNode",},
303 {"X3DSoundNode",},
304 {"X3DSoundSourceNode",},
305 {"X3DTouchSensorNode",},
306*/
307 {"inputOnly",PKW_inputOnly},
308 {"outputOnly",PKW_outputOnly},
309 {"inputOutput",PKW_inputOutput},
310 {"initializeOnly",PKW_initializeOnly},
311 {NULL,0}
312};
313
314struct string_int *lookup_string_int(struct string_int *table, const char *searchkey, int *index){
315 int i;
316 //struct string_int *retval = NULL;
317 *index = -1;
318 if(!table) return NULL;
319 i = 0;
320 while(table[i].c){
321 if(!strcmp(table[i].c,searchkey)){
322 //found it
323 (*index) = i;
324 return &table[i];
325 }
326 i++;
327 }
328 return NULL;
329}
330
331int X3DConstantsGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
332 int nr = 1;
333 fwretval->_integer = lookup_X3DConstants[index].i;
334 fwretval->itype = 'I';
335 return nr;
336}
337
338int len_constants(){
339 int len = (sizeof(lookup_X3DConstants) / sizeof(struct string_int)) -1;
340 return len;
341}
342int X3DConstantsIterator(int index, FWType fwt, FWPointer *pointer, const char **name, int *lastProp, int *jndex, char *type, char *readOnly){
343 index ++;
344 (*jndex) = 0;
345 if(index < len_constants()){
346 (*name) = lookup_X3DConstants[index].c;
347 (*jndex) = index;
348 (*lastProp) = index;
349 (*type) = 'I';
350 (*readOnly) = 'T';
351 return index;
352 }
353 return -1;
354}
355struct FWTYPE X3DConstantsType = {
356 AUXTYPE_X3DConstants,
357 'P',
358 "X3DConstants",
359 0, //sizeof(struct X3DRoute),
360 NULL, //no constructor for X3DRoute
361 NULL, //no constructor args
362 NULL, //X3DConstantsProperties - lets have fun and use the custom HAS function
363 X3DConstantsIterator, //custom Iterator function - returns the index used in the Getter and has
364 X3DConstantsGetter,
365 NULL,
366 0,0, //takes int index in prop
367 NULL,
368};
369
370
371
372
373int VRBrowserGetName(FWType fwtype, void *ec, void * fwn, int argc, FWval fwpars, FWval fwretval)
374{
375 fwretval->_string = BrowserName;
376 fwretval->itype = 'S';
377 return 1;
378}
379int VRBrowserGetVersion(FWType fwtype, void *ec, void * fwn, int argc, FWval fwpars, FWval fwretval)
380{
381 fwretval->_string = libFreeWRL_get_version();
382 fwretval->itype = 'S';
383 return 1;
384}
385int VRBrowserGetCurrentSpeed(FWType fwtype, void *ec, void * fwn, int argc, FWval fwpars, FWval fwretval)
386{
387 char string[1000];
388 sprintf (string,"%f",gglobal()->Mainloop.BrowserSpeed);
389 fwretval->_string = strdup(string);
390 fwretval->itype = 'S';
391 return 1;
392}
393
394int VRBrowserGetCurrentFrameRate(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
395{
396 char string[1000];
397 sprintf (string,"%6.2f",gglobal()->Mainloop.BrowserFPS);
398 fwretval->_string = strdup(string);
399 fwretval->itype = 'S';
400 return 1;
401}
402int VRBrowserGetWorldURL(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
403{
404 fwretval->_string = BrowserFullPath;
405 fwretval->itype = 'S';
406 return 1;
407}
408const char *flexiString(FWval fwpars, char *buffer)
409{
410 //allow MFString[0], SFString or ecma String
411 //if buffer is given: MF is converted to '["MF[0]"] ["MF[1]"] [...' format
412 //if buffer is NULL, MF[0] is returned
413 //char *tptr;
414 const char *_costr;
415 int lenbuf = 1000;
416
417 _costr = NULL;
418 //if(fwpars[0].itype == 'S')
419 // _costr = fwpars[0]._string;
420 //else
421 if(fwpars[0].itype == 'W'){
422 switch(fwpars[0]._web3dval.fieldType){
423 case FIELDTYPE_SFString:
424 {
425 //Q. shoulD we ever get in here? SFString is supposed to be represented by an ECMA type in javascript
426 struct Uni_String *sfs = (struct Uni_String*)fwpars[0]._web3dval.native;
427 _costr = sfs->strptr;
428 }
429 break;
430 case FIELDTYPE_MFString:
431 {
432 struct Multi_String *mfs = (struct Multi_String*)fwpars[0]._web3dval.native;
433 if(buffer){
434 int i, l1, l2, l3, lt;
435 char *start = "[\"";
436 char *end = "\"] ";
437 l1 = strlen(start);
438 l2 = strlen(end);
439 buffer[0] = '\0';
440 lt = 1;
441 for(i=0;i<mfs->n;i++){
442 l3 = strlen(mfs->p[i]->strptr);
443 if(lt + l1 + l2 + l3 > lenbuf) break;
444 strcat(buffer,"[\"");
445 strcat(buffer,mfs->p[i]->strptr);
446 strcat(buffer,"\"] ");
447 lt += l1 + l2 + l3;
448 }
449 _costr = buffer;
450 }else{
451 _costr = mfs->p[0]->strptr;
452 }
453 }
454 break;
455 }
456 }
457 return _costr;
458}
459
460int VRBrowserReplaceWorld(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
461{
462 //char *tptr;
463 char*_costr;
464
465 _costr = strdup(flexiString(&fwpars[0],NULL));
466 EAI_RW(_costr);
467 return 0;
468}
469
470
471/* used in loadURL*/
472void conCat_duk (char *out, char *in) {
473
474 while (strlen (in) > 0) {
475 strcat (out," :loadURLStringBreak:");
476 while (*out != '\0') out++;
477
478 if (*in == '[') in++;
479 while ((*in != '\0') && (*in == ' ')) in++;
480 if (*in == '"') {
481 in++;
482 /* printf ("have the initial quote string here is %s\n",in); */
483 while (*in != '"') { *out = *in; out++; in++; }
484 *out = '\0';
485 /* printf ("found string is :%s:\n",tfilename); */
486 }
487
488 /* skip along to the start of the next name */
489 if (*in == '"') in++;
490 if (*in == ',') in++;
491 if (*in == ']') in++; /* this allows us to leave */
492 }
493}
494
495void createLoadUrlString_duk(char *out, int outLen, char *url, char *param) {
496 int commacount1;
497 int commacount2;
498 char *tptr;
499
500 /* mimic the EAI loadURL, java code is:
501 // send along sizes of the Strings
502 SysString = "" + url.length + " " + parameter.length;
503
504 for (count=0; count<url.length; count++) {
505 SysString = SysString + " :loadURLStringBreak:" + url[count];
506 }
507
508 for (count=0; count<parameter.length; count++) {
509 SysString = SysString + " :loadURLStringBreak:" + parameter[count];
510 }
511 */
512
513 /* find out how many elements there are */
514
515 commacount1 = 0; commacount2 = 0;
516 tptr = url; while (*tptr != '\0') { if (*tptr == '"') commacount1 ++; tptr++; }
517 tptr = param; while (*tptr != '\0') { if (*tptr == '"') commacount2 ++; tptr++; }
518 commacount1 = commacount1 / 2;
519 commacount2 = commacount2 / 2;
520
521 if (( strlen(url) +
522 strlen(param) +
523 (commacount1 * strlen (" :loadURLStringBreak:")) +
524 (commacount2 * strlen (" :loadURLStringBreak:"))) > (outLen - 20)) {
525 printf ("createLoadUrlString, string too long\n");
526 return;
527 }
528
529 sprintf (out,"%d %d",commacount1,commacount2);
530
531 /* go to the end of this string */
532 while (*out != '\0') out++;
533
534 /* go through the elements and find which (if any) url exists */
535 conCat_duk (out,url);
536 while (*out != '\0') out++;
537 conCat_duk (out,param);
538}
539struct X3D_Anchor* get_EAIEventsIn_AnchorNode();
540int VRBrowserLoadURL(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
541{
542 char *url, *parameter;
543 char bufferUrl[1000];
544 char bufferParam[1000];
545 char myBuf[1000];
546
547 url = strdup(flexiString(&fwpars[0],bufferUrl));
548 parameter = strdup(flexiString(&fwpars[1],bufferParam));
549 /* we use the EAI code for this - so reformat this for the EAI format */
550 {
551 /* make up the URL from what we currently know */
552 createLoadUrlString_duk(myBuf,1000,url, parameter);
553 createLoadURL(myBuf);
554
555 /* now tell the fwl_RenderSceneUpdateScene that BrowserAction is requested... */
556 setAnchorsAnchor( get_EAIEventsIn_AnchorNode()); //&gglobal().EAIEventsIn.EAI_AnchorNode;
557 }
558 gglobal()->RenderFuncs.BrowserAction = TRUE;
559 return 0;
560}
561int VRBrowserSetDescription(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
562{
563 //const char *_costr = NULL;
564 if(fwpars[0].itype == 'S')
565 gglobal()->Mainloop.BrowserDescription = fwpars[0]._string;
566 return 0;
567}
568int VRBrowserCreateX3DFromString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
569{
570 /* for the return of the nodes */
571 struct X3D_Group *retGroup;
572 int i, iret = 0;
573 //char *xstr;
574 //char *tmpstr;
575 //char *separator;
576 int ra;
577 //int count;
578 //int wantedsize;
579 //int MallocdSize;
580 ttglobal tg = gglobal();
581 struct VRMLParser *globalParser = (struct VRMLParser *)tg->CParse.globalParser;
582 const char *_c = fwpars[0]._string;
583
584 /* do the call to make the VRML code - create a new browser just for this string */
585 retGroup = createNewX3DNode0(NODE_Group); //don't register, we'll gc here
586 gglobal()->ProdCon.savedParser = (void *)globalParser; globalParser = NULL;
587 ra = EAI_CreateX3d("String",_c,ec,retGroup); //includes executionContext for __nodes and __subContexts
588 globalParser = (struct VRMLParser*)gglobal()->ProdCon.savedParser; /* restore it */
589 if(retGroup->children.n > 0) {
590 struct Multi_Node *mfn = (struct Multi_Node *)malloc(sizeof(struct Multi_Node));
591 memcpy(mfn,&retGroup->children,sizeof(struct Multi_Node));
592 FREE_IF_NZ(retGroup);
593 for(i=0;i<mfn->n;i++){
594 mfn->p[i]->_parentVector->n = 0;
595 }
596 fwretval->_web3dval.native = mfn;
597 fwretval->_web3dval.fieldType = FIELDTYPE_MFNode; //Group
598 fwretval->_web3dval.gc = 1; //will be GCd by nodelist
599 fwretval->itype = 'W';
600 iret = 1;
601 }
602 FREE_IF_NZ(retGroup);
603
604
605 return iret;
606}
607//int jsrrunScript(duk_context *ctx, char *script, FWval retval);
608int VRBrowserCreateVrmlFromString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
609{
610 /* for the return of the nodes */
611 struct X3D_Group *retGroup;
612 //char *xstr;
613 //char *tmpstr;
614 //char *separator;
615 int i, ra;
616 int iret; //count,
617 //int wantedsize;
618 //int MallocdSize;
619 ttglobal tg = gglobal();
620 struct VRMLParser *globalParser = (struct VRMLParser *)tg->CParse.globalParser;
621 const char *_c = fwpars[0]._string; //fwpars[0]._web3dval.anyvrml->sfstring->strptr;
622
623 iret = 0;
624 retGroup = createNewX3DNode0(NODE_Group); //don't register, we'll gc here
625 gglobal()->ProdCon.savedParser = (void *)globalParser; globalParser = NULL;
626 ra = EAI_CreateVrml("String",_c,ec,retGroup); //includes executionContext for __nodes and __subContexts
627 globalParser = (struct VRMLParser*)gglobal()->ProdCon.savedParser; /* restore it */
628 if(retGroup->children.n > 0) {
629 struct Multi_Node *mfn = (struct Multi_Node *)malloc(sizeof(struct Multi_Node));
630 memcpy(mfn,&retGroup->children,sizeof(struct Multi_Node));
631 for(i=0;i<mfn->n;i++){
632 mfn->p[i]->_parentVector->n = 0;
633 }
634 fwretval->_web3dval.native = mfn;
635 fwretval->_web3dval.fieldType = FIELDTYPE_MFNode; //Group
636 fwretval->_web3dval.gc = 1; //FIXED for SFNode. //DONT GC - will cause Browser.deleteRoute to bomb. //will be GCd by nodelist but needs gc for text/Fontstyle_place.x3d
637 fwretval->itype = 'W';
638 iret = 1;
639 }
640 deleteVector(struct X3D_Node*,retGroup->_parentVector);
641 FREE_IF_NZ(retGroup);
642
643 return iret;
644
645}
646void *createNewX3DNode(int nt);
647void add_node_to_broto_context(struct X3D_Proto *currentContext,struct X3D_Node *node);
648int VRBrowserCreateNodeFromString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
649{
650 int i, iret, isVRML,isX3D;
651 struct X3D_Node *node;
652 const char *_c = fwpars[0]._string;
653
654 node = NULL;
655 isVRML = FALSE;
656 isX3D = FALSE;
657 iret = 0;
658 for(i=0;i<strlen(_c);i++){
659 if(_c[i] == '<') isX3D = TRUE;
660 if(_c[i] == '{') isVRML = TRUE;
661 }
662 if(!isX3D && !isVRML){
663 //might be just a node name ie createNode('Cone');
664 int ctype;
665 //check builtins
666 ctype = findFieldInNODES(_c);
667 if (ctype > -1) {
668 node = (struct X3D_Node*)createNewX3DNode(ctype);
669 add_node_to_broto_context(ec,node);
670 }
671 //check protos? No: there's a separate createProto() function for those.
672 }
673 if(!node){
674 //more general might have parameters ie createNode("Cone { radius .5 }")
675 if(isVRML)
676 iret = VRBrowserCreateVrmlFromString(fwtype,ec,fwn,argc,fwpars,fwretval);
677 else
678 iret = VRBrowserCreateX3DFromString(fwtype,ec,fwn,argc,fwpars,fwretval);
679 if(iret){
680 node = fwretval->_web3dval.anyvrml->mfnode.p[0];
681 node->_executionContext = ec;
682 }
683 }
684 if(node){
685 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
686 fwretval->_web3dval.anyvrml->sfnode = node;
687 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
688 fwretval->_web3dval.gc = 0;
689 fwretval->itype = 'W';
690 iret = 1;
691 }
692 return iret;
693}
694void send_resource_to_parser_async(resource_item_t *res);
695int VRBrowserCreateVrmlFromURL(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
696{
697 //Browser.createVrmlFromURL(urlString,group,'addChildren');
698 //(MFString,SFNode,string)
699 int i, iret, type,kind,ifield,ifound;
700 union anyVrml *value;
701 struct X3D_Node *target_node;
702 struct Multi_String *url;
703 const char *cfield;
704 resource_item_t *res;
705
706 url = NULL;
707 target_node = NULL;
708 cfield = NULL;
709 if(fwpars[0].itype == 'W')
710 url = &fwpars[0]._web3dval.anyvrml->mfstring;
711
712 if(fwpars[1].itype == 'W')
713 if(fwpars[1]._web3dval.fieldType == FIELDTYPE_SFNode)
714 target_node = fwpars[1]._web3dval.anyvrml->sfnode;
715 if(fwpars[2].itype == 'S')
716 cfield = fwpars[2]._string;
717
718 if(!url || !target_node || !cfield){
719 ConsoleMessage("createX3DFromURL parameters: (MFString url, SFNode target_node, string target_field\n");
720 iret = 0;
721 return iret;
722 }
723 //lookup field on node
724 ifound = getFieldFromNodeAndName(target_node,cfield,&type,&kind,&ifield,&value);
725 if(!ifound){
726 ConsoleMessage("createX3DFromURL no field named %s on nodetype %s\n",cfield,stringNodeType(target_node->_nodeType));
727 iret = 0;
728 return iret;
729 }
730
731
732 //res = resource_create_single(url);
733 res = resource_create_multi(url);
734 res->ectx = ec;
735 res->whereToPlaceData = target_node;
736 res->offsetFromWhereToPlaceData = (int) ((size_t)value - (size_t) target_node); //offsetof (struct X3D_Group, children);
737 //iret = parser_process_res_VRML_X3D(res);
738
739 send_resource_to_parser_async(res);
740 iret = 1;
741 return iret;
742}
743
744/* we add/remove routes with this call */
745void jsRegisterRoute_HIDE(
746 struct X3D_Node* from, int fromOfs,
747 struct X3D_Node* to, int toOfs,
748 int len, const char *adrem) {
749 int ad;
750
751 if (strcmp("addRoute",adrem) == 0)
752 ad = 1;
753 else ad = 0;
754
755 CRoutes_Register(ad, from, fromOfs, to, toOfs , len,
756 returnInterpolatorPointer(to->_nodeType), 0, 0);
757}
758struct brotoRoute *createNewBrotoRoute();
759int getFieldFromNodeAndNameC(struct X3D_Node* node,const char *fieldname, int *type, int *kind, int *iifield, int *builtIn, union anyVrml **value, const char **cname);
760void *addDeleteRoute0(void *fwn, const char* callingFunc, struct X3D_Node* fromNode, const char *sfromField, struct X3D_Node* toNode, const char *stoField){
761 void *retval;
762 int fromType,toType,fromKind,toKind,fromField,toField,fromBuiltIn,toBuiltIn;
763 const char *fromCname,*toCname;
764 int i, len, fromOfs, toOfs;
765 union anyVrml *fromValue, *toValue;
766
767 getFieldFromNodeAndNameC(fromNode,sfromField,&fromType,&fromKind,&fromField,&fromBuiltIn,&fromValue,&fromCname);
768 getFieldFromNodeAndNameC(toNode,stoField,&toType,&toKind,&toField,&toBuiltIn,&toValue,&toCname);
769
770 /* do we have a mismatch here? */
771 if (fromType != toType) {
772 printf ("Javascript routing problem - can not route from %s to %s\n",
773 stringNodeType(fromNode->_nodeType),
774 stringNodeType(toNode->_nodeType));
775 return NULL;
776 }
777
778 len = returnRoutingElementLength(toType);
779 {
780 struct brotoRoute *broute;
781 struct X3D_Proto *ec = (struct X3D_Proto*)fwn;
782 if(!ec) ec = (struct X3D_Proto*)fromNode->_executionContext;
783 if(!strcmp(callingFunc,"addRoute")){
784 broute = createNewBrotoRoute();
785 broute->from.node = fromNode;
786 broute->from.ifield = fromField;
787 broute->from.builtIn = fromBuiltIn;
788 //broute->from.Ofs = fromOfs;
789 broute->from.ftype = fromType;
790 broute->to.node = toNode;
791 broute->to.ifield = toField;
792 broute->to.builtIn = toBuiltIn;
793 //broute->to.Ofs = toOfs;
794 broute->to.ftype = toType;
795 broute->lastCommand = 1; //added above (won't be added if an import weak route)
796 CRoutes_RegisterSimpleB(broute->from.node,broute->from.ifield,broute->from.builtIn,broute->to.node,broute->to.ifield,broute->to.builtIn,broute->ft);
797 broute->ft = fromType == toType ? fromType : -1;
798 if(!ec->__ROUTES)
799 ec->__ROUTES = newStack(struct brotoRoute *);
800 stack_push(struct brotoRoute *, ec->__ROUTES, broute);
801 retval = (void*)broute;
802 }else{
803 //deleteRoute
804 if(ec->__ROUTES)
805 for(i=0;i<vectorSize(ec->__ROUTES);i++){
806 broute = vector_get(struct brotoRoute*,ec->__ROUTES,i);
807 if(broute->from.node == fromNode && broute->from.ifield == fromField
808 && broute->to.node == toNode && broute->to.ifield == toField){
809 if(broute->lastCommand == 1)
810 CRoutes_RemoveSimpleB(broute->from.node,broute->from.ifield,broute->from.builtIn,broute->to.node,broute->to.ifield,broute->to.builtIn,broute->ft);
811 broute->lastCommand = 0;
812 vector_remove_elem(struct brotoRoute*,ec->__ROUTES,i);
813 FREE_IF_NZ(broute);
814 break;
815 }
816 }
817 retval = NULL;
818 }
819 }
820 return retval;
821
822}
823
824void * addDeleteRoute(void *fwn, char* callingFunc, int argc, FWval fwpars, FWval fwretval){
825 struct X3D_Node *fromNode;
826 struct X3D_Node *toNode;
827 const char *fromField, *toField;
828 void *retval;
829
830 //if(0){ //!strcmp(callingFunc,"deleteRoute")){
831 // fromNode = fwpars[0]._web3dval.native;
832 // toNode = fwpars[2]._web3dval.native;
833 //}
834 fromNode = fwpars[0]._web3dval.anyvrml->sfnode; //.native;
835 toNode = fwpars[2]._web3dval.anyvrml->sfnode; //.native;
836
837 fromField = fwpars[1]._string;
838 toField = fwpars[3]._string;
839
840 retval = addDeleteRoute0(fwn,callingFunc,fromNode, fromField, toNode, toField);
841 return retval;
842}
843int X3DExecutionContext_deleteRoute(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
844 //we're expecting an X3DRoute struct parameter.
845 int nr = 0;
846 void *xroute;
847 struct X3D_Node *fromNode, *toNode;
848 const char *fromField, *toField;
849 int fromIfield, toIfield, fromBuiltIn, toBuiltIn;
850 int ftype,kind;
851 union anyVrml *value;
852
853 if(fwpars[0].itype != 'P') return nr;
854
855 {
856 struct brotoRoute* broute = (struct brotoRoute*)fwpars[0]._pointer.native;
857 fromNode = broute->from.node;
858 fromIfield = broute->from.ifield;
859 fromBuiltIn = broute->from.builtIn;
860 toNode = broute->to.node;
861 toIfield = broute->to.ifield;
862 toBuiltIn = broute->to.builtIn;
863 }
864 getFieldFromNodeAndIndexSource(fromNode,fromIfield,fromBuiltIn,&fromField,&ftype,&kind,&value);
865 getFieldFromNodeAndIndexSource(toNode,toIfield,toBuiltIn,&toField,&ftype,&kind,&value);
866 xroute = addDeleteRoute0(fwn,"deleteRoute",fromNode, fromField, toNode, toField);
867 return nr;
868}
869
870int VRBrowserAddRoute(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
871 void *xroute;
872 int nr = 0;
873 xroute = addDeleteRoute(fwn,"addRoute",argc,fwpars,fwretval);
874 if(xroute){
875 fwretval->_web3dval.fieldType = AUXTYPE_X3DRoute; //AUXTYPE_X3DScene;
876 fwretval->_web3dval.native = xroute;
877 fwretval->_web3dval.gc = 0;
878 fwretval->itype = 'P';
879 nr = 1;
880 }
881 return nr;
882}
883int VRBrowserDeleteRoute(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
884 void *xroute;
885 int nr = 0;
886 xroute = addDeleteRoute(fwn,"deleteRoute",argc,fwpars,fwretval);
887 return nr;
888}
889int VRBrowserPrint(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
890{
891 const char *_costr = NULL;
892 if(fwpars[0].itype == 'S'){
893 _costr = fwpars[0]._string; //fwpars[0]._web3dval.anyvrml->sfstring->strptr;
894 if(_costr)
895 ConsoleMessage("%s",_costr);
896 }
897 return 0;
898}
899int VRBrowserPrintln(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
900{
901 const char *_costr = NULL;
902 if(fwpars[0].itype == 'S'){
903 _costr = fwpars[0]._string; //fwpars[0]._web3dval.anyvrml->sfstring->strptr;
904 if(_costr)
905 ConsoleMessage("%s\n",_costr);
906 }
907 return 0;
908}
909
910FWFunctionSpec (BrowserFunctions)[] = {
911 {"getName", VRBrowserGetName, 'S',{0,0,0,NULL}},
912 {"getVersion", VRBrowserGetVersion, 'S',{0,0,0,NULL}},
913 {"getCurrentSpeed", VRBrowserGetCurrentSpeed, 'S',{0,0,0,NULL}},
914 {"getCurrentFrameRate", VRBrowserGetCurrentFrameRate, 'S',{0,0,0,NULL}},
915 {"getWorldURL", VRBrowserGetWorldURL, 'S',{0,0,0,NULL}},
916 {"replaceWorld", VRBrowserReplaceWorld, '0',{1,-1,0,"Z"}},
917 {"loadURL", VRBrowserLoadURL, '0',{2,1,'T',"FF"}},
918 {"setDescription", VRBrowserSetDescription, '0',{1,-1,0,"S"}},
919 {"createVrmlFromString", VRBrowserCreateVrmlFromString, 'W',{1,-1,0,"S"}},
920 {"createVrmlFromURL", VRBrowserCreateVrmlFromURL,'0',{3,3,0,"WWS"}},
921 {"createX3DFromString", VRBrowserCreateX3DFromString, 'W',{1,-1,0,"S"}},
922 {"createX3DFromURL", VRBrowserCreateVrmlFromURL, '0',{3,3,0,"WWS"}},
923 {"addRoute", VRBrowserAddRoute, 'P',{4,-1,0,"WSWS"}},
924 {"deleteRoute", VRBrowserDeleteRoute, '0',{4,-1,0,"WSWS"}},
925 {"print", VRBrowserPrint, '0',{1,-1,0,"S"}},
926 {"println", VRBrowserPrintln, '0',{1,-1,0,"S"}},
927
928 //{importDocument, X3dBrowserImportDocument, 0), //not sure we need/want this, what does it do?
929 //{getRenderingProperty, X3dGetRenderingProperty, 0},
930 //{addBrowserListener, X3dAddBrowserListener, 0},
931 //{removeBrowserListener, X3dRemoveBrowserListener, 0},
932
933 {0}
934};
935
936
937//typedef struct FWPropertySpec {
938// const char *name; //NULL means index int: SFVec3f[0], MF[i]
939// char index; //stable property index for switch/casing instead of strcmp on name
940// char type; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr
941// char isReadOnly; //T/F
942//} FWPropertySpec;
943
944
945FWPropertySpec (BrowserProperties)[] = {
946 {"name", 0, 'S', 'T'},
947 {"version", 1, 'S', 'T'},
948 {"currentSpeed", 2, 'D', 'T'},
949 {"currentFrameRate", 3, 'D', 'T'},
950 {"description", 4, 'S', 0},
951 {"supportedComponents", 5, 'P', 'T'},
952 {"supportedProfiles", 6, 'P', 'T'},
953 {"currentScene", 7, 'P', 'T'},
954 {NULL,0,0,0},
955};
956struct proftablestruct {
957 int profileName;
958 const int *profileTable;
959 int level; //dug9
960};
961struct proftablestruct *getProfTable();
962const int * getCapabilitiesTable();
963int BrowserGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
964 int nr = 1;
965 //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
966 switch (index) {
967 case 0: //name
968 fwretval->_string = BrowserName;
969 fwretval->itype = 'S';
970 break;
971 case 1: //version
972 fwretval->_string = libFreeWRL_get_version();
973 fwretval->itype = 'S';
974 break;
975 case 2: //currentSpeed
976 fwretval->_numeric = gglobal()->Mainloop.BrowserSpeed;
977 fwretval->itype = 'D';
978 break;
979 case 3: //currentFrameRate
980 fwretval->_numeric = gglobal()->Mainloop.BrowserFPS;
981 fwretval->itype = 'D';
982 break;
983 case 4: //description
984 fwretval->_string = gglobal()->Mainloop.BrowserDescription; //this is settable
985 fwretval->itype = 'S';
986 break;
987 case 5: //supportedComponents
988 fwretval->_pointer.fieldType = AUXTYPE_ComponentInfoArray;
989 fwretval->_pointer.native = (void*)getCapabilitiesTable(); //TO-DO something about component info array
990 fwretval->_pointer.gc = 0;
991 fwretval->itype = 'P';
992 break;
993 case 6: //supportedProfiles
994 fwretval->_pointer.fieldType = AUXTYPE_ProfileInfoArray;
995 fwretval->_pointer.native = (void*)getProfTable(); //TO-DO something about profile info array
996 fwretval->_pointer.gc = 0;
997 fwretval->itype = 'P';
998 break;
999 case 7: //currentScene
1000 fwretval->_web3dval.fieldType = AUXTYPE_X3DExecutionContext; //AUXTYPE_X3DScene;
1001 fwretval->_web3dval.native = (void *)(struct X3D_Node*)ec; //X3DScene || X3DExecutionContext
1002 fwretval->_web3dval.gc = 0;
1003 //change this to (Script)._executionContext when brotos working fully
1004 fwretval->itype = 'P';
1005 break;
1006 default:
1007 nr = 0;
1008 }
1009 return nr;
1010}
1011int BrowserSetter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
1012 switch (index) {
1013 case 4: //description is settable
1014 gglobal()->Mainloop.BrowserDescription = fwval->_string; //fwval->_web3dval.anyvrml->sfstring->strptr;
1015 break;
1016 default:
1017 break;
1018 }
1019 return TRUE;
1020}
1021
1022
1023struct FWTYPE BrowserType = {
1024 AUXTYPE_X3DBrowser,
1025 'P',
1026 "X3DBrowser",
1027 0, //sizeof(struct X3DBrowser),
1028 NULL, //no constructor for Browser
1029 NULL, //no constructor args
1030 BrowserProperties,
1031 NULL, //no special has
1032 BrowserGetter,
1033 BrowserSetter,
1034 0, 0, //takes int index in prop
1035 BrowserFunctions,
1036};
1037
1038
1039
1040
1041/* ProfileInfo, ProfileInfoArray, ComponentInfo, ComponentInfoArray
1042 I decided to do these as thin getter wrappers on the bits and pieces defined
1043 in Structs.h, GeneratedCode.c and capabilitiesHandler.c
1044 The Array types return the info type wrapper with private native member == index into
1045 the native array.
1046*/
1047//ComonentInfo{
1048//String name;
1049//Numeric level;
1050//String Title;
1051//String providerUrl;
1052//}
1053
1054int capabilitiesHandler_getTableLength(int* table);
1055int capabilitiesHandler_getComponentLevel(int *table, int comp);
1056int capabilitiesHandler_getProfileLevel(int prof);
1057const int *capabilitiesHandler_getProfileComponent(int prof);
1058const int *capabilitiesHandler_getCapabilitiesTable();
1059/*
1060typedef struct intTableIndex{
1061 int* table;
1062 int index;
1063} *IntTableIndex;
1064*/
1065
1066
1067//ComponentInfoArray{
1068//numeric length;
1069//ComponentInfo [integer index];
1070//}
1071
1072int *intdup(int value){
1073 int* p = malloc(sizeof(int));
1074 memcpy(p,&value,sizeof(int));
1075 return p;
1076}
1077int ComponentInfoArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1078 int *_table;
1079 int nr = 1;
1080 _table = (int *)fwn;
1081 //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1082 if(index == -1){
1083//extern const char *COMPONENTS[];
1084//extern const int COMPONENTS_COUNT;
1085 int _length = capabilitiesHandler_getTableLength(_table); //COMPONENTS_COUNT;
1086 //fwretval->_integer = _length;
1087 fwretval->itype = 'I';
1088 fwretval->_integer = _length;
1089
1090 }else if(index > -1 && index < COMPONENTS_COUNT ){
1091 fwretval->_pointer.native = &_table[2*index];
1092 fwretval->_pointer.fieldType = AUXTYPE_ComponentInfo;
1093 fwretval->_pointer.gc = 0;
1094 fwretval->itype = 'P';
1095 }
1096 return nr;
1097}
1098
1099
1100FWPropertySpec (ComponentInfoArrayProperties)[] = {
1101 {"length", -1, 'I', 'T'},
1102 {NULL,0,0,0},
1103};
1104
1105struct FWTYPE ComponentInfoArrayType = {
1106 AUXTYPE_ComponentInfoArray,
1107 'P',
1108 "ComponentInfoArray",
1109 0, //sizeof(struct X3DBrowser),
1110 NULL, //no constructor for Browser
1111 NULL, //no constructor args
1112 ComponentInfoArrayProperties,
1113 NULL, //no special has
1114 ComponentInfoArrayGetter,
1115 NULL,
1116 'P', 'T', //takes int index in prop of this type
1117 NULL,
1118};
1119
1120FWPropertySpec (ComponentInfoProperties)[] = {
1121 {"name", 0, 'S', 'T'},
1122 {"Title", 1, 'S', 'T'},
1123 {"level", 2, 'I', 'T'},
1124 {"providerUrl", 3, 'S', 'T'},
1125 {NULL,0,0,0},
1126};
1127
1128
1129int ComponentInfoGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1130 int nr, *tableEntry, nameIndex;
1131 tableEntry = (int *)fwn;
1132 nr = 1;
1133 //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1134 switch (index) {
1135 case 0://name
1136 case 1://Title
1137 nameIndex = tableEntry[0];
1138 fwretval->_string = COMPONENTS[nameIndex];
1139 fwretval->itype = 'S';
1140 break;
1141 case 2://level
1142 fwretval->_integer = tableEntry[1];
1143 fwretval->itype = 'I';
1144 break;
1145 case 3://providerUrl
1146 fwretval->_string = "freewrl.sourceforge.net";
1147 fwretval->itype = 'S';
1148 break;
1149 default:
1150 nr = 0;
1151 break;
1152 }
1153 return nr;
1154}
1155
1156struct FWTYPE ComponentInfoType = {
1157 AUXTYPE_ComponentInfo,
1158 'P',
1159 "ComponentInfo",
1160 0, //sizeof(struct X3DBrowser),
1161 NULL, //no constructor for Browser
1162 NULL, //no constructor args
1163 ComponentInfoProperties,
1164 NULL, //no special has
1165 ComponentInfoGetter,
1166 NULL,
1167 0,0, //takes int index in prop
1168 NULL,
1169};
1170
1171
1172
1173//ProfileInfoArray{
1174//numeric length;
1175//ProfileInfo [integer index];
1176//}
1177
1178
1179int ProfileInfoArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1180 struct proftablestruct *_table;
1181 int nr = 1;
1182 _table = (struct proftablestruct *)fwn;
1183 //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1184 if(index == -1){
1185//extern const char *COMPONENTS[];
1186//extern const int COMPONENTS_COUNT;
1187 fwretval->_integer = PROFILES_COUNT; // _length;
1188 fwretval->itype = 'I';
1189 }else if(index > -1 && index < PROFILES_COUNT ){
1190 fwretval->_pointer.native = &_table[index];
1191 fwretval->_pointer.fieldType = AUXTYPE_ProfileInfo;
1192 fwretval->_pointer.gc = 0;
1193 fwretval->itype = 'P';
1194 }
1195 return nr;
1196}
1197
1198
1199FWPropertySpec (ProfileInfoArrayProperties)[] = {
1200 {"length", -1, 'I', 'T'},
1201 {NULL,0,0,0},
1202};
1203
1204struct FWTYPE ProfileInfoArrayType = {
1205 AUXTYPE_ProfileInfoArray,
1206 'P',
1207 "ProfileInfoArray",
1208 0, //sizeof(struct X3DBrowser),
1209 NULL, //no constructor for Browser
1210 NULL, //no constructor args
1211 ProfileInfoArrayProperties,
1212 NULL, //no special has
1213 ProfileInfoArrayGetter,
1214 NULL,
1215 'P', 'T',//takes int index in prop, readOnly
1216 NULL,
1217};
1218
1219
1220//ProfileInfo{
1221//String name;
1222//Numeric level;
1223//String Title;
1224//String providerUrl;
1225//ComonentInfoArray components;
1226//}
1227
1228FWPropertySpec (ProfileInfoProperties)[] = {
1229 {"name", 0, 'S', 'T'},
1230 {"Title", 1, 'I', 'T'},
1231 {"level", 2, 'S', 'T'},
1232 {"providerUrl", 3, 'S', 'T'},
1233 {"components", 4, 'P', 'T'}, //writable? if so then I need a constructor for ComponentInfo?
1234 {NULL,0,0,0},
1235};
1236
1237
1238int ProfileInfoGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1239 int nr, nameIndex;
1240 struct proftablestruct *tableEntry;
1241 tableEntry = (struct proftablestruct *)fwn;
1242 nr = 1;
1243 //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1244 switch (index) {
1245 case 0://name
1246 case 1://Title
1247 nameIndex = tableEntry->profileName;
1248 fwretval->_string = stringProfileType(nameIndex);
1249 fwretval->itype = 'S';
1250 break;
1251 case 2://level
1252 fwretval->_integer = tableEntry->level;
1253 fwretval->itype = 'I';
1254 break;
1255 case 3://providerUrl
1256 fwretval->_string = "freewrl.sourceforge.net";
1257 fwretval->itype = 'S';
1258 break;
1259 case 4://components
1260 fwretval->_pointer.native = (void *)tableEntry->profileTable;
1261 fwretval->_pointer.fieldType = AUXTYPE_ComponentInfoArray;
1262 fwretval->_pointer.gc = 0;
1263 fwretval->itype = 'P';
1264 break;
1265 default:
1266 nr = 0;
1267 break;
1268 }
1269 return nr;
1270}
1271
1272struct FWTYPE ProfileInfoType = {
1273 AUXTYPE_ProfileInfo,
1274 'P',
1275 "ProfileInfo",
1276 0, //sizeof(struct X3DBrowser),
1277 NULL, //no constructor for Browser
1278 NULL, //no constructor args
1279 ProfileInfoProperties,
1280 NULL, //no special has
1281 ProfileInfoGetter,
1282 NULL,
1283 0,0, //takes int index in prop
1284 NULL,
1285};
1286
1287
1288
1289
1290struct X3D_Node *broto_search_DEFname(struct X3D_Proto *context, const char *name);
1291struct X3D_Node * broto_search_ALLnames(struct X3D_Proto *context, const char *name, int *source);
1292int X3DExecutionContext_getNamedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1293 int nr = 0;
1294 struct X3D_Node* node = NULL;
1295 //broto warning - DEF name list should be per-executionContext
1296 //struct X3D_Proto *ec = (struct X3D_Proto *)fwn; //we want the script node's parent context for imported nodes, I think
1297 node = broto_search_DEFname(ec, fwpars[0]._string);
1298
1299 if(node){
1300 //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1301 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1302 fwretval->_web3dval.anyvrml->sfnode = node;
1303 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1304 fwretval->_web3dval.gc = 1;
1305 fwretval->itype = 'W';
1306 nr = 1;
1307 }
1308 return nr;
1309}
1310
1311int X3DExecutionContext_updateNamedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1312 int i, nr = 0;
1313 //broto warning - DEF name list should be per-executionContext
1314 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1315 struct X3D_Node* node = NULL;
1316 struct brotoDefpair *bd;
1317 int found = 0;
1318 const char *defname;
1319 defname = fwpars[0]._string;
1320 node = X3D_NODE(fwpars[1]._web3dval.native);
1321 if(_ec->__DEFnames){
1322 for(i=0;i<vectorSize(_ec->__DEFnames);i++){
1323 bd = vector_get(struct brotoDefpair *,_ec->__DEFnames,i);
1324 //Q. is it the DEF we search for, and node we replace, OR
1325 // is it the node we search for, and DEF we replace?
1326 if(!strcmp(bd->name,defname)){
1327 bd->node = node;
1328 found = 1;
1329 break;
1330 }
1331 if(bd->node == node){
1332 bd->name = strdup(defname);
1333 found = 2;
1334 break;
1335 }
1336 }
1337 }
1338 if(!found){
1339 //I guess its an add
1340 if(!_ec->__DEFnames)
1341 _ec->__DEFnames = newVector(struct brotoDefpair*,4);
1342 bd = (struct brotoDefpair*)malloc(sizeof(struct brotoDefpair));
1343 bd->node = node;
1344 bd->name = strdup(defname);
1345 stack_push(struct brotoDefpair *,_ec->__DEFnames,bd);
1346 }
1347 return nr;
1348}
1349int remove_broto_node(struct X3D_Proto *context, struct X3D_Node* node);
1350int X3DExecutionContext_removeNamedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1351 int i, nr = 0;
1352 //broto warning - DEF name list should be per-executionContext
1353 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1354 struct X3D_Node* node = NULL;
1355
1356 const char *defname;
1357 defname = fwpars[0]._string;
1358 if(_ec->__DEFnames){
1359 struct brotoDefpair *bd;
1360 for(i=0;i<vectorSize(_ec->__DEFnames);i++){
1361 bd = vector_get(struct brotoDefpair *,_ec->__DEFnames,i);
1362 if(!strcmp(bd->name,defname)){
1363 node = bd->node;
1364 //Q. are we supposed to delete the node
1365 //OR are we just supposed to remove the DEF name mapping?
1366 //remove DEF name mapping:
1367 vector_remove_elem(struct brotoDefpair *,_ec->__DEFnames,i);
1368 //remove node
1369 remove_broto_node(_ec,node);
1370 break;
1371 }
1372 }
1373 }
1374
1375 return nr;
1376}
1377void add_node_to_broto_context(struct X3D_Proto *context,struct X3D_Node *node);
1378int X3DExecutionContext_createProto(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1379 int nr = 0;
1380 struct X3D_Node* node = NULL;
1381 //broto warning - DEF name list should be per-executionContext
1382 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1383 struct X3D_Proto *proto;
1384 proto = NULL;
1385
1386 if( isAvailableBroto(fwpars[0]._string, ec, &proto))
1387 {
1388 struct X3D_Proto *source, *dest;
1389 node=X3D_NODE(brotoInstance(proto,1));
1390 node->_executionContext = X3D_NODE(ec); //me->ptr;
1391 add_node_to_broto_context(ec,node);
1392 //during parsing, setting of fields would occur between instance and body,
1393 //so field values perculate down.
1394 //here we elect default field values
1395 source = X3D_PROTO(X3D_PROTO(node)->__prototype);
1396 dest = X3D_PROTO(node);
1397 deep_copy_broto_body2(&source,&dest);
1398 }
1399 if(node){
1400 //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1401 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1402 fwretval->_web3dval.anyvrml->sfnode = node;
1403 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1404 fwretval->_web3dval.gc = 1;
1405 fwretval->itype = 'W';
1406 nr = 1;
1407 }
1408 return nr;
1409}
1410
1411int X3DExecutionContext_getImportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1412 int nr = 0;
1413 struct X3D_Node* node = NULL;
1414 //broto warning - DEF name list should be per-executionContext
1415 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1416 //struct IMEXPORT *mxp;
1417 int source;
1418 //mxp = broto_search_IMPORTname(ec, fwpars[0]._string);
1419 //if(mxp){
1420 // node = mxp->nodeptr;
1421 //}
1422 node = broto_search_ALLnames(ec, fwpars[0]._string,&source);
1423 if(source == 0) node = NULL; //source ==1,2 is for IMPORT and EXPORT
1424 if(node){
1425 //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1426 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1427 fwretval->_web3dval.anyvrml->sfnode = node;
1428 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1429 fwretval->_web3dval.gc = 1;
1430 fwretval->itype = 'W';
1431 nr = 1;
1432 }
1433 return nr;
1434}
1435
1436void update_weakRoutes(struct X3D_Proto *context);
1437int X3DExecutionContext_updateImportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1438 // I think what they mean by updateImportedNode(string,string[,string]) is:
1439 // updateImportedNode(Inline DEF name, Inline's Export AS name [,optional Import AS name])
1440 int i, nr = 0;
1441 //broto warning - DEF name list should be per-executionContext
1442 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1443 struct X3D_Node* node = NULL;
1444
1445 const char *as, *mxname, *nline;
1446 int found = 0;
1447 struct IMEXPORT *mxp;
1448
1449 nline = fwpars[0]._string;
1450 mxname = fwpars[1]._string;
1451 as = mxname;
1452 if(argc == 3)
1453 as = fwpars[2]._string;
1454 node = X3D_NODE(fwpars[1]._web3dval.native);
1455 if(_ec->__IMPORTS){
1456 for(i=0;i<vectorSize(_ec->__IMPORTS);i++){
1457 mxp = vector_get(struct IMEXPORT *,_ec->__IMPORTS,i);
1458 //Q. is it the DEF we search for, and node we replace, OR
1459 // is it the node we search for, and DEF we replace?
1460 if(!strcmp(nline,mxp->inlinename) && !strcmp(mxp->mxname,mxname)){
1461 mxp->as = strdup(as);
1462 found = 1;
1463 break;
1464 }
1465 }
1466 }
1467 if(!found){
1468 //I guess its an add
1469 if(!_ec->__IMPORTS)
1470 _ec->__IMPORTS = newVector(struct IMEXPORT *,4);
1471 mxp = (struct IMEXPORT *)malloc(sizeof(struct IMEXPORT));
1472 mxp->mxname = strdup(mxname);
1473 mxp->as = strdup(as);
1474 mxp->inlinename = strdup(nline);
1475 stack_push(struct IMEXPORT *,_ec->__IMPORTS,mxp);
1476 }
1477 update_weakRoutes(_ec);
1478 return nr;
1479}
1480
1481
1482int X3DExecutionContext_removeImportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1483 int i,nr = 0;
1484 //broto warning - DEF name list should be per-executionContext
1485 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1486 //struct X3D_Node* node = NULL;
1487
1488 const char *defname;
1489 defname = fwpars[0]._string;
1490 if(_ec->__IMPORTS){
1491 struct IMEXPORT *mxp;
1492 for(i=0;i<vectorSize(_ec->__IMPORTS);i++){
1493 mxp = vector_get(struct IMEXPORT *,_ec->__IMPORTS,i);
1494 if(!strcmp(mxp->as,defname)){
1495 //remove IMPORT name mapping:
1496 vector_remove_elem(struct IMEXPORT *,_ec->__IMPORTS,i);
1497 update_weakRoutes(_ec);
1498 break;
1499 }
1500 }
1501 }
1502 return nr;
1503}
1504
1505
1506int X3DScene_getExportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1507 int nr = 0;
1508 struct X3D_Node* node = NULL;
1509 //broto warning - DEF name list should be per-executionContext
1510 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1511 struct IMEXPORT *mxp;
1512 mxp = broto_search_EXPORTname(ec, fwpars[0]._string);
1513 if(mxp){
1514 node = mxp->nodeptr;
1515 }
1516 if(node){
1517 //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1518 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1519 fwretval->_web3dval.anyvrml->sfnode = node;
1520 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1521 fwretval->_web3dval.gc = 1;
1522 fwretval->itype = 'W';
1523 nr = 1;
1524 }
1525 return nr;
1526}
1527
1528int X3DScene_updateExportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1529 int i, nr = 0;
1530 //broto warning - DEF name list should be per-executionContext
1531 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1532 struct X3D_Node* node = NULL;
1533
1534 const char *defname;
1535 int found = 0;
1536 struct IMEXPORT *mxp;
1537
1538 defname = fwpars[0]._string;
1539 node = X3D_NODE(fwpars[1]._web3dval.anyvrml->sfnode);
1540 if(_ec->__EXPORTS){
1541 for(i=0;i<vectorSize(_ec->__EXPORTS);i++){
1542 mxp = vector_get(struct IMEXPORT *,_ec->__EXPORTS,i);
1543 //Q. is it the DEF we search for, and node we replace, OR
1544 // is it the node we search for, and DEF we replace?
1545 if(!strcmp(mxp->as,defname)){
1546 mxp->nodeptr = node;
1547 found = 1;
1548 break;
1549 }
1550 if(mxp->nodeptr == node){
1551 mxp->as = strdup(defname);
1552 found = 2;
1553 break;
1554 }
1555 }
1556 }
1557 if(!found){
1558 //I guess its an add
1559 if(!_ec->__EXPORTS)
1560 _ec->__EXPORTS = newVector(struct IMEXPORT *,4);
1561 mxp = (struct IMEXPORT *)malloc(sizeof(struct IMEXPORT));
1562 mxp->nodeptr = node;
1563 mxp->mxname = strdup(defname);
1564 mxp->as = mxp->mxname;
1565 stack_push(struct IMEXPORT *,_ec->__EXPORTS,mxp);
1566 }
1567 if(_ec->_executionContext){
1568 //update weak routes in the importing context, which should be the parent context of the Inline node
1569 //and the Inline should be our current context. I think.
1570 update_weakRoutes(X3D_PROTO(_ec->_executionContext));
1571 }
1572 return nr;
1573}
1574
1575int X3DScene_removeExportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1576 int i, nr = 0;
1577 //broto warning - DEF name list should be per-executionContext
1578 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1579 //struct X3D_Node* node = NULL;
1580
1581 const char *defname;
1582 defname = fwpars[0]._string;
1583 if(_ec->__EXPORTS){
1584 struct IMEXPORT *mxp;
1585 for(i=0;i<vectorSize(_ec->__EXPORTS);i++){
1586 mxp = vector_get(struct IMEXPORT *,_ec->__EXPORTS,i);
1587 if(!strcmp(mxp->as,defname)){
1588 //remove EXPORT name mapping:
1589 vector_remove_elem(struct IMEXPORT *,_ec->__EXPORTS,i);
1590 break;
1591 }
1592 }
1593 }
1594 if(_ec->_executionContext){
1595 //update weak routes in the importing context, which should be the parent context of the Inline node
1596 //and the Inline should be our current context. I think.
1597 update_weakRoutes(X3D_PROTO(_ec->_executionContext));
1598 }
1599 return nr;
1600}
1601int X3DScene_setMetaData(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1602 int nr = 0;
1603 const char *name, *value;
1604 name = fwpars[0]._string;
1605 value = fwpars[1]._string;
1606 //strdup and put in a global or per-scene or per execution context (name,value) list
1607 return nr;
1608}
1609int X3DScene_getMetaData(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1610 int nr = 0;
1611 const char *name;
1612 char *value;
1613 value = NULL;
1614 name = fwpars[0]._string;
1615 //do a search in the perscene/perexecution context array
1616 if(value){
1617 fwretval->_string = value;
1618 fwretval->itype = 'S';
1619 nr = 1;
1620 }
1621 return nr;
1622}
1623
1624static FWFunctionSpec (X3DExecutionContextFunctions)[] = {
1625 //executionContext
1626 {"addRoute", VRBrowserAddRoute, 'P',{4,-1,0,"WSWS"}},
1627 {"deleteRoute", X3DExecutionContext_deleteRoute,'0',{1,-1,0,"P"}},
1628 {"createNode", VRBrowserCreateNodeFromString, 'W',{1,-1,0,"S"}},
1629 {"createProto", X3DExecutionContext_createProto, 'W',{1,-1,0,"S"}},
1630 {"getImportedNode", X3DExecutionContext_getImportedNode, 'W',{1,-1,0,"S"}},
1631 {"updateImportedNode", X3DExecutionContext_updateImportedNode, '0',{3,-1,0,"SSS"}},
1632 {"removeImportedNode", X3DExecutionContext_removeImportedNode, '0',{1,-1,0,"S"}},
1633 {"getNamedNode", X3DExecutionContext_getNamedNode, 'W',{1,-1,0,"S"}},
1634 {"updateNamedNode", X3DExecutionContext_updateNamedNode, '0',{2,-1,0,"SW"}},
1635 {"removeNamedNode", X3DExecutionContext_removeNamedNode, '0',{1,-1,0,"S"}},
1637 {"setMetaData", X3DScene_setMetaData, '0',{2,-1,0,"SS"}},
1638 {"getMetaData", X3DScene_getMetaData, 'S',{1,-1,0,"S"}},
1639 {"getExportedNode", X3DScene_getExportedNode, 'W',{1,-1,0,"S"}},
1640 {"updateExportedNode", X3DScene_updateExportedNode, '0',{2,-1,0,"SW"}},
1641 {"removeExportedNode", X3DScene_removeExportedNode, '0',{1,-1,0,"S"}},
1642 {0}
1643};
1644
1645
1646
1647static FWPropertySpec (X3DExecutionContextProperties)[] = {
1648 //executionContext
1649 {"specificationVersion", 0, 'S', 'T'},
1650 {"encoding", 1, 'S', 'T'},
1651 {"profile", 2, 'P', 'T'},
1652 {"components", 3, 'P', 'T'},
1653 {"worldURL", 4, 'S', 'T'},
1654 {"rootNodes", 5, 'W', 'T'},
1655 {"protos", 6, 'P', 'T'},
1656 {"externprotos", 7, 'P', 'T'},
1657 {"routes", 8, 'P', 'T'},
1658 //scene
1659 {"isScene", 9, 'B', 'T'}, //else protoInstance. extra beyond specs - I think flux has it.
1660 {0}
1661};
1662static int _TRUE = TRUE;
1663static int _FALSE = FALSE;
1664int X3DExecutionContextGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1665 struct X3D_Proto * ecc;
1666 int nr = 1;
1667 ecc = (struct X3D_Proto*)fwn;
1668 //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1669 switch (index) {
1670 case 0: //specificationVersion
1671 {
1672 char str[32];
1673 //sprintf(str,"{%d,%d,%d}",inputFileVersion[0],inputFileVersion[1],inputFileVersion[2]);
1674 if(ecc->__loadResource || ecc->_parentResource){
1675 int specver;
1676 specver = ecc->__specversion;
1677 sprintf(str,"{%d.%d.%d}",specver/100,(specver/10)%10,specver % 10);
1678 }
1679 fwretval->_string = strdup(str);
1680 fwretval->itype = 'S';
1681 }
1682 break;
1683 case 1: //encoding string readonly
1684 {
1685 //Valid values are "ASCII", "VRML", "XML", "BINARY", "SCRIPTED", "BIFS", "NONE"
1686 fwretval->_string = "not filled in yet sb. VRML or XML or ..";
1687 fwretval->itype = 'S';
1688 }
1689 break;
1690 case 2: //profile
1691 {
1692 struct proftablestruct * profile;
1693 int index = gglobal()->Mainloop.scene_profile;
1694 profile = getProfTable();
1695 fwretval->_pointer.native = &profile[index];
1696 fwretval->_pointer.fieldType = AUXTYPE_ProfileInfo;
1697 fwretval->_pointer.gc = 0;
1698 fwretval->itype = 'P';
1699 }
1700 break;
1701 case 3: //components
1702 fwretval->_pointer.native = (void *)gglobal()->Mainloop.scene_components;
1703 fwretval->_pointer.fieldType = AUXTYPE_ComponentInfoArray;
1704 fwretval->_pointer.gc = 0;
1705 fwretval->itype = 'P';
1706 break;
1707 case 4: //worldURL
1708 fwretval->_string = gglobal()->Mainloop.url; //this is settable
1709 fwretval->itype = 'S';
1710 break;
1711 case 5: //rootNodes
1712 fwretval->_web3dval.native = (void *)&ecc->__children; //broto warning: inside a proto should be the rootnodes of the protobody
1713 fwretval->_web3dval.fieldType = FIELDTYPE_MFNode;
1714 fwretval->_web3dval.gc = 0;
1715 fwretval->itype = 'W';
1716 break;
1717 case 6: //protos
1718 fwretval->_pointer.fieldType = AUXTYPE_X3DProtoArray;
1719 fwretval->_pointer.native = (void*)ecc->__protoDeclares; //broto: this should be a per-context array
1720 fwretval->_pointer.gc = 0;
1721 fwretval->itype = 'P';
1722 break;
1723 case 7: //externprotos
1724 fwretval->_pointer.fieldType = AUXTYPE_X3DExternProtoArray;
1725 fwretval->_pointer.native = (void*)ecc->__externProtoDeclares; //broto: this should be a per-context array
1726 fwretval->_pointer.gc = 0;
1727 fwretval->itype = 'P';
1728 break;
1729 case 8: //routes
1730 fwretval->_pointer.fieldType = AUXTYPE_X3DRouteArray;
1731 fwretval->_pointer.native = (void*)ecc->__ROUTES; //broto: this should be a per-context array
1732 fwretval->_pointer.gc = 0;
1733 fwretval->itype = 'P';
1734 break;
1735 case 9: //isScene
1736 //fwretval->_boolean = TRUE; //broto warning: should be false inside a protoinstance body
1737 fwretval->itype = 'B';
1738 {
1739 unsigned char flag = ciflag_get(ecc->__protoFlags,2);
1740 if(flag == 2)
1741 fwretval->_boolean = TRUE;
1742 else
1743 fwretval->_boolean = FALSE;
1744 }
1745 break;
1746 default:
1747 nr = 0;
1748 }
1749 return nr;
1750}
1751
1752struct FWTYPE X3DExecutionContextType = {
1753 AUXTYPE_X3DExecutionContext,
1754 'P',
1755 "X3DExecutionContext",
1756 0, //sizeof(struct X3DBrowser),
1757 NULL, //no constructor
1758 NULL, //no constructor args
1759 X3DExecutionContextProperties,
1760 NULL, //no special has
1761 X3DExecutionContextGetter,
1762 NULL,
1763 0,0, //takes int index in prop
1764 X3DExecutionContextFunctions,
1765};
1766
1767struct CRStruct *getCRoutes();
1768int getCRouteCount();
1769int *getCRouteCounter();
1770int X3DRouteArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1771
1772 int nr = 0;
1773 //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1774 if(index == -1){
1775 int _length;
1776 _length = vectorSize(fwn);
1777 fwretval->_integer = _length;
1778 fwretval->itype = 'I';
1779 nr = 1;
1780 }else if(index > -1 ){
1781 if(index < vectorSize(fwn)){
1782 fwretval->_pointer.native = vector_get(void *, fwn, index); //struct brotoRoute *
1783 fwretval->_pointer.gc = 0;
1784 fwretval->_pointer.fieldType = AUXTYPE_X3DRoute;
1785 fwretval->itype = 'P';
1786 nr = 1;
1787 }
1788 }
1789 return nr;
1790}
1791
1792
1793FWPropertySpec (X3DRouteArrayProperties)[] = {
1794 {"length", -1, 'I', 'T'},
1795 {NULL,0,0,0},
1796};
1797
1798struct FWTYPE X3DRouteArrayType = {
1799 AUXTYPE_X3DRouteArray,
1800 'P',
1801 "X3DRouteArray",
1802 0, //sizeof(struct X3DRoute),
1803 NULL, //no constructor for X3DRoute
1804 NULL, //no constructor args
1805 X3DRouteArrayProperties,
1806 NULL, //no special has
1807 X3DRouteArrayGetter,
1808 NULL,
1809 'P', 'T',//takes int index in prop, readonly
1810 NULL,
1811};
1812
1813//X3DRoute{
1814//SFNode sourceNode;
1815//String sourceField;
1816//SFNode destinationNode;
1817//String destinationField;
1818//}
1819
1820FWPropertySpec (X3DRouteProperties)[] = {
1821 {"sourceNode", 0, 'W', 'T'},
1822 {"sourceField", 1, 'S', 'T'},
1823 {"destinationNode", 2, 'W', 'T'},
1824 {"destinationField", 3, 'S', 'T'},
1825 {NULL,0,0,0},
1826};
1827int X3DRouteGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1828 union anyVrml *value;
1829 int type, kind;
1830 const char *fieldname; // , *stofield; //*sfromfield,
1831 struct X3D_Node *fromNode, *toNode;
1832 int fromIndex, toIndex, fromBuiltIn, toBuiltIn;
1833 int nr = 1;
1834 {
1835 struct brotoRoute* broute = (struct brotoRoute*)fwn;
1836 fromNode = broute->from.node;
1837 fromIndex = broute->from.ifield;
1838 fromBuiltIn = broute->from.builtIn;
1839 toNode = broute->to.node;
1840 toIndex = broute->to.ifield;
1841 toBuiltIn = broute->to.builtIn;
1842 }
1843 if(!fromNode || !toNode) return 0;
1844
1845 //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1846 switch(index){
1847 case 0: //fromNode
1848 //fwretval->_web3dval.native = (void*)fromNode; //route->routeFromNode;
1849 //((union anyVrml*)fwpars[0]._web3dval.native)->sfnode
1850 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1851 fwretval->_web3dval.anyvrml->sfnode = fromNode;
1852 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1853 fwretval->_web3dval.gc = 1;
1854 fwretval->itype = 'W';
1855 break;
1856 case 1: //fromField
1857 //fieldname = findFIELDNAMESfromNodeOffset0(fromNode,fromOffset);
1858 getFieldFromNodeAndIndexSource(fromNode,fromIndex,fromBuiltIn,&fieldname,&type,&kind,&value);
1859 fwretval->_string = fieldname; //NULL;
1860 fwretval->itype = 'S';
1861 break;
1862 case 2: //toNode
1863 //fwretval->_web3dval.native = (void*)toNode; //route->routeFromNode;
1864 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1865 fwretval->_web3dval.anyvrml->sfnode = toNode;
1866 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1867 fwretval->itype = 'W';
1868 fwretval->_web3dval.gc = 1;
1869 break;
1870 case 3: //toField
1871 //getFieldFromNodeAndIndex(route->tonodes[0].routeToNode,route->tonodes[0].foffset,&fieldname,&type,&kind,&value);
1872 getFieldFromNodeAndIndexSource(toNode,toIndex,toBuiltIn,&fieldname,&type,&kind,&value);
1873 fwretval->_string = fieldname;
1874 fwretval->itype = 'S';
1875 break;
1876 default:
1877 nr = 0;
1878 }
1879 return nr;
1880}
1881
1882
1883struct FWTYPE X3DRouteType = {
1884 AUXTYPE_X3DRoute,
1885 'P',
1886 "X3DRoute",
1887 0, //sizeof(struct X3DRoute),
1888 NULL, //no constructor for X3DRoute
1889 NULL, //no constructor args
1890 X3DRouteProperties,
1891 NULL, //no special has
1892 X3DRouteGetter,
1893 NULL,
1894 0,0, //takes int index in prop
1895 NULL,
1896};
1897
1898
1899
1900int X3DProtoArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1901
1902 int nr = 0;
1903 //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1904 if(index == -1){
1905 int _length;
1906 _length = vectorSize(fwn);
1907 fwretval->_integer = _length;
1908 fwretval->itype = 'I';
1909 nr = 1;
1910 }else if(index > -1 ){
1911 if(index < vectorSize(fwn)){
1912 fwretval->_pointer.native = vector_get(void *, fwn, index); //struct X3D_Proto *
1913 fwretval->_pointer.gc = 1;
1914 fwretval->_pointer.fieldType = AUXTYPE_X3DProto;
1915 fwretval->itype = 'P';
1916 nr = 1;
1917 }
1918 }
1919 return nr;
1920}
1921
1922
1923FWPropertySpec (X3DProtoArrayProperties)[] = {
1924 {"length", -1, 'I', 'T'},
1925 {NULL,0,0,0},
1926};
1927
1928struct FWTYPE X3DProtoArrayType = {
1929 AUXTYPE_X3DProtoArray,
1930 'P',
1931 "X3DProtoArray",
1932 0, //sizeof(struct X3DProto),
1933 NULL, //no constructor for X3DProto
1934 NULL, //no constructor args
1935 X3DProtoArrayProperties,
1936 NULL, //no special has
1937 X3DProtoArrayGetter,
1938 NULL,
1939 'P', 'T',//takes int index in prop, readonly
1940 NULL,
1941};
1942
1943struct FWTYPE X3DExternProtoArrayType = {
1944 AUXTYPE_X3DExternProtoArray,
1945 'P',
1946 "X3DExternProtoArray",
1947 0, //sizeof(struct X3DProto),
1948 NULL, //no constructor for X3DProto
1949 NULL, //no constructor args
1950 X3DProtoArrayProperties,
1951 NULL, //no special has
1952 X3DProtoArrayGetter,
1953 NULL,
1954 'P', 'T',//takes int index in prop, readonly
1955 NULL,
1956};
1957
1958
1959struct tuplePointerInt {
1960 void *pointer;
1961 int integer;
1962};
1963
1964FWPropertySpec (X3DProtoProperties)[] = {
1965 {"name", 0, 'S', 'T'},
1966 {"fields", 1, 'W', 'T'},
1967 {"isExternProto", 2, 'B', 'T'},
1968 {NULL,0,0,0},
1969};
1970int X3DProtoGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1971 int nr = 0;
1972 //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1973 switch(index){
1974 case 0: //name
1975 fwretval->_string = X3D_PROTO(fwn)->__typename; //NULL;
1976 fwretval->itype = 'S';
1977 break;
1978 case 1: //fields
1979 fwretval->_web3dval.native = fwn; //we'll get field[i] from the proto later (void*)X3D_PROTO(fwn)->__protoDef; //route->routeFromNode;
1980 fwretval->_web3dval.fieldType = AUXTYPE_X3DFieldDefinitionArray;
1981 fwretval->itype = 'W';
1982 fwretval->_web3dval.gc = 0;
1983 break;
1984 case 2: //isExternProto
1985 fwretval->itype = 'B';
1986 {
1987 unsigned char flag = ciflag_get(X3D_PROTO(fwn)->__protoFlags,3);
1988 if(flag == 1)
1989 fwretval->_boolean = TRUE;
1990 else
1991 fwretval->_boolean = FALSE;
1992 }
1993 default:
1994 nr = 0;
1995 }
1996 return nr;
1997}
1998
1999
2000struct FWTYPE X3DProtoType = {
2001 AUXTYPE_X3DProto,
2002 'P',
2003 "X3DProtoDeclaration",
2004 0, //sizeof(struct X3DProto),
2005 NULL, //no constructor for X3DProto
2006 NULL, //no constructor args
2007 X3DProtoProperties,
2008 NULL, //no special has
2009 X3DProtoGetter,
2010 NULL,
2011 0,0, //takes int index in prop
2012 NULL,
2013};
2014struct FWTYPE X3DExternProtoType = {
2015 AUXTYPE_X3DExternProto,
2016 'P',
2017 "X3DExternProtoDeclaration",
2018 0, //sizeof(struct X3DProto),
2019 NULL, //no constructor for X3DProto
2020 NULL, //no constructor args
2021 X3DProtoProperties, //it tests if its extern or not
2022 NULL, //no special has
2023 X3DProtoGetter,
2024 NULL,
2025 0,0, //takes int index in prop
2026 NULL,
2027};
2028
2029int count_fields(struct X3D_Node* node);
2030int X3DFieldDefinitionArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2031
2032 int nr = 0;
2033 struct X3D_Node *node = (struct X3D_Node*)fwn;
2034
2035 //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
2036 if(index == -1){
2037 int _length = 0;
2038 //I suspect this fieldDefinition stuff is for ProtoDeclares and ExternProtoDeclares only, not builtin or protoInstances or scripts
2039 _length = count_fields(node);
2040 fwretval->_integer = _length;
2041 fwretval->itype = 'I';
2042 nr = 1;
2043 }else if(index > -1 ){
2044 if(index < vectorSize(fwn)){
2045 struct tuplePointerInt *tpi = malloc(sizeof(struct tuplePointerInt));
2046 tpi->pointer = (void*)node;
2047 tpi->integer = index;
2048 fwretval->_pointer.native = tpi; //vector_get(void *, fwn, index); //struct X3D_Proto *
2049 fwretval->_pointer.gc = 1;
2050 fwretval->_pointer.fieldType = AUXTYPE_X3DFieldDefinition;
2051 fwretval->itype = 'P';
2052 nr = 1;
2053 }
2054 }
2055 return nr;
2056}
2057
2058
2059FWPropertySpec (X3DFieldDefinitionArrayProperties)[] = {
2060 {"length", -1, 'I', 'T'},
2061 {NULL,0,0,0},
2062};
2063
2064struct FWTYPE X3DFieldDefinitionArrayType = {
2065 AUXTYPE_X3DFieldDefinitionArray,
2066 'P',
2067 "X3DFieldDefinitionArray",
2068 0, //sizeof(struct X3DProto),
2069 NULL, //no constructor for X3DProto
2070 NULL, //no constructor args
2071 X3DFieldDefinitionArrayProperties,
2072 NULL, //no special has
2073 X3DFieldDefinitionArrayGetter,
2074 NULL,
2075 'P', 'T',//takes int index in prop, readonly
2076 NULL,
2077};
2078
2079FWPropertySpec (X3DFieldDefinitionProperties)[] = {
2080 {"name", 0, 'S', 'T'},
2081 {"accessType", 1, 'I', 'T'},
2082 {"dataType", 2, 'I', 'T'},
2083 {NULL,0,0,0},
2084};
2085int X3DFieldDefinitionGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2086 int ifield, type,kind, konstindex, nr = 0;
2087 struct string_int * si;
2088 union anyVrml *value;
2089 struct X3D_Node* node;
2090 const char *fname;
2091 struct tuplePointerInt *tpi = (struct tuplePointerInt*)fwn;
2092 node = tpi->pointer;
2093 ifield = tpi->integer;
2094 //I suspect FieldDefinitions are for ProtoDeclarations only,
2095 // but freewrl Brotos can use the same function for nodes and declares
2096 if(getFieldFromNodeAndIndexSource(node,ifield,TRUE,&fname,&type,&kind,&value)){
2097 //if(getFieldFromNodeAndIndex(node,ifield,&fname,&type,&kind,&value)){
2098 //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
2099 switch(index){
2100 case 0: //name
2101 fwretval->_string = fname; //NULL;
2102 fwretval->itype = 'S';
2103 break;
2104 case 1: //accessType
2105 si = lookup_string_int(lookup_X3DConstants,PROTOKEYWORDS[kind],&konstindex);
2106 fwretval->_integer = konstindex; //index into x3dconstants table
2107 fwretval->itype = 'I';
2108 break;
2109 case 2: //dataType
2110 si = lookup_string_int(lookup_X3DConstants,FIELDTYPES[type],&konstindex);
2111 fwretval->_integer = konstindex; //index into x3dconstants table
2112 fwretval->itype = 'I';
2113 break;
2114 default:
2115 nr = 0;
2116 }
2117 }
2118 return nr;
2119}
2120
2121
2122struct FWTYPE X3DFieldDefinitionType = {
2123 AUXTYPE_X3DFieldDefinition,
2124 'P',
2125 "X3DFieldDefinition",
2126 0, //sizeof(struct X3DFieldDefinition),
2127 NULL, //no constructor for X3DProto
2128 NULL, //no constructor args
2129 X3DFieldDefinitionProperties,
2130 NULL, //no special has
2131 X3DFieldDefinitionGetter,
2132 NULL,
2133 0,0, //takes int index in prop
2134 NULL,
2135};
2136
2137
2138
2139
2140
2141
2142void initVRMLBrowser(FWType* typeArray, int *n){
2143 typeArray[*n] = &X3DRouteType; (*n)++;
2144 typeArray[*n] = &X3DRouteArrayType; (*n)++;
2145 typeArray[*n] = &X3DExecutionContextType; (*n)++;
2146 typeArray[*n] = &ProfileInfoType; (*n)++;
2147 typeArray[*n] = &ProfileInfoArrayType; (*n)++;
2148 typeArray[*n] = &ComponentInfoType; (*n)++;
2149 typeArray[*n] = &ComponentInfoArrayType; (*n)++;
2150 typeArray[*n] = &BrowserType; (*n)++;
2151 typeArray[*n] = &X3DConstantsType; (*n)++;
2152
2153 typeArray[*n] = &X3DProtoType; (*n)++;
2154 typeArray[*n] = &X3DProtoArrayType; (*n)++;
2155 typeArray[*n] = &X3DExternProtoType; (*n)++;
2156 typeArray[*n] = &X3DExternProtoArrayType; (*n)++;
2157 typeArray[*n] = &X3DFieldDefinitionType; (*n)++;
2158 typeArray[*n] = &X3DFieldDefinitionArrayType; (*n)++;
2159
2160}
2161#endif /* ifdef JAVASCRIPT_DUK */