FreeWRL / FreeX3D 4.3.0
EAIHelpers.c
1/*
2
3
4Small 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
66NOTE - originally, when perl parsing was used, there used to be a perl
67NodeNumber, and a memory location. Now, there is only a memory location...
68
69Interface functions, for PROTO field access. From an email from Daniel:
70
71Access fields:
72size_t protoDefiniton_getFieldCount(protoDef)
73struct ProtoFieldDecl* protoDefinition_getFieldByNum(protoDef, index)
74
75Properties of struct ProtoFieldDecl:
76indexT protoFieldDecl_getType(fdecl)
77indexT protoFieldDEcl_getAccessType(fdecl)
78
79Get name:
80indexT protoFieldDecl_getIndexName(fdecl)
81const char* protoFieldDecl_getStringName(lexer, fdecl)
82
83Default value:
84union anyVrml protoFieldDecl_getDefaultValue(fdecl)
85this union contains fields for every specific type, see CParseGeneral.h for exact structure.
86
87This 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;
97typedef struct pEAIHelpers{
98 struct Vector *EAINodeIndex;
99} * ppEAIHelpers;
100void *EAIHelpers_constructor()
101{
102 void *v = MALLOCV(sizeof(struct pEAIHelpers));
103 memset(v,0,sizeof(struct pEAIHelpers));
104 return v;
105}
106void 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 */
153char *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 */
189static 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 */
218int 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 */
240int 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 */
253struct 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!!! */
285int 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 */
347int 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 */
353int 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
376int 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
420int 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}
427struct ProtoDefinition *getVRMLbrotoDefinition (struct X3D_Proto *me);
428/* in this proto expansion, just go and get the expanded node/field IF POSSIBLE */
429static 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
487void 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
696char *EAI_GetTypeName (unsigned int uretval) {
697 printf ("HELP::EAI_GetTypeName %d\n",uretval);
698 return "unknownType";
699}
700
701
702int SAI_IntRetCommand (char cmnd, const char *fn) {
703 printf ("HELP::SAI_IntRetCommand, %c, %s\n",cmnd,fn);
704 return 0;
705}
706
707char * 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 */
713struct 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 */
735void 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 */
795char *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 */
841void 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 */
860int* 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 */
871void 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 */
909void 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