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 {"SFVec4f",FIELDTYPE_SFVec4f},
253 {"MFVec4f",FIELDTYPE_MFVec3f},
254 {"SFVec2d",FIELDTYPE_SFVec2d},
255 {"MFVec2d",FIELDTYPE_MFVec2d},
256 {"SFVec3d",FIELDTYPE_SFVec3d},
257 {"MFVec3d",FIELDTYPE_MFVec3d},
258 {"SFVec4d",FIELDTYPE_SFVec4d},
259 {"MFVec4d",FIELDTYPE_MFVec4d},
260 {"SFRotation",FIELDTYPE_SFRotation},
261 {"MFRotation",FIELDTYPE_MFRotation},
262 {"SFColor",FIELDTYPE_SFColor},
263 {"MFColor",FIELDTYPE_MFColor},
264 {"SFImage",FIELDTYPE_SFImage},
265 {"MFImage",FIELDTYPE_MFImage},
266 {"SFColorRGBA",FIELDTYPE_SFColorRGBA},
267 {"MFColorRGBA",FIELDTYPE_MFColorRGBA},
268 {"SFString",FIELDTYPE_SFString},
269 {"MFString",FIELDTYPE_MFString},
270 {"SFMatrix3f",FIELDTYPE_SFMatrix3f},
271 {"MFMatrix3f",FIELDTYPE_MFMatrix3f},
272 {"SFMatrix4f",FIELDTYPE_SFMatrix4f},
273 {"MFMatrix4f",FIELDTYPE_MFMatrix4f},
274 {"SFMatrix3d",FIELDTYPE_SFMatrix3d},
275 {"MFMatrix3d",FIELDTYPE_MFMatrix3d},
276 {"SFMatrix4d",FIELDTYPE_SFMatrix4d},
277 {"MFMatrix4d",FIELDTYPE_MFMatrix4d},
278/*
279 {"X3DBoundedObject",},
280 {"X3DMetadataObject",},
281 {"X3DUrlObject",},
282 {"X3DTriggerNode",},
283 {"X3DInfoNode",},
284 {"X3DAppearanceNode",},
285 {"X3DAppearanceChildNode",},
286 {"X3DMaterialNode",},
287 {"X3DTextureNode",},
288 {"X3DTexture2DNode",},
289 {"X3DTexture3DNode",},
290 {"X3DTextureTransformNode",},
291 {"X3DGeometryNode",},
292 {"X3DGeometry3DNode",},
293 {"X3DCoordinateNode",},
294 {"X3DParametricGeometryNode",},
295 {"X3DGeometricPropertyNode",},
296 {"X3DColorNode",},
297 {"X3DProtoInstance",},
298 {"X3DNormalNode",},
299 {"X3DTextureCoordinateNode",},
300 {"X3DFontStyleNode",},
301 {"X3DGroupingNode ",},
302 {"X3DChildNode",},
303 {"X3DBindableNode",},
304 {"X3DBackgroundNode",},
305 {"X3DInterpolatorNode",},
306 {"X3DShapeNode",},
307 {"X3DScriptNode",},
308 {"X3DSensorNode",},
309 {"X3DEnvironmentalSensorNode",},
310 {"X3DLightNode",},
311 {"X3DNetworkSensorNode",},
312 {"X3DPointingDeviceSensorNode",},
313 {"X3DDragSensorNode",},
314 {"X3DKeyDeviceSensorNode",},
315 {"X3DSequencerNode",},
316 {"X3DTimeDependentNode",},
317 {"X3DSoundNode",},
318 {"X3DSoundSourceNode",},
319 {"X3DTouchSensorNode",},
320*/
321 {"inputOnly",PKW_inputOnly},
322 {"outputOnly",PKW_outputOnly},
323 {"inputOutput",PKW_inputOutput},
324 {"initializeOnly",PKW_initializeOnly},
325 {NULL,0}
326};
327
328struct string_int *lookup_string_int(struct string_int *table, const char *searchkey, int *index){
329 int i;
330 //struct string_int *retval = NULL;
331 *index = -1;
332 if(!table) return NULL;
333 i = 0;
334 while(table[i].c){
335 if(!strcmp(table[i].c,searchkey)){
336 //found it
337 (*index) = i;
338 return &table[i];
339 }
340 i++;
341 }
342 return NULL;
343}
344
345int X3DConstantsGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
346 int nr = 1;
347 fwretval->_integer = lookup_X3DConstants[index].i;
348 fwretval->itype = 'I';
349 return nr;
350}
351
352int len_constants(){
353 int len = (sizeof(lookup_X3DConstants) / sizeof(struct string_int)) -1;
354 return len;
355}
356int X3DConstantsIterator(int index, FWType fwt, FWPointer *pointer, const char **name, int *lastProp, int *jndex, char *type, char *readOnly){
357 index ++;
358 (*jndex) = 0;
359 if(index < len_constants()){
360 (*name) = lookup_X3DConstants[index].c;
361 (*jndex) = index;
362 (*lastProp) = index;
363 (*type) = 'I';
364 (*readOnly) = 'T';
365 return index;
366 }
367 return -1;
368}
369struct FWTYPE X3DConstantsType = {
370 AUXTYPE_X3DConstants,
371 'P',
372 "X3DConstants",
373 0, //sizeof(struct X3DRoute),
374 NULL, //no constructor for X3DRoute
375 NULL, //no constructor args
376 NULL, //X3DConstantsProperties - lets have fun and use the custom HAS function
377 X3DConstantsIterator, //custom Iterator function - returns the index used in the Getter and has
378 X3DConstantsGetter,
379 NULL,
380 0,0, //takes int index in prop
381 NULL,
382};
383
384
385
386
387int VRBrowserGetName(FWType fwtype, void *ec, void * fwn, int argc, FWval fwpars, FWval fwretval)
388{
389 fwretval->_string = BrowserName;
390 fwretval->itype = 'S';
391 return 1;
392}
393int VRBrowserGetVersion(FWType fwtype, void *ec, void * fwn, int argc, FWval fwpars, FWval fwretval)
394{
395 fwretval->_string = libFreeWRL_get_version();
396 fwretval->itype = 'S';
397 return 1;
398}
399int VRBrowserGetCurrentSpeed(FWType fwtype, void *ec, void * fwn, int argc, FWval fwpars, FWval fwretval)
400{
401 char string[1000];
402 sprintf (string,"%f",gglobal()->Mainloop.BrowserSpeed);
403 fwretval->_string = strdup(string);
404 fwretval->itype = 'S';
405 return 1;
406}
407
408int VRBrowserGetCurrentFrameRate(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
409{
410 char string[1000];
411 sprintf (string,"%6.2f",gglobal()->Mainloop.BrowserFPS);
412 fwretval->_string = strdup(string);
413 fwretval->itype = 'S';
414 return 1;
415}
416int VRBrowserGetWorldURL(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
417{
418 fwretval->_string = BrowserFullPath;
419 fwretval->itype = 'S';
420 return 1;
421}
422const char *flexiString(FWval fwpars, char *buffer)
423{
424 //allow MFString[0], SFString or ecma String
425 //if buffer is given: MF is converted to '["MF[0]"] ["MF[1]"] [...' format
426 //if buffer is NULL, MF[0] is returned
427 //char *tptr;
428 const char *_costr;
429 int lenbuf = 1000;
430
431 _costr = NULL;
432 //if(fwpars[0].itype == 'S')
433 // _costr = fwpars[0]._string;
434 //else
435 if(fwpars[0].itype == 'W'){
436 switch(fwpars[0]._web3dval.fieldType){
437 case FIELDTYPE_SFString:
438 {
439 //Q. shoulD we ever get in here? SFString is supposed to be represented by an ECMA type in javascript
440 struct Uni_String *sfs = (struct Uni_String*)fwpars[0]._web3dval.native;
441 _costr = sfs->strptr;
442 }
443 break;
444 case FIELDTYPE_MFString:
445 {
446 struct Multi_String *mfs = (struct Multi_String*)fwpars[0]._web3dval.native;
447 if(buffer){
448 int i, l1, l2, l3, lt;
449 char *start = "[\"";
450 char *end = "\"] ";
451 l1 = strlen(start);
452 l2 = strlen(end);
453 buffer[0] = '\0';
454 lt = 1;
455 for(i=0;i<mfs->n;i++){
456 l3 = strlen(mfs->p[i]->strptr);
457 if(lt + l1 + l2 + l3 > lenbuf) break;
458 strcat(buffer,"[\"");
459 strcat(buffer,mfs->p[i]->strptr);
460 strcat(buffer,"\"] ");
461 lt += l1 + l2 + l3;
462 }
463 _costr = buffer;
464 }else{
465 _costr = mfs->p[0]->strptr;
466 }
467 }
468 break;
469 }
470 }
471 return _costr;
472}
473
474int VRBrowserReplaceWorld(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
475{
476 //char *tptr;
477 char*_costr;
478
479 _costr = strdup(flexiString(&fwpars[0],NULL));
480 EAI_RW(_costr);
481 return 0;
482}
483
484
485/* used in loadURL*/
486void conCat_duk (char *out, char *in) {
487
488 while (strlen (in) > 0) {
489 strcat (out," :loadURLStringBreak:");
490 while (*out != '\0') out++;
491
492 if (*in == '[') in++;
493 while ((*in != '\0') && (*in == ' ')) in++;
494 if (*in == '"') {
495 in++;
496 /* printf ("have the initial quote string here is %s\n",in); */
497 while (*in != '"') { *out = *in; out++; in++; }
498 *out = '\0';
499 /* printf ("found string is :%s:\n",tfilename); */
500 }
501
502 /* skip along to the start of the next name */
503 if (*in == '"') in++;
504 if (*in == ',') in++;
505 if (*in == ']') in++; /* this allows us to leave */
506 }
507}
508
509void createLoadUrlString_duk(char *out, int outLen, char *url, char *param) {
510 int commacount1;
511 int commacount2;
512 char *tptr;
513
514 /* mimic the EAI loadURL, java code is:
515 // send along sizes of the Strings
516 SysString = "" + url.length + " " + parameter.length;
517
518 for (count=0; count<url.length; count++) {
519 SysString = SysString + " :loadURLStringBreak:" + url[count];
520 }
521
522 for (count=0; count<parameter.length; count++) {
523 SysString = SysString + " :loadURLStringBreak:" + parameter[count];
524 }
525 */
526
527 /* find out how many elements there are */
528
529 commacount1 = 0; commacount2 = 0;
530 tptr = url; while (*tptr != '\0') { if (*tptr == '"') commacount1 ++; tptr++; }
531 tptr = param; while (*tptr != '\0') { if (*tptr == '"') commacount2 ++; tptr++; }
532 commacount1 = commacount1 / 2;
533 commacount2 = commacount2 / 2;
534
535 if (( strlen(url) +
536 strlen(param) +
537 (commacount1 * strlen (" :loadURLStringBreak:")) +
538 (commacount2 * strlen (" :loadURLStringBreak:"))) > (outLen - 20)) {
539 printf ("createLoadUrlString, string too long\n");
540 return;
541 }
542
543 sprintf (out,"%d %d",commacount1,commacount2);
544
545 /* go to the end of this string */
546 while (*out != '\0') out++;
547
548 /* go through the elements and find which (if any) url exists */
549 conCat_duk (out,url);
550 while (*out != '\0') out++;
551 conCat_duk (out,param);
552}
553struct X3D_Anchor* get_EAIEventsIn_AnchorNode();
554int VRBrowserLoadURL(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
555{
556 char *url, *parameter;
557 char bufferUrl[1000];
558 char bufferParam[1000];
559 char myBuf[1000];
560
561 url = strdup(flexiString(&fwpars[0],bufferUrl));
562 parameter = strdup(flexiString(&fwpars[1],bufferParam));
563 /* we use the EAI code for this - so reformat this for the EAI format */
564 {
565 /* make up the URL from what we currently know */
566 createLoadUrlString_duk(myBuf,1000,url, parameter);
567 createLoadURL(myBuf);
568
569 /* now tell the fwl_RenderSceneUpdateScene that BrowserAction is requested... */
570 setAnchorsAnchor( get_EAIEventsIn_AnchorNode()); //&gglobal().EAIEventsIn.EAI_AnchorNode;
571 }
572 gglobal()->RenderFuncs.BrowserAction = TRUE;
573 return 0;
574}
575int VRBrowserSetDescription(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
576{
577 //const char *_costr = NULL;
578 if(fwpars[0].itype == 'S')
579 gglobal()->Mainloop.BrowserDescription = fwpars[0]._string;
580 return 0;
581}
582int VRBrowserCreateX3DFromString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
583{
584 /* for the return of the nodes */
585 struct X3D_Group *retGroup;
586 int i, iret = 0;
587 //char *xstr;
588 //char *tmpstr;
589 //char *separator;
590 int ra;
591 //int count;
592 //int wantedsize;
593 //int MallocdSize;
594 ttglobal tg = gglobal();
595 struct VRMLParser *globalParser = (struct VRMLParser *)tg->CParse.globalParser;
596 const char *_c = fwpars[0]._string;
597
598 /* do the call to make the VRML code - create a new browser just for this string */
599 retGroup = createNewX3DNode0(NODE_Group); //don't register, we'll gc here
600 gglobal()->ProdCon.savedParser = (void *)globalParser; globalParser = NULL;
601 ra = EAI_CreateX3d("String",_c,ec,retGroup); //includes executionContext for __nodes and __subContexts
602 globalParser = (struct VRMLParser*)gglobal()->ProdCon.savedParser; /* restore it */
603 if(retGroup->children.n > 0) {
604 struct Multi_Node *mfn = (struct Multi_Node *)malloc(sizeof(struct Multi_Node));
605 memcpy(mfn,&retGroup->children,sizeof(struct Multi_Node));
606 FREE_IF_NZ(retGroup);
607 for(i=0;i<mfn->n;i++){
608 mfn->p[i]->_parentVector->n = 0;
609 }
610 fwretval->_web3dval.native = mfn;
611 fwretval->_web3dval.fieldType = FIELDTYPE_MFNode; //Group
612 fwretval->_web3dval.gc = 1; //will be GCd by nodelist
613 fwretval->itype = 'W';
614 iret = 1;
615 }
616 FREE_IF_NZ(retGroup);
617
618
619 return iret;
620}
621//int jsrrunScript(duk_context *ctx, char *script, FWval retval);
622int VRBrowserCreateVrmlFromString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
623{
624 /* for the return of the nodes */
625 struct X3D_Group *retGroup;
626 //char *xstr;
627 //char *tmpstr;
628 //char *separator;
629 int i, ra;
630 int iret; //count,
631 //int wantedsize;
632 //int MallocdSize;
633 ttglobal tg = gglobal();
634 struct VRMLParser *globalParser = (struct VRMLParser *)tg->CParse.globalParser;
635 const char *_c = fwpars[0]._string; //fwpars[0]._web3dval.anyvrml->sfstring->strptr;
636
637 iret = 0;
638 retGroup = createNewX3DNode0(NODE_Group); //don't register, we'll gc here
639 gglobal()->ProdCon.savedParser = (void *)globalParser; globalParser = NULL;
640 ra = EAI_CreateVrml("String",_c,ec,retGroup); //includes executionContext for __nodes and __subContexts
641 globalParser = (struct VRMLParser*)gglobal()->ProdCon.savedParser; /* restore it */
642 if(retGroup->children.n > 0) {
643 struct Multi_Node *mfn = (struct Multi_Node *)malloc(sizeof(struct Multi_Node));
644 memcpy(mfn,&retGroup->children,sizeof(struct Multi_Node));
645 for(i=0;i<mfn->n;i++){
646 mfn->p[i]->_parentVector->n = 0;
647 }
648 fwretval->_web3dval.native = mfn;
649 fwretval->_web3dval.fieldType = FIELDTYPE_MFNode; //Group
650 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
651 fwretval->itype = 'W';
652 iret = 1;
653 }
654 deleteVector(struct X3D_Node*,retGroup->_parentVector);
655 FREE_IF_NZ(retGroup);
656
657 return iret;
658
659}
660void *createNewX3DNode(int nt);
661void add_node_to_broto_context(struct X3D_Proto *currentContext,struct X3D_Node *node);
662int VRBrowserCreateNodeFromString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
663{
664 int i, iret, isVRML,isX3D;
665 struct X3D_Node *node;
666 const char *_c = fwpars[0]._string;
667
668 node = NULL;
669 isVRML = FALSE;
670 isX3D = FALSE;
671 iret = 0;
672 for(i=0;i<strlen(_c);i++){
673 if(_c[i] == '<') isX3D = TRUE;
674 if(_c[i] == '{') isVRML = TRUE;
675 }
676 if(!isX3D && !isVRML){
677 //might be just a node name ie createNode('Cone');
678 int ctype;
679 //check builtins
680 ctype = findFieldInNODES(_c);
681 if (ctype > -1) {
682 node = (struct X3D_Node*)createNewX3DNode(ctype);
683 add_node_to_broto_context(ec,node);
684 }
685 //check protos? No: there's a separate createProto() function for those.
686 }
687 if(!node){
688 //more general might have parameters ie createNode("Cone { radius .5 }")
689 if(isVRML)
690 iret = VRBrowserCreateVrmlFromString(fwtype,ec,fwn,argc,fwpars,fwretval);
691 else
692 iret = VRBrowserCreateX3DFromString(fwtype,ec,fwn,argc,fwpars,fwretval);
693 if(iret){
694 node = fwretval->_web3dval.anyvrml->mfnode.p[0];
695 node->_executionContext = ec;
696 }
697 }
698 if(node){
699 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
700 fwretval->_web3dval.anyvrml->sfnode = node;
701 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
702 fwretval->_web3dval.gc = 0;
703 fwretval->itype = 'W';
704 iret = 1;
705 }
706 return iret;
707}
708void send_resource_to_parser_async(resource_item_t *res);
709int VRBrowserCreateVrmlFromURL(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
710{
711 //Browser.createVrmlFromURL(urlString,group,'addChildren');
712 //(MFString,SFNode,string)
713 int i, iret, type,kind,ifield,ifound;
714 union anyVrml *value;
715 struct X3D_Node *target_node;
716 struct Multi_String *url;
717 const char *cfield;
718 resource_item_t *res;
719
720 url = NULL;
721 target_node = NULL;
722 cfield = NULL;
723 if(fwpars[0].itype == 'W')
724 url = &fwpars[0]._web3dval.anyvrml->mfstring;
725
726 if(fwpars[1].itype == 'W')
727 if(fwpars[1]._web3dval.fieldType == FIELDTYPE_SFNode)
728 target_node = fwpars[1]._web3dval.anyvrml->sfnode;
729 if(fwpars[2].itype == 'S')
730 cfield = fwpars[2]._string;
731
732 if(!url || !target_node || !cfield){
733 ConsoleMessage("createX3DFromURL parameters: (MFString url, SFNode target_node, string target_field\n");
734 iret = 0;
735 return iret;
736 }
737 //lookup field on node
738 ifound = getFieldFromNodeAndName(target_node,cfield,&type,&kind,&ifield,&value);
739 if(!ifound){
740 ConsoleMessage("createX3DFromURL no field named %s on nodetype %s\n",cfield,stringNodeType(target_node->_nodeType));
741 iret = 0;
742 return iret;
743 }
744
745
746 //res = resource_create_single(url);
747 res = resource_create_multi(url);
748 res->ectx = ec;
749 res->whereToPlaceData = target_node;
750 res->offsetFromWhereToPlaceData = (int) ((size_t)value - (size_t) target_node); //offsetof (struct X3D_Group, children);
751 //iret = parser_process_res_VRML_X3D(res);
752
753 send_resource_to_parser_async(res);
754 iret = 1;
755 return iret;
756}
757
758/* we add/remove routes with this call */
759void jsRegisterRoute_HIDE(
760 struct X3D_Node* from, int fromOfs,
761 struct X3D_Node* to, int toOfs,
762 int len, const char *adrem) {
763 int ad;
764
765 if (strcmp("addRoute",adrem) == 0)
766 ad = 1;
767 else ad = 0;
768
769 CRoutes_Register(ad, from, fromOfs, to, toOfs , len,
770 returnInterpolatorPointer(to->_nodeType), 0, 0);
771}
772struct brotoRoute *createNewBrotoRoute();
773int getFieldFromNodeAndNameC(struct X3D_Node* node,const char *fieldname, int *type, int *kind, int *iifield, int *builtIn, union anyVrml **value, const char **cname);
774void *addDeleteRoute0(void *fwn, const char* callingFunc, struct X3D_Node* fromNode, const char *sfromField, struct X3D_Node* toNode, const char *stoField){
775 void *retval;
776 int fromType,toType,fromKind,toKind,fromField,toField,fromBuiltIn,toBuiltIn;
777 const char *fromCname,*toCname;
778 int i, len, fromOfs, toOfs;
779 union anyVrml *fromValue, *toValue;
780
781 getFieldFromNodeAndNameC(fromNode,sfromField,&fromType,&fromKind,&fromField,&fromBuiltIn,&fromValue,&fromCname);
782 getFieldFromNodeAndNameC(toNode,stoField,&toType,&toKind,&toField,&toBuiltIn,&toValue,&toCname);
783
784 /* do we have a mismatch here? */
785 if (fromType != toType) {
786 printf ("Javascript routing problem - can not route from %s to %s\n",
787 stringNodeType(fromNode->_nodeType),
788 stringNodeType(toNode->_nodeType));
789 return NULL;
790 }
791
792 len = returnRoutingElementLength(toType);
793 {
794 struct brotoRoute *broute;
795 struct X3D_Proto *ec = (struct X3D_Proto*)fwn;
796 if(!ec) ec = (struct X3D_Proto*)fromNode->_executionContext;
797 if(!strcmp(callingFunc,"addRoute")){
798 broute = createNewBrotoRoute();
799 broute->from.node = fromNode;
800 broute->from.ifield = fromField;
801 broute->from.builtIn = fromBuiltIn;
802 //broute->from.Ofs = fromOfs;
803 broute->from.ftype = fromType;
804 broute->to.node = toNode;
805 broute->to.ifield = toField;
806 broute->to.builtIn = toBuiltIn;
807 //broute->to.Ofs = toOfs;
808 broute->to.ftype = toType;
809 broute->lastCommand = 1; //added above (won't be added if an import weak route)
810 CRoutes_RegisterSimpleB(broute->from.node,broute->from.ifield,broute->from.builtIn,broute->to.node,broute->to.ifield,broute->to.builtIn,broute->ft);
811 broute->ft = fromType == toType ? fromType : -1;
812 if(!ec->__ROUTES)
813 ec->__ROUTES = newStack(struct brotoRoute *);
814 stack_push(struct brotoRoute *, ec->__ROUTES, broute);
815 retval = (void*)broute;
816 }else{
817 //deleteRoute
818 if(ec->__ROUTES)
819 for(i=0;i<vectorSize(ec->__ROUTES);i++){
820 broute = vector_get(struct brotoRoute*,ec->__ROUTES,i);
821 if(broute->from.node == fromNode && broute->from.ifield == fromField
822 && broute->to.node == toNode && broute->to.ifield == toField){
823 if(broute->lastCommand == 1)
824 CRoutes_RemoveSimpleB(broute->from.node,broute->from.ifield,broute->from.builtIn,broute->to.node,broute->to.ifield,broute->to.builtIn,broute->ft);
825 broute->lastCommand = 0;
826 vector_remove_elem(struct brotoRoute*,ec->__ROUTES,i);
827 FREE_IF_NZ(broute);
828 break;
829 }
830 }
831 retval = NULL;
832 }
833 }
834 return retval;
835
836}
837
838void * addDeleteRoute(void *fwn, char* callingFunc, int argc, FWval fwpars, FWval fwretval){
839 struct X3D_Node *fromNode;
840 struct X3D_Node *toNode;
841 const char *fromField, *toField;
842 void *retval;
843
844 //if(0){ //!strcmp(callingFunc,"deleteRoute")){
845 // fromNode = fwpars[0]._web3dval.native;
846 // toNode = fwpars[2]._web3dval.native;
847 //}
848 fromNode = fwpars[0]._web3dval.anyvrml->sfnode; //.native;
849 toNode = fwpars[2]._web3dval.anyvrml->sfnode; //.native;
850
851 fromField = fwpars[1]._string;
852 toField = fwpars[3]._string;
853
854 retval = addDeleteRoute0(fwn,callingFunc,fromNode, fromField, toNode, toField);
855 return retval;
856}
857int X3DExecutionContext_deleteRoute(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
858 //we're expecting an X3DRoute struct parameter.
859 int nr = 0;
860 void *xroute;
861 struct X3D_Node *fromNode, *toNode;
862 const char *fromField, *toField;
863 int fromIfield, toIfield, fromBuiltIn, toBuiltIn;
864 int ftype,kind;
865 union anyVrml *value;
866
867 if(fwpars[0].itype != 'P') return nr;
868
869 {
870 struct brotoRoute* broute = (struct brotoRoute*)fwpars[0]._pointer.native;
871 fromNode = broute->from.node;
872 fromIfield = broute->from.ifield;
873 fromBuiltIn = broute->from.builtIn;
874 toNode = broute->to.node;
875 toIfield = broute->to.ifield;
876 toBuiltIn = broute->to.builtIn;
877 }
878 getFieldFromNodeAndIndexSource(fromNode,fromIfield,fromBuiltIn,&fromField,&ftype,&kind,&value);
879 getFieldFromNodeAndIndexSource(toNode,toIfield,toBuiltIn,&toField,&ftype,&kind,&value);
880 xroute = addDeleteRoute0(fwn,"deleteRoute",fromNode, fromField, toNode, toField);
881 return nr;
882}
883
884int VRBrowserAddRoute(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
885 void *xroute;
886 int nr = 0;
887 xroute = addDeleteRoute(fwn,"addRoute",argc,fwpars,fwretval);
888 if(xroute){
889 fwretval->_web3dval.fieldType = AUXTYPE_X3DRoute; //AUXTYPE_X3DScene;
890 fwretval->_web3dval.native = xroute;
891 fwretval->_web3dval.gc = 0;
892 fwretval->itype = 'P';
893 nr = 1;
894 }
895 return nr;
896}
897int VRBrowserDeleteRoute(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
898 void *xroute;
899 int nr = 0;
900 xroute = addDeleteRoute(fwn,"deleteRoute",argc,fwpars,fwretval);
901 return nr;
902}
903int VRBrowserPrint(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
904{
905 const char *_costr = NULL;
906 if(fwpars[0].itype == 'S'){
907 _costr = fwpars[0]._string; //fwpars[0]._web3dval.anyvrml->sfstring->strptr;
908 if(_costr)
909 ConsoleMessage("%s",_costr);
910 }
911 return 0;
912}
913int VRBrowserPrintln(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
914{
915 const char *_costr = NULL;
916 if(fwpars[0].itype == 'S'){
917 _costr = fwpars[0]._string; //fwpars[0]._web3dval.anyvrml->sfstring->strptr;
918 if(_costr)
919 ConsoleMessage("%s\n",_costr);
920 }
921 return 0;
922}
923
924FWFunctionSpec (BrowserFunctions)[] = {
925 {"getName", VRBrowserGetName, 'S',{0,0,0,NULL}},
926 {"getVersion", VRBrowserGetVersion, 'S',{0,0,0,NULL}},
927 {"getCurrentSpeed", VRBrowserGetCurrentSpeed, 'S',{0,0,0,NULL}},
928 {"getCurrentFrameRate", VRBrowserGetCurrentFrameRate, 'S',{0,0,0,NULL}},
929 {"getWorldURL", VRBrowserGetWorldURL, 'S',{0,0,0,NULL}},
930 {"replaceWorld", VRBrowserReplaceWorld, '0',{1,-1,0,"Z"}},
931 {"loadURL", VRBrowserLoadURL, '0',{2,1,'T',"FF"}},
932 {"setDescription", VRBrowserSetDescription, '0',{1,-1,0,"S"}},
933 {"createVrmlFromString", VRBrowserCreateVrmlFromString, 'W',{1,-1,0,"S"}},
934 {"createVrmlFromURL", VRBrowserCreateVrmlFromURL,'0',{3,3,0,"WWS"}},
935 {"createX3DFromString", VRBrowserCreateX3DFromString, 'W',{1,-1,0,"S"}},
936 {"createX3DFromURL", VRBrowserCreateVrmlFromURL, '0',{3,3,0,"WWS"}},
937 {"addRoute", VRBrowserAddRoute, 'P',{4,-1,0,"WSWS"}},
938 {"deleteRoute", VRBrowserDeleteRoute, '0',{4,-1,0,"WSWS"}},
939 {"print", VRBrowserPrint, '0',{1,-1,0,"S"}},
940 {"println", VRBrowserPrintln, '0',{1,-1,0,"S"}},
941
942 //{importDocument, X3dBrowserImportDocument, 0), //not sure we need/want this, what does it do?
943 //{getRenderingProperty, X3dGetRenderingProperty, 0},
944 //{addBrowserListener, X3dAddBrowserListener, 0},
945 //{removeBrowserListener, X3dRemoveBrowserListener, 0},
946
947 {0}
948};
949
950
951//typedef struct FWPropertySpec {
952// const char *name; //NULL means index int: SFVec3f[0], MF[i]
953// char index; //stable property index for switch/casing instead of strcmp on name
954// char type; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr
955// char isReadOnly; //T/F
956//} FWPropertySpec;
957
958
959FWPropertySpec (BrowserProperties)[] = {
960 {"name", 0, 'S', 'T'},
961 {"version", 1, 'S', 'T'},
962 {"currentSpeed", 2, 'D', 'T'},
963 {"currentFrameRate", 3, 'D', 'T'},
964 {"description", 4, 'S', 0},
965 {"supportedComponents", 5, 'P', 'T'},
966 {"supportedProfiles", 6, 'P', 'T'},
967 {"currentScene", 7, 'P', 'T'},
968 {NULL,0,0,0},
969};
970
971
972struct proftablestruct {
973 int profileName;
974 const int *profileTable;
975 int level; //dug9
976};
977struct proftablestruct *getProfTable();
978const int * getCapabilitiesTable();
979int BrowserGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
980 int nr = 1;
981 //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)
982 switch (index) {
983 case 0: //name
984 fwretval->_string = BrowserName;
985 fwretval->itype = 'S';
986 break;
987 case 1: //version
988 fwretval->_string = libFreeWRL_get_version();
989 fwretval->itype = 'S';
990 break;
991 case 2: //currentSpeed
992 fwretval->_numeric = gglobal()->Mainloop.BrowserSpeed;
993 fwretval->itype = 'D';
994 break;
995 case 3: //currentFrameRate
996 fwretval->_numeric = gglobal()->Mainloop.BrowserFPS;
997 fwretval->itype = 'D';
998 break;
999 case 4: //description
1000 fwretval->_string = gglobal()->Mainloop.BrowserDescription; //this is settable
1001 fwretval->itype = 'S';
1002 break;
1003 case 5: //supportedComponents
1004 fwretval->_pointer.fieldType = AUXTYPE_ComponentInfoArray;
1005 fwretval->_pointer.native = (void*)getCapabilitiesTable(); //TO-DO something about component info array
1006 fwretval->_pointer.gc = 0;
1007 fwretval->itype = 'P';
1008 break;
1009 case 6: //supportedProfiles
1010 fwretval->_pointer.fieldType = AUXTYPE_ProfileInfoArray;
1011 fwretval->_pointer.native = (void*)getProfTable(); //TO-DO something about profile info array
1012 fwretval->_pointer.gc = 0;
1013 fwretval->itype = 'P';
1014 break;
1015 case 7: //currentScene
1016 fwretval->_web3dval.fieldType = AUXTYPE_X3DExecutionContext; //AUXTYPE_X3DScene;
1017 fwretval->_web3dval.native = (void *)(struct X3D_Node*)ec; //X3DScene || X3DExecutionContext
1018 fwretval->_web3dval.gc = 0;
1019 //change this to (Script)._executionContext when brotos working fully
1020 fwretval->itype = 'P';
1021 break;
1022 default:
1023 nr = 0;
1024 }
1025 return nr;
1026}
1027int BrowserSetter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
1028 switch (index) {
1029 case 4: //description is settable
1030 gglobal()->Mainloop.BrowserDescription = fwval->_string; //fwval->_web3dval.anyvrml->sfstring->strptr;
1031 break;
1032 default:
1033 break;
1034 }
1035 return TRUE;
1036}
1037
1038
1039struct FWTYPE BrowserType = {
1040 AUXTYPE_X3DBrowser,
1041 'P',
1042 "X3DBrowser",
1043 0, //sizeof(struct X3DBrowser),
1044 NULL, //no constructor for Browser
1045 NULL, //no constructor args
1046 BrowserProperties,
1047 NULL, //no special has
1048 BrowserGetter,
1049 BrowserSetter,
1050 0, 0, //takes int index in prop
1051 BrowserFunctions,
1052};
1053
1054
1055
1056
1057/* ProfileInfo, ProfileInfoArray, ComponentInfo, ComponentInfoArray
1058 I decided to do these as thin getter wrappers on the bits and pieces defined
1059 in Structs.h, GeneratedCode.c and capabilitiesHandler.c
1060 The Array types return the info type wrapper with private native member == index into
1061 the native array.
1062*/
1063//ComonentInfo{
1064//String name;
1065//Numeric level;
1066//String Title;
1067//String providerUrl;
1068//}
1069
1070int capabilitiesHandler_getTableLength(int* table);
1071int capabilitiesHandler_getComponentLevel(int *table, int comp);
1072int capabilitiesHandler_getProfileLevel(int prof);
1073const int *capabilitiesHandler_getProfileComponent(int prof);
1074const int *capabilitiesHandler_getCapabilitiesTable();
1075/*
1076typedef struct intTableIndex{
1077 int* table;
1078 int index;
1079} *IntTableIndex;
1080*/
1081
1082
1083//ComponentInfoArray{
1084//numeric length;
1085//ComponentInfo [integer index];
1086//}
1087
1088int *intdup(int value){
1089 int* p = malloc(sizeof(int));
1090 memcpy(p,&value,sizeof(int));
1091 return p;
1092}
1093int ComponentInfoArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1094 int *_table;
1095 int nr = 1;
1096 _table = (int *)fwn;
1097 //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)
1098 if(index == -1){
1099//extern const char *COMPONENTS[];
1100//extern const int COMPONENTS_COUNT;
1101 int _length = capabilitiesHandler_getTableLength(_table); //COMPONENTS_COUNT;
1102 //fwretval->_integer = _length;
1103 fwretval->itype = 'I';
1104 fwretval->_integer = _length;
1105
1106 }else if(index > -1 && index < COMPONENTS_COUNT ){
1107 fwretval->_pointer.native = &_table[2*index];
1108 fwretval->_pointer.fieldType = AUXTYPE_ComponentInfo;
1109 fwretval->_pointer.gc = 0;
1110 fwretval->itype = 'P';
1111 }
1112 return nr;
1113}
1114
1115
1116FWPropertySpec (ComponentInfoArrayProperties)[] = {
1117 {"length", -1, 'I', 'T'},
1118 {NULL,0,0,0},
1119};
1120
1121struct FWTYPE ComponentInfoArrayType = {
1122 AUXTYPE_ComponentInfoArray,
1123 'P',
1124 "ComponentInfoArray",
1125 0, //sizeof(struct X3DBrowser),
1126 NULL, //no constructor for Browser
1127 NULL, //no constructor args
1128 ComponentInfoArrayProperties,
1129 NULL, //no special has
1130 ComponentInfoArrayGetter,
1131 NULL,
1132 'P', 'T', //takes int index in prop of this type
1133 NULL,
1134};
1135
1136FWPropertySpec (ComponentInfoProperties)[] = {
1137 {"name", 0, 'S', 'T'},
1138 {"title", 1, 'S', 'T'},
1139 {"level", 2, 'I', 'T'},
1140 {"providerUrl", 3, 'S', 'T'},
1141 {NULL,0,0,0},
1142};
1143
1144
1145int ComponentInfoGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1146 int nr, *tableEntry, nameIndex;
1147 tableEntry = (int *)fwn;
1148 nr = 1;
1149 //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)
1150 switch (index) {
1151 case 0://name
1152 case 1://title
1153 nameIndex = tableEntry[0];
1154 fwretval->_string = COMPONENTS[nameIndex];
1155 fwretval->itype = 'S';
1156 break;
1157 case 2://level
1158 fwretval->_integer = tableEntry[1];
1159 fwretval->itype = 'I';
1160 break;
1161 case 3://providerUrl
1162 fwretval->_string = "freewrl.sourceforge.net";
1163 fwretval->itype = 'S';
1164 break;
1165 default:
1166 nr = 0;
1167 break;
1168 }
1169 return nr;
1170}
1171
1172struct FWTYPE ComponentInfoType = {
1173 AUXTYPE_ComponentInfo,
1174 'P',
1175 "ComponentInfo",
1176 0, //sizeof(struct X3DBrowser),
1177 NULL, //no constructor for Browser
1178 NULL, //no constructor args
1179 ComponentInfoProperties,
1180 NULL, //no special has
1181 ComponentInfoGetter,
1182 NULL,
1183 0,0, //takes int index in prop
1184 NULL,
1185};
1186
1187
1188
1189//ProfileInfoArray{
1190//numeric length;
1191//ProfileInfo [integer index];
1192//}
1193
1194
1195int ProfileInfoArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1196 struct proftablestruct *_table;
1197 int nr = 1;
1198 _table = (struct proftablestruct *)fwn;
1199 //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)
1200 if(index == -1){
1201//extern const char *COMPONENTS[];
1202//extern const int COMPONENTS_COUNT;
1203 fwretval->_integer = PROFILES_COUNT; // _length;
1204 fwretval->itype = 'I';
1205 }else if(index > -1 && index < PROFILES_COUNT ){
1206 fwretval->_pointer.native = &_table[index];
1207 fwretval->_pointer.fieldType = AUXTYPE_ProfileInfo;
1208 fwretval->_pointer.gc = 0;
1209 fwretval->itype = 'P';
1210 }
1211 return nr;
1212}
1213
1214
1215FWPropertySpec (ProfileInfoArrayProperties)[] = {
1216 {"length", -1, 'I', 'T'},
1217 {NULL,0,0,0},
1218};
1219
1220struct FWTYPE ProfileInfoArrayType = {
1221 AUXTYPE_ProfileInfoArray,
1222 'P',
1223 "ProfileInfoArray",
1224 0, //sizeof(struct X3DBrowser),
1225 NULL, //no constructor for Browser
1226 NULL, //no constructor args
1227 ProfileInfoArrayProperties,
1228 NULL, //no special has
1229 ProfileInfoArrayGetter,
1230 NULL,
1231 'P', 'T',//takes int index in prop, readOnly
1232 NULL,
1233};
1234
1235
1236//ProfileInfo{
1237//String name;
1238//Numeric level;
1239//String Title;
1240//String providerUrl;
1241//ComonentInfoArray components;
1242//}
1243
1244FWPropertySpec (ProfileInfoProperties)[] = {
1245 {"name", 0, 'S', 'T'},
1246 {"Title", 1, 'I', 'T'},
1247 {"level", 2, 'S', 'T'},
1248 {"providerUrl", 3, 'S', 'T'},
1249 {"components", 4, 'P', 'T'}, //writable? if so then I need a constructor for ComponentInfo?
1250 {NULL,0,0,0},
1251};
1252
1253
1254int ProfileInfoGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1255 int nr, nameIndex;
1256 struct proftablestruct *tableEntry;
1257 tableEntry = (struct proftablestruct *)fwn;
1258 nr = 1;
1259 //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)
1260 switch (index) {
1261 case 0://name
1262 case 1://Title
1263 nameIndex = tableEntry->profileName;
1264 fwretval->_string = stringProfileType(nameIndex);
1265 fwretval->itype = 'S';
1266 break;
1267 case 2://level
1268 fwretval->_integer = tableEntry->level;
1269 fwretval->itype = 'I';
1270 break;
1271 case 3://providerUrl
1272 fwretval->_string = "freewrl.sourceforge.net";
1273 fwretval->itype = 'S';
1274 break;
1275 case 4://components
1276 fwretval->_pointer.native = (void *)tableEntry->profileTable;
1277 fwretval->_pointer.fieldType = AUXTYPE_ComponentInfoArray;
1278 fwretval->_pointer.gc = 0;
1279 fwretval->itype = 'P';
1280 break;
1281 default:
1282 nr = 0;
1283 break;
1284 }
1285 return nr;
1286}
1287
1288struct FWTYPE ProfileInfoType = {
1289 AUXTYPE_ProfileInfo,
1290 'P',
1291 "ProfileInfo",
1292 0, //sizeof(struct X3DBrowser),
1293 NULL, //no constructor for Browser
1294 NULL, //no constructor args
1295 ProfileInfoProperties,
1296 NULL, //no special has
1297 ProfileInfoGetter,
1298 NULL,
1299 0,0, //takes int index in prop
1300 NULL,
1301};
1302
1303
1304
1305
1306struct X3D_Node *broto_search_DEFname(struct X3D_Proto *context, const char *name);
1307struct X3D_Node * broto_search_ALLnames(struct X3D_Proto *context, const char *name, int *source);
1308int X3DExecutionContext_getNamedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1309 int nr = 0;
1310 struct X3D_Node* node = NULL;
1311 //broto warning - DEF name list should be per-executionContext
1312 //struct X3D_Proto *ec = (struct X3D_Proto *)fwn; //we want the script node's parent context for imported nodes, I think
1313 node = broto_search_DEFname(ec, fwpars[0]._string);
1314
1315 if(node){
1316 //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1317 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1318 fwretval->_web3dval.anyvrml->sfnode = node;
1319 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1320 fwretval->_web3dval.gc = 1;
1321 fwretval->itype = 'W';
1322 nr = 1;
1323 }
1324 return nr;
1325}
1326
1327int X3DExecutionContext_updateNamedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1328 int i, nr = 0;
1329 //broto warning - DEF name list should be per-executionContext
1330 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1331 struct X3D_Node* node = NULL;
1332 struct brotoDefpair *bd;
1333 int found = 0;
1334 const char *defname;
1335 defname = fwpars[0]._string;
1336 node = X3D_NODE(fwpars[1]._web3dval.native);
1337 if(_ec->__DEFnames){
1338 struct Vector* defnames = (struct Vector*)_ec->__DEFnames;
1339 for(i=0;i<vectorSize(defnames);i++){
1340 bd = vector_get_ptr(struct brotoDefpair,defnames,i);
1341 //Q. is it the DEF we search for, and node we replace, OR
1342 // is it the node we search for, and DEF we replace?
1343 if(!strcmp(bd->name,defname)){
1344 bd->node = node;
1345 found = 1;
1346 break;
1347 }
1348 if(bd->node == node){
1349 bd->name = strdup(defname);
1350 found = 2;
1351 break;
1352 }
1353 }
1354 }
1355 if(!found){
1356 //I guess its an add
1357 if(!_ec->__DEFnames)
1358 _ec->__DEFnames = newVector(struct brotoDefpair*,4);
1359 struct brotoDefpair bd2;
1360 memset(&bd2, 0, sizeof(struct brotoDefpair));
1361 bd2.node = node;
1362 bd2.name = strdup(defname);
1363 stack_push(struct brotoDefpair,(struct Vector*)_ec->__DEFnames,bd2);
1364 }
1365 return nr;
1366}
1367void remove_node_from_parents_children(struct X3D_Node* node) {
1368 for (int i = 0; i < vectorSize(node->_parentVector); i++) {
1369 struct X3D_Node* pnode = vector_get(struct X3D_Node*, node->_parentVector, i);
1370 int type, kind, iifield;
1371 union anyVrml* value, *valuer;
1372 int kids = getFieldFromNodeAndName(pnode, "children", &type, &kind, &iifield, &value);
1373 if(!kids) kids = getFieldFromNodeAndName(pnode, "__children", &type, &kind, &iifield, &value);
1374 if(kids){
1375 //if(getFieldFromNodeAndName(pnode, "children", &type, &kind, &iifield, &valuer))
1376 // AddRemoveChildren(node, value, (struct X3D_Node**)valuer->mfnode.p, valuer->mfnode.n, 2, __FILE__, __LINE__);
1377 // removeChildren->n = 0;
1378 //else {
1379 int n = 0;
1380 int done = FALSE;
1381 for (int j = 0; j < value->mfnode.n; j++) {
1382 if (value->mfnode.p[j] == node) {
1383 if (!done) {
1384 remove_parent(node, pnode);
1385 done = TRUE;
1386 }
1387 }
1388 else {
1389 value->mfnode.p[n] = value->mfnode.p[j];
1390 n++;
1391 }
1392 }
1393 value->mfnode.n = n;
1394 }
1395 }
1396
1397}
1398int remove_broto_node(struct X3D_Proto *context, struct X3D_Node* node);
1399int X3DExecutionContext_removeNamedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1400 int i, nr = 0;
1401 //broto warning - DEF name list should be per-executionContext
1402 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1403 struct X3D_Node* node = NULL;
1404
1405 const char *defname;
1406 defname = fwpars[0]._string;
1407 if(_ec->__DEFnames){
1408 struct brotoDefpair *bd;
1409 for(i=0;i<vectorSize(_ec->__DEFnames);i++){
1410 bd = vector_get_ptr(struct brotoDefpair,_ec->__DEFnames,i);
1411 if(!strcmp(bd->name,defname)){
1412 node = bd->node;
1413 //Q. are we supposed to delete the node
1414 //OR are we just supposed to remove the DEF name mapping?
1415 //remove DEF name mapping:
1416 vector_remove_elem(struct brotoDefpair,_ec->__DEFnames,i);
1417 //remove node
1418 remove_node_from_parents_children(node);
1419 remove_broto_node(_ec,node);
1420 break;
1421 }
1422 }
1423 }
1424
1425 return nr;
1426}
1427void add_node_to_broto_context(struct X3D_Proto *context,struct X3D_Node *node);
1428int X3DExecutionContext_createProto(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1429 int nr = 0;
1430 struct X3D_Node* node = NULL;
1431 //broto warning - DEF name list should be per-executionContext
1432 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1433 struct X3D_Proto *proto;
1434 proto = NULL;
1435
1436 if( isAvailableBroto(fwpars[0]._string, ec, &proto))
1437 {
1438 struct X3D_Proto *source, *dest;
1439 node=X3D_NODE(brotoInstance(proto,1));
1440 node->_executionContext = X3D_NODE(ec); //me->ptr;
1441 add_node_to_broto_context(ec,node);
1442 //during parsing, setting of fields would occur between instance and body,
1443 //so field values perculate down.
1444 //here we elect default field values
1445 source = X3D_PROTO(X3D_PROTO(node)->__prototype);
1446 dest = X3D_PROTO(node);
1447 deep_copy_broto_body2(&source,&dest);
1448 }
1449 if(node){
1450 //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1451 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1452 fwretval->_web3dval.anyvrml->sfnode = node;
1453 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1454 fwretval->_web3dval.gc = 1;
1455 fwretval->itype = 'W';
1456 nr = 1;
1457 }
1458 return nr;
1459}
1460
1461int X3DExecutionContext_getImportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1462 int nr = 0;
1463 struct X3D_Node* node = NULL;
1464 //broto warning - DEF name list should be per-executionContext
1465 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1466 //struct IMEXPORT *mxp;
1467 int source;
1468 //mxp = broto_search_IMPORTname(ec, fwpars[0]._string);
1469 //if(mxp){
1470 // node = mxp->nodeptr;
1471 //}
1472 node = broto_search_ALLnames(ec, fwpars[0]._string,&source);
1473 if(source == 0) node = NULL; //source ==1,2 is for IMPORT and EXPORT
1474 if(node){
1475 //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1476 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1477 fwretval->_web3dval.anyvrml->sfnode = node;
1478 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1479 fwretval->_web3dval.gc = 1;
1480 fwretval->itype = 'W';
1481 nr = 1;
1482 }
1483 return nr;
1484}
1485
1486void update_weakRoutes(struct X3D_Proto *context);
1487int X3DExecutionContext_updateImportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1488 //2023 interpretation of parameters:
1489 // string1 is the main scene local DEF name (the AS name)
1490 // string2 is the inline export name
1491 // no need for 3rd string for inline name:
1492 // - if you want to say which inline, use <inline name>.<export name> in string2
1493 // - otherwise if no "." it assumes that's the export name and will search for that in all inlines
1494 //
1495 int i, nr = 0;
1496 //broto warning - DEF name list should be per-executionContext
1497 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1498 struct X3D_Node* node = NULL;
1499
1500 const char* as, * mxname, * impname;
1501 char* nline;
1502 int found = 0;
1503 struct IMEXPORT *mxp;
1504
1505 as = fwpars[0]._string;
1506 mxname = fwpars[1]._string;
1507 impname = strdup(mxname);
1508 nline = NULL;
1509 const char* dot = strstr(mxname, ".");
1510 if (dot) {
1511 nline = strdup(mxname);
1512 nline[dot - mxname] = 0;
1513 impname = strdup(&dot[1]);
1514 }
1515 printf("as [%s] impname [%s] nline [%s]\n", as, impname, nline);
1516 node = X3D_NODE(fwpars[1]._web3dval.native);
1517 if(_ec->__IMPORTS){
1518 for(i=0;i<vectorSize(_ec->__IMPORTS);i++){
1519 mxp = vector_get(struct IMEXPORT *,_ec->__IMPORTS,i);
1520 //Q. is it the DEF we search for, and node we replace, OR
1521 // is it the node we search for, and DEF we replace?
1522 int inlineOK = !nline || !strcmp(nline, mxp->inlinename);
1523 int asOK = !strcmp(as, mxp->as);
1524 int impOK = !strcmp(impname, mxp->mxname);
1525 if (inlineOK && impOK) {
1526 //if (!strcmp(nline, mxp->inlinename) && !strcmp(mxp->mxname, mxname)) {
1527 printf("updating import new as [%s] old import [%s] inline [%s]\n", as, impname, nline);
1528 mxp->as = strdup(as);
1529 found = 1;
1530 break;
1531 }
1532 }
1533 }
1534 if(!found){
1535 //I guess its an add
1536 if(!_ec->__IMPORTS)
1537 _ec->__IMPORTS = newVector(struct IMEXPORT *,4);
1538 mxp = (struct IMEXPORT *)malloc(sizeof(struct IMEXPORT));
1539 mxp->mxname = strdup(impname);
1540 mxp->as = strdup(as);
1541 mxp->inlinename = nline ? strdup(nline) : NULL;
1542 printf("adding import mapping as [%s] import [%s] inline [%s]\n", impname, as, nline);
1543 stack_push(struct IMEXPORT *,_ec->__IMPORTS,mxp);
1544 }
1545 update_weakRoutes(_ec);
1546 return nr;
1547}
1548
1549
1550int X3DExecutionContext_removeImportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1551 int i,nr = 0;
1552 //broto warning - DEF name list should be per-executionContext
1553 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1554 //struct X3D_Node* node = NULL;
1555
1556 const char *defname;
1557 defname = fwpars[0]._string;
1558 if(_ec->__IMPORTS){
1559 struct IMEXPORT *mxp;
1560 for(i=0;i<vectorSize(_ec->__IMPORTS);i++){
1561 mxp = vector_get(struct IMEXPORT *,_ec->__IMPORTS,i);
1562 if(!strcmp(mxp->as,defname)){
1563 //remove IMPORT name mapping:
1564 vector_remove_elem(struct IMEXPORT *,_ec->__IMPORTS,i);
1565 update_weakRoutes(_ec);
1566 break;
1567 }
1568 }
1569 }
1570 return nr;
1571}
1572
1573
1574int X3DScene_getExportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1575 int nr = 0;
1576 struct X3D_Node* node = NULL;
1577 //broto warning - DEF name list should be per-executionContext
1578 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1579 struct IMEXPORT *mxp;
1580 mxp = broto_search_EXPORTname(ec, fwpars[0]._string);
1581 if(mxp){
1582 node = mxp->nodeptr;
1583 }
1584 if(node){
1585 //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1586 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1587 fwretval->_web3dval.anyvrml->sfnode = node;
1588 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1589 fwretval->_web3dval.gc = 1;
1590 fwretval->itype = 'W';
1591 nr = 1;
1592 }
1593 return nr;
1594}
1595
1596int X3DScene_updateExportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1597 int i, nr = 0;
1598 //broto warning - DEF name list should be per-executionContext
1599 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1600 struct X3D_Node* node = NULL;
1601
1602 const char *defname;
1603 int found = 0;
1604 struct IMEXPORT *mxp;
1605
1606 defname = fwpars[0]._string;
1607 node = X3D_NODE(fwpars[1]._web3dval.anyvrml->sfnode);
1608 if(_ec->__EXPORTS){
1609 for(i=0;i<vectorSize(_ec->__EXPORTS);i++){
1610 mxp = vector_get(struct IMEXPORT *,_ec->__EXPORTS,i);
1611 //Q. is it the DEF we search for, and node we replace, OR
1612 // is it the node we search for, and DEF we replace?
1613 if(!strcmp(mxp->as,defname)){
1614 mxp->nodeptr = node;
1615 found = 1;
1616 break;
1617 }
1618 if(mxp->nodeptr == node){
1619 mxp->as = strdup(defname);
1620 found = 2;
1621 break;
1622 }
1623 }
1624 }
1625 if(!found){
1626 //I guess its an add
1627 if(!_ec->__EXPORTS)
1628 _ec->__EXPORTS = newVector(struct IMEXPORT *,4);
1629 mxp = (struct IMEXPORT *)malloc(sizeof(struct IMEXPORT));
1630 mxp->nodeptr = node;
1631 mxp->mxname = strdup(defname);
1632 mxp->as = mxp->mxname;
1633 stack_push(struct IMEXPORT *,_ec->__EXPORTS,mxp);
1634 }
1635 if(_ec->_executionContext){
1636 //update weak routes in the importing context, which should be the parent context of the Inline node
1637 //and the Inline should be our current context. I think.
1638 update_weakRoutes(X3D_PROTO(_ec->_executionContext));
1639 }
1640 return nr;
1641}
1642
1643int X3DScene_removeExportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1644 int i, nr = 0;
1645 //broto warning - DEF name list should be per-executionContext
1646 struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1647 //struct X3D_Node* node = NULL;
1648
1649 const char *defname;
1650 defname = fwpars[0]._string;
1651 if(_ec->__EXPORTS){
1652 struct IMEXPORT *mxp;
1653 for(i=0;i<vectorSize(_ec->__EXPORTS);i++){
1654 mxp = vector_get(struct IMEXPORT *,_ec->__EXPORTS,i);
1655 if(!strcmp(mxp->as,defname)){
1656 //remove EXPORT name mapping:
1657 vector_remove_elem(struct IMEXPORT *,_ec->__EXPORTS,i);
1658 break;
1659 }
1660 }
1661 }
1662 if(_ec->_executionContext){
1663 //update weak routes in the importing context, which should be the parent context of the Inline node
1664 //and the Inline should be our current context. I think.
1665 update_weakRoutes(X3D_PROTO(_ec->_executionContext));
1666 }
1667 return nr;
1668}
1669int X3DExecutionContext_toString(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
1670 int nr = 0;
1671 char* value;
1672 value = NULL;
1673
1674 char str[200];
1675 struct X3D_Proto* ecc = (struct X3D_Proto*)ec;
1676 sprintf(str, "%p", (void*)ecc);
1677 value = strdup(str);
1678 //do a search in the perscene/perexecution context array
1679 if (value) {
1680 fwretval->_string = value;
1681 fwretval->itype = 'S';
1682 nr = 1;
1683 }
1684 return nr;
1685
1686}
1687int X3DScene_setMetaData(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1688 int nr = 0;
1689 const char *name, *content;
1690 name = fwpars[0]._string;
1691 content = fwpars[1]._string;
1692 //strdup and put in a global or per-scene or per execution context (name,value) list
1693 struct X3D_Proto* _ec = (struct X3D_Proto*)fwn;
1694 if (!_ec->__META)
1695 _ec->__META = newVector(struct metarecord, 10);
1696
1697 struct Vector* metalist = (struct Vector*)_ec->__META;
1698 struct metarecord* mr;
1699 int done = FALSE;
1700 for (int i = 0; i < vectorSize(metalist); i++) {
1701 mr = vector_get_ptr(struct metarecord, metalist, i);
1702 if (!strcmp(mr->name, name)) {
1703 mr->content = strdup(content);
1704 done = TRUE;
1705 break;
1706 }
1707 }
1708 if (!done) {
1709 //add
1710 struct metarecord mr2;
1711 mr2.name = strdup(name);
1712 mr2.content = strdup(content);
1713 vector_pushBack(struct metarecord, metalist, mr2);
1714 }
1715 return nr;
1716}
1717int X3DScene_getMetaData(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1718 int nr = 0;
1719 const char *name;
1720 char *content;
1721 content = NULL;
1722 name = fwpars[0]._string;
1723 //do a search in the perscene/perexecution context array
1724 struct X3D_Proto* _ec = (struct X3D_Proto*)fwn;
1725 if (_ec->__META) {
1726 struct Vector* metalist = (struct Vector*)_ec->__META;
1727 struct metarecord* mr;
1728 for (int i = 0; i < vectorSize(metalist); i++) {
1729 mr = vector_get_ptr(struct metarecord, metalist, i);
1730 if (!strcmp(mr->name, name)) {
1731 content = strdup(mr->content);
1732 break;
1733 }
1734 }
1735 }
1736 if(content){
1737 fwretval->_string = content;
1738 fwretval->itype = 'S';
1739 nr = 1;
1740 }
1741 return nr;
1742}
1743
1744static FWFunctionSpec (X3DExecutionContextFunctions)[] = {
1745 //executionContext
1746 {"addRoute", VRBrowserAddRoute, 'P',{4,-1,0,"WSWS"}},
1747 {"deleteRoute", X3DExecutionContext_deleteRoute,'0',{1,-1,0,"P"}},
1748 {"createNode", VRBrowserCreateNodeFromString, 'W',{1,-1,0,"S"}},
1749 {"createProto", X3DExecutionContext_createProto, 'W',{1,-1,0,"S"}},
1750 {"getImportedNode", X3DExecutionContext_getImportedNode, 'W',{1,-1,0,"S"}},
1751 {"updateImportedNode", X3DExecutionContext_updateImportedNode, '0',{2,-1,0,"SS"}},
1752 {"removeImportedNode", X3DExecutionContext_removeImportedNode, '0',{1,-1,0,"S"}},
1753 {"getNamedNode", X3DExecutionContext_getNamedNode, 'W',{1,-1,0,"S"}},
1754 {"updateNamedNode", X3DExecutionContext_updateNamedNode, '0',{2,-1,0,"SW"}},
1755 {"removeNamedNode", X3DExecutionContext_removeNamedNode, '0',{1,-1,0,"S"}},
1756 {"toString",X3DExecutionContext_toString,'S',{0,0,0,NULL}},
1758 {"setMetaData", X3DScene_setMetaData, '0',{2,-1,0,"SS"}},
1759 {"getMetaData", X3DScene_getMetaData, 'S',{1,-1,0,"S"}},
1760 {"getExportedNode", X3DScene_getExportedNode, 'W',{1,-1,0,"S"}},
1761 {"updateExportedNode", X3DScene_updateExportedNode, '0',{2,-1,0,"SW"}},
1762 {"removeExportedNode", X3DScene_removeExportedNode, '0',{1,-1,0,"S"}},
1763 {0}
1764};
1765
1766
1767
1768static FWPropertySpec (X3DExecutionContextProperties)[] = {
1769 //executionContext
1770 {"specificationVersion", 0, 'S', 'T'},
1771 {"encoding", 1, 'S', 'T'},
1772 {"profile", 2, 'P', 'T'},
1773 {"components", 3, 'P', 'T'},
1774 {"worldURL", 4, 'S', 'T'},
1775 {"rootNodes", 5, 'W', 'T'},
1776 {"protos", 6, 'P', 'T'},
1777 {"externprotos", 7, 'P', 'T'},
1778 {"routes", 8, 'P', 'T'},
1779 //scene
1780 {"isScene", 9, 'B', 'T'}, //else protoInstance. extra beyond specs - I think flux has it.
1781 {0}
1782};
1783static int _TRUE = TRUE;
1784static int _FALSE = FALSE;
1785int X3DExecutionContextGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1786 struct X3D_Proto * ecc;
1787 int nr = 1;
1788 ecc = (struct X3D_Proto*)fwn;
1789 //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)
1790 switch (index) {
1791 case 0: //specificationVersion
1792 {
1793 char str[32];
1794 //sprintf(str,"{%d,%d,%d}",inputFileVersion[0],inputFileVersion[1],inputFileVersion[2]);
1795 if(ecc->__loadResource || ecc->_parentResource){
1796 int specver;
1797 specver = ecc->__specversion;
1798 sprintf(str,"{%d.%d.%d}",specver/100,(specver/10)%10,specver % 10);
1799 }
1800 fwretval->_string = strdup(str);
1801 fwretval->itype = 'S';
1802 }
1803 break;
1804 case 1: //encoding string readonly
1805 {
1806 //Valid values are "ASCII", "VRML", "XML", "BINARY", "SCRIPTED", "BIFS", "NONE"
1807 fwretval->_string = "not filled in yet sb. VRML or XML or ..";
1808 fwretval->itype = 'S';
1809 }
1810 break;
1811 case 2: //profile
1812 {
1813 struct proftablestruct * profile;
1814 int index = gglobal()->Mainloop.scene_profile;
1815 profile = getProfTable();
1816 fwretval->_pointer.native = &profile[index];
1817 fwretval->_pointer.fieldType = AUXTYPE_ProfileInfo;
1818 fwretval->_pointer.gc = 0;
1819 fwretval->itype = 'P';
1820 }
1821 break;
1822 case 3: //components
1823 fwretval->_pointer.native = (void *)gglobal()->Mainloop.scene_components;
1824 fwretval->_pointer.fieldType = AUXTYPE_ComponentInfoArray;
1825 fwretval->_pointer.gc = 0;
1826 fwretval->itype = 'P';
1827 break;
1828 case 4: //worldURL
1829 fwretval->_string = gglobal()->Mainloop.url; //this is settable
1830 fwretval->itype = 'S';
1831 break;
1832 case 5: //rootNodes
1833 fwretval->_web3dval.native = (void *)&ecc->__children; //broto warning: inside a proto should be the rootnodes of the protobody
1834 fwretval->_web3dval.fieldType = FIELDTYPE_MFNode;
1835 fwretval->_web3dval.gc = 0;
1836 fwretval->itype = 'W';
1837 break;
1838 case 6: //protos
1839 fwretval->_pointer.fieldType = AUXTYPE_X3DProtoArray;
1840 fwretval->_pointer.native = (void*)ecc->__protoDeclares; //broto: this should be a per-context array
1841 fwretval->_pointer.gc = 0;
1842 fwretval->itype = 'P';
1843 break;
1844 case 7: //externprotos
1845 fwretval->_pointer.fieldType = AUXTYPE_X3DExternProtoArray;
1846 fwretval->_pointer.native = (void*)ecc->__externProtoDeclares; //broto: this should be a per-context array
1847 fwretval->_pointer.gc = 0;
1848 fwretval->itype = 'P';
1849 break;
1850 case 8: //routes
1851 fwretval->_pointer.fieldType = AUXTYPE_X3DRouteArray;
1852 fwretval->_pointer.native = (void*)ecc->__ROUTES; //broto: this should be a per-context array
1853 fwretval->_pointer.gc = 0;
1854 fwretval->itype = 'P';
1855 break;
1856 case 9: //isScene
1857 //fwretval->_boolean = TRUE; //broto warning: should be false inside a protoinstance body
1858 fwretval->itype = 'B';
1859 {
1860 unsigned char flag = ciflag_get(ecc->__protoFlags,2);
1861 if(flag == 2)
1862 fwretval->_boolean = TRUE;
1863 else
1864 fwretval->_boolean = FALSE;
1865 }
1866 break;
1867 default:
1868 nr = 0;
1869 }
1870 return nr;
1871}
1872
1873struct FWTYPE X3DExecutionContextType = {
1874 AUXTYPE_X3DExecutionContext,
1875 'P',
1876 "X3DExecutionContext",
1877 0, //sizeof(struct X3DBrowser),
1878 NULL, //no constructor
1879 NULL, //no constructor args
1880 X3DExecutionContextProperties,
1881 NULL, //no special has
1882 X3DExecutionContextGetter,
1883 NULL,
1884 0,0, //takes int index in prop
1885 X3DExecutionContextFunctions,
1886};
1887
1888struct CRStruct *getCRoutes();
1889int getCRouteCount();
1890int *getCRouteCounter();
1891int X3DRouteArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1892
1893 int nr = 0;
1894 //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)
1895 if(index == -1){
1896 int _length;
1897 _length = vectorSize(fwn);
1898 fwretval->_integer = _length;
1899 fwretval->itype = 'I';
1900 nr = 1;
1901 }else if(index > -1 ){
1902 if(index < vectorSize(fwn)){
1903 fwretval->_pointer.native = vector_get(void *, fwn, index); //struct brotoRoute *
1904 fwretval->_pointer.gc = 0;
1905 fwretval->_pointer.fieldType = AUXTYPE_X3DRoute;
1906 fwretval->itype = 'P';
1907 nr = 1;
1908 }
1909 }
1910 return nr;
1911}
1912
1913
1914FWPropertySpec (X3DRouteArrayProperties)[] = {
1915 {"length", -1, 'I', 'T'},
1916 {NULL,0,0,0},
1917};
1918
1919struct FWTYPE X3DRouteArrayType = {
1920 AUXTYPE_X3DRouteArray,
1921 'P',
1922 "X3DRouteArray",
1923 0, //sizeof(struct X3DRoute),
1924 NULL, //no constructor for X3DRoute
1925 NULL, //no constructor args
1926 X3DRouteArrayProperties,
1927 NULL, //no special has
1928 X3DRouteArrayGetter,
1929 NULL,
1930 'P', 'T',//takes int index in prop, readonly
1931 NULL,
1932};
1933
1934//X3DRoute{
1935//SFNode sourceNode;
1936//String sourceField;
1937//SFNode destinationNode;
1938//String destinationField;
1939//}
1940char* lookup_brotoDefname(struct X3D_Proto* ec, struct X3D_Node* node);
1941int X3DRouteToString(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
1942 int nr = 0;
1943 char* value;
1944 value = NULL;
1945
1946 char str[200];
1947 struct X3D_Proto* ecc = (struct X3D_Proto*)ec;
1948 struct brotoRoute* route = (struct brotoRoute*)fwn;
1949 //struct brotoRoute* route = vector_get(struct brotoRoute*, ecc->__ROUTES, _index);
1950
1951 //getSpecificRoute(_index, &fromNode, &fromOffset, &toNode, &toOffset);
1952 char* fromName = lookup_brotoDefname(ecc, route->from.node); // parser_getNameFromNode(route->from.node);
1953 char* toName = lookup_brotoDefname(ecc, route->from.node); // parser_getNameFromNode(route->to.node);
1954 char* fromfield = findFIELDNAMESfromNodeOffset0(route->from.node, route->from.ifield);
1955 char* tofield = findFIELDNAMESfromNodeOffset0(route->to.node, route->to.ifield);
1956
1957 sprintf(str, "[ROUTE %s.%s TO %s.%s]", fromName, fromfield, toName, tofield);
1958 value = strdup(str);
1959 //do a search in the perscene/perexecution context array
1960 if (value) {
1961 fwretval->_string = value;
1962 fwretval->itype = 'S';
1963 nr = 1;
1964 }
1965 return nr;
1966}
1967
1968FWFunctionSpec(X3DRouteFunctions)[] = {
1969 {"toString", X3DRouteToString, 'S',{0,0,0,NULL}},
1970 {0}
1971};
1972
1973FWPropertySpec (X3DRouteProperties)[] = {
1974 {"sourceNode", 0, 'W', 'T'},
1975 {"sourceField", 1, 'S', 'T'},
1976 {"destinationNode", 2, 'W', 'T'},
1977 {"destinationField", 3, 'S', 'T'},
1978 {NULL,0,0,0},
1979};
1980int X3DRouteGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1981 union anyVrml *value;
1982 int type, kind;
1983 const char *fieldname; // , *stofield; //*sfromfield,
1984 struct X3D_Node *fromNode, *toNode;
1985 int fromIndex, toIndex, fromBuiltIn, toBuiltIn;
1986 int nr = 1;
1987 {
1988 struct brotoRoute* broute = (struct brotoRoute*)fwn;
1989 fromNode = broute->from.node;
1990 fromIndex = broute->from.ifield;
1991 fromBuiltIn = broute->from.builtIn;
1992 toNode = broute->to.node;
1993 toIndex = broute->to.ifield;
1994 toBuiltIn = broute->to.builtIn;
1995 }
1996 if(!fromNode || !toNode) return 0;
1997
1998 //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)
1999 switch(index){
2000 case 0: //sourceNode
2001 //fwretval->_web3dval.native = (void*)fromNode; //route->routeFromNode;
2002 //((union anyVrml*)fwpars[0]._web3dval.native)->sfnode
2003 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
2004 fwretval->_web3dval.anyvrml->sfnode = fromNode;
2005 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
2006 fwretval->_web3dval.gc = 1;
2007 fwretval->itype = 'W';
2008 break;
2009 case 1: //sourceField
2010 //fieldname = findFIELDNAMESfromNodeOffset0(fromNode,fromOffset);
2011 getFieldFromNodeAndIndexSource(fromNode,fromIndex,fromBuiltIn,&fieldname,&type,&kind,&value);
2012 fwretval->_string = fieldname; //NULL;
2013 fwretval->itype = 'S';
2014 break;
2015 case 2: //destinationNode
2016 //fwretval->_web3dval.native = (void*)toNode; //route->routeFromNode;
2017 fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
2018 fwretval->_web3dval.anyvrml->sfnode = toNode;
2019 fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
2020 fwretval->itype = 'W';
2021 fwretval->_web3dval.gc = 1;
2022 break;
2023 case 3: //destinationField
2024 //getFieldFromNodeAndIndex(route->tonodes[0].routeToNode,route->tonodes[0].foffset,&fieldname,&type,&kind,&value);
2025 getFieldFromNodeAndIndexSource(toNode,toIndex,toBuiltIn,&fieldname,&type,&kind,&value);
2026 fwretval->_string = fieldname;
2027 fwretval->itype = 'S';
2028 break;
2029 default:
2030 nr = 0;
2031 }
2032 return nr;
2033}
2034
2035
2036struct FWTYPE X3DRouteType = {
2037 AUXTYPE_X3DRoute,
2038 'P',
2039 "X3DRoute",
2040 0, //sizeof(struct X3DRoute),
2041 NULL, //no constructor for X3DRoute
2042 NULL, //no constructor args
2043 X3DRouteProperties,
2044 NULL, //no special has
2045 X3DRouteGetter,
2046 NULL,
2047 0,0, //takes int index in prop
2048 X3DRouteFunctions,
2049};
2050
2051
2052
2053int X3DProtoArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2054
2055 int nr = 0;
2056 Stack* parray = (Stack*)fwn;
2057 //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)
2058 if(index == -1){
2059 int _length;
2060 _length = vectorSize(parray);
2061 fwretval->_integer = _length;
2062 fwretval->itype = 'I';
2063 nr = 1;
2064 }else if(index > -1 ){
2065 if(index < vectorSize(fwn)){
2066 fwretval->_pointer.native = (void*)vector_get(struct X3D_Proto *, parray, index); //struct X3D_Proto *
2067 fwretval->_pointer.gc = 0;
2068 fwretval->_pointer.fieldType = AUXTYPE_X3DProto;
2069 fwretval->itype = 'P';
2070 nr = 1;
2071 }
2072 }
2073 return nr;
2074}
2075
2076
2077FWPropertySpec (X3DProtoArrayProperties)[] = {
2078 {"length", -1, 'I', 'T'},
2079 {NULL,0,0,0},
2080};
2081
2082struct FWTYPE X3DProtoArrayType = {
2083 AUXTYPE_X3DProtoArray,
2084 'P',
2085 "X3DProtoArray",
2086 0, //sizeof(struct X3DProto),
2087 NULL, //no constructor for X3DProto
2088 NULL, //no constructor args
2089 X3DProtoArrayProperties,
2090 NULL, //no special has
2091 X3DProtoArrayGetter,
2092 NULL,
2093 'P', 'T',//takes int index in prop, readonly
2094 NULL,
2095};
2096
2097struct FWTYPE X3DExternProtoArrayType = {
2098 AUXTYPE_X3DExternProtoArray,
2099 'P',
2100 "X3DExternProtoArray",
2101 0, //sizeof(struct X3DProto),
2102 NULL, //no constructor for X3DProto
2103 NULL, //no constructor args
2104 X3DProtoArrayProperties,
2105 NULL, //no special has
2106 X3DProtoArrayGetter,
2107 NULL,
2108 'P', 'T',//takes int index in prop, readonly
2109 NULL,
2110};
2111
2112
2113struct tuplePointerInt {
2114 void *pointer;
2115 int integer;
2116};
2117
2118FWPropertySpec (X3DProtoProperties)[] = {
2119 {"name", 0, 'S', 'T'},
2120 {"fields", 1, 'W', 'T'},
2121 {"isExternProto", 2, 'B', 'T'},
2122 {NULL,0,0,0},
2123};
2124int X3DProtoGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2125 int nr = 0;
2126 //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)
2127 struct ProtoDefinition* pd = (struct ProtoDefinition*)X3D_PROTO(fwn)->__protoDef;
2128 switch(index){
2129 case 0: //name
2130 fwretval->_string = strdup(pd->protoName); // X3D_PROTO(fwn)->__typename; //NULL;
2131 fwretval->itype = 'S';
2132 fwretval->_web3dval.gc = 0;
2133 nr = 1;
2134 break;
2135 case 1: //fields
2136 fwretval->_web3dval.native = pd->iface; // fwn; //we'll get field[i] from the proto later (void*)X3D_PROTO(fwn)->__protoDef; //route->routeFromNode;
2137 fwretval->_web3dval.fieldType = AUXTYPE_X3DFieldDefinitionArray;
2138 fwretval->itype = 'W';
2139 fwretval->_web3dval.gc = 0;
2140 nr = 1;
2141 break;
2142 case 2: //isExternProto
2143 fwretval->itype = 'B';
2144 fwretval->_web3dval.gc = 0;
2145 {
2146 unsigned char flag = ciflag_get(X3D_PROTO(fwn)->__protoFlags,3);
2147 if(flag == 1)
2148 fwretval->_boolean = TRUE;
2149 else
2150 fwretval->_boolean = FALSE;
2151 }
2152 nr = 1;
2153 break;
2154 default:
2155 nr = 0;
2156 }
2157 return nr;
2158}
2159
2160
2161struct FWTYPE X3DProtoType = {
2162 AUXTYPE_X3DProto,
2163 'P',
2164 "X3DProtoDeclaration",
2165 0, //sizeof(struct X3DProto),
2166 NULL, //no constructor for X3DProto
2167 NULL, //no constructor args
2168 X3DProtoProperties,
2169 NULL, //no special has
2170 X3DProtoGetter,
2171 NULL,
2172 0,0, //takes int index in prop
2173 NULL,
2174};
2175struct FWTYPE X3DExternProtoType = {
2176 AUXTYPE_X3DExternProto,
2177 'P',
2178 "X3DExternProtoDeclaration",
2179 0, //sizeof(struct X3DProto),
2180 NULL, //no constructor for X3DProto
2181 NULL, //no constructor args
2182 X3DProtoProperties, //it tests if its extern or not
2183 NULL, //no special has
2184 X3DProtoGetter,
2185 NULL,
2186 0,0, //takes int index in prop
2187 NULL,
2188};
2189
2190int count_fields(struct X3D_Node* node);
2191int X3DFieldDefinitionArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2192
2193 int nr = 0;
2194 //struct X3D_Node *node = (struct X3D_Node*)fwn;
2195 Stack* iface = (Stack*)fwn;
2196 //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)
2197 if(index == -1){
2198 int _length = 0;
2199 //I suspect this fieldDefinition stuff is for ProtoDeclares and ExternProtoDeclares only, not builtin or protoInstances or scripts
2200 _length = vectorSize(iface); // count_fields(node);
2201 fwretval->_integer = _length;
2202 fwretval->itype = 'I';
2203 nr = 1;
2204 }else if(index > -1 ){
2205 if(index < vectorSize(fwn)){
2206 //struct tuplePointerInt *tpi = malloc(sizeof(struct tuplePointerInt));
2207 //tpi->pointer = (void*)node;
2208 //tpi->integer = index;
2209 struct ProtoFieldDecl* pfield = vector_get(struct ProtoFieldDecl*, iface, index);
2210 fwretval->_pointer.native = pfield; //vector_get(void *, fwn, index); //struct X3D_Proto *
2211 fwretval->_pointer.gc = 0;
2212 fwretval->_pointer.fieldType = AUXTYPE_X3DFieldDefinition;
2213 fwretval->itype = 'P';
2214 nr = 1;
2215 }
2216 }
2217 return nr;
2218}
2219
2220
2221FWPropertySpec (X3DFieldDefinitionArrayProperties)[] = {
2222 {"length", -1, 'I', 'T'},
2223 {NULL,0,0,0},
2224};
2225
2226struct FWTYPE X3DFieldDefinitionArrayType = {
2227 AUXTYPE_X3DFieldDefinitionArray,
2228 'P',
2229 "X3DFieldDefinitionArray",
2230 0, //sizeof(struct X3DProto),
2231 NULL, //no constructor for X3DProto
2232 NULL, //no constructor args
2233 X3DFieldDefinitionArrayProperties,
2234 NULL, //no special has
2235 X3DFieldDefinitionArrayGetter,
2236 NULL,
2237 'P', 'T',//takes int index in prop, readonly
2238 NULL,
2239};
2240
2241FWPropertySpec (X3DFieldDefinitionProperties)[] = {
2242 {"name", 0, 'S', 'T'},
2243 {"accessType", 1, 'I', 'T'},
2244 {"dataType", 2, 'I', 'T'},
2245 {NULL,0,0,0},
2246};
2247int X3DFieldDefinitionGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2248 int ifield, type,kind, konstindex, nr = 0;
2249 struct string_int * si;
2250 union anyVrml *value;
2251 struct X3D_Node* node;
2252 const char *fname;
2253 //struct tuplePointerInt *tpi = (struct tuplePointerInt*)fwn;
2254 //node = tpi->pointer;
2255 //ifield = tpi->integer;
2256 //I suspect FieldDefinitions are for ProtoDeclarations only,
2257 // but freewrl Brotos can use the same function for nodes and declares
2258 struct ProtoFieldDecl* pfield = (struct ProtoFieldDecl*)fwn;
2259
2260// if(getFieldFromNodeAndIndexSource(node,ifield,TRUE,&fname,&type,&kind,&value)){
2261 //if(getFieldFromNodeAndIndex(node,ifield,&fname,&type,&kind,&value)){
2262 //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)
2263 switch(index){
2264 case 0: //name
2265 fwretval->_string = pfield->cname; // fname; //NULL;
2266 fwretval->itype = 'S';
2267 nr = 1;
2268 break;
2269 case 1: //accessType
2270 //si = lookup_string_int(lookup_X3DConstants,PROTOKEYWORDS[pfield->mode],&konstindex);
2271 fwretval->_integer = pfield->mode; // konstindex; //index into x3dconstants table
2272 fwretval->itype = 'I';
2273 nr = 1;
2274 break;
2275 case 2: //dataType
2276 //si = lookup_string_int(lookup_X3DConstants,FIELDTYPES[pfield->type],&konstindex);
2277 fwretval->_integer = pfield->type; // konstindex; //index into x3dconstants table
2278 fwretval->itype = 'I';
2279 nr = 1;
2280 break;
2281 default:
2282 nr = 0;
2283 }
2284// }
2285 return nr;
2286}
2287
2288
2289struct FWTYPE X3DFieldDefinitionType = {
2290 AUXTYPE_X3DFieldDefinition,
2291 'P',
2292 "X3DFieldDefinition",
2293 0, //sizeof(struct X3DFieldDefinition),
2294 NULL, //no constructor for X3DProto
2295 NULL, //no constructor args
2296 X3DFieldDefinitionProperties,
2297 NULL, //no special has
2298 X3DFieldDefinitionGetter,
2299 NULL,
2300 0,0, //takes int index in prop
2301 NULL,
2302};
2303
2304
2305
2306
2307extern struct FWTYPE X3DMatrix3Type;
2308extern struct FWTYPE X3DMatrix4Type;
2309
2310void initVRMLBrowser(FWType* typeArray, int *n){
2311 typeArray[*n] = &X3DRouteType; (*n)++;
2312 typeArray[*n] = &X3DRouteArrayType; (*n)++;
2313 typeArray[*n] = &X3DExecutionContextType; (*n)++;
2314 typeArray[*n] = &ProfileInfoType; (*n)++;
2315 typeArray[*n] = &ProfileInfoArrayType; (*n)++;
2316 typeArray[*n] = &ComponentInfoType; (*n)++;
2317 typeArray[*n] = &ComponentInfoArrayType; (*n)++;
2318 typeArray[*n] = &BrowserType; (*n)++;
2319 typeArray[*n] = &X3DConstantsType; (*n)++;
2320
2321 typeArray[*n] = &X3DProtoType; (*n)++;
2322 typeArray[*n] = &X3DProtoArrayType; (*n)++;
2323 typeArray[*n] = &X3DExternProtoType; (*n)++;
2324 typeArray[*n] = &X3DExternProtoArrayType; (*n)++;
2325 typeArray[*n] = &X3DFieldDefinitionType; (*n)++;
2326 typeArray[*n] = &X3DFieldDefinitionArrayType; (*n)++;
2327
2328}
2329#endif /* ifdef JAVASCRIPT_DUK */