FreeWRL/FreeX3D  3.0.0
jsVRMLBrowser_duk.c
1 /*
2 
3 
4 Javascript 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
28 X3DRoute type is broken
29 X3DScene/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 /*
91 ComonentInfo{
92 String name;
93 Numeric level;
94 String Title;
95 String providerUrl;
96 }
97 
98 ComponentInfoArray{
99 numeric length;
100 ComponentInfo [integer index];
101 }
102 
103 
104 ProfileInfo{
105 String name;
106 Numeric level;
107 String Title;
108 String providerUrl;
109 ComonentInfoArray components;
110 }
111 ProfileInfoArray{
112 numeric length;
113 ProfileInfo [integer index];
114 }
115 
116 X3DFieldDefinition{
117 //properties
118 String name;
119 numeric accessType; //e.g.. inputOnly
120 numeric dataType; //e.g. SFBool
121 }
122 
123 FieldDefinitionArray{
124 numeric length;
125 X3DFieldDefinition [integer index];
126 }
127 
128 
129 ProtoDeclaration{
130 //properties
131 String name;
132 FieldDefinitionArray fields;
133 Boolean isExternProto;
134 //functions
135 SFNode newInstance();
136 }
137 
138 ExternProtoDeclaration : ProtoDeclaration {
139 //properties
140 MFString urls;
141 numeric loadState;
142 //functions
143 void loadNow();
144 }
145 
146 ProtoDeclarationArray{
147 numeric length;
148 X3DProtoDeclaration [integer index];
149 }
150 
151 ExternProtoDeclarationArray{
152 numeric length;
153 X3DExternProtoDeclaration [integer index];
154 }
155 
156 Route{
157 }
158 RouteArray{
159 numeric length;
160 Route [integer index];
161 }
162 
163 
164 ExecutionContext{
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 
188 Scene : 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
200 X3DBrowser{
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 
222 struct string_int{
223  char *c;
224  int i;
225 };
226 
227 struct 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 
314 struct string_int *lookup_string_int(struct string_int *table, 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 
331 int 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 
338 int len_constants(){
339  int len = (sizeof(lookup_X3DConstants) / sizeof(struct string_int)) -1;
340  return len;
341 }
342 int X3DConstantsIterator(int index, FWTYPE *fwt, FWPointer *pointer, 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 }
355 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 
373 int VrmlBrowserGetName(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 }
379 int VrmlBrowserGetVersion(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 }
385 int VrmlBrowserGetCurrentSpeed(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 
394 int VrmlBrowserGetCurrentFrameRate(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 }
402 int VrmlBrowserGetWorldURL(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 }
408 const 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 
460 int VrmlBrowserReplaceWorld(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*/
472 void conCat (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 
495 void createLoadUrlString(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 (out,url);
536  while (*out != '\0') out++;
537  conCat (out,param);
538 }
539 struct X3D_Anchor* get_EAIEventsIn_AnchorNode();
540 int VrmlBrowserLoadURL(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(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 }
561 int VrmlBrowserSetDescription(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 }
568 int VrmlBrowserCreateX3DFromString(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);
608 int VrmlBrowserCreateVrmlFromString(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 }
646 void *createNewX3DNode(int nt);
647 void add_node_to_broto_context(struct X3D_Proto *currentContext,struct X3D_Node *node);
648 int VrmlBrowserCreateNodeFromString(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 = VrmlBrowserCreateVrmlFromString(fwtype,ec,fwn,argc,fwpars,fwretval);
677  else
678  iret = VrmlBrowserCreateX3DFromString(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 }
694 void send_resource_to_parser_async(resource_item_t *res);
695 int VrmlBrowserCreateVrmlFromURL(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  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 */
745 void jsRegisterRoute(
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 }
758 struct brotoRoute *createNewBrotoRoute();
759 void *addDeleteRoute0(void *fwn, char*callingFunc, struct X3D_Node* fromNode, char *sfromField, struct X3D_Node* toNode, char *stoField){
760  void *retval;
761  int fromType,toType,fromKind,toKind,fromField,toField;
762  int i, len, fromOfs, toOfs;
763  union anyVrml *fromValue, *toValue;
764 
765  getFieldFromNodeAndName(fromNode,sfromField,&fromType,&fromKind,&fromField,&fromValue);
766  getFieldFromNodeAndName(toNode,stoField,&toType,&toKind,&toField,&toValue);
767 
768  /* do we have a mismatch here? */
769  if (fromType != toType) {
770  printf ("Javascript routing problem - can not route from %s to %s\n",
771  stringNodeType(fromNode->_nodeType),
772  stringNodeType(toNode->_nodeType));
773  return NULL;
774  }
775 
776  len = returnRoutingElementLength(toType);
777  {
778  struct brotoRoute *broute;
779  struct X3D_Proto *ec = (struct X3D_Proto*)fwn;
780  if(!ec) ec = (struct X3D_Proto*)fromNode->_executionContext;
781  if(!strcmp(callingFunc,"addRoute")){
782  broute = createNewBrotoRoute();
783  broute->from.node = fromNode;
784  broute->from.ifield = fromField;
785  //broute->from.Ofs = fromOfs;
786  broute->from.ftype = fromType;
787  broute->to.node = toNode;
788  broute->to.ifield = toField;
789  //broute->to.Ofs = toOfs;
790  broute->to.ftype = toType;
791  broute->lastCommand = 1; //added above (won't be added if an import weak route)
792  CRoutes_RegisterSimpleB(broute->from.node,broute->from.ifield,broute->to.node,broute->to.ifield,broute->ft);
793  broute->ft = fromType == toType ? fromType : -1;
794  if(!ec->__ROUTES)
795  ec->__ROUTES = newStack(struct brotoRoute *);
796  stack_push(struct brotoRoute *, ec->__ROUTES, broute);
797  retval = (void*)broute;
798  }else{
799  //deleteRoute
800  if(ec->__ROUTES)
801  for(i=0;i<vectorSize(ec->__ROUTES);i++){
802  broute = vector_get(struct brotoRoute*,ec->__ROUTES,i);
803  if(broute->from.node == fromNode && broute->from.ifield == fromField
804  && broute->to.node == toNode && broute->to.ifield == toField){
805  if(broute->lastCommand == 1)
806  CRoutes_RemoveSimpleB(broute->from.node,broute->from.ifield,broute->to.node,broute->to.ifield,broute->ft);
807  broute->lastCommand = 0;
808  vector_remove_elem(struct brotoRoute*,ec->__ROUTES,i);
809  FREE_IF_NZ(broute);
810  break;
811  }
812  }
813  retval = NULL;
814  }
815  }
816  return retval;
817 
818 }
819 
820 void * addDeleteRoute(void *fwn, char* callingFunc, int argc, FWval fwpars, FWval fwretval){
821  struct X3D_Node *fromNode;
822  struct X3D_Node *toNode;
823  const char *fromField, *toField;
824  void *retval;
825 
826  //if(0){ //!strcmp(callingFunc,"deleteRoute")){
827  // fromNode = fwpars[0]._web3dval.native;
828  // toNode = fwpars[2]._web3dval.native;
829  //}
830  fromNode = fwpars[0]._web3dval.anyvrml->sfnode; //.native;
831  toNode = fwpars[2]._web3dval.anyvrml->sfnode; //.native;
832 
833  fromField = fwpars[1]._string;
834  toField = fwpars[3]._string;
835 
836  retval = addDeleteRoute0(fwn,callingFunc,fromNode, fromField, toNode, toField);
837  return retval;
838 }
839 int X3DExecutionContext_deleteRoute(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
840  //we're expecting an X3DRoute struct parameter.
841  int nr = 0;
842  void *xroute;
843  struct X3D_Node *fromNode, *toNode;
844  char *fromField, *toField;
845  int fromIfield, toIfield;
846  int ftype,kind;
847  union anyVrml *value;
848 
849  if(fwpars[0].itype != 'P') return nr;
850 
851  {
852  struct brotoRoute* broute = (struct brotoRoute*)fwpars[0]._pointer.native;
853  fromNode = broute->from.node;
854  fromIfield = broute->from.ifield;
855  toNode = broute->to.node;
856  toIfield = broute->to.ifield;
857  }
858  getFieldFromNodeAndIndex(fromNode,fromIfield,&fromField,&ftype,&kind,&value);
859  getFieldFromNodeAndIndex(toNode,toIfield,&toField,&ftype,&kind,&value);
860  xroute = addDeleteRoute0(fwn,"deleteRoute",fromNode, fromField, toNode, toField);
861  return nr;
862 }
863 
864 int VrmlBrowserAddRoute(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
865  void *xroute;
866  int nr = 0;
867  xroute = addDeleteRoute(fwn,"addRoute",argc,fwpars,fwretval);
868  if(xroute){
869  fwretval->_web3dval.fieldType = AUXTYPE_X3DRoute; //AUXTYPE_X3DScene;
870  fwretval->_web3dval.native = xroute;
871  fwretval->_web3dval.gc = 0;
872  fwretval->itype = 'P';
873  nr = 1;
874  }
875  return nr;
876 }
877 int VrmlBrowserDeleteRoute(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
878  void *xroute;
879  int nr = 0;
880  xroute = addDeleteRoute(fwn,"deleteRoute",argc,fwpars,fwretval);
881  return nr;
882 }
883 int VrmlBrowserPrint(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
884 {
885  const char *_costr = NULL;
886  if(fwpars[0].itype == 'S'){
887  _costr = fwpars[0]._string; //fwpars[0]._web3dval.anyvrml->sfstring->strptr;
888  if(_costr)
889  ConsoleMessage("%s",_costr);
890  }
891  return 0;
892 }
893 int VrmlBrowserPrintln(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
894 {
895  const char *_costr = NULL;
896  if(fwpars[0].itype == 'S'){
897  _costr = fwpars[0]._string; //fwpars[0]._web3dval.anyvrml->sfstring->strptr;
898  if(_costr)
899  ConsoleMessage("%s\n",_costr);
900  }
901  return 0;
902 }
903 
904 FWFunctionSpec (BrowserFunctions)[] = {
905  {"getName", VrmlBrowserGetName, 'S',{0,0,0,NULL}},
906  {"getVersion", VrmlBrowserGetVersion, 'S',{0,0,0,NULL}},
907  {"getCurrentSpeed", VrmlBrowserGetCurrentSpeed, 'S',{0,0,0,NULL}},
908  {"getCurrentFrameRate", VrmlBrowserGetCurrentFrameRate, 'S',{0,0,0,NULL}},
909  {"getWorldURL", VrmlBrowserGetWorldURL, 'S',{0,0,0,NULL}},
910  {"replaceWorld", VrmlBrowserReplaceWorld, '0',{1,-1,0,"Z"}},
911  {"loadURL", VrmlBrowserLoadURL, '0',{2,1,'T',"FF"}},
912  {"setDescription", VrmlBrowserSetDescription, '0',{1,-1,0,"S"}},
913  {"createVrmlFromString", VrmlBrowserCreateVrmlFromString, 'W',{1,-1,0,"S"}},
914  {"createVrmlFromURL", VrmlBrowserCreateVrmlFromURL,'0',{3,3,0,"WWS"}},
915  {"createX3DFromString", VrmlBrowserCreateX3DFromString, 'W',{1,-1,0,"S"}},
916  {"createX3DFromURL", VrmlBrowserCreateVrmlFromURL, '0',{3,3,0,"WWS"}},
917  {"addRoute", VrmlBrowserAddRoute, 'P',{4,-1,0,"WSWS"}},
918  {"deleteRoute", VrmlBrowserDeleteRoute, '0',{4,-1,0,"WSWS"}},
919  {"print", VrmlBrowserPrint, '0',{1,-1,0,"S"}},
920  {"println", VrmlBrowserPrintln, '0',{1,-1,0,"S"}},
921 
922  //{importDocument, X3dBrowserImportDocument, 0), //not sure we need/want this, what does it do?
923  //{getRenderingProperty, X3dGetRenderingProperty, 0},
924  //{addBrowserListener, X3dAddBrowserListener, 0},
925  //{removeBrowserListener, X3dRemoveBrowserListener, 0},
926 
927  {0}
928 };
929 
930 
931 //typedef struct FWPropertySpec {
932 // const char *name; //NULL means index int: SFVec3f[0], MF[i]
933 // char index; //stable property index for switch/casing instead of strcmp on name
934 // char type; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr
935 // char isReadOnly; //T/F
936 //} FWPropertySpec;
937 
938 
939 FWPropertySpec (BrowserProperties)[] = {
940  {"name", 0, 'S', 'T'},
941  {"version", 1, 'S', 'T'},
942  {"currentSpeed", 2, 'D', 'T'},
943  {"currentFrameRate", 3, 'D', 'T'},
944  {"description", 4, 'S', 0},
945  {"supportedComponents", 5, 'P', 'T'},
946  {"supportedProfiles", 6, 'P', 'T'},
947  {"currentScene", 7, 'P', 'T'},
948  {NULL,0,0,0},
949 };
950 struct proftablestruct {
951  int profileName;
952  const int *profileTable;
953  int level; //dug9
954 };
955 struct proftablestruct *getProfTable();
956 const int * getCapabilitiesTable();
957 int BrowserGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
958  int nr = 1;
959  //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)
960  switch (index) {
961  case 0: //name
962  fwretval->_string = BrowserName;
963  fwretval->itype = 'S';
964  break;
965  case 1: //version
966  fwretval->_string = libFreeWRL_get_version();
967  fwretval->itype = 'S';
968  break;
969  case 2: //currentSpeed
970  fwretval->_numeric = gglobal()->Mainloop.BrowserSpeed;
971  fwretval->itype = 'D';
972  break;
973  case 3: //currentFrameRate
974  fwretval->_numeric = gglobal()->Mainloop.BrowserFPS;
975  fwretval->itype = 'D';
976  break;
977  case 4: //description
978  fwretval->_string = gglobal()->Mainloop.BrowserDescription; //this is settable
979  fwretval->itype = 'S';
980  break;
981  case 5: //supportedComponents
982  fwretval->_pointer.fieldType = AUXTYPE_ComponentInfoArray;
983  fwretval->_pointer.native = (void*)getCapabilitiesTable(); //TO-DO something about component info array
984  fwretval->_pointer.gc = 0;
985  fwretval->itype = 'P';
986  break;
987  case 6: //supportedProfiles
988  fwretval->_pointer.fieldType = AUXTYPE_ProfileInfoArray;
989  fwretval->_pointer.native = (void*)getProfTable(); //TO-DO something about profile info array
990  fwretval->_pointer.gc = 0;
991  fwretval->itype = 'P';
992  break;
993  case 7: //currentScene
994  fwretval->_web3dval.fieldType = AUXTYPE_X3DExecutionContext; //AUXTYPE_X3DScene;
995  fwretval->_web3dval.native = (void *)(struct X3D_Node*)ec; //X3DScene || X3DExecutionContext
996  fwretval->_web3dval.gc = 0;
997  //change this to (Script)._executionContext when brotos working fully
998  fwretval->itype = 'P';
999  break;
1000  default:
1001  nr = 0;
1002  }
1003  return nr;
1004 }
1005 int BrowserSetter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
1006  switch (index) {
1007  case 4: //description is settable
1008  gglobal()->Mainloop.BrowserDescription = fwval->_string; //fwval->_web3dval.anyvrml->sfstring->strptr;
1009  break;
1010  default:
1011  break;
1012  }
1013  return TRUE;
1014 }
1015 
1016 
1017 FWTYPE BrowserType = {
1018  AUXTYPE_X3DBrowser,
1019  'P',
1020  "X3DBrowser",
1021  0, //sizeof(struct X3DBrowser),
1022  NULL, //no constructor for Browser
1023  NULL, //no constructor args
1024  BrowserProperties,
1025  NULL, //no special has
1026  BrowserGetter,
1027  BrowserSetter,
1028  0, 0, //takes int index in prop
1029  BrowserFunctions,
1030 };
1031 
1032 
1033 
1034 
1035 /* ProfileInfo, ProfileInfoArray, ComponentInfo, ComponentInfoArray
1036  I decided to do these as thin getter wrappers on the bits and pieces defined
1037  in Structs.h, GeneratedCode.c and capabilitiesHandler.c
1038  The Array types return the info type wrapper with private native member == index into
1039  the native array.
1040 */
1041 //ComonentInfo{
1042 //String name;
1043 //Numeric level;
1044 //String Title;
1045 //String providerUrl;
1046 //}
1047 
1048 int capabilitiesHandler_getTableLength(int* table);
1049 int capabilitiesHandler_getComponentLevel(int *table, int comp);
1050 int capabilitiesHandler_getProfileLevel(int prof);
1051 const int *capabilitiesHandler_getProfileComponent(int prof);
1052 const int *capabilitiesHandler_getCapabilitiesTable();
1053 /*
1054 typedef struct intTableIndex{
1055  int* table;
1056  int index;
1057 } *IntTableIndex;
1058 */
1059 
1060 
1061 //ComponentInfoArray{
1062 //numeric length;
1063 //ComponentInfo [integer index];
1064 //}
1065 
1066 int *intdup(int value){
1067  int* p = malloc(sizeof(int));
1068  memcpy(p,&value,sizeof(int));
1069  return p;
1070 }
1071 int ComponentInfoArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1072  int *_table;
1073  int nr = 1;
1074  _table = (int *)fwn;
1075  //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)
1076  if(index == -1){
1077 //extern const char *COMPONENTS[];
1078 //extern const int COMPONENTS_COUNT;
1079  int _length = capabilitiesHandler_getTableLength(_table); //COMPONENTS_COUNT;
1080  //fwretval->_integer = _length;
1081  fwretval->itype = 'I';
1082  fwretval->_integer = _length;
1083 
1084  }else if(index > -1 && index < COMPONENTS_COUNT ){
1085  fwretval->_pointer.native = &_table[2*index];
1086  fwretval->_pointer.fieldType = AUXTYPE_ComponentInfo;
1087  fwretval->_pointer.gc = 0;
1088  fwretval->itype = 'P';
1089  }
1090  return nr;
1091 }
1092 
1093 
1094 FWPropertySpec (ComponentInfoArrayProperties)[] = {
1095  {"length", -1, 'I', 'T'},
1096  {NULL,0,0,0},
1097 };
1098 
1099 FWTYPE ComponentInfoArrayType = {
1100  AUXTYPE_ComponentInfoArray,
1101  'P',
1102  "ComponentInfoArray",
1103  0, //sizeof(struct X3DBrowser),
1104  NULL, //no constructor for Browser
1105  NULL, //no constructor args
1106  ComponentInfoArrayProperties,
1107  NULL, //no special has
1108  ComponentInfoArrayGetter,
1109  NULL,
1110  'P', 'T', //takes int index in prop of this type
1111  NULL,
1112 };
1113 
1114 FWPropertySpec (ComponentInfoProperties)[] = {
1115  {"name", 0, 'S', 'T'},
1116  {"Title", 1, 'S', 'T'},
1117  {"level", 2, 'I', 'T'},
1118  {"providerUrl", 3, 'S', 'T'},
1119  {NULL,0,0,0},
1120 };
1121 
1122 
1123 int ComponentInfoGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1124  int nr, *tableEntry, nameIndex;
1125  tableEntry = (int *)fwn;
1126  nr = 1;
1127  //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)
1128  switch (index) {
1129  case 0://name
1130  case 1://Title
1131  nameIndex = tableEntry[0];
1132  fwretval->_string = COMPONENTS[nameIndex];
1133  fwretval->itype = 'S';
1134  break;
1135  case 2://level
1136  fwretval->_integer = tableEntry[1];
1137  fwretval->itype = 'I';
1138  break;
1139  case 3://providerUrl
1140  fwretval->_string = "freewrl.sourceforge.net";
1141  fwretval->itype = 'S';
1142  break;
1143  default:
1144  nr = 0;
1145  break;
1146  }
1147  return nr;
1148 }
1149 
1150 FWTYPE ComponentInfoType = {
1151  AUXTYPE_ComponentInfo,
1152  'P',
1153  "ComponentInfo",
1154  0, //sizeof(struct X3DBrowser),
1155  NULL, //no constructor for Browser
1156  NULL, //no constructor args
1157  ComponentInfoProperties,
1158  NULL, //no special has
1159  ComponentInfoGetter,
1160  NULL,
1161  0,0, //takes int index in prop
1162  NULL,
1163 };
1164 
1165 
1166 
1167 //ProfileInfoArray{
1168 //numeric length;
1169 //ProfileInfo [integer index];
1170 //}
1171 
1172 
1173 int ProfileInfoArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1174  struct proftablestruct *_table;
1175  int nr = 1;
1176  _table = (struct proftablestruct *)fwn;
1177  //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)
1178  if(index == -1){
1179 //extern const char *COMPONENTS[];
1180 //extern const int COMPONENTS_COUNT;
1181  fwretval->_integer = PROFILES_COUNT; // _length;
1182  fwretval->itype = 'I';
1183  }else if(index > -1 && index < PROFILES_COUNT ){
1184  fwretval->_pointer.native = &_table[index];
1185  fwretval->_pointer.fieldType = AUXTYPE_ProfileInfo;
1186  fwretval->_pointer.gc = 0;
1187  fwretval->itype = 'P';
1188  }
1189  return nr;
1190 }
1191 
1192 
1193 FWPropertySpec (ProfileInfoArrayProperties)[] = {
1194  {"length", -1, 'I', 'T'},
1195  {NULL,0,0,0},
1196 };
1197 
1198 FWTYPE ProfileInfoArrayType = {
1199  AUXTYPE_ProfileInfoArray,
1200  'P',
1201  "ProfileInfoArray",
1202  0, //sizeof(struct X3DBrowser),
1203  NULL, //no constructor for Browser
1204  NULL, //no constructor args
1205  ProfileInfoArrayProperties,
1206  NULL, //no special has
1207  ProfileInfoArrayGetter,
1208  NULL,
1209  'P', 'T',//takes int index in prop, readOnly
1210  NULL,
1211 };
1212 
1213 
1214 //ProfileInfo{
1215 //String name;
1216 //Numeric level;
1217 //String Title;
1218 //String providerUrl;
1219 //ComonentInfoArray components;
1220 //}
1221 
1222 FWPropertySpec (ProfileInfoProperties)[] = {
1223  {"name", 0, 'S', 'T'},
1224  {"Title", 1, 'I', 'T'},
1225  {"level", 2, 'S', 'T'},
1226  {"providerUrl", 3, 'S', 'T'},
1227  {"components", 4, 'P', 'T'}, //writable? if so then I need a constructor for ComponentInfo?
1228  {NULL,0,0,0},
1229 };
1230 
1231 
1232 int ProfileInfoGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1233  int nr, nameIndex;
1234  struct proftablestruct *tableEntry;
1235  tableEntry = (struct proftablestruct *)fwn;
1236  nr = 1;
1237  //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)
1238  switch (index) {
1239  case 0://name
1240  case 1://Title
1241  nameIndex = tableEntry->profileName;
1242  fwretval->_string = stringProfileType(nameIndex);
1243  fwretval->itype = 'S';
1244  break;
1245  case 2://level
1246  fwretval->_integer = tableEntry->level;
1247  fwretval->itype = 'I';
1248  break;
1249  case 3://providerUrl
1250  fwretval->_string = "freewrl.sourceforge.net";
1251  fwretval->itype = 'S';
1252  break;
1253  case 4://components
1254  fwretval->_pointer.native = (void *)tableEntry->profileTable;
1255  fwretval->_pointer.fieldType = AUXTYPE_ComponentInfoArray;
1256  fwretval->_pointer.gc = 0;
1257  fwretval->itype = 'P';
1258  break;
1259  default:
1260  nr = 0;
1261  break;
1262  }
1263  return nr;
1264 }
1265 
1266 FWTYPE ProfileInfoType = {
1267  AUXTYPE_ProfileInfo,
1268  'P',
1269  "ProfileInfo",
1270  0, //sizeof(struct X3DBrowser),
1271  NULL, //no constructor for Browser
1272  NULL, //no constructor args
1273  ProfileInfoProperties,
1274  NULL, //no special has
1275  ProfileInfoGetter,
1276  NULL,
1277  0,0, //takes int index in prop
1278  NULL,
1279 };
1280 
1281 
1282 
1283 
1284 struct X3D_Node *broto_search_DEFname(struct X3D_Proto *context, const char *name);
1285 struct X3D_Node * broto_search_ALLnames(struct X3D_Proto *context, char *name, int *source);
1286 int X3DExecutionContext_getNamedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1287  int nr = 0;
1288  struct X3D_Node* node = NULL;
1289  //broto warning - DEF name list should be per-executionContext
1290  //struct X3D_Proto *ec = (struct X3D_Proto *)fwn; //we want the script node's parent context for imported nodes, I think
1291  node = broto_search_DEFname(ec, fwpars[0]._string);
1292 
1293  if(node){
1294  //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1295  fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1296  fwretval->_web3dval.anyvrml->sfnode = node;
1297  fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1298  fwretval->_web3dval.gc = 1;
1299  fwretval->itype = 'W';
1300  nr = 1;
1301  }
1302  return nr;
1303 }
1304 
1305 int X3DExecutionContext_updateNamedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1306  int i, nr = 0;
1307  //broto warning - DEF name list should be per-executionContext
1308  struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1309  struct X3D_Node* node = NULL;
1310  struct brotoDefpair *bd;
1311  int found = 0;
1312  char *defname;
1313  defname = fwpars[0]._string;
1314  node = X3D_NODE(fwpars[1]._web3dval.native);
1315  if(_ec->__DEFnames){
1316  for(i=0;i<vectorSize(_ec->__DEFnames);i++){
1317  bd = vector_get(struct brotoDefpair *,_ec->__DEFnames,i);
1318  //Q. is it the DEF we search for, and node we replace, OR
1319  // is it the node we search for, and DEF we replace?
1320  if(!strcmp(bd->name,defname)){
1321  bd->node = node;
1322  found = 1;
1323  break;
1324  }
1325  if(bd->node == node){
1326  bd->name = strdup(defname);
1327  found = 2;
1328  break;
1329  }
1330  }
1331  }
1332  if(!found){
1333  //I guess its an add
1334  if(!_ec->__DEFnames)
1335  _ec->__DEFnames = newVector(struct brotoDefpair*,4);
1336  bd = (struct brotoDefpair*)malloc(sizeof(struct brotoDefpair));
1337  bd->node = node;
1338  bd->name = strdup(defname);
1339  stack_push(struct brotoDefpair *,_ec->__DEFnames,bd);
1340  }
1341  return nr;
1342 }
1343 int remove_broto_node(struct X3D_Proto *context, struct X3D_Node* node);
1344 int X3DExecutionContext_removeNamedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1345  int i, nr = 0;
1346  //broto warning - DEF name list should be per-executionContext
1347  struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1348  struct X3D_Node* node = NULL;
1349 
1350  char *defname;
1351  defname = fwpars[0]._string;
1352  if(_ec->__DEFnames){
1353  struct brotoDefpair *bd;
1354  for(i=0;i<vectorSize(_ec->__DEFnames);i++){
1355  bd = vector_get(struct brotoDefpair *,_ec->__DEFnames,i);
1356  if(!strcmp(bd->name,defname)){
1357  node = bd->node;
1358  //Q. are we supposed to delete the node
1359  //OR are we just supposed to remove the DEF name mapping?
1360  //remove DEF name mapping:
1361  vector_remove_elem(struct brotoDefpair *,_ec->__DEFnames,i);
1362  //remove node
1363  remove_broto_node(_ec,node);
1364  break;
1365  }
1366  }
1367  }
1368 
1369  return nr;
1370 }
1371 void add_node_to_broto_context(struct X3D_Proto *context,struct X3D_Node *node);
1372 int X3DExecutionContext_createProto(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1373  int nr = 0;
1374  struct X3D_Node* node = NULL;
1375  //broto warning - DEF name list should be per-executionContext
1376  struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1377  struct X3D_Proto *proto;
1378  proto = NULL;
1379 
1380  if( isAvailableBroto(fwpars[0]._string, ec, &proto))
1381  {
1382  struct X3D_Proto *source, *dest;
1383  node=X3D_NODE(brotoInstance(proto,1));
1384  node->_executionContext = X3D_NODE(ec); //me->ptr;
1385  add_node_to_broto_context(ec,node);
1386  //during parsing, setting of fields would occur between instance and body,
1387  //so field values perculate down.
1388  //here we elect default field values
1389  source = X3D_PROTO(X3D_PROTO(node)->__prototype);
1390  dest = X3D_PROTO(node);
1391  deep_copy_broto_body2(&source,&dest);
1392  }
1393  if(node){
1394  //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1395  fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1396  fwretval->_web3dval.anyvrml->sfnode = node;
1397  fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1398  fwretval->_web3dval.gc = 1;
1399  fwretval->itype = 'W';
1400  nr = 1;
1401  }
1402  return nr;
1403 }
1404 
1405 int X3DExecutionContext_getImportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1406  int nr = 0;
1407  struct X3D_Node* node = NULL;
1408  //broto warning - DEF name list should be per-executionContext
1409  struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1410  //struct IMEXPORT *mxp;
1411  int source;
1412  //mxp = broto_search_IMPORTname(ec, fwpars[0]._string);
1413  //if(mxp){
1414  // node = mxp->nodeptr;
1415  //}
1416  node = broto_search_ALLnames(ec, fwpars[0]._string,&source);
1417  if(source == 0) node = NULL; //source ==1,2 is for IMPORT and EXPORT
1418  if(node){
1419  //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1420  fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1421  fwretval->_web3dval.anyvrml->sfnode = node;
1422  fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1423  fwretval->_web3dval.gc = 1;
1424  fwretval->itype = 'W';
1425  nr = 1;
1426  }
1427  return nr;
1428 }
1429 
1430 void update_weakRoutes(struct X3D_Proto *context);
1431 int X3DExecutionContext_updateImportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1432  // I think what they mean by updateImportedNode(string,string[,string]) is:
1433  // updateImportedNode(Inline DEF name, Inline's Export AS name [,optional Import AS name])
1434  int i, nr = 0;
1435  //broto warning - DEF name list should be per-executionContext
1436  struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1437  struct X3D_Node* node = NULL;
1438 
1439  char *mxname, *as, *nline;
1440  int found = 0;
1441  struct IMEXPORT *mxp;
1442 
1443  nline = fwpars[0]._string;
1444  mxname = fwpars[1]._string;
1445  as = mxname;
1446  if(argc == 3)
1447  as = fwpars[2]._string;
1448  node = X3D_NODE(fwpars[1]._web3dval.native);
1449  if(_ec->__IMPORTS){
1450  for(i=0;i<vectorSize(_ec->__IMPORTS);i++){
1451  mxp = vector_get(struct IMEXPORT *,_ec->__IMPORTS,i);
1452  //Q. is it the DEF we search for, and node we replace, OR
1453  // is it the node we search for, and DEF we replace?
1454  if(!strcmp(nline,mxp->inlinename) && !strcmp(mxp->mxname,mxname)){
1455  mxp->as = strdup(as);
1456  found = 1;
1457  break;
1458  }
1459  }
1460  }
1461  if(!found){
1462  //I guess its an add
1463  if(!_ec->__IMPORTS)
1464  _ec->__IMPORTS = newVector(struct IMEXPORT *,4);
1465  mxp = (struct IMEXPORT *)malloc(sizeof(struct IMEXPORT));
1466  mxp->mxname = strdup(mxname);
1467  mxp->as = strdup(as);
1468  mxp->inlinename = strdup(nline);
1469  stack_push(struct IMEXPORT *,_ec->__IMPORTS,mxp);
1470  }
1471  update_weakRoutes(_ec);
1472  return nr;
1473 }
1474 
1475 
1476 int X3DExecutionContext_removeImportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1477  int i,nr = 0;
1478  //broto warning - DEF name list should be per-executionContext
1479  struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1480  //struct X3D_Node* node = NULL;
1481 
1482  char *defname;
1483  defname = fwpars[0]._string;
1484  if(_ec->__IMPORTS){
1485  struct IMEXPORT *mxp;
1486  for(i=0;i<vectorSize(_ec->__IMPORTS);i++){
1487  mxp = vector_get(struct IMEXPORT *,_ec->__IMPORTS,i);
1488  if(!strcmp(mxp->as,defname)){
1489  //remove IMPORT name mapping:
1490  vector_remove_elem(struct IMEXPORT *,_ec->__IMPORTS,i);
1491  update_weakRoutes(_ec);
1492  break;
1493  }
1494  }
1495  }
1496  return nr;
1497 }
1498 
1499 
1500 int X3DScene_getExportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1501  int nr = 0;
1502  struct X3D_Node* node = NULL;
1503  //broto warning - DEF name list should be per-executionContext
1504  struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1505  struct IMEXPORT *mxp;
1506  mxp = broto_search_EXPORTname(ec, fwpars[0]._string);
1507  if(mxp){
1508  node = mxp->nodeptr;
1509  }
1510  if(node){
1511  //fwretval->_web3dval.native = node; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1512  fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1513  fwretval->_web3dval.anyvrml->sfnode = node;
1514  fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1515  fwretval->_web3dval.gc = 1;
1516  fwretval->itype = 'W';
1517  nr = 1;
1518  }
1519  return nr;
1520 }
1521 
1522 int X3DScene_updateExportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1523  int i, nr = 0;
1524  //broto warning - DEF name list should be per-executionContext
1525  struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1526  struct X3D_Node* node = NULL;
1527 
1528  char *defname;
1529  int found = 0;
1530  struct IMEXPORT *mxp;
1531 
1532  defname = fwpars[0]._string;
1533  node = X3D_NODE(fwpars[1]._web3dval.anyvrml->sfnode);
1534  if(_ec->__EXPORTS){
1535  for(i=0;i<vectorSize(_ec->__EXPORTS);i++){
1536  mxp = vector_get(struct IMEXPORT *,_ec->__EXPORTS,i);
1537  //Q. is it the DEF we search for, and node we replace, OR
1538  // is it the node we search for, and DEF we replace?
1539  if(!strcmp(mxp->as,defname)){
1540  mxp->nodeptr = node;
1541  found = 1;
1542  break;
1543  }
1544  if(mxp->nodeptr == node){
1545  mxp->as = strdup(defname);
1546  found = 2;
1547  break;
1548  }
1549  }
1550  }
1551  if(!found){
1552  //I guess its an add
1553  if(!_ec->__EXPORTS)
1554  _ec->__EXPORTS = newVector(struct IMEXPORT *,4);
1555  mxp = (struct IMEXPORT *)malloc(sizeof(struct IMEXPORT));
1556  mxp->nodeptr = node;
1557  mxp->mxname = strdup(defname);
1558  mxp->as = mxp->mxname;
1559  stack_push(struct IMEXPORT *,_ec->__EXPORTS,mxp);
1560  }
1561  if(_ec->_executionContext){
1562  //update weak routes in the importing context, which should be the parent context of the Inline node
1563  //and the Inline should be our current context. I think.
1564  update_weakRoutes(X3D_PROTO(_ec->_executionContext));
1565  }
1566  return nr;
1567 }
1568 
1569 int X3DScene_removeExportedNode(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1570  int i, nr = 0;
1571  //broto warning - DEF name list should be per-executionContext
1572  struct X3D_Proto *_ec = (struct X3D_Proto *)fwn;
1573  //struct X3D_Node* node = NULL;
1574 
1575  char *defname;
1576  defname = fwpars[0]._string;
1577  if(_ec->__EXPORTS){
1578  struct IMEXPORT *mxp;
1579  for(i=0;i<vectorSize(_ec->__EXPORTS);i++){
1580  mxp = vector_get(struct IMEXPORT *,_ec->__EXPORTS,i);
1581  if(!strcmp(mxp->as,defname)){
1582  //remove EXPORT name mapping:
1583  vector_remove_elem(struct IMEXPORT *,_ec->__EXPORTS,i);
1584  break;
1585  }
1586  }
1587  }
1588  if(_ec->_executionContext){
1589  //update weak routes in the importing context, which should be the parent context of the Inline node
1590  //and the Inline should be our current context. I think.
1591  update_weakRoutes(X3D_PROTO(_ec->_executionContext));
1592  }
1593  return nr;
1594 }
1595 int X3DScene_setMetaData(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1596  int nr = 0;
1597  char *name, *value;
1598  name = fwpars[0]._string;
1599  value = fwpars[1]._string;
1600  //strdup and put in a global or per-scene or per execution context (name,value) list
1601  return nr;
1602 }
1603 int X3DScene_getMetaData(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1604  int nr = 0;
1605  char *name, *value;
1606  value = NULL;
1607  name = fwpars[0]._string;
1608  //do a search in the perscene/perexecution context array
1609  if(value){
1610  fwretval->_string = value;
1611  fwretval->itype = 'S';
1612  nr = 1;
1613  }
1614  return nr;
1615 }
1616 
1617 static FWFunctionSpec (X3DExecutionContextFunctions)[] = {
1618  //executionContext
1619  {"addRoute", VrmlBrowserAddRoute, 'P',{4,-1,0,"WSWS"}},
1620  {"deleteRoute", X3DExecutionContext_deleteRoute,'0',{1,-1,0,"P"}},
1621  {"createNode", VrmlBrowserCreateNodeFromString, 'W',{1,-1,0,"S"}},
1622  {"createProto", X3DExecutionContext_createProto, 'W',{1,-1,0,"S"}},
1623  {"getImportedNode", X3DExecutionContext_getImportedNode, 'W',{1,-1,0,"S"}},
1624  {"updateImportedNode", X3DExecutionContext_updateImportedNode, '0',{3,-1,0,"SSS"}},
1625  {"removeImportedNode", X3DExecutionContext_removeImportedNode, '0',{1,-1,0,"S"}},
1626  {"getNamedNode", X3DExecutionContext_getNamedNode, 'W',{1,-1,0,"S"}},
1627  {"updateNamedNode", X3DExecutionContext_updateNamedNode, '0',{2,-1,0,"SW"}},
1628  {"removeNamedNode", X3DExecutionContext_removeNamedNode, '0',{1,-1,0,"S"}},
1630  {"setMetaData", X3DScene_setMetaData, '0',{2,-1,0,"SS"}},
1631  {"getMetaData", X3DScene_getMetaData, 'S',{1,-1,0,"S"}},
1632  {"getExportedNode", X3DScene_getExportedNode, 'W',{1,-1,0,"S"}},
1633  {"updateExportedNode", X3DScene_updateExportedNode, '0',{2,-1,0,"SW"}},
1634  {"removeExportedNode", X3DScene_removeExportedNode, '0',{1,-1,0,"S"}},
1635  {0}
1636 };
1637 
1638 
1639 
1640 static FWPropertySpec (X3DExecutionContextProperties)[] = {
1641  //executionContext
1642  {"specificationVersion", 0, 'S', 'T'},
1643  {"encoding", 1, 'S', 'T'},
1644  {"profile", 2, 'P', 'T'},
1645  {"components", 3, 'P', 'T'},
1646  {"worldURL", 4, 'S', 'T'},
1647  {"rootNodes", 5, 'W', 'T'},
1648  {"protos", 6, 'P', 'T'},
1649  {"externprotos", 7, 'P', 'T'},
1650  {"routes", 8, 'P', 'T'},
1651  //scene
1652  {"isScene", 9, 'B', 'T'}, //else protoInstance. extra beyond specs - I think flux has it.
1653  {0}
1654 };
1655 static int _TRUE = TRUE;
1656 static int _FALSE = FALSE;
1657 int X3DExecutionContextGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1658  struct X3D_Proto * ecc;
1659  int nr = 1;
1660  ecc = (struct X3D_Proto*)fwn;
1661  //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)
1662  switch (index) {
1663  case 0: //specificationVersion
1664  {
1665  char str[32];
1666  sprintf(str,"{%d,%d,%d}",inputFileVersion[0],inputFileVersion[1],inputFileVersion[2]);
1667  fwretval->_string = strdup(str);
1668  fwretval->itype = 'S';
1669  }
1670  break;
1671  case 1: //encoding string readonly
1672  {
1673  //Valid values are "ASCII", "VRML", "XML", "BINARY", "SCRIPTED", "BIFS", "NONE"
1674  fwretval->_string = "not filled in yet sb. VRML or XML or ..";
1675  fwretval->itype = 'S';
1676  }
1677  break;
1678  case 2: //profile
1679  {
1680  struct proftablestruct * profile;
1681  int index = gglobal()->Mainloop.scene_profile;
1682  profile = getProfTable();
1683  fwretval->_pointer.native = &profile[index];
1684  fwretval->_pointer.fieldType = AUXTYPE_ProfileInfo;
1685  fwretval->_pointer.gc = 0;
1686  fwretval->itype = 'P';
1687  }
1688  break;
1689  case 3: //components
1690  fwretval->_pointer.native = (void *)gglobal()->Mainloop.scene_components;
1691  fwretval->_pointer.fieldType = AUXTYPE_ComponentInfoArray;
1692  fwretval->_pointer.gc = 0;
1693  fwretval->itype = 'P';
1694  break;
1695  case 4: //worldURL
1696  fwretval->_string = gglobal()->Mainloop.url; //this is settable
1697  fwretval->itype = 'S';
1698  break;
1699  case 5: //rootNodes
1700  fwretval->_web3dval.native = (void *)&ecc->__children; //broto warning: inside a proto should be the rootnodes of the protobody
1701  fwretval->_web3dval.fieldType = FIELDTYPE_MFNode;
1702  fwretval->_web3dval.gc = 0;
1703  fwretval->itype = 'W';
1704  break;
1705  case 6: //protos
1706  fwretval->_pointer.fieldType = AUXTYPE_X3DProtoArray;
1707  fwretval->_pointer.native = (void*)ecc->__protoDeclares; //broto: this should be a per-context array
1708  fwretval->_pointer.gc = 0;
1709  fwretval->itype = 'P';
1710  break;
1711  case 7: //externprotos
1712  fwretval->_pointer.fieldType = AUXTYPE_X3DExternProtoArray;
1713  fwretval->_pointer.native = (void*)ecc->__externProtoDeclares; //broto: this should be a per-context array
1714  fwretval->_pointer.gc = 0;
1715  fwretval->itype = 'P';
1716  break;
1717  case 8: //routes
1718  fwretval->_pointer.fieldType = AUXTYPE_X3DRouteArray;
1719  fwretval->_pointer.native = (void*)ecc->__ROUTES; //broto: this should be a per-context array
1720  fwretval->_pointer.gc = 0;
1721  fwretval->itype = 'P';
1722  break;
1723  case 9: //isScene
1724  //fwretval->_boolean = TRUE; //broto warning: should be false inside a protoinstance body
1725  fwretval->itype = 'B';
1726  {
1727  unsigned char flag = ciflag_get(ecc->__protoFlags,2);
1728  if(flag == 2)
1729  fwretval->_boolean = TRUE;
1730  else
1731  fwretval->_boolean = FALSE;
1732  }
1733  break;
1734  default:
1735  nr = 0;
1736  }
1737  return nr;
1738 }
1739 
1740 FWTYPE X3DExecutionContextType = {
1741  AUXTYPE_X3DExecutionContext,
1742  'P',
1743  "X3DExecutionContext",
1744  0, //sizeof(struct X3DBrowser),
1745  NULL, //no constructor
1746  NULL, //no constructor args
1747  X3DExecutionContextProperties,
1748  NULL, //no special has
1749  X3DExecutionContextGetter,
1750  NULL,
1751  0,0, //takes int index in prop
1752  X3DExecutionContextFunctions,
1753 };
1754 
1755 struct CRStruct *getCRoutes();
1756 int getCRouteCount();
1757 int *getCRouteCounter();
1758 int X3DRouteArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1759 
1760  int nr = 0;
1761  //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)
1762  if(index == -1){
1763  int _length;
1764  _length = vectorSize(fwn);
1765  fwretval->_integer = _length;
1766  fwretval->itype = 'I';
1767  nr = 1;
1768  }else if(index > -1 ){
1769  if(index < vectorSize(fwn)){
1770  fwretval->_pointer.native = vector_get(void *, fwn, index); //struct brotoRoute *
1771  fwretval->_pointer.gc = 0;
1772  fwretval->_pointer.fieldType = AUXTYPE_X3DRoute;
1773  fwretval->itype = 'P';
1774  nr = 1;
1775  }
1776  }
1777  return nr;
1778 }
1779 
1780 
1781 FWPropertySpec (X3DRouteArrayProperties)[] = {
1782  {"length", -1, 'I', 'T'},
1783  {NULL,0,0,0},
1784 };
1785 
1786 FWTYPE X3DRouteArrayType = {
1787  AUXTYPE_X3DRouteArray,
1788  'P',
1789  "X3DRouteArray",
1790  0, //sizeof(struct X3DRoute),
1791  NULL, //no constructor for X3DRoute
1792  NULL, //no constructor args
1793  X3DRouteArrayProperties,
1794  NULL, //no special has
1795  X3DRouteArrayGetter,
1796  NULL,
1797  'P', 'T',//takes int index in prop, readonly
1798  NULL,
1799 };
1800 
1801 //X3DRoute{
1802 //SFNode sourceNode;
1803 //String sourceField;
1804 //SFNode destinationNode;
1805 //String destinationField;
1806 //}
1807 
1808 FWPropertySpec (X3DRouteProperties)[] = {
1809  {"sourceNode", 0, 'W', 'T'},
1810  {"sourceField", 1, 'S', 'T'},
1811  {"destinationNode", 2, 'W', 'T'},
1812  {"destinationField", 3, 'S', 'T'},
1813  {NULL,0,0,0},
1814 };
1815 int X3DRouteGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1816  union anyVrml *value;
1817  int type, kind;
1818  char *fieldname; // , *stofield; //*sfromfield,
1819  struct X3D_Node *fromNode, *toNode;
1820  int fromIndex, toIndex;
1821  int nr = 1;
1822  {
1823  struct brotoRoute* broute = (struct brotoRoute*)fwn;
1824  fromNode = broute->from.node;
1825  fromIndex = broute->from.ifield;
1826  toNode = broute->to.node;
1827  toIndex = broute->to.ifield;
1828  }
1829  if(!fromNode || !toNode) return 0;
1830 
1831  //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)
1832  switch(index){
1833  case 0: //fromNode
1834  //fwretval->_web3dval.native = (void*)fromNode; //route->routeFromNode;
1835  //((union anyVrml*)fwpars[0]._web3dval.native)->sfnode
1836  fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1837  fwretval->_web3dval.anyvrml->sfnode = fromNode;
1838  fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1839  fwretval->_web3dval.gc = 1;
1840  fwretval->itype = 'W';
1841  break;
1842  case 1: //fromField
1843  //fieldname = findFIELDNAMESfromNodeOffset0(fromNode,fromOffset);
1844  getFieldFromNodeAndIndex(fromNode,fromIndex,&fieldname,&type,&kind,&value);
1845  fwretval->_string = fieldname; //NULL;
1846  fwretval->itype = 'S';
1847  break;
1848  case 2: //toNode
1849  //fwretval->_web3dval.native = (void*)toNode; //route->routeFromNode;
1850  fwretval->_web3dval.anyvrml = malloc(sizeof(union anyVrml));
1851  fwretval->_web3dval.anyvrml->sfnode = toNode;
1852  fwretval->_web3dval.fieldType = FIELDTYPE_SFNode;
1853  fwretval->itype = 'W';
1854  fwretval->_web3dval.gc = 1;
1855  break;
1856  case 3: //toField
1857  //getFieldFromNodeAndIndex(route->tonodes[0].routeToNode,route->tonodes[0].foffset,&fieldname,&type,&kind,&value);
1858  getFieldFromNodeAndIndex(toNode,toIndex,&fieldname,&type,&kind,&value);
1859  fwretval->_string = fieldname;
1860  fwretval->itype = 'S';
1861  break;
1862  default:
1863  nr = 0;
1864  }
1865  return nr;
1866 }
1867 
1868 
1869 FWTYPE X3DRouteType = {
1870  AUXTYPE_X3DRoute,
1871  'P',
1872  "X3DRoute",
1873  0, //sizeof(struct X3DRoute),
1874  NULL, //no constructor for X3DRoute
1875  NULL, //no constructor args
1876  X3DRouteProperties,
1877  NULL, //no special has
1878  X3DRouteGetter,
1879  NULL,
1880  0,0, //takes int index in prop
1881  NULL,
1882 };
1883 
1884 
1885 
1886 int X3DProtoArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1887 
1888  int nr = 0;
1889  //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)
1890  if(index == -1){
1891  int _length;
1892  _length = vectorSize(fwn);
1893  fwretval->_integer = _length;
1894  fwretval->itype = 'I';
1895  nr = 1;
1896  }else if(index > -1 ){
1897  if(index < vectorSize(fwn)){
1898  fwretval->_pointer.native = vector_get(void *, fwn, index); //struct X3D_Proto *
1899  fwretval->_pointer.gc = 1;
1900  fwretval->_pointer.fieldType = AUXTYPE_X3DProto;
1901  fwretval->itype = 'P';
1902  nr = 1;
1903  }
1904  }
1905  return nr;
1906 }
1907 
1908 
1909 FWPropertySpec (X3DProtoArrayProperties)[] = {
1910  {"length", -1, 'I', 'T'},
1911  {NULL,0,0,0},
1912 };
1913 
1914 FWTYPE X3DProtoArrayType = {
1915  AUXTYPE_X3DProtoArray,
1916  'P',
1917  "X3DProtoArray",
1918  0, //sizeof(struct X3DProto),
1919  NULL, //no constructor for X3DProto
1920  NULL, //no constructor args
1921  X3DProtoArrayProperties,
1922  NULL, //no special has
1923  X3DProtoArrayGetter,
1924  NULL,
1925  'P', 'T',//takes int index in prop, readonly
1926  NULL,
1927 };
1928 
1929 FWTYPE X3DExternProtoArrayType = {
1930  AUXTYPE_X3DExternProtoArray,
1931  'P',
1932  "X3DExternProtoArray",
1933  0, //sizeof(struct X3DProto),
1934  NULL, //no constructor for X3DProto
1935  NULL, //no constructor args
1936  X3DProtoArrayProperties,
1937  NULL, //no special has
1938  X3DProtoArrayGetter,
1939  NULL,
1940  'P', 'T',//takes int index in prop, readonly
1941  NULL,
1942 };
1943 
1944 
1945 struct tuplePointerInt {
1946  void *pointer;
1947  int integer;
1948 };
1949 
1950 FWPropertySpec (X3DProtoProperties)[] = {
1951  {"name", 0, 'S', 'T'},
1952  {"fields", 1, 'W', 'T'},
1953  {"isExternProto", 2, 'B', 'T'},
1954  {NULL,0,0,0},
1955 };
1956 int X3DProtoGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1957  int nr = 0;
1958  //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)
1959  switch(index){
1960  case 0: //name
1961  fwretval->_string = X3D_PROTO(fwn)->__typename; //NULL;
1962  fwretval->itype = 'S';
1963  break;
1964  case 1: //fields
1965  fwretval->_web3dval.native = fwn; //we'll get field[i] from the proto later (void*)X3D_PROTO(fwn)->__protoDef; //route->routeFromNode;
1966  fwretval->_web3dval.fieldType = AUXTYPE_X3DFieldDefinitionArray;
1967  fwretval->itype = 'W';
1968  fwretval->_web3dval.gc = 0;
1969  break;
1970  case 2: //isExternProto
1971  fwretval->itype = 'B';
1972  {
1973  unsigned char flag = ciflag_get(X3D_PROTO(fwn)->__protoFlags,3);
1974  if(flag == 1)
1975  fwretval->_boolean = TRUE;
1976  else
1977  fwretval->_boolean = FALSE;
1978  }
1979  default:
1980  nr = 0;
1981  }
1982  return nr;
1983 }
1984 
1985 
1986 FWTYPE X3DProtoType = {
1987  AUXTYPE_X3DProto,
1988  'P',
1989  "X3DProtoDeclaration",
1990  0, //sizeof(struct X3DProto),
1991  NULL, //no constructor for X3DProto
1992  NULL, //no constructor args
1993  X3DProtoProperties,
1994  NULL, //no special has
1995  X3DProtoGetter,
1996  NULL,
1997  0,0, //takes int index in prop
1998  NULL,
1999 };
2000 FWTYPE X3DExternProtoType = {
2001  AUXTYPE_X3DExternProto,
2002  'P',
2003  "X3DExternProtoDeclaration",
2004  0, //sizeof(struct X3DProto),
2005  NULL, //no constructor for X3DProto
2006  NULL, //no constructor args
2007  X3DProtoProperties, //it tests if its extern or not
2008  NULL, //no special has
2009  X3DProtoGetter,
2010  NULL,
2011  0,0, //takes int index in prop
2012  NULL,
2013 };
2014 
2015 int count_fields(struct X3D_Node* node);
2016 int X3DFieldDefinitionArrayGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2017 
2018  int nr = 0;
2019  struct X3D_Node *node = (struct X3D_Node*)fwn;
2020 
2021  //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)
2022  if(index == -1){
2023  int _length = 0;
2024  //I suspect this fieldDefinition stuff is for ProtoDeclares and ExternProtoDeclares only, not builtin or protoInstances or scripts
2025  _length = count_fields(node);
2026  fwretval->_integer = _length;
2027  fwretval->itype = 'I';
2028  nr = 1;
2029  }else if(index > -1 ){
2030  if(index < vectorSize(fwn)){
2031  struct tuplePointerInt *tpi = malloc(sizeof(struct tuplePointerInt));
2032  tpi->pointer = (void*)node;
2033  tpi->integer = index;
2034  fwretval->_pointer.native = tpi; //vector_get(void *, fwn, index); //struct X3D_Proto *
2035  fwretval->_pointer.gc = 1;
2036  fwretval->_pointer.fieldType = AUXTYPE_X3DFieldDefinition;
2037  fwretval->itype = 'P';
2038  nr = 1;
2039  }
2040  }
2041  return nr;
2042 }
2043 
2044 
2045 FWPropertySpec (X3DFieldDefinitionArrayProperties)[] = {
2046  {"length", -1, 'I', 'T'},
2047  {NULL,0,0,0},
2048 };
2049 
2050 FWTYPE X3DFieldDefinitionArrayType = {
2051  AUXTYPE_X3DFieldDefinitionArray,
2052  'P',
2053  "X3DFieldDefinitionArray",
2054  0, //sizeof(struct X3DProto),
2055  NULL, //no constructor for X3DProto
2056  NULL, //no constructor args
2057  X3DFieldDefinitionArrayProperties,
2058  NULL, //no special has
2059  X3DFieldDefinitionArrayGetter,
2060  NULL,
2061  'P', 'T',//takes int index in prop, readonly
2062  NULL,
2063 };
2064 
2065 FWPropertySpec (X3DFieldDefinitionProperties)[] = {
2066  {"name", 0, 'S', 'T'},
2067  {"accessType", 1, 'I', 'T'},
2068  {"dataType", 2, 'I', 'T'},
2069  {NULL,0,0,0},
2070 };
2071 int X3DFieldDefinitionGetter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2072  int ifield, type,kind, konstindex, nr = 0;
2073  struct string_int * si;
2074  union anyVrml *value;
2075  struct X3D_Node* node;
2076  char *fname;
2077  struct tuplePointerInt *tpi = (struct tuplePointerInt*)fwn;
2078  node = tpi->pointer;
2079  ifield = tpi->integer;
2080  //I suspect FieldDefinitions are for ProtoDeclarations only,
2081  // but freewrl Brotos can use the same function for nodes and declares
2082  if(getFieldFromNodeAndIndex(node,ifield,&fname,&type,&kind,&value)){
2083  //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)
2084  switch(index){
2085  case 0: //name
2086  fwretval->_string = fname; //NULL;
2087  fwretval->itype = 'S';
2088  break;
2089  case 1: //accessType
2090  si = lookup_string_int(lookup_X3DConstants,PROTOKEYWORDS[kind],&konstindex);
2091  fwretval->_integer = konstindex; //index into x3dconstants table
2092  fwretval->itype = 'I';
2093  break;
2094  case 2: //dataType
2095  si = lookup_string_int(lookup_X3DConstants,FIELDTYPES[type],&konstindex);
2096  fwretval->_integer = konstindex; //index into x3dconstants table
2097  fwretval->itype = 'I';
2098  break;
2099  default:
2100  nr = 0;
2101  }
2102  }
2103  return nr;
2104 }
2105 
2106 
2107 FWTYPE X3DFieldDefinitionType = {
2108  AUXTYPE_X3DFieldDefinition,
2109  'P',
2110  "X3DFieldDefinition",
2111  0, //sizeof(struct X3DFieldDefinition),
2112  NULL, //no constructor for X3DProto
2113  NULL, //no constructor args
2114  X3DFieldDefinitionProperties,
2115  NULL, //no special has
2116  X3DFieldDefinitionGetter,
2117  NULL,
2118  0,0, //takes int index in prop
2119  NULL,
2120 };
2121 
2122 
2123 
2124 
2125 
2126 
2127 void initVRMLBrowser(FWTYPE** typeArray, int *n){
2128  typeArray[*n] = &X3DRouteType; (*n)++;
2129  typeArray[*n] = &X3DRouteArrayType; (*n)++;
2130  typeArray[*n] = &X3DExecutionContextType; (*n)++;
2131  typeArray[*n] = &ProfileInfoType; (*n)++;
2132  typeArray[*n] = &ProfileInfoArrayType; (*n)++;
2133  typeArray[*n] = &ComponentInfoType; (*n)++;
2134  typeArray[*n] = &ComponentInfoArrayType; (*n)++;
2135  typeArray[*n] = &BrowserType; (*n)++;
2136  typeArray[*n] = &X3DConstantsType; (*n)++;
2137 
2138  typeArray[*n] = &X3DProtoType; (*n)++;
2139  typeArray[*n] = &X3DProtoArrayType; (*n)++;
2140  typeArray[*n] = &X3DExternProtoType; (*n)++;
2141  typeArray[*n] = &X3DExternProtoArrayType; (*n)++;
2142  typeArray[*n] = &X3DFieldDefinitionType; (*n)++;
2143  typeArray[*n] = &X3DFieldDefinitionArrayType; (*n)++;
2144 
2145 }
2146 #endif /* ifdef JAVASCRIPT_DUK */
Definition: FWTYPE.h:64
Definition: FWTYPE.h:112