FreeWRL / FreeX3D 4.3.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
21struct EAI_ListenerStruct *EAI_ListenerTable = 0;
22int MaxEAIListeners = 0;
23int AdviseIndex = -1;
24
25//int X3DAdvise (X3DEventOut *node, void *fn) {
26int X3DAdvise (X3DEventOut *node, void *fn)
27{
28 return X3DAdviseArg(node, fn, NULL);
29}
30
31int 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
78void _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++;
99 while (iscntrl(*line)) line++;
100 sscanf (line,"%d",&evIndex);
101
102 /* get to the data */
103 while (!iscntrl(*line)) line++;
104 while (iscntrl(*line)) line++;
105
106 #ifdef VERBOSE
107 printf ("event time %lf index %d data :%s:\n",evTime, evIndex, line);
108 #endif
109
110 /* does this advise callback exist? */
111 count=0;
112 while (EAI_ListenerTable[count].FreeWRL_RegisterNumber != evIndex) {
113 //printf ("compared %d to %d\n",EAI_ListenerTable[count].FreeWRL_RegisterNumber, evIndex);
114 count ++;
115 if (count > AdviseIndex) {
116 printf ("hmmm - Advise retval %d >= max %d\n",count,AdviseIndex);
117 return;
118 }
119 }
120
121 /* ok, we have the Advise Index. */
122 if (EAI_ListenerTable[count].datasize != 0) {
123 char *da = EAI_ListenerTable[count].dataArea;
124 Parser_scanStringValueToMem_C(&da[sizeof(int)], //0,
125 EAI_ListenerTable[count].type, line, 0);
126
127 }
128 if (EAI_ListenerTable[count].functionHandler != 0) {
129 X3DNode *pnode;
130 pnode = (X3DNode *)EAI_ListenerTable[count].dataArea;
131 pnode->type = EAI_ListenerTable[count].type;
132 //EAI_ListenerTable[count].functionHandler(pnode,evTime);
133 EAI_ListenerTable[count].functionHandler(pnode,evTime,EAI_ListenerTable[count].arg);
134 } else {
135 if (_X3D_FreeWRL_Swig_FD) {
136#ifdef WIN32
137 send(_X3D_FreeWRL_Swig_FD, (const char *) EAI_ListenerTable[count].FreeWRL_RegisterNumber, sizeof(EAI_ListenerTable[count].FreeWRL_RegisterNumber),0);
138 send(_X3D_FreeWRL_Swig_FD, (const char *) EAI_ListenerTable[count].dataArea, sizeof(EAI_ListenerTable[count].dataArea),0);
139#else
140 {
141 // JAS - Apr 2017.
142 // issue with casting an int to a const void*...
143 // lets try this:
144 void *tmp = NULL;
145 memcpy(tmp,&(EAI_ListenerTable[count].FreeWRL_RegisterNumber),
146 sizeof (int));
147
148 wc = write(_X3D_FreeWRL_Swig_FD,
149 (const void *)/* EAI_ListenerTable[count].FreeWRL_RegisterNumber, */
150 tmp,
151 sizeof(EAI_ListenerTable[count].FreeWRL_RegisterNumber));
152 }
153
154
155 wc = write(_X3D_FreeWRL_Swig_FD,
156 EAI_ListenerTable[count].dataArea,
157 sizeof(EAI_ListenerTable[count].dataArea));
158#endif
159 } else {
160 printf("no socket connected for callbacks!");
161 }
162 }
163 }
164}