FreeWRL/FreeX3D  3.0.0
EAI_C_Advise.c
1 #ifndef WIN32
2 #include "config.h"
3 #include "system.h"
4 #endif
5 #include "EAI_C.h"
6 #define LOCK_ADVISE_TABLE printf ("locking advise table\n");
7 #define UNLOCK_ADVISE_TABLE printf ("unlocking advise table\n");
8 
9 #define UNUSED(v) ((void) v) // compiler mitigation
10 
12  int FreeWRL_RegisterNumber;
13  int type;
14  int datasize;
15  void *dataArea;
16  //void (*functionHandler)(X3DNode*, double);
17  void *arg;
18  void (*functionHandler)(X3DNode*, double, void *arg);
19 };
20 
21 struct EAI_ListenerStruct *EAI_ListenerTable = 0;
22 int MaxEAIListeners = 0;
23 int AdviseIndex = -1;
24 
25 //int X3DAdvise (X3DEventOut *node, void *fn) {
26 int X3DAdvise (X3DEventOut *node, void *fn)
27 {
28  return X3DAdviseArg(node, fn, NULL);
29 }
30 
31 int X3DAdviseArg (X3DEventOut *node, void *fn, void *arg) {
32 
33 
34  AdviseIndex ++;
35  /* Browser.RegisterListener (f, userData, nodeptr,offset,datatype , datasize, EventType); */
36 
37  /* save the data, and the node, so that if this listener is called, we can call
38  the function and pass it the correct X3DNode */
39 
40  /*printf ("in X3DAdvise, we have queryno %d nodeptr %d offset %d datatype %d datasize %d field %s\n",
41  AdviseIndex, node->nodeptr, node->offset, node->datatype, node->datasize, node->field); */
42 
43 /*
44  EAIoutSender.send ("" + queryno + "G " + nodeptr + " " + offset + " " + datatype +
45  " " + datasize + "\n");
46 */
47 
48 
49 
50 
51  if (AdviseIndex >= MaxEAIListeners) {
52  /* oooh! not enough room at the table */
53  LOCK_ADVISE_TABLE
54  MaxEAIListeners += 100; /* arbitrary number */
55  EAI_ListenerTable = (struct EAI_ListenerStruct*)realloc (EAI_ListenerTable, sizeof(*EAI_ListenerTable) * MaxEAIListeners);
56  UNLOCK_ADVISE_TABLE
57  }
58 
59  /* record this one... */
60  EAI_ListenerTable[AdviseIndex].type = node->datatype;
61  EAI_ListenerTable[AdviseIndex].FreeWRL_RegisterNumber = _X3D_queryno;
62  EAI_ListenerTable[AdviseIndex].datasize = node->datasize;
63  if (node->datasize>0)
64  EAI_ListenerTable[AdviseIndex].dataArea = malloc (sizeof(int) + node->datasize);
65  else
66  EAI_ListenerTable[AdviseIndex].dataArea = malloc (sizeof(int)); //NULL;
67  EAI_ListenerTable[AdviseIndex].functionHandler = fn;
68  EAI_ListenerTable[AdviseIndex].arg = arg;
69 
70  /* and, tell FreeWRL about this one */
71  _RegisterListener (node,AdviseIndex);
72 
73  //printf ("X3DAdvise, index %d\n",AdviseIndex);
74  return AdviseIndex;
75 }
76 
77 
78 void _handleFreeWRLcallback (char *line) {
79  double evTime;
80  int evIndex;
81  int count;
82  size_t wc;
83 
84  UNUSED(wc);
85 
86  //printf ("handleFreeWRLcallback - line :%s:\n",line);
87  /* something funny at the beginning of time? */
88  if (AdviseIndex < 0) return;
89 
90  if (strstr(line,"EV_EOT") == NULL) {
91  printf ("handle_callback - no eot in string %s\n",line);
92  } else {
93  /* skip past the "EV" and get to the event time */
94  while ((!isdigit(*line)) && (*line != '\0')) line++;
95  sscanf (line, "%lf",&evTime);
96 
97  /* get the event number */
98  while (!iscntrl(*line)) line++; while (iscntrl(*line)) line++;
99  sscanf (line,"%d",&evIndex);
100 
101  /* get to the data */
102  while (!iscntrl(*line)) line++; while (iscntrl(*line)) line++;
103 
104  #ifdef VERBOSE
105  printf ("event time %lf index %d data :%s:\n",evTime, evIndex, line);
106  #endif
107 
108  /* does this advise callback exist? */
109  count=0;
110  while (EAI_ListenerTable[count].FreeWRL_RegisterNumber != evIndex) {
111  //printf ("compared %d to %d\n",EAI_ListenerTable[count].FreeWRL_RegisterNumber, evIndex);
112  count ++;
113  if (count > AdviseIndex) {
114  printf ("hmmm - Advise retval %d >= max %d\n",count,AdviseIndex);
115  return;
116  }
117  }
118 
119  /* ok, we have the Advise Index. */
120  if (EAI_ListenerTable[count].datasize != 0) {
121  char *da = EAI_ListenerTable[count].dataArea;
122  Parser_scanStringValueToMem_C(&da[sizeof(int)], //0,
123  EAI_ListenerTable[count].type, line, 0);
124 
125  }
126  if (EAI_ListenerTable[count].functionHandler != 0) {
127  X3DNode *pnode;
128  pnode = (X3DNode *)EAI_ListenerTable[count].dataArea;
129  pnode->type = EAI_ListenerTable[count].type;
130  //EAI_ListenerTable[count].functionHandler(pnode,evTime);
131  EAI_ListenerTable[count].functionHandler(pnode,evTime,EAI_ListenerTable[count].arg);
132  } else {
133  if (_X3D_FreeWRL_Swig_FD) {
134 #ifdef WIN32
135  send(_X3D_FreeWRL_Swig_FD, (const char *) EAI_ListenerTable[count].FreeWRL_RegisterNumber, sizeof(EAI_ListenerTable[count].FreeWRL_RegisterNumber),0);
136  send(_X3D_FreeWRL_Swig_FD, (const char *) EAI_ListenerTable[count].dataArea, sizeof(EAI_ListenerTable[count].dataArea),0);
137 #else
138  {
139  // JAS - Apr 2017.
140  // issue with casting an int to a const void*...
141  // lets try this:
142  void *tmp = NULL;
143  memcpy(tmp,&(EAI_ListenerTable[count].FreeWRL_RegisterNumber),
144  sizeof (int));
145 
146  wc = write(_X3D_FreeWRL_Swig_FD,
147  (const void *)/* EAI_ListenerTable[count].FreeWRL_RegisterNumber, */
148  tmp,
149  sizeof(EAI_ListenerTable[count].FreeWRL_RegisterNumber));
150  }
151 
152 
153  wc = write(_X3D_FreeWRL_Swig_FD,
154  EAI_ListenerTable[count].dataArea,
155  sizeof(EAI_ListenerTable[count].dataArea));
156 #endif
157  } else {
158  printf("no socket connected for callbacks!");
159  }
160  }
161  }
162 }