diff --git a/androidgcs/src/org/openpilot/uavtalk/UAVObject.java b/androidgcs/src/org/openpilot/uavtalk/UAVObject.java index 6d35df822..adfece03e 100644 --- a/androidgcs/src/org/openpilot/uavtalk/UAVObject.java +++ b/androidgcs/src/org/openpilot/uavtalk/UAVObject.java @@ -1,6 +1,7 @@ package org.openpilot.uavtalk; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.List; import java.util.ListIterator; import java.util.Observer; @@ -128,8 +129,7 @@ public abstract class UAVObject { // this.mutex = new QMutex(QMutex::Recursive); }; - public void initialize(int instID) { - // QMutexLocker locker(mutex); + public synchronized void initialize(int instID) { this.instID = instID; } @@ -146,9 +146,8 @@ public abstract class UAVObject { * @throws Exception * When unable to unpack a field */ - public void initializeFields(List fields, ByteBuffer data, + public synchronized void initializeFields(List fields, ByteBuffer data, int numBytes) { - // TODO: QMutexLocker locker(mutex); this.numBytes = numBytes; this.fields = fields; // Initialize fields @@ -267,15 +266,13 @@ public abstract class UAVObject { * Get the number of fields held by this object */ public int getNumFields() { - // QMutexLocker locker(mutex); return fields.size(); } /** * Get the object's fields */ - public List getFields() { - // QMutexLocker locker(mutex); + public synchronized List getFields() { return fields; } @@ -286,7 +283,6 @@ public abstract class UAVObject { * @returns The field or NULL if not found */ public UAVObjectField getField(String name) { - // QMutexLocker locker(mutex); // Look for field ListIterator li = fields.listIterator(); while (li.hasNext()) { @@ -307,8 +303,7 @@ public abstract class UAVObject { * @returns The number of bytes copied * @note The array must already have enough space allocated for the object */ - public int pack(ByteBuffer dataOut) throws Exception { - // QMutexLocker locker(mutex); + public synchronized int pack(ByteBuffer dataOut) throws Exception { if (dataOut.remaining() < getNumBytes()) throw new Exception("Not enough bytes in ByteBuffer to pack object"); int numBytes = 0; @@ -329,7 +324,7 @@ public abstract class UAVObject { * @throws Exception * @returns The number of bytes copied */ - public int unpack(ByteBuffer dataIn) { + public synchronized int unpack(ByteBuffer dataIn) { if( dataIn == null ) return 0; @@ -532,8 +527,17 @@ public abstract class UAVObject { /** * Java specific functions */ - public UAVObject clone() { - return (UAVObject) clone(); + public synchronized UAVObject clone() { + UAVObject newObj = clone(); + List newFields = new ArrayList(); + ListIterator li = fields.listIterator(); + while(li.hasNext()) { + UAVObjectField nf = li.next().clone(); + nf.initialize(newObj); + newFields.add(nf); + } + newObj.initializeFields(newFields, ByteBuffer.allocate(numBytes), numBytes); + return newObj; } /** diff --git a/androidgcs/src/org/openpilot/uavtalk/UAVObjectField.java b/androidgcs/src/org/openpilot/uavtalk/UAVObjectField.java index 21444a04b..2fd7f7846 100644 --- a/androidgcs/src/org/openpilot/uavtalk/UAVObjectField.java +++ b/androidgcs/src/org/openpilot/uavtalk/UAVObjectField.java @@ -617,6 +617,17 @@ public class UAVObjectField { return num; } + + @Override + public UAVObjectField clone() + { + UAVObjectField newField = new UAVObjectField(new String(name), new String(units), type, + new ArrayList(elementNames), + new ArrayList(options)); + newField.initialize(obj); + newField.data = data; + return newField; + } private String name; private String units; @@ -626,7 +637,7 @@ public class UAVObjectField { private int numElements; private int numBytesPerElement; private int offset; - private Object data; private UAVObject obj; + protected Object data; } diff --git a/androidgcs/src/org/openpilot/uavtalk/UAVObjectManager.java b/androidgcs/src/org/openpilot/uavtalk/UAVObjectManager.java index 74ddb95fb..63f535eac 100644 --- a/androidgcs/src/org/openpilot/uavtalk/UAVObjectManager.java +++ b/androidgcs/src/org/openpilot/uavtalk/UAVObjectManager.java @@ -3,9 +3,29 @@ package org.openpilot.uavtalk; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; +import java.util.Observable; +import java.util.Observer; public class UAVObjectManager { + public class CallbackListener extends Observable { + public void event (UAVObject obj) { + setChanged(); + notifyObservers(obj); + } + } + private CallbackListener newInstance = new CallbackListener(); + public void addNewInstanceObserver(Observer o) { + synchronized(newInstance) { + newInstance.addObserver(o); + } + } + private CallbackListener newObject = new CallbackListener(); + public void addNewObjectObserver(Observer o) { + synchronized(newObject) { + newObject.addObserver(o); + } + } private final int MAX_INSTANCES = 10; // Use array list to store objects since rarely added or deleted @@ -79,11 +99,12 @@ public class UAVObjectManager { UAVDataObject newObj = obj.clone(instID); newObj.initialize(mobj); instList.add(newObj); - // emit new instance signal + newInstance.event(newObj); } obj.initialize(mobj); //emit new instance signal instList.add(obj); + newInstance.event(obj); instIter = instList.listIterator(); while(instIter.hasNext()) { @@ -101,13 +122,13 @@ public class UAVObjectManager { UAVDataObject cobj = obj.clone(instId); cobj.initialize(mobj); instList.add(cobj); - // emit newInstance(cobj); + newInstance.event(cobj); } // Finally, initialize the actual object instance obj.initialize(mobj); // Add the actual object instance in the list instList.add(obj); - //emit newInstance(obj); + newInstance.event(obj); return true; } @@ -149,81 +170,67 @@ public class UAVObjectManager { /** * Same as getObjects() but will only return DataObjects. */ - public List< List > getDataObjects() + public synchronized List< List > getDataObjects() { - assert(false); // TOOD This - return new ArrayList>(); - - /* QMutexLocker locker(mutex); - QList< QList > dObjects; + List< List > dObjects = new ArrayList< List > (); // Go through objects and copy to new list when types match - for (int objidx = 0; objidx < objects.length(); ++objidx) - { - if (objects[objidx].length() > 0) - { - // Check type - UAVDataObject* obj = dynamic_cast(objects[objidx][0]); - if (obj != NULL) - { - // Create instance list - QList list; - // Go through instances and cast them to UAVDataObject, then add to list - for (int instidx = 0; instidx < objects[objidx].length(); ++instidx) - { - obj = dynamic_cast(objects[objidx][instidx]); - if (obj != NULL) - { - list.append(obj); - } - } - // Append to object list - dObjects.append(list); - } + ListIterator> objIt = objects.listIterator(0); + + // Check if this object type is already in the list + while(objIt.hasNext()) { + List instList = objIt.next(); + + // If no instances skip + if(instList.size() == 0) + continue; + + // If meta data skip + if(instList.get(0).isMetadata()) + continue; + + List newInstList = new ArrayList(); + ListIterator instIt = instList.listIterator(); + while(instIt.hasNext()) { + newInstList.add((UAVDataObject) instIt.next()); } - }*/ + dObjects.add(newInstList); + } // Done + return dObjects; } /** * Same as getObjects() but will only return MetaObjects. */ - public List > getMetaObjects() + public synchronized List > getMetaObjects() { - assert(false); // TODO - return new ArrayList< List >(); - /* - QMutexLocker locker(mutex); - QList< QList > mObjects; + List< List > mObjects = new ArrayList< List > (); // Go through objects and copy to new list when types match - for (int objidx = 0; objidx < objects.length(); ++objidx) - { - if (objects[objidx].length() > 0) - { - // Check type - UAVMetaObject* obj = dynamic_cast(objects[objidx][0]); - if (obj != NULL) - { - // Create instance list - QList list; - // Go through instances and cast them to UAVMetaObject, then add to list - for (int instidx = 0; instidx < objects[objidx].length(); ++instidx) - { - obj = dynamic_cast(objects[objidx][instidx]); - if (obj != NULL) - { - list.append(obj); - } - } - // Append to object list - mObjects.append(list); - } + ListIterator> objIt = objects.listIterator(0); + + // Check if this object type is already in the list + while(objIt.hasNext()) { + List instList = objIt.next(); + + // If no instances skip + if(instList.size() == 0) + continue; + + // If meta data skip + if(!instList.get(0).isMetadata()) + continue; + + List newInstList = new ArrayList(); + ListIterator instIt = instList.listIterator(); + while(instIt.hasNext()) { + newInstList.add((UAVMetaObject) instIt.next()); } + mObjects.add(newInstList); } // Done return mObjects; - */ } @@ -270,7 +277,6 @@ public class UAVObjectManager { */ public synchronized UAVObject getObject(String name, int objId, int instId) { - //QMutexLocker locker(mutex); // Check if this object type is already in the list ListIterator> objIter = objects.listIterator(); while(objIter.hasNext()) {