fiore@3: #include "CollectionsManager.h" fiore@3: fiore@3: void CollectionsManager::init(void){ fiore@3: /**************** init jni variables **********************/ fiore@3: fiore@3: // --- classes --- fiore@3: // get the java haptics class fiore@3: hapticClass = env->GetObjectClass(*haptics); fiore@3: if(hapticClass == NULL){ fiore@3: stopExecution("Could not find the Haptics class"); fiore@3: } fiore@3: fiore@3: bitsetClass = env->FindClass("Ljava/util/BitSet;"); fiore@3: if(bitsetClass == NULL) fiore@3: stopExecution("failed to find bitset class"); fiore@3: fiore@3: //get the node list class fiore@3: listClass = env->FindClass("Ljava/util/ArrayList;"); fiore@3: if(listClass == NULL) fiore@3: stopExecution("failed to find list class"); fiore@3: fiore@3: // get the Node class to call the get method on the node list fiore@3: hapticNodeClass = env->FindClass("Luk/ac/qmul/eecs/ccmi/haptics/Node;"); fiore@3: if(hapticNodeClass == NULL){ fiore@3: stopExecution("Could not find the Node class"); fiore@3: } fiore@3: fiore@3: // get the Edge class to call the get method on the edge list fiore@3: hapticEdgeClass = env->FindClass("Luk/ac/qmul/eecs/ccmi/haptics/Edge;"); fiore@3: if(hapticEdgeClass == NULL){ fiore@3: stopExecution("Could not find the Edge class"); fiore@3: } fiore@3: // --- methods --- fiore@3: // "get" method id fiore@3: getMethodId = env->GetMethodID(listClass, "get", "(I)Ljava/lang/Object;"); fiore@3: if(getMethodId == NULL) fiore@3: stopExecution("Could not retrieve the get method id"); fiore@3: fiore@3: //size method id fiore@3: sizeMethodId = env->GetMethodID(listClass, "size", "()I"); fiore@3: if(sizeMethodId == NULL) fiore@3: stopExecution("failed to get size method id"); fiore@3: fiore@3: //get method of the BitSet class fiore@3: getBitMethodId = env->GetMethodID(bitsetClass, "get","(I)Z"); fiore@3: if(getBitMethodId == NULL) fiore@3: stopExecution("failed to get the get method id of the BitSet class"); fiore@3: fiore@3: getNodeFromIDMethodId = env->GetMethodID(hapticClass,"getNodeFromID","(I)Luk/ac/qmul/eecs/ccmi/haptics/Node;"); fiore@3: if(getNodeFromIDMethodId == NULL){ fiore@3: stopExecution("failed to get getNodeFromID of the Haptics class"); fiore@3: } fiore@3: fiore@3: getEdgeFromIDMethodId = env->GetMethodID(hapticClass,"getEdgeFromID","(I)Luk/ac/qmul/eecs/ccmi/haptics/Edge;"); fiore@3: if(getEdgeFromIDMethodId == NULL){ fiore@3: stopExecution("failed to get getEdgeFromID of the Haptics class"); fiore@3: } fiore@3: fiore@3: // -- field id's -- fiore@3: //retrieve edgeList field id fiore@3: edgeListfieldId = env->GetFieldID(hapticClass,"currentEdges", "Ljava/util/ArrayList;"); fiore@3: if(edgeListfieldId == NULL){ fiore@3: stopExecution("failed to find the edge list field id"); fiore@3: } fiore@3: fiore@3: //retrieve nodeList field id fiore@3: nodeListfieldId = env->GetFieldID(hapticClass,"currentNodes", "Ljava/util/ArrayList;"); fiore@3: if(nodeListfieldId == NULL){ fiore@3: stopExecution("failed to find the node list field id"); fiore@3: } fiore@3: fiore@3: // Node fields id's fiore@3: xFieldId = env->GetFieldID(hapticNodeClass,"x","D"); fiore@3: if(xFieldId == NULL) fiore@3: stopExecution("Could not find the x field ID"); fiore@3: fiore@3: fiore@3: yFieldId = env->GetFieldID(hapticNodeClass,"y","D"); fiore@3: if(yFieldId == NULL) fiore@3: stopExecution("Could not find the y field ID"); fiore@3: fiore@3: nodeHapticIdFieldId = env->GetFieldID(hapticNodeClass, "hapticId", "I"); fiore@3: if(nodeHapticIdFieldId == NULL) fiore@3: stopExecution("Could not find the node hapticId field ID"); fiore@3: fiore@3: nodeDiagramIdFieldId = env->GetFieldID(hapticNodeClass, "diagramId", "I"); fiore@3: if(nodeDiagramIdFieldId == NULL) fiore@3: stopExecution("Could not find the node diagramId field ID"); fiore@3: fiore@3: // Edge field id's fiore@3: // edge.hapticId fiore@3: edgeHapticIdFieldId = env->GetFieldID(hapticEdgeClass, "hapticId", "I"); fiore@3: if(edgeHapticIdFieldId == NULL) fiore@3: stopExecution("Could not find the edge hapticId field ID"); fiore@3: fiore@3: edgeDiagramIdFieldId = env->GetFieldID(hapticEdgeClass, "diagramId", "I"); fiore@3: if(edgeDiagramIdFieldId == NULL) fiore@3: stopExecution("Could not find the edge diagramId field ID"); fiore@3: fiore@3: // stipplePattern fiore@3: stipplePatternfieldId = env->GetFieldID(hapticEdgeClass, "stipplePattern", "I"); fiore@3: if(stipplePatternfieldId == NULL){ fiore@3: stopExecution("Could not find the stipplePattern field ID"); fiore@3: } fiore@3: fiore@3: edgeSizefieldId = env->GetFieldID(hapticEdgeClass, "size", "I"); fiore@3: if(edgeSizefieldId == NULL) fiore@3: stopExecution("Could not find edge size field ID"); fiore@3: fiore@3: edgeXsFieldId = env->GetFieldID(hapticEdgeClass,"xs", "[D"); fiore@3: if(edgeXsFieldId == NULL) fiore@3: stopExecution("Could not find edge xs field ID"); fiore@3: fiore@3: edgeYsFieldId = env->GetFieldID(hapticEdgeClass,"ys", "[D"); fiore@3: if(edgeYsFieldId == NULL) fiore@3: stopExecution("Could not find edge ys field ID"); fiore@3: fiore@3: edgeAdjMatrixFieldId = env->GetFieldID(hapticEdgeClass,"adjMatrix", "[Ljava/util/BitSet;"); fiore@3: if(edgeAdjMatrixFieldId == NULL) fiore@3: stopExecution("Could not find edge adjMatrix field ID"); fiore@3: fiore@3: attractPointXFieldId = env->GetFieldID(hapticEdgeClass, "attractPointX", "D"); fiore@3: if(attractPointXFieldId == NULL) fiore@3: stopExecution("Could not find the edge attractPointX field ID"); fiore@3: fiore@3: attractPointYFieldId = env->GetFieldID(hapticEdgeClass, "attractPointY", "D"); fiore@3: if(attractPointYFieldId == NULL) fiore@3: stopExecution("Could not find the edge attractPointY field ID"); fiore@3: fiore@3: edgeNodeStartFieldId = env->GetFieldID(hapticEdgeClass, "nodeStart", "I"); fiore@3: if(edgeNodeStartFieldId == NULL) fiore@3: stopExecution("Could not find the edge nodeStart field ID"); fiore@3: } fiore@3: fiore@3: const jint CollectionsManager::getNodesNum() { fiore@3: /* to read the node list field into the nodeList variable each time we get the size fiore@3: * is needed as, when the tab is switched the nodeList variables still points to the fiore@3: * previuos tab's node list. We do it only here and not in getNodeData because fiore@3: * getNodesData follows this call before releasing the monitor, therefore fiore@3: * data integrity is granted. fiore@3: */ fiore@3: env->DeleteLocalRef(nodeList); fiore@3: nodeList = env->GetObjectField(*haptics, nodeListfieldId); fiore@3: if(nodeList == NULL){ fiore@3: stopExecution("could not get the node list field of Haptic Class"); fiore@3: } fiore@3: fiore@3: jint size = env->CallIntMethod( nodeList, sizeMethodId); fiore@3: checkExceptions(env,"Could not call ArrayList.size()"); fiore@3: return size; fiore@3: } fiore@3: fiore@3: const jint CollectionsManager::getEdgesNum(){ fiore@3: env->DeleteLocalRef(edgeList); fiore@3: edgeList = env->GetObjectField(*haptics, edgeListfieldId); fiore@3: if(edgeList == NULL){ fiore@3: stopExecution("could not get the edge list field of Haptic Class"); fiore@3: } fiore@3: fiore@3: jint size = env->CallIntMethod( edgeList, sizeMethodId); fiore@3: checkExceptions(env, "Could not call ArrayList.size()"); fiore@3: return size; fiore@3: } fiore@3: fiore@3: CollectionsManager::NodeData & CollectionsManager::getNodeData(const int i){ fiore@3: // get the i-th node fiore@3: jobject currentNode = env->CallObjectMethod(nodeList,getMethodId,i); fiore@3: checkExceptions(env,"Could not call ArrayList.size()"); fiore@3: fillupNodeData(nd,currentNode); fiore@3: env->DeleteLocalRef(currentNode); fiore@3: return nd; fiore@3: } fiore@3: fiore@3: CollectionsManager::EdgeData & CollectionsManager::getEdgeData(const int i){ fiore@3: /* first we look for the i-th edge in the Haptics java class. Once we get it, fiore@3: * we need all the coordinates of the node this edge is connecting, so that we fiore@3: * can draw it. The edge mantains a list of references to such nodes. fiore@3: */ fiore@3: fiore@3: // get the i-th edge fiore@3: jobject currentEdge = env->CallObjectMethod(edgeList,getMethodId,i); fiore@3: checkExceptions(env, "Could not call ArrayList.get(int) in the haptics edges"); fiore@3: if(currentEdge == NULL) fiore@3: stopExecution("Could not find get current Edge"); fiore@3: jint size = env->GetIntField(currentEdge, edgeSizefieldId); fiore@3: ed.setSize(size); fiore@3: fillupEdgeData(ed,currentEdge); fiore@3: env->DeleteLocalRef(currentEdge); fiore@3: return ed; fiore@3: } fiore@3: fiore@3: bool CollectionsManager::isNode(const jint id) const{ fiore@3: if(env->MonitorEnter(*haptics) != JNI_OK){ fiore@3: throw(NULL); fiore@3: } fiore@3: jobject currentNode = env->CallObjectMethod(*haptics,getNodeFromIDMethodId,id); fiore@3: checkExceptions(env, "Could not call Haptics.getNodeFromIDMethodId in CollectionsManager::isNode"); fiore@3: bool retVal = (currentNode != NULL); fiore@3: env->DeleteLocalRef(currentNode); fiore@3: if(env->MonitorExit(*haptics) != JNI_OK){ fiore@3: throw(NULL); fiore@3: } fiore@3: return retVal; fiore@3: } fiore@3: fiore@3: CollectionsManager::NodeData & CollectionsManager::getNodeDataFromID(const jint id){ fiore@3: if(env->MonitorEnter(*haptics) != JNI_OK){ fiore@3: throw(NULL); fiore@3: } fiore@3: jobject currentNode = env->CallObjectMethod(*haptics,getNodeFromIDMethodId,id); fiore@3: checkExceptions(env, "Could not call Haptics.getNodeFromIDMethodId in CollectionsManager::getNodeDataFromID"); fiore@3: if(currentNode == NULL){ fiore@3: env->DeleteLocalRef(currentNode); fiore@3: throw(NULL); fiore@3: } fiore@3: fillupNodeData(nd,currentNode); fiore@3: env->DeleteLocalRef(currentNode); fiore@3: if(env->MonitorExit(*haptics) != JNI_OK){ fiore@3: throw(NULL); fiore@3: } fiore@3: return nd; fiore@3: } fiore@3: fiore@3: bool CollectionsManager::isEdge(const jint id) const{ fiore@3: if(env->MonitorEnter(*haptics) != JNI_OK){ fiore@3: throw(NULL); fiore@3: } fiore@3: jobject currentEdge = env->CallObjectMethod(*haptics,getEdgeFromIDMethodId,id); fiore@3: checkExceptions(env, "Could not call Haptics.getEdgeFromIDMethodId in CollectionsManager::isEdge"); fiore@3: bool retVal = (currentEdge != NULL); fiore@3: env->DeleteLocalRef(currentEdge); fiore@3: if(env->MonitorExit(*haptics) != JNI_OK){ fiore@3: throw(NULL); fiore@3: } fiore@3: return retVal; fiore@3: } fiore@3: fiore@3: CollectionsManager::EdgeData & CollectionsManager::getEdgeDataFromID(const jint id){ fiore@3: if(env->MonitorEnter(*haptics) != JNI_OK){ fiore@3: throw(NULL); fiore@3: } fiore@3: jobject currentEdge = env->CallObjectMethod(*haptics,getEdgeFromIDMethodId,id); fiore@3: checkExceptions(env, "Could not call Haptics.getEdgeFromIDMethodId in CollectionsManager::getEdgeDataFromID"); fiore@3: if(currentEdge == NULL){ fiore@3: env->DeleteLocalRef(currentEdge); fiore@3: throw(NULL); fiore@3: } fiore@3: fiore@3: jint size = env->GetIntField(currentEdge, edgeSizefieldId); fiore@3: ed.setSize(size); fiore@3: fillupEdgeData(ed,currentEdge); fiore@3: env->DeleteLocalRef(currentEdge); fiore@3: if(env->MonitorExit(*haptics) != JNI_OK){ fiore@3: throw(NULL); fiore@3: } fiore@3: return ed; fiore@3: } fiore@3: fiore@3: void CollectionsManager::fillupNodeData(NodeData & nd, jobject & currentNode){ fiore@3: //reads the fields of the current node fiore@3: nd.x = env->GetDoubleField(currentNode,xFieldId); fiore@3: nd.y = env->GetDoubleField(currentNode,yFieldId); fiore@3: hduVector3Dd glCoordinatePosition; fiore@3: // takes coordinates from the screen. Needs to convert the y axis as in openGL (0,0) = bottom left corner fiore@3: fromScreen(hduVector3Dd(nd.x, screenHeight - nd.y, 0),glCoordinatePosition); fiore@3: nd.x = glCoordinatePosition[0]; fiore@3: nd.y = glCoordinatePosition[1]; fiore@3: nd.hapticId = env->GetIntField(currentNode, nodeHapticIdFieldId); fiore@3: nd.diagramId = env->GetIntField(currentNode, nodeDiagramIdFieldId); fiore@3: } fiore@3: fiore@3: void CollectionsManager::fillupEdgeData(EdgeData & ed, jobject & currentEdge){ fiore@3: /* get the array of x coordinates */ fiore@3: jobject xsAsObj = env->GetObjectField(currentEdge,edgeXsFieldId); fiore@3: if(xsAsObj == NULL) fiore@3: stopExecution("Cannot get the xs field"); fiore@3: jdoubleArray *jxs = reinterpret_cast(&xsAsObj); fiore@3: double * xs = env->GetDoubleArrayElements(*jxs, NULL); fiore@3: if(xs == NULL) fiore@3: stopExecution("Cannot get the xs field array of double"); fiore@3: fiore@3: /* get the array of y coordinates */ fiore@3: jobject ysAsObj = env->GetObjectField(currentEdge,edgeYsFieldId); fiore@3: if(ysAsObj == NULL) fiore@3: stopExecution("Cannot get the xs field"); fiore@3: fiore@3: jdoubleArray *jys = reinterpret_cast(&ysAsObj); fiore@3: double * ys = env->GetDoubleArrayElements(*jys, NULL); fiore@3: if(ys == NULL) fiore@3: stopExecution("Cannot get the ys field array of double"); fiore@3: // copy the data into the edgeData object fiore@3: for(unsigned int i=0; iReleaseDoubleArrayElements(*jxs, xs, 0); fiore@3: env->ReleaseDoubleArrayElements(*jys, ys, 0); fiore@3: env->DeleteLocalRef(xsAsObj); fiore@3: env->DeleteLocalRef(ysAsObj); fiore@3: jobject adjMatrixAsObj = env->GetObjectField(currentEdge, edgeAdjMatrixFieldId); fiore@3: if(adjMatrixAsObj == NULL) fiore@3: stopExecution("Cannot get the adjMatrix field"); fiore@3: jobjectArray *jadjMatrix = reinterpret_cast(&adjMatrixAsObj); fiore@3: fiore@3: for(unsigned int i=0; iGetObjectArrayElement(*jadjMatrix,i); fiore@3: if(adjMatrixBitSet == NULL) fiore@3: stopExecution("Cannot get the adjMatrix field array element"); fiore@3: for(unsigned int j=0;jCallBooleanMethod(adjMatrixBitSet,getBitMethodId,j); fiore@3: checkExceptions(env,"Could not call BitSet.get()"); fiore@3: if(b == JNI_TRUE) fiore@3: ed.adjMatrix[i][j] = true; fiore@3: else fiore@3: ed.adjMatrix[i][j] = false; fiore@3: } fiore@3: env->DeleteLocalRef(adjMatrixBitSet); fiore@3: } fiore@3: env->DeleteLocalRef(adjMatrixAsObj); fiore@3: fiore@3: // set the haptic id used by the haptic device fiore@3: ed.hapticId = env->GetIntField(currentEdge, edgeHapticIdFieldId); fiore@3: // set the diagram id used in the java thread fiore@3: ed.diagramId = env->GetIntField(currentEdge, edgeDiagramIdFieldId); fiore@3: // set the stipple pattern fiore@3: ed.stipplePattern = env->GetIntField(currentEdge, stipplePatternfieldId); fiore@3: // set the attract point fiore@3: ed.attractPoint[0] = env->GetDoubleField(currentEdge, attractPointXFieldId); fiore@3: ed.attractPoint[1] = env->GetDoubleField(currentEdge, attractPointYFieldId); fiore@3: hduVector3Dd glCoordinatePosition; fiore@3: fromScreen(hduVector3Dd(ed.attractPoint[0], screenHeight - ed.attractPoint[1], 0),glCoordinatePosition); fiore@3: ed.attractPoint[0] = glCoordinatePosition[0]; fiore@3: ed.attractPoint[1] = glCoordinatePosition[1]; fiore@3: //set the index from which the nodes start in the adjMatrix fiore@3: ed.nodeStart = env->GetIntField(currentEdge, edgeNodeStartFieldId); fiore@3: }