FreeWRL/FreeX3D  3.0.0
EAIHelpers.c
1 /*
2 
3 
4 Small routines to help with interfacing EAI to Daniel Kraft's parser.
5 
6 */
7 
8 
9 /****************************************************************************
10  This file is part of the FreeWRL/FreeX3D Distribution.
11 
12  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
13 
14  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
15  it under the terms of the GNU Lesser Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  GNU General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
26 ****************************************************************************/
27 
28 
29 
30 #include <config.h>
31 #include <system.h>
32 #include <display.h>
33 #include <internal.h>
34 
35 #include <libFreeWRL.h>
36 
37 #include "../vrml_parser/Structs.h"
38 #include "../main/headers.h"
39 
40 #include "../x3d_parser/Bindable.h"
41 #include "../scenegraph/Collision.h"
42 #include "../scenegraph/quaternion.h"
43 
44 #include "EAIHeaders.h"
45 #include "SensInterps.h"
46 
47 #include "../vrml_parser/Structs.h"
48 #include "../main/headers.h"
49 #include "../vrml_parser/CParseGeneral.h"
50 #include "../scenegraph/Vector.h"
51 #include "../vrml_parser/CFieldDecls.h"
52 #include "../world_script/CScripts.h"
53 #include "../world_script/fieldSet.h"
54 #include "../world_script/fieldGet.h"
55 #include "../vrml_parser/CParseParser.h"
56 #include "../vrml_parser/CParseLexer.h"
57 #include "../vrml_parser/CParse.h"
58 
59 #include "../x3d_parser/X3DParser.h"
60 
61 #include "EAIHelpers.h"
62 
63 
64 /*
65 
66 NOTE - originally, when perl parsing was used, there used to be a perl
67 NodeNumber, and a memory location. Now, there is only a memory location...
68 
69 Interface functions, for PROTO field access. From an email from Daniel:
70 
71 Access fields:
72 size_t protoDefiniton_getFieldCount(protoDef)
73 struct ProtoFieldDecl* protoDefinition_getFieldByNum(protoDef, index)
74 
75 Properties of struct ProtoFieldDecl:
76 indexT protoFieldDecl_getType(fdecl)
77 indexT protoFieldDEcl_getAccessType(fdecl)
78 
79 Get name:
80 indexT protoFieldDecl_getIndexName(fdecl)
81 const char* protoFieldDecl_getStringName(lexer, fdecl)
82 
83 Default value:
84 union anyVrml protoFieldDecl_getDefaultValue(fdecl)
85 this union contains fields for every specific type, see CParseGeneral.h for exact structure.
86 
87 This struct contains both a node and an ofs field.
88 
89 ************************************************************************/
90 
91 /* responses get sent to the connecting program. The outBuffer is the place where
92  these commands are placed */
93 
94 //char *outBuffer = NULL;
95 //int outBufferLen = 0;
96 //static struct Vector *EAINodeIndex = NULL;
97 typedef struct pEAIHelpers{
98  struct Vector *EAINodeIndex;
99 } * ppEAIHelpers;
100 void *EAIHelpers_constructor()
101 {
102  void *v = MALLOCV(sizeof(struct pEAIHelpers));
103  memset(v,0,sizeof(struct pEAIHelpers));
104  return v;
105 }
106 void EAIHelpers_init(struct tEAIHelpers* t){
107  //public
108  t->outBuffer = NULL;
109  t->outBufferLen = 0;
110  //private
111  t->prv = EAIHelpers_constructor();
112  {
113  ppEAIHelpers p = (ppEAIHelpers)t->prv;
114  p->EAINodeIndex = NULL;
115  }
116 }
117 
118 
119 
120 
121 /************************************************************************************************/
122 /* */
123 /* EAI NODE TABLE */
124 /* */
125 /************************************************************************************************/
126 
127 /* store enough stuff in here so that each field can be read/written, no matter whether it is a
128  PROTO, SCRIPT, or regular node. */
129 
130 
131 
133  struct X3D_Node* thisFieldNodePointer; /* ok, if this is a PROTO expansion, points to actual node */
134  int fieldOffset;
135  int datalen;
136  int typeString;
137  int scripttype;
138  char *invokedPROTOValue; /* proto field value on invocation (default, or supplied) */
139 };
140 
142  struct X3D_Node* actualNodePtr;
143  int nodeType; /* EAI_NODETYPE_STANDARD =regular node,
144  EAI_NODETYPE_PROTO = PROTO,
145  EAI_NODETYPE_SCRIPT = script */
146  struct Vector* nodeParams;
147 };
148 
149 
150 
151 
152 /* get an actual memory pointer to field, assumes both node has passed ok check */
153 char *getEAIMemoryPointer (int node, int field) {
154  char *memptr;
155  struct EAINodeIndexStruct *me;
156  struct EAINodeParams *myParam;
157  ppEAIHelpers p = (ppEAIHelpers)gglobal()->EAIHelpers.prv;
158  me = vector_get(struct EAINodeIndexStruct *, p->EAINodeIndex,node);
159  if (me == NULL) {
160  printf ("bad node in getEAIMemoryPointer\n");
161  return NULL;
162  }
163 
164  /* we CAN NOT do this with a script */
165  if (me->nodeType == EAI_NODETYPE_SCRIPT) {
166  ConsoleMessage ("EAI error - getting EAIMemoryPointer on a Script node");
167  return NULL;
168  }
169 
170  myParam = vector_get(struct EAINodeParams *, me->nodeParams, field);
171 
172  if (myParam == NULL) {
173  printf ("bad field in getEAIMemoryPointer\n");
174  return NULL;
175  }
176 
177 
178  /* use the memory address associated with this field, because this may have changed for proto invocations */
179  memptr = (char *)myParam->thisFieldNodePointer;
180  memptr += myParam->fieldOffset;
181  /* printf ("getEAIMemoryPointer, nf %d:%d, node %u offset %d total %u\n",
182  node,field,getEAINodeFromTable(node,field), myParam->fieldOffset, memptr);
183  */
184 
185  return memptr;
186 }
187 
188 /* get the parameters during proto invocation. Might not ever have been ISd */
189 static char * getEAIInvokedValue(int node, int field) {
190  /* make sure we are a PROTO */
191  struct EAINodeIndexStruct *me;
192  struct EAINodeParams *myParam;
193  ppEAIHelpers p = (ppEAIHelpers)gglobal()->EAIHelpers.prv;
194 
195  me = vector_get(struct EAINodeIndexStruct *, p->EAINodeIndex,node);
196  if (me == NULL) {
197  printf ("bad node in getEAIInvokedValue\n");
198  return NULL;
199  }
200 
201  myParam = vector_get(struct EAINodeParams *, me->nodeParams, field);
202 
203  if (myParam == NULL) {
204  printf ("bad field in getEAIInvokedValue\n");
205  return NULL;
206  }
207 
208  if (me->nodeType != EAI_NODETYPE_PROTO) {
209  ConsoleMessage ("getting EAIInvokedValue on a node that is NOT a PROTO");
210  return NULL;
211  }
212 
213  return myParam->invokedPROTOValue;
214 }
215 
216 
217 /* return the actual field offset as defined; change fieldHandle into an actual value */
218 int getEAIActualOffset(int node, int field) {
219  struct EAINodeIndexStruct *me;
220  struct EAINodeParams *myParam;
221  ppEAIHelpers p = (ppEAIHelpers)gglobal()->EAIHelpers.prv;
222 
223  me = vector_get(struct EAINodeIndexStruct *, p->EAINodeIndex,node);
224  if (me == NULL) {
225  printf ("bad node in getEAIActualOffset\n");
226  return 0;
227  }
228 
229  myParam = vector_get(struct EAINodeParams *, me->nodeParams, field);
230 
231  if (myParam == NULL) {
232  printf ("bad field in getEAIActualOffset\n");
233  return 0;
234  }
235 
236  return myParam->fieldOffset;
237 }
238 
239 /* returns node type - see above for definitions */
240 int getEAINodeTypeFromTable(int node) {
241  struct EAINodeIndexStruct *me;
242  ppEAIHelpers p = (ppEAIHelpers)gglobal()->EAIHelpers.prv;
243 
244  me = vector_get(struct EAINodeIndexStruct *, p->EAINodeIndex,node);
245  if (me == NULL) {
246  printf ("bad node in getEAINodeFromTable\n");
247  return 0;
248  }
249  return me->nodeType;
250 }
251 
252 /* return a registered node. If index==0, return NULL */
253 struct X3D_Node *getEAINodeFromTable(int index, int field) {
254  struct EAINodeIndexStruct *me;
255  struct EAINodeParams *myParam;
256  ppEAIHelpers p = (ppEAIHelpers)gglobal()->EAIHelpers.prv;
257 
258  me = vector_get(struct EAINodeIndexStruct *, p->EAINodeIndex,index);
259 
260  if (me==NULL) {
261  printf ("internal EAI error - requesting %d, highest node %d\n",
262  index,vectorSize(p->EAINodeIndex) /* lastNodeRequested */);
263  return NULL;
264  }
265 
266  /* do we want the (possibly) PROTO Definition node, or the node that
267  is tied to the exact field? Only in PROTO expansions will they be different,
268  when possibly an IS'd field is within a sub-node of the PROTO */
269 
270  if (field <0) return me->actualNodePtr;
271 
272  /* go and return the node associated directly with this field */
273  /* printf ("getEAINodeFromTable, asking for field %d of node %d\n",field,index); */
274  myParam = vector_get(struct EAINodeParams *, me->nodeParams, field);
275 
276  if (myParam == NULL) {
277  printf ("bad field in getEAINodeFromTable\n");
278  return NULL;
279  }
280 
281  return myParam->thisFieldNodePointer;
282 }
283 
284 /* return an index to a node table. return value 0 means ERROR!!! */
285 int registerEAINodeForAccess(struct X3D_Node* myn) {
286  int ctr;
287  int mynindex = 0;
288  int eaiverbose;
289  ppEAIHelpers p;
290  ttglobal tg = gglobal();
291  eaiverbose = tg->EAI_C_CommonFunctions.eaiverbose;
292  p = (ppEAIHelpers)tg->EAIHelpers.prv;
293 
294  if (myn == NULL) return -1;
295  if (eaiverbose) printf ("registerEAINodeForAccess - myn %p, type %s\n",myn,stringNodeType(myn->_nodeType));
296 
297  if (p->EAINodeIndex == NULL) {
298  struct EAINodeIndexStruct *newp = MALLOC (struct EAINodeIndexStruct *, sizeof (struct EAINodeIndexStruct));
299 
300  if (eaiverbose) printf ("creating EAINodeIndexVector\n");
301  p->EAINodeIndex = newVector(struct EAINodeIndexStruct*, 512);
302  /* push a dummy one here, as we do not want to return an index of zero */
303  vector_pushBack(struct EAINodeIndexStruct *, p->EAINodeIndex, newp);
304 
305  }
306 
307  /* ok, index zero of the EAINodeIndex is invalid, so we look at 1 to (size) -1 */
308  for (ctr=1; ctr<=vectorSize(p->EAINodeIndex)-1; ctr++) {
309  struct EAINodeIndexStruct *me;
310 
311  me = vector_get(struct EAINodeIndexStruct *, p->EAINodeIndex, ctr);
312  if (me->actualNodePtr == myn) {
313  if (eaiverbose) printf ("registerEAINodeForAccess - already got node\n");
314  mynindex = ctr;
315  break;
316  }
317  }
318 
319  /* did we find this node already? */
320  if (mynindex == 0) {
321  struct EAINodeIndexStruct *newp = MALLOC (struct EAINodeIndexStruct *, sizeof (struct EAINodeIndexStruct));
322 
323  newp->actualNodePtr = myn;
324  newp->nodeParams = NULL;
325  /* save the node type; either this is a EAI_NODETYPE_SCRIPT, EAI_NODETYPE_PROTO, or EAI_NODETYPE_STANDARD */
326  if (myn->_nodeType == NODE_Script) newp->nodeType = EAI_NODETYPE_SCRIPT;
327  //else if ((myn->_nodeType == NODE_Group) & (X3D_GROUP(myn)->FreeWRL__protoDef != INT_ID_UNDEFINED))
328  else if(isProto(myn))
329  newp->nodeType = EAI_NODETYPE_PROTO;
330  else newp->nodeType = EAI_NODETYPE_STANDARD;
331 
332 
333  vector_pushBack(struct EAINodeIndexStruct *, p->EAINodeIndex, newp);
334 
335  mynindex = vectorSize(p->EAINodeIndex) -1;
336 
337  if (eaiverbose) printf ("registerEAINodeForAccess returning index %d nt %s, internal type %d\n",mynindex,
338  stringNodeType(myn->_nodeType),newp->nodeType);
339  }
340  return mynindex;
341 }
342 
343 
344 /***************************************************************************************************/
345 
346 /* this is like EAI_GetNode, but is just for the rootNode of the scene graph */
347 int EAI_GetRootNode(void) {
348  return registerEAINodeForAccess(X3D_NODE(rootNode()));
349 }
350 
351 
352 /* get a node pointer in memory for a node. Return the node pointer, or NULL if it fails */
353 int EAI_GetNode(const char *str) {
354 
355  struct X3D_Node * myNode;
356  int eaiverbose = gglobal()->EAI_C_CommonFunctions.eaiverbose;
357  if (eaiverbose) {
358  printf ("EAI_GetNode - getting %s\n",str);
359  }
360 
361  /* Try to get X3D node name */
362  myNode = X3DParser_getNodeFromName(str);
363 
364  if (myNode == NULL) {
365  /* Try to get VRML node name */
366  myNode = parser_getNodeFromName(str);
367  }
368 
369  if (myNode != NULL)
370  return registerEAINodeForAccess(myNode);
371  return 0;
372 }
373 
374 //saves a vector of registered node addresses in the output parameter parentNodesAdr. The output parameter must be freed by the caller
375 //returns the number of registered nodes or -1 if an error occurred
376 int EAI_GetNodeParents(int cNode, int **parentNodesAdr)
377 {
378  int parentAdr;
379  int i;
380  int parentVectorSize;
381  struct X3D_Node * myNode;
382  struct X3D_Node * parentNode;
383  int* tmp;
384 
385  //get the node
386  myNode = getEAINodeFromTable(cNode, -1);
387 
388  if(!myNode)
389  return -1;
390 
391  parentVectorSize = myNode->_parentVector->n;
392 
393  tmp =(int*) calloc(parentVectorSize,sizeof(int));
394 
395  //cycle along the parent vector
396  for(i=0; i < parentVectorSize; i++)
397  {
398  //get the "i" parent
399  parentNode = vector_get(struct X3D_Node *,myNode->_parentVector,i);
400 
401  //register the "i" parent and get the address registration
402  parentAdr = registerEAINodeForAccess(parentNode);
403 
404  //save the address registration in the int array we passed as output parameter
405  tmp[i] = parentAdr;
406 
407  //if the address registration is "0" an error occurred, we exit returning an error code (-1)
408  if(!parentAdr) {
409  FREE_IF_NZ(tmp);
410  return -1;
411  }
412  }
413 
414  *parentNodesAdr = tmp;
415  //all done, we return the count of found parents
416  return i;
417 }
418 
419 
420 int mapToKEYWORDindex (indexT pkwIndex) {
421  if (pkwIndex == PKW_inputOutput) return KW_inputOutput;
422  if (pkwIndex == PKW_inputOnly) return KW_inputOnly;
423  if (pkwIndex == PKW_outputOnly) return KW_outputOnly;
424  if (pkwIndex == PKW_initializeOnly) return KW_initializeOnly;
425  return 0;
426 }
427 struct ProtoDefinition *getVRMLbrotoDefinition (struct X3D_Proto *me);
428 /* in this proto expansion, just go and get the expanded node/field IF POSSIBLE */
429 static int changeExpandedPROTOtoActualNode(int cNode, struct X3D_Node **np, char **fp, int direction) {
430  struct ProtoDefinition *myProtoDecl;
431  char thisID[2000];
432  int eaiverbose = gglobal()->EAI_C_CommonFunctions.eaiverbose;
433 
434  /* first, is this node a PROTO? We look at the actual table to determine if it is special or not */
435  if (getEAINodeTypeFromTable(cNode) != EAI_NODETYPE_PROTO) {
436  return TRUE;
437  }
438 
439  /* yes, it is a PROTO */
440  if (eaiverbose) {
441  printf ("changeExpanded - looking for field %s in node...\n",*fp);
442  }
443 
444  myProtoDecl = getVRMLbrotoDefinition(X3D_PROTO(*np));
445  if (eaiverbose) {
446  printf ("and, the proto name is %s\n",myProtoDecl->protoName);
447  }
448 
449  /* make up the name of the Metadata field associated with this one */
450  if (strlen(*fp)>1000) return FALSE;
451 
452  sprintf (thisID,"PROTO_%p_%s",myProtoDecl,*fp);
453 
454  if (eaiverbose) printf ("looking for name :%s:\n",thisID);
455 
456  *np = parser_getNodeFromName(thisID);
457  if ((*np) == 0) return FALSE;
458 
459  if (eaiverbose) {
460  printf ("np is %p\n", *np);
461  printf ("and, found node %p type %s\n",*np, stringNodeType((*np)->_nodeType));
462  }
463 
464  /* change the fieldName, depending on the direction */
465  /* see if this is an input or output request from nodes =0, tonodes = 1 */
466  if (direction == 0) *fp = "valueChanged"; else *fp = "setValue";
467 
468  return TRUE;
469 }
470 
471 
472 
473 /* get the type of a node; node must exist in table
474  input:
475  cNode = handle for node pointer into memory - if not valid, this routine returns everything as zeroes
476  fieldString = - eg, "addChildren"
477  accessMethod = "eventIn", "eventOut", "field" or...???
478 
479  returns:
480  cNodePtr = C node pointer;
481  fieldOffset = offset;
482  dataLen = data len;
483  typeString = mapFieldTypeToEAItype (ctype);
484  scripttype = 0 - meaning, not to/from a javascript. (see CRoutes.c for values and more info)
485 */
486 
487 void EAI_GetType (int cNode, char *inputFieldString, char *accessMethod,
488  int *cNodePtr, int *fieldOffset,
489  int *dataLen, int *typeString, int *scripttype, int *accessType) {
490 
491  struct EAINodeIndexStruct *me;
492  struct EAINodeParams *newp;
493  struct X3D_Node* nodePtr = getEAINodeFromTable(cNode,-1);
494  char *fieldString = inputFieldString;
495  int myField;
496  int ctype;
497  int myFieldOffs;
498  char *invokedValPtr = NULL; /* for PROTOs - invocation value */
499  int myScriptType = EAI_NODETYPE_STANDARD;
500  int direction;
501  // struct X3D_Node* protoBaseNode;
502  int isProtoExpansion = FALSE;
503  int eaiverbose;
504  ppEAIHelpers p;
505  ttglobal tg = gglobal();
506  eaiverbose = tg->EAI_C_CommonFunctions.eaiverbose;
507  p = (ppEAIHelpers)tg->EAIHelpers.prv;
508 
509  eaiverbose = gglobal()->EAI_C_CommonFunctions.eaiverbose;
510 
511  /* see if this is an input or output request from nodes =0, tonodes = 1 */
512  direction=0;
513  if (strncmp(accessMethod,"in",strlen("in")) == 0) direction=1;
514  else if (strncmp(accessMethod,"eventIn",strlen("eventIn"))==0) direction=1;
515 
516  /*if (direction==0) {
517  printf ("EAI_GetType, this is a FROM route (%s)\n",accessMethod);
518  } else {
519  printf ("EAI_GetType, this is a TO route (%s)\n",accessMethod);
520  } */
521 
522 
523  if (eaiverbose) {
524  printf ("call to EAI_GetType, cNode %d fieldString :%s: accessMethod %s\n",cNode,fieldString,accessMethod);
525  }
526 
527  /* is this a valid C node? if so, lets just get the info... */
528  if ((cNode == 0) || (cNode > vectorSize(p->EAINodeIndex) /* lastNodeRequested */)) {
529  printf ("THIS IS AN ERROR! CNode is zero!!!\n");
530  *cNodePtr = 0; *fieldOffset = 0; *dataLen = 0; *typeString = 0; *scripttype=0; *accessType=KW_eventIn;
531  return;
532  }
533 
534  if (eaiverbose) {
535  printf ("start of EAI_GetType, this is a valid C node %p\n",nodePtr);
536  printf (" of string type %s\n",stringNodeType(nodePtr->_nodeType));
537  }
538 
539  myFieldOffs = -999;
540 
541  /* is this a field of the actual base type? */
542  /* did not find the field as an ISd field - is this a field of the actual X3D base node?? */
543  /* mimic POSSIBLE_PROTO_EXPANSION(nodePtr,protoBaseNode); */
544 
545 /* unused
546  if (nodePtr == NULL) protoBaseNode = NULL;
547  else {if (X3D_NODE(nodePtr)->_nodeType == NODE_Group) {
548  if (X3D_GROUP(nodePtr)->children.n>0) {
549  protoBaseNode = X3D_GROUP(nodePtr)->children.p[0];
550  } else protoBaseNode = NULL;
551  } else protoBaseNode = nodePtr; };
552 */
553 
554  /* is this a proto expansion? */
555  //if (X3D_NODE(nodePtr)->_nodeType == NODE_Group) {
556  // if (X3D_GROUP(nodePtr)->FreeWRL__protoDef != INT_ID_UNDEFINED) {
557  if(isProto(nodePtr))
558  isProtoExpansion = TRUE;
559  // }
560  //}
561 
562  if (isProtoExpansion) {
563  /* this possibly is an expanded PROTO?, change the nodePtr and fieldString around */
564  if (!changeExpandedPROTOtoActualNode (cNode, &nodePtr, &fieldString,direction)) {
565  ConsoleMessage ("Did NOT find field :%s: in PROTO expansion",fieldString);
566  }
567  } else {
568  if (eaiverbose) printf ("EAI_GetType - no, this is NOT a proto node\n");
569  }
570 
571  if (nodePtr == NULL) {
572  if (isProtoExpansion)
573  ConsoleMessage ("error looking up field :%s: a PROTO Definition\n", fieldString);
574  else
575  ConsoleMessage ("error looking up field :%s: in an unknown node\n", fieldString);
576  return;
577  }
578 
579  if (eaiverbose) {
580  printf ("node here is %p\n",nodePtr);
581  printf ("ok, going to try and find field :%s: in a node of type :%s:\n",fieldString,stringNodeType(nodePtr->_nodeType));
582  }
583 
584  /* try finding it, maybe with a "set_" or "changed" removed */
585  myField = findRoutedFieldInFIELDNAMES(nodePtr,fieldString,direction);
586 
587  if (eaiverbose) printf ("EAI_GetType, for field %s, myField is %d\n",fieldString,myField);
588 
589  /* find offsets, etc */
590  findFieldInOFFSETS(nodePtr->_nodeType, myField, &myFieldOffs, &ctype, accessType);
591 
592  if (eaiverbose) {
593  printf ("EAI_GetType, after changeExpandedPROTOtoActualNode, C node %p\n",nodePtr);
594  printf (" of string type %s\n",stringNodeType(nodePtr->_nodeType));
595  }
596 
597 
598  if (eaiverbose) printf ("EAI_GetType, after findFieldInOFFSETS, have myFieldOffs %u, ctype %d, accessType %d \n",myFieldOffs, ctype, *accessType);
599 
600  /* is this a Script, or just an invalid field?? */
601  if (myFieldOffs <= 0) {
602  int i;
603 
604  /* is this a Script node? */
605  if (nodePtr->_nodeType == NODE_Script) {
606  struct Shader_Script* myScript;
607  struct CRjsnameStruct *JSparamnames = getJSparamnames();
608  struct VRMLParser *globalParser = (struct VRMLParser *)gglobal()->CParse.globalParser;
609  if (eaiverbose)
610  printf ("EAI_GetType, node is a Script node...\n");
611  myScript = X3D_SCRIPT(nodePtr)->__scriptObj;
612  myScriptType = EAI_NODETYPE_SCRIPT;
613 
614  for (i = 0; i != vectorSize(myScript->fields); ++i) {
615  struct ScriptFieldDecl* sfield = vector_get(struct ScriptFieldDecl*, myScript->fields, i);
616 
617  if (eaiverbose)
618  printf (" field %d, name %s type %s (type %s accessType %d (%s), indexName %d, stringType %s)\n",
619  i,
620  fieldDecl_getShaderScriptName(sfield->fieldDecl),
621  stringFieldtypeType(fieldDecl_getType(sfield->fieldDecl)),
622  stringFieldtypeType(fieldDecl_getType(sfield->fieldDecl)),
623  fieldDecl_getAccessType(sfield->fieldDecl),
624  stringPROTOKeywordType(fieldDecl_getAccessType(sfield->fieldDecl)),
625  fieldDecl_getIndexName(sfield->fieldDecl),
626  fieldDecl_getStringName(globalParser->lexer,sfield->fieldDecl)
627  );
628 
629 
630  if (strcmp(fieldString,fieldDecl_getShaderScriptName(sfield->fieldDecl)) == 0) {
631  /* call JSparamIndex to get a unique index for this name - this is used for ALL
632  script access, whether from EAI or not */
633  if(eaiverbose)
634  printf ("found it at index, %d but returning JSparamIndex %d\n",i,
635  fieldDecl_getShaderScriptIndex(sfield->fieldDecl));
636 
637  myFieldOffs = fieldDecl_getShaderScriptIndex(sfield->fieldDecl);
638  /* switch from "PKW" to "KW" types */
639  *accessType = mapToKEYWORDindex(fieldDecl_getAccessType(sfield->fieldDecl));
640  ctype = fieldDecl_getType(sfield->fieldDecl);
641  break;
642  }
643  }
644 
645  } else {
646  if (nodePtr != NULL)
647  printf ("EAI_GetType, warning: field :%s: not not found in node of type :%s:\n",fieldString,stringNodeType(nodePtr->_nodeType));
648  else
649  printf ("EAI_GetType, warning: field :%s: not not found in node with pointer of NULL\n",fieldString);
650  }
651 
652  }
653 
654  /* save these indexes */
655 
656  me = vector_get(struct EAINodeIndexStruct *, p->EAINodeIndex, cNode);
657  if (me->nodeParams == NULL) {
658  struct EAINodeParams *np = MALLOC (struct EAINodeParams *, sizeof (struct EAINodeParams));
659  if (eaiverbose) printf ("creating new field vector for this node\n");
660  me->nodeParams = newVector(struct EAINodeParams*, 4);
661  /* push a dummy one here, as we do not want to return an index of zero */
662  vector_pushBack(struct EAINodeParams *, me->nodeParams, np);
663  }
664 
665  newp = MALLOC (struct EAINodeParams *, sizeof (struct EAINodeParams));
666  newp->fieldOffset = myFieldOffs;
667  newp->datalen = ctype;
668  newp->typeString = mapFieldTypeToEAItype(ctype);
669  newp->scripttype = myScriptType;
670  newp->invokedPROTOValue = invokedValPtr;
671 
672  /* has the node type changed, maybe because of a PROTO expansion? */
673  if (me->actualNodePtr != nodePtr) {
674  /* printf ("iEAI_GetType, node pointer changed, using new node pointer\n"); */
675  newp->thisFieldNodePointer= nodePtr;
676  } else {
677  /* printf ("EAI_GetType, node is same as parent node\n"); */
678  newp->thisFieldNodePointer= me->actualNodePtr;
679  }
680 
681  vector_pushBack(struct EAINodeParams *, me->nodeParams, newp);
682 
683  /*
684  printf ("end of GetType, orig nodeptr %u, now %u\n",me->actualNodePtr, nodePtr);
685  printf ("end of GetType, now, EAI node type %d\n",me->nodeType);
686  */
687 
688  *fieldOffset = vectorSize(me->nodeParams)-1; /* the entry into this field array for this node */
689  *dataLen = (int) newp->datalen; /* data len */
690  *typeString = newp->typeString; /* data type in EAI type */
691  *scripttype =newp->scripttype;
692  *cNodePtr = cNode; /* keep things with indexes */
693 }
694 
695 
696 char *EAI_GetTypeName (unsigned int uretval) {
697  printf ("HELP::EAI_GetTypeName %d\n",uretval);
698  return "unknownType";
699 }
700 
701 
702 int SAI_IntRetCommand (char cmnd, const char *fn) {
703  printf ("HELP::SAI_IntRetCommand, %c, %s\n",cmnd,fn);
704  return 0;
705 }
706 
707 char * SAI_StrRetCommand (char cmnd, const char *fn) {
708  printf ("HELP::SAI_StrRetCommand, %c, %s\n",cmnd,fn);
709  return "iunknownreturn";
710 }
711 
712 /* returns an viewpoint node or NULL if not found */
713 struct X3D_Node *EAI_GetViewpoint(const char *str) {
714  struct X3D_Node * myNode;
715 
716  /* Try to get X3D node name */
717 
718  #ifdef IPHONE
719  myNode = NULL;
720  printf ("X3DParser_getNodeFromName not here yet\n");
721  #else
722  myNode = X3DParser_getNodeFromName(str);
723  #endif
724  if (myNode == NULL) {
725  /* Try to get VRML node name */
726  myNode = parser_getNodeFromName(str);
727  }
728 
729  return myNode;
730 }
731 
732 
733 
734 /* we have a GETVALUE command coming in */
735 void handleEAIGetValue (char command, char *bufptr, int repno) {
736  struct X3D_Node *myNode;
737  int nodeIndex, fieldIndex, length;
738  char ctmp[4000];
739  int retint;
740  struct EAINodeIndexStruct *me;
741  struct EAINodeParams *myParam;
742  int eaiverbose;
743  ppEAIHelpers p;
744  ttglobal tg;
745  UNUSED(retint); // compiler warning mitigation
746 
747  tg = gglobal();
748  eaiverbose = gglobal()->EAI_C_CommonFunctions.eaiverbose;
749  p = (ppEAIHelpers)gglobal()->EAIHelpers.prv;
750 
751  eaiverbose = gglobal()->EAI_C_CommonFunctions.eaiverbose;
752 
753  if (eaiverbose) printf ("GETVALUE %s \n",bufptr);
754 
755  /* format: ptr, offset, type, length (bytes)*/
756  retint=sscanf (bufptr, "%d %d %c %d", &nodeIndex,&fieldIndex,ctmp,&length);
757  myNode = getEAINodeFromTable(nodeIndex, fieldIndex);
758 
759  /* if myNode is NULL, we have an error, baby */
760  if (myNode == NULL) {
761  printf ("handleEAIGetValue - node does not exist!\n");
762  return;
763  }
764  me = vector_get(struct EAINodeIndexStruct *, p->EAINodeIndex, nodeIndex);
765 
766  if (me==NULL) {
767  printf ("handleEAIGetValue - node does not exist in vector!\n");
768  return;
769  }
770 
771  /* printf ("handleEAIGetValue, node %u, type %s\n",myNode, stringNodeType(myNode->_nodeType)); */
772 
773  /* is the pointer a pointer to a PROTO?? If so, then the getType did not find
774  an actual field (an IS'd field??) in a proto expansion for us. We have to
775  go through, as the offset will be the index in the PROTO field for us to get
776  the value for */
777 
778 
779  myParam = vector_get(struct EAINodeParams *, me->nodeParams, fieldIndex);
780 
781  if (myParam == NULL) {
782  printf ("bad field in handleEAIGetValue\n");
783  return;
784  }
785 
786  if (myParam->invokedPROTOValue != NULL) {
787  sprintf (tg->EAIHelpers.outBuffer,"RE\n%f\n%d\n%s",TickTime(),repno,getEAIInvokedValue(nodeIndex,fieldIndex));
788  } else {
789  EAI_Convert_mem_to_ASCII (repno,"RE",mapEAItypeToFieldType(ctmp[0]),getEAIMemoryPointer(nodeIndex,fieldIndex), tg->EAIHelpers.outBuffer);
790  }
791 }
792 
793 
794 /* this is a debugging function */
795 char *eaiPrintCommand (char command) {
796 
797  switch (command) {
798 
799  case GETNODE: return ("GETNODE");
800  case GETEAINODETYPE: return ("GETEAINODETYPE");
801  case SENDCHILD: return ("SENDCHILD");
802  case SENDEVENT: return ("SENDEVENT");
803  case GETVALUE: return ("GETVALUE");
804  case GETFIELDTYPE: return ("GETFIELDTYPE");
805  case REGLISTENER: return ("REGLISTENER");
806  case ADDROUTE: return ("ADDROUTE");
807  case REREADWRL: return ("REREADWRL");
808  case DELETEROUTE: return ("DELETEROUTE");
809  case GETNAME: return ("GETNAME");
810  case GETVERSION: return ("GETVERSION");
811  case GETCURSPEED: return ("GETCURSPEED");
812  case GETFRAMERATE: return ("GETFRAMERATE");
813  case GETURL: return ("GETURL");
814  case REPLACEWORLD: return ("REPLACEWORLD");
815  case LOADURL: return ("LOADURL");
816  case VIEWPOINT: return ("VIEWPOINT");
817  case CREATEVS: return ("CREATEVS");
818  case CREATEVU: return ("CREATEVU");
819  case STOPFREEWRL: return ("STOPFREEWRL");
820  case UNREGLISTENER: return ("UNREGLISTENER");
821  case GETRENDPROP: return ("GETRENDPROP");
822  case GETENCODING: return ("GETENCODING");
823  case CREATENODE: return ("CREATENODE");
824  case CREATEPROTO: return ("CREATEPROTO");
825  case UPDNAMEDNODE: return ("UPDNAMEDNODE");
826  case REMNAMEDNODE: return ("REMNAMEDNODE");
827  case GETPROTODECL: return ("GETPROTODECL");
828  case UPDPROTODECL: return ("UPDPROTODECL");
829  case REMPROTODECL: return ("REMPROTODECL");
830  case GETFIELDDEFS: return ("GETFIELDDEFS");
831  case GETNODEDEFNAME: return ("GETNODEDEFNAME");
832  case GETROUTES: return ("GETROUTES");
833  case GETNODETYPE: return ("GETNODETYPE");
834  default:{} ;
835  }
836  return "unknown command...";
837 }
838 
839 
840 /* append str to the outbuffer, REALLOC if necessary */
841 void outBufferCat (char *str) {
842  int a,b;
843  struct tEAIHelpers* t = &gglobal()->EAIHelpers;
844  a = (int) strlen (t->outBuffer);
845  b = (int) strlen (str);
846 
847  /* should we increase the size here? */
848  if ((a+b+2) >= t->outBufferLen) {
849  t->outBufferLen = a+b+200; /* give it more space, and a bit more, so maybe
850  REALLOC does not need to be called all the time */
851  t->outBuffer = REALLOC(t->outBuffer, t->outBufferLen);
852  }
853  strcat (t->outBuffer, str);
854 }
855 
856 
857 #ifdef SWAMPTEA
858 
859 /* SWAMPTEA specific: get a switch node "whichChoice" pointer */
860 int* getSwitchNodeFromTable(int cNode) {
861  ppEAIHelpers p;
862  ttglobal tg = gglobal();
863  struct EAINodeIndexStruct *me;
864 
865  p = (ppEAIHelpers)gglobal()->EAIHelpers.prv;
866  me = vector_get(struct EAINodeIndexStruct *, p->EAINodeIndex,cNode);
867  return offsetPointer_deref (int *, me->actualNodePtr, offsetof (struct X3D_Switch, whichChoice));
868 }
869 
870 /* SWAMPTEA specific: move a little cone up/down depending on a fraction */
871 void confidenceConeSet(int coneNode, int shown,int found) {
872  ppEAIHelpers p;
873  ttglobal tg = gglobal();
874 
875  struct X3D_Transform *trans;
876  struct EAINodeIndexStruct *me;
877  struct SFVec3f *translation;
878 
879 #define CONE_MOVE_HEIGHT 14.0
880 
881  p = (ppEAIHelpers)gglobal()->EAIHelpers.prv;
882  // bounds check
883  if (coneNode <=0) return;
884 
885  me = vector_get(struct EAINodeIndexStruct *, p->EAINodeIndex,coneNode);
886  trans = X3D_TRANSFORM(me->actualNodePtr);
887 
888  if (trans->_nodeType != NODE_Transform) {
889  ConsoleMessage ("confidence - not a Transform");
890  return;
891  }
892 
893  if (found==0) {
894  ConsoleMessage ("confidence - nothing found, nothing to do");
895  return;
896  }
897 
898  // find the translation field of this Transform
899  translation = offsetPointer_deref (struct SFVec3f*, trans, offsetof (struct X3D_Transform, translation));
900  // move it in the "Y" axis
901  translation->c[1] = (float)shown/(float)found*CONE_MOVE_HEIGHT - (CONE_MOVE_HEIGHT/2);
902 
903  // tell the system to recalculate it all
904  trans->_change ++;
905 }
906 
907 
908 /* SWAMPTEA specific: add/delete this texture to our multitexture */
909 void textureToMultiTexture(int texNode, int MultiTexture, int add) {
910  ppEAIHelpers p;
911  ttglobal tg = gglobal();
912 
913  char line[200];
914  struct X3D_Node *MultiTexNode;
915  struct X3D_Node *myTex;
916  int addFlag;
917  struct EAINodeIndexStruct *me;
918 
919  p = (ppEAIHelpers)gglobal()->EAIHelpers.prv;
920 
921  if (add) addFlag=1; else addFlag=2;
922 
923 
924 
925  sprintf (line,"textureToMultiTexture, texnode %d multitexture %d add %d",texNode,MultiTexture,add);
926  ConsoleMessage(line);
927 
928  // bounds checking
929  if ((texNode <=0) || (MultiTexture<=0)) {
930  sprintf (line,"textureToMultiTexture, can not do: texnode %d multitexture %d add %d",texNode,MultiTexture,add);
931  ConsoleMessage (line);
932  return;
933  }
934 
935  me = vector_get(struct EAINodeIndexStruct *, p->EAINodeIndex,MultiTexture);
936  MultiTexNode = me->actualNodePtr;
937  me = vector_get(struct EAINodeIndexStruct *, p->EAINodeIndex,texNode);
938  myTex = me->actualNodePtr;
939 
940  sprintf (line,"textureToMultitexture, adding a :%s: to a :%s:",stringNodeType(myTex->_nodeType),
941  stringNodeType(MultiTexNode->_nodeType));
942  ConsoleMessage(line);
943 
944  if ((myTex->_nodeType!=NODE_PixelTexture) && (MultiTexNode->_nodeType != NODE_MultiTexture)) {
945  ConsoleMessage ("textureToMultitexture, wrong type(s)");
946  return;
947  }
948 
949  /* is it there already? */
950  if (add) {
951  int count;
952  struct Multi_Node *texture = offsetPointer_deref(struct Multi_Node *, MultiTexNode, offsetof (struct X3D_MultiTexture, texture));
953  for (count=0; count<texture->n; count++) {
954  if (texture->p[count] == myTex) return;
955  }
956 
957  }
958 
959  AddRemoveChildren (X3D_NODE(MultiTexNode),
960  offsetPointer_deref(void *, MultiTexNode, offsetof (struct X3D_MultiTexture, texture)),
961  (struct X3D_Node * *)&myTex,1,addFlag,__FILE__,__LINE__);
962 }
963 
964 #endif //SWAMPTEA
Definition: Vector.h:36