fiore@3
|
1 #include "CollectionsManager.h"
|
fiore@3
|
2
|
fiore@3
|
3 void CollectionsManager::init(void){
|
fiore@3
|
4 /**************** init jni variables **********************/
|
fiore@3
|
5
|
fiore@3
|
6 // --- classes ---
|
fiore@3
|
7 // get the java haptics class
|
fiore@3
|
8 hapticClass = env->GetObjectClass(*haptics);
|
fiore@3
|
9 if(hapticClass == NULL){
|
fiore@3
|
10 stopExecution("Could not find the Haptics class");
|
fiore@3
|
11 }
|
fiore@3
|
12
|
fiore@3
|
13 bitsetClass = env->FindClass("Ljava/util/BitSet;");
|
fiore@3
|
14 if(bitsetClass == NULL)
|
fiore@3
|
15 stopExecution("failed to find bitset class");
|
fiore@3
|
16
|
fiore@3
|
17 //get the node list class
|
fiore@3
|
18 listClass = env->FindClass("Ljava/util/ArrayList;");
|
fiore@3
|
19 if(listClass == NULL)
|
fiore@3
|
20 stopExecution("failed to find list class");
|
fiore@3
|
21
|
fiore@3
|
22 // get the Node class to call the get method on the node list
|
fiore@3
|
23 hapticNodeClass = env->FindClass("Luk/ac/qmul/eecs/ccmi/haptics/Node;");
|
fiore@3
|
24 if(hapticNodeClass == NULL){
|
fiore@3
|
25 stopExecution("Could not find the Node class");
|
fiore@3
|
26 }
|
fiore@3
|
27
|
fiore@3
|
28 // get the Edge class to call the get method on the edge list
|
fiore@3
|
29 hapticEdgeClass = env->FindClass("Luk/ac/qmul/eecs/ccmi/haptics/Edge;");
|
fiore@3
|
30 if(hapticEdgeClass == NULL){
|
fiore@3
|
31 stopExecution("Could not find the Edge class");
|
fiore@3
|
32 }
|
fiore@3
|
33 // --- methods ---
|
fiore@3
|
34 // "get" method id
|
fiore@3
|
35 getMethodId = env->GetMethodID(listClass, "get", "(I)Ljava/lang/Object;");
|
fiore@3
|
36 if(getMethodId == NULL)
|
fiore@3
|
37 stopExecution("Could not retrieve the get method id");
|
fiore@3
|
38
|
fiore@3
|
39 //size method id
|
fiore@3
|
40 sizeMethodId = env->GetMethodID(listClass, "size", "()I");
|
fiore@3
|
41 if(sizeMethodId == NULL)
|
fiore@3
|
42 stopExecution("failed to get size method id");
|
fiore@3
|
43
|
fiore@3
|
44 //get method of the BitSet class
|
fiore@3
|
45 getBitMethodId = env->GetMethodID(bitsetClass, "get","(I)Z");
|
fiore@3
|
46 if(getBitMethodId == NULL)
|
fiore@3
|
47 stopExecution("failed to get the get method id of the BitSet class");
|
fiore@3
|
48
|
fiore@3
|
49 getNodeFromIDMethodId = env->GetMethodID(hapticClass,"getNodeFromID","(I)Luk/ac/qmul/eecs/ccmi/haptics/Node;");
|
fiore@3
|
50 if(getNodeFromIDMethodId == NULL){
|
fiore@3
|
51 stopExecution("failed to get getNodeFromID of the Haptics class");
|
fiore@3
|
52 }
|
fiore@3
|
53
|
fiore@3
|
54 getEdgeFromIDMethodId = env->GetMethodID(hapticClass,"getEdgeFromID","(I)Luk/ac/qmul/eecs/ccmi/haptics/Edge;");
|
fiore@3
|
55 if(getEdgeFromIDMethodId == NULL){
|
fiore@3
|
56 stopExecution("failed to get getEdgeFromID of the Haptics class");
|
fiore@3
|
57 }
|
fiore@3
|
58
|
fiore@3
|
59 // -- field id's --
|
fiore@3
|
60 //retrieve edgeList field id
|
fiore@3
|
61 edgeListfieldId = env->GetFieldID(hapticClass,"currentEdges", "Ljava/util/ArrayList;");
|
fiore@3
|
62 if(edgeListfieldId == NULL){
|
fiore@3
|
63 stopExecution("failed to find the edge list field id");
|
fiore@3
|
64 }
|
fiore@3
|
65
|
fiore@3
|
66 //retrieve nodeList field id
|
fiore@3
|
67 nodeListfieldId = env->GetFieldID(hapticClass,"currentNodes", "Ljava/util/ArrayList;");
|
fiore@3
|
68 if(nodeListfieldId == NULL){
|
fiore@3
|
69 stopExecution("failed to find the node list field id");
|
fiore@3
|
70 }
|
fiore@3
|
71
|
fiore@3
|
72 // Node fields id's
|
fiore@3
|
73 xFieldId = env->GetFieldID(hapticNodeClass,"x","D");
|
fiore@3
|
74 if(xFieldId == NULL)
|
fiore@3
|
75 stopExecution("Could not find the x field ID");
|
fiore@3
|
76
|
fiore@3
|
77
|
fiore@3
|
78 yFieldId = env->GetFieldID(hapticNodeClass,"y","D");
|
fiore@3
|
79 if(yFieldId == NULL)
|
fiore@3
|
80 stopExecution("Could not find the y field ID");
|
fiore@3
|
81
|
fiore@3
|
82 nodeHapticIdFieldId = env->GetFieldID(hapticNodeClass, "hapticId", "I");
|
fiore@3
|
83 if(nodeHapticIdFieldId == NULL)
|
fiore@3
|
84 stopExecution("Could not find the node hapticId field ID");
|
fiore@3
|
85
|
fiore@3
|
86 nodeDiagramIdFieldId = env->GetFieldID(hapticNodeClass, "diagramId", "I");
|
fiore@3
|
87 if(nodeDiagramIdFieldId == NULL)
|
fiore@3
|
88 stopExecution("Could not find the node diagramId field ID");
|
fiore@3
|
89
|
fiore@3
|
90 // Edge field id's
|
fiore@3
|
91 // edge.hapticId
|
fiore@3
|
92 edgeHapticIdFieldId = env->GetFieldID(hapticEdgeClass, "hapticId", "I");
|
fiore@3
|
93 if(edgeHapticIdFieldId == NULL)
|
fiore@3
|
94 stopExecution("Could not find the edge hapticId field ID");
|
fiore@3
|
95
|
fiore@3
|
96 edgeDiagramIdFieldId = env->GetFieldID(hapticEdgeClass, "diagramId", "I");
|
fiore@3
|
97 if(edgeDiagramIdFieldId == NULL)
|
fiore@3
|
98 stopExecution("Could not find the edge diagramId field ID");
|
fiore@3
|
99
|
fiore@3
|
100 // stipplePattern
|
fiore@3
|
101 stipplePatternfieldId = env->GetFieldID(hapticEdgeClass, "stipplePattern", "I");
|
fiore@3
|
102 if(stipplePatternfieldId == NULL){
|
fiore@3
|
103 stopExecution("Could not find the stipplePattern field ID");
|
fiore@3
|
104 }
|
fiore@3
|
105
|
fiore@3
|
106 edgeSizefieldId = env->GetFieldID(hapticEdgeClass, "size", "I");
|
fiore@3
|
107 if(edgeSizefieldId == NULL)
|
fiore@3
|
108 stopExecution("Could not find edge size field ID");
|
fiore@3
|
109
|
fiore@3
|
110 edgeXsFieldId = env->GetFieldID(hapticEdgeClass,"xs", "[D");
|
fiore@3
|
111 if(edgeXsFieldId == NULL)
|
fiore@3
|
112 stopExecution("Could not find edge xs field ID");
|
fiore@3
|
113
|
fiore@3
|
114 edgeYsFieldId = env->GetFieldID(hapticEdgeClass,"ys", "[D");
|
fiore@3
|
115 if(edgeYsFieldId == NULL)
|
fiore@3
|
116 stopExecution("Could not find edge ys field ID");
|
fiore@3
|
117
|
fiore@3
|
118 edgeAdjMatrixFieldId = env->GetFieldID(hapticEdgeClass,"adjMatrix", "[Ljava/util/BitSet;");
|
fiore@3
|
119 if(edgeAdjMatrixFieldId == NULL)
|
fiore@3
|
120 stopExecution("Could not find edge adjMatrix field ID");
|
fiore@3
|
121
|
fiore@3
|
122 attractPointXFieldId = env->GetFieldID(hapticEdgeClass, "attractPointX", "D");
|
fiore@3
|
123 if(attractPointXFieldId == NULL)
|
fiore@3
|
124 stopExecution("Could not find the edge attractPointX field ID");
|
fiore@3
|
125
|
fiore@3
|
126 attractPointYFieldId = env->GetFieldID(hapticEdgeClass, "attractPointY", "D");
|
fiore@3
|
127 if(attractPointYFieldId == NULL)
|
fiore@3
|
128 stopExecution("Could not find the edge attractPointY field ID");
|
fiore@3
|
129
|
fiore@3
|
130 edgeNodeStartFieldId = env->GetFieldID(hapticEdgeClass, "nodeStart", "I");
|
fiore@3
|
131 if(edgeNodeStartFieldId == NULL)
|
fiore@3
|
132 stopExecution("Could not find the edge nodeStart field ID");
|
fiore@3
|
133 }
|
fiore@3
|
134
|
fiore@3
|
135 const jint CollectionsManager::getNodesNum() {
|
fiore@3
|
136 /* to read the node list field into the nodeList variable each time we get the size
|
fiore@3
|
137 * is needed as, when the tab is switched the nodeList variables still points to the
|
fiore@3
|
138 * previuos tab's node list. We do it only here and not in getNodeData because
|
fiore@3
|
139 * getNodesData follows this call before releasing the monitor, therefore
|
fiore@3
|
140 * data integrity is granted.
|
fiore@3
|
141 */
|
fiore@3
|
142 env->DeleteLocalRef(nodeList);
|
fiore@3
|
143 nodeList = env->GetObjectField(*haptics, nodeListfieldId);
|
fiore@3
|
144 if(nodeList == NULL){
|
fiore@3
|
145 stopExecution("could not get the node list field of Haptic Class");
|
fiore@3
|
146 }
|
fiore@3
|
147
|
fiore@3
|
148 jint size = env->CallIntMethod( nodeList, sizeMethodId);
|
fiore@3
|
149 checkExceptions(env,"Could not call ArrayList<Node>.size()");
|
fiore@3
|
150 return size;
|
fiore@3
|
151 }
|
fiore@3
|
152
|
fiore@3
|
153 const jint CollectionsManager::getEdgesNum(){
|
fiore@3
|
154 env->DeleteLocalRef(edgeList);
|
fiore@3
|
155 edgeList = env->GetObjectField(*haptics, edgeListfieldId);
|
fiore@3
|
156 if(edgeList == NULL){
|
fiore@3
|
157 stopExecution("could not get the edge list field of Haptic Class");
|
fiore@3
|
158 }
|
fiore@3
|
159
|
fiore@3
|
160 jint size = env->CallIntMethod( edgeList, sizeMethodId);
|
fiore@3
|
161 checkExceptions(env, "Could not call ArrayList<Edge>.size()");
|
fiore@3
|
162 return size;
|
fiore@3
|
163 }
|
fiore@3
|
164
|
fiore@3
|
165 CollectionsManager::NodeData & CollectionsManager::getNodeData(const int i){
|
fiore@3
|
166 // get the i-th node
|
fiore@3
|
167 jobject currentNode = env->CallObjectMethod(nodeList,getMethodId,i);
|
fiore@3
|
168 checkExceptions(env,"Could not call ArrayList<Node>.size()");
|
fiore@3
|
169 fillupNodeData(nd,currentNode);
|
fiore@3
|
170 env->DeleteLocalRef(currentNode);
|
fiore@3
|
171 return nd;
|
fiore@3
|
172 }
|
fiore@3
|
173
|
fiore@3
|
174 CollectionsManager::EdgeData & CollectionsManager::getEdgeData(const int i){
|
fiore@3
|
175 /* first we look for the i-th edge in the Haptics java class. Once we get it,
|
fiore@3
|
176 * we need all the coordinates of the node this edge is connecting, so that we
|
fiore@3
|
177 * can draw it. The edge mantains a list of references to such nodes.
|
fiore@3
|
178 */
|
fiore@3
|
179
|
fiore@3
|
180 // get the i-th edge
|
fiore@3
|
181 jobject currentEdge = env->CallObjectMethod(edgeList,getMethodId,i);
|
fiore@3
|
182 checkExceptions(env, "Could not call ArrayList<Edge>.get(int) in the haptics edges");
|
fiore@3
|
183 if(currentEdge == NULL)
|
fiore@3
|
184 stopExecution("Could not find get current Edge");
|
fiore@3
|
185 jint size = env->GetIntField(currentEdge, edgeSizefieldId);
|
fiore@3
|
186 ed.setSize(size);
|
fiore@3
|
187 fillupEdgeData(ed,currentEdge);
|
fiore@3
|
188 env->DeleteLocalRef(currentEdge);
|
fiore@3
|
189 return ed;
|
fiore@3
|
190 }
|
fiore@3
|
191
|
fiore@3
|
192 bool CollectionsManager::isNode(const jint id) const{
|
fiore@3
|
193 if(env->MonitorEnter(*haptics) != JNI_OK){
|
fiore@3
|
194 throw(NULL);
|
fiore@3
|
195 }
|
fiore@3
|
196 jobject currentNode = env->CallObjectMethod(*haptics,getNodeFromIDMethodId,id);
|
fiore@3
|
197 checkExceptions(env, "Could not call Haptics.getNodeFromIDMethodId in CollectionsManager::isNode");
|
fiore@3
|
198 bool retVal = (currentNode != NULL);
|
fiore@3
|
199 env->DeleteLocalRef(currentNode);
|
fiore@3
|
200 if(env->MonitorExit(*haptics) != JNI_OK){
|
fiore@3
|
201 throw(NULL);
|
fiore@3
|
202 }
|
fiore@3
|
203 return retVal;
|
fiore@3
|
204 }
|
fiore@3
|
205
|
fiore@3
|
206 CollectionsManager::NodeData & CollectionsManager::getNodeDataFromID(const jint id){
|
fiore@3
|
207 if(env->MonitorEnter(*haptics) != JNI_OK){
|
fiore@3
|
208 throw(NULL);
|
fiore@3
|
209 }
|
fiore@3
|
210 jobject currentNode = env->CallObjectMethod(*haptics,getNodeFromIDMethodId,id);
|
fiore@3
|
211 checkExceptions(env, "Could not call Haptics.getNodeFromIDMethodId in CollectionsManager::getNodeDataFromID");
|
fiore@3
|
212 if(currentNode == NULL){
|
fiore@3
|
213 env->DeleteLocalRef(currentNode);
|
fiore@3
|
214 throw(NULL);
|
fiore@3
|
215 }
|
fiore@3
|
216 fillupNodeData(nd,currentNode);
|
fiore@3
|
217 env->DeleteLocalRef(currentNode);
|
fiore@3
|
218 if(env->MonitorExit(*haptics) != JNI_OK){
|
fiore@3
|
219 throw(NULL);
|
fiore@3
|
220 }
|
fiore@3
|
221 return nd;
|
fiore@3
|
222 }
|
fiore@3
|
223
|
fiore@3
|
224 bool CollectionsManager::isEdge(const jint id) const{
|
fiore@3
|
225 if(env->MonitorEnter(*haptics) != JNI_OK){
|
fiore@3
|
226 throw(NULL);
|
fiore@3
|
227 }
|
fiore@3
|
228 jobject currentEdge = env->CallObjectMethod(*haptics,getEdgeFromIDMethodId,id);
|
fiore@3
|
229 checkExceptions(env, "Could not call Haptics.getEdgeFromIDMethodId in CollectionsManager::isEdge");
|
fiore@3
|
230 bool retVal = (currentEdge != NULL);
|
fiore@3
|
231 env->DeleteLocalRef(currentEdge);
|
fiore@3
|
232 if(env->MonitorExit(*haptics) != JNI_OK){
|
fiore@3
|
233 throw(NULL);
|
fiore@3
|
234 }
|
fiore@3
|
235 return retVal;
|
fiore@3
|
236 }
|
fiore@3
|
237
|
fiore@3
|
238 CollectionsManager::EdgeData & CollectionsManager::getEdgeDataFromID(const jint id){
|
fiore@3
|
239 if(env->MonitorEnter(*haptics) != JNI_OK){
|
fiore@3
|
240 throw(NULL);
|
fiore@3
|
241 }
|
fiore@3
|
242 jobject currentEdge = env->CallObjectMethod(*haptics,getEdgeFromIDMethodId,id);
|
fiore@3
|
243 checkExceptions(env, "Could not call Haptics.getEdgeFromIDMethodId in CollectionsManager::getEdgeDataFromID");
|
fiore@3
|
244 if(currentEdge == NULL){
|
fiore@3
|
245 env->DeleteLocalRef(currentEdge);
|
fiore@3
|
246 throw(NULL);
|
fiore@3
|
247 }
|
fiore@3
|
248
|
fiore@3
|
249 jint size = env->GetIntField(currentEdge, edgeSizefieldId);
|
fiore@3
|
250 ed.setSize(size);
|
fiore@3
|
251 fillupEdgeData(ed,currentEdge);
|
fiore@3
|
252 env->DeleteLocalRef(currentEdge);
|
fiore@3
|
253 if(env->MonitorExit(*haptics) != JNI_OK){
|
fiore@3
|
254 throw(NULL);
|
fiore@3
|
255 }
|
fiore@3
|
256 return ed;
|
fiore@3
|
257 }
|
fiore@3
|
258
|
fiore@3
|
259 void CollectionsManager::fillupNodeData(NodeData & nd, jobject & currentNode){
|
fiore@3
|
260 //reads the fields of the current node
|
fiore@3
|
261 nd.x = env->GetDoubleField(currentNode,xFieldId);
|
fiore@3
|
262 nd.y = env->GetDoubleField(currentNode,yFieldId);
|
fiore@3
|
263 hduVector3Dd glCoordinatePosition;
|
fiore@3
|
264 // takes coordinates from the screen. Needs to convert the y axis as in openGL (0,0) = bottom left corner
|
fiore@3
|
265 fromScreen(hduVector3Dd(nd.x, screenHeight - nd.y, 0),glCoordinatePosition);
|
fiore@3
|
266 nd.x = glCoordinatePosition[0];
|
fiore@3
|
267 nd.y = glCoordinatePosition[1];
|
fiore@3
|
268 nd.hapticId = env->GetIntField(currentNode, nodeHapticIdFieldId);
|
fiore@3
|
269 nd.diagramId = env->GetIntField(currentNode, nodeDiagramIdFieldId);
|
fiore@3
|
270 }
|
fiore@3
|
271
|
fiore@3
|
272 void CollectionsManager::fillupEdgeData(EdgeData & ed, jobject & currentEdge){
|
fiore@3
|
273 /* get the array of x coordinates */
|
fiore@3
|
274 jobject xsAsObj = env->GetObjectField(currentEdge,edgeXsFieldId);
|
fiore@3
|
275 if(xsAsObj == NULL)
|
fiore@3
|
276 stopExecution("Cannot get the xs field");
|
fiore@3
|
277 jdoubleArray *jxs = reinterpret_cast<jdoubleArray*>(&xsAsObj);
|
fiore@3
|
278 double * xs = env->GetDoubleArrayElements(*jxs, NULL);
|
fiore@3
|
279 if(xs == NULL)
|
fiore@3
|
280 stopExecution("Cannot get the xs field array of double");
|
fiore@3
|
281
|
fiore@3
|
282 /* get the array of y coordinates */
|
fiore@3
|
283 jobject ysAsObj = env->GetObjectField(currentEdge,edgeYsFieldId);
|
fiore@3
|
284 if(ysAsObj == NULL)
|
fiore@3
|
285 stopExecution("Cannot get the xs field");
|
fiore@3
|
286
|
fiore@3
|
287 jdoubleArray *jys = reinterpret_cast<jdoubleArray*>(&ysAsObj);
|
fiore@3
|
288 double * ys = env->GetDoubleArrayElements(*jys, NULL);
|
fiore@3
|
289 if(ys == NULL)
|
fiore@3
|
290 stopExecution("Cannot get the ys field array of double");
|
fiore@3
|
291 // copy the data into the edgeData object
|
fiore@3
|
292 for(unsigned int i=0; i<ed.getSize(); i++){
|
fiore@3
|
293 ed.x[i] = xs[i];
|
fiore@3
|
294 ed.y[i] = ys[i];
|
fiore@3
|
295 // takes coordinates from the screen (needs to convert the y axis as in openGL 0 = bottom left corner
|
fiore@3
|
296 hduVector3Dd glCoordinatePosition;
|
fiore@3
|
297 fromScreen(hduVector3Dd(ed.x[i], screenHeight - ed.y[i], 0),glCoordinatePosition);
|
fiore@3
|
298 ed.x[i] = glCoordinatePosition[0];
|
fiore@3
|
299 ed.y[i] = glCoordinatePosition[1];
|
fiore@3
|
300 }
|
fiore@3
|
301 env->ReleaseDoubleArrayElements(*jxs, xs, 0);
|
fiore@3
|
302 env->ReleaseDoubleArrayElements(*jys, ys, 0);
|
fiore@3
|
303 env->DeleteLocalRef(xsAsObj);
|
fiore@3
|
304 env->DeleteLocalRef(ysAsObj);
|
fiore@3
|
305 jobject adjMatrixAsObj = env->GetObjectField(currentEdge, edgeAdjMatrixFieldId);
|
fiore@3
|
306 if(adjMatrixAsObj == NULL)
|
fiore@3
|
307 stopExecution("Cannot get the adjMatrix field");
|
fiore@3
|
308 jobjectArray *jadjMatrix = reinterpret_cast<jobjectArray*>(&adjMatrixAsObj);
|
fiore@3
|
309
|
fiore@3
|
310 for(unsigned int i=0; i<ed.getSize(); i++){
|
fiore@3
|
311 jobject adjMatrixBitSet = env->GetObjectArrayElement(*jadjMatrix,i);
|
fiore@3
|
312 if(adjMatrixBitSet == NULL)
|
fiore@3
|
313 stopExecution("Cannot get the adjMatrix field array element");
|
fiore@3
|
314 for(unsigned int j=0;j<ed.getSize(); j++){
|
fiore@3
|
315 jboolean b = env->CallBooleanMethod(adjMatrixBitSet,getBitMethodId,j);
|
fiore@3
|
316 checkExceptions(env,"Could not call BitSet.get()");
|
fiore@3
|
317 if(b == JNI_TRUE)
|
fiore@3
|
318 ed.adjMatrix[i][j] = true;
|
fiore@3
|
319 else
|
fiore@3
|
320 ed.adjMatrix[i][j] = false;
|
fiore@3
|
321 }
|
fiore@3
|
322 env->DeleteLocalRef(adjMatrixBitSet);
|
fiore@3
|
323 }
|
fiore@3
|
324 env->DeleteLocalRef(adjMatrixAsObj);
|
fiore@3
|
325
|
fiore@3
|
326 // set the haptic id used by the haptic device
|
fiore@3
|
327 ed.hapticId = env->GetIntField(currentEdge, edgeHapticIdFieldId);
|
fiore@3
|
328 // set the diagram id used in the java thread
|
fiore@3
|
329 ed.diagramId = env->GetIntField(currentEdge, edgeDiagramIdFieldId);
|
fiore@3
|
330 // set the stipple pattern
|
fiore@3
|
331 ed.stipplePattern = env->GetIntField(currentEdge, stipplePatternfieldId);
|
fiore@3
|
332 // set the attract point
|
fiore@3
|
333 ed.attractPoint[0] = env->GetDoubleField(currentEdge, attractPointXFieldId);
|
fiore@3
|
334 ed.attractPoint[1] = env->GetDoubleField(currentEdge, attractPointYFieldId);
|
fiore@3
|
335 hduVector3Dd glCoordinatePosition;
|
fiore@3
|
336 fromScreen(hduVector3Dd(ed.attractPoint[0], screenHeight - ed.attractPoint[1], 0),glCoordinatePosition);
|
fiore@3
|
337 ed.attractPoint[0] = glCoordinatePosition[0];
|
fiore@3
|
338 ed.attractPoint[1] = glCoordinatePosition[1];
|
fiore@3
|
339 //set the index from which the nodes start in the adjMatrix
|
fiore@3
|
340 ed.nodeStart = env->GetIntField(currentEdge, edgeNodeStartFieldId);
|
fiore@3
|
341 } |