/** ****************************************************************************** * * @file uavobjectmanager.cpp * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief * @see The GNU Public License (GPL) Version 3 * @defgroup uavobjectsplugin * @{ * *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "uavobjectmanager.h" /** * Constructor */ UAVObjectManager::UAVObjectManager() { mutex = new QMutex(QMutex::Recursive); } UAVObjectManager::~UAVObjectManager() { delete mutex; } /** * Register an object with the manager. This function must be called for all newly created instances. * A new instance can be created directly by instantiating a new object or by calling clone() of * an existing object. The object will be registered and will be properly initialized so that it can accept * updates. */ bool UAVObjectManager::registerObject(UAVDataObject* obj) { QMutexLocker locker(mutex); // Check if this object type is already in the list for (int objidx = 0; objidx < objects.length(); ++objidx) { // Check if the object ID is in the list if (objects[objidx].length() > 0 && objects[objidx][0]->getObjID() == obj->getObjID()) { // Check if this is a single instance object, if yes we can not add a new instance if (obj->isSingleInstance()) { return false; } // The object type has alredy been added, so now we need to initialize the new instance with the appropriate id // There is a single metaobject for all object instances of this type, so no need to create a new one // Get object type metaobject from existing instance UAVDataObject* refObj = dynamic_cast(objects[objidx][0]); if (refObj == NULL) { return false; } UAVMetaObject* mobj = refObj->getMetaObject(); // If the instance ID is specified and not at the default value (0) then we need to make sure // that there are no gaps in the instance list. If gaps are found then then additional instances // will be created. if ( (obj->getInstID() > 0) && (obj->getInstID() < MAX_INSTANCES) ) { for (int instidx = 0; instidx < objects[objidx].length(); ++instidx) { if ( objects[objidx][instidx]->getInstID() == obj->getInstID() ) { // Instance conflict, do not add return false; } } // Check if there are any gaps between the requested instance ID and the ones in the list, // if any then create the missing instances. for (quint32 instidx = objects[objidx].length(); instidx < obj->getInstID(); ++instidx) { UAVDataObject* cobj = obj->clone(instidx); cobj->initialize(mobj); objects[objidx].append(cobj); emit newInstance(cobj); } // Finally, initialize the actual object instance obj->initialize(mobj); } else if (obj->getInstID() == 0) { // Assign the next available ID and initialize the object instance obj->initialize(objects[objidx].length(), mobj); } else { return false; } // Add the actual object instance in the list objects[objidx].append(obj); emit newInstance(obj); return true; } } // If this point is reached then this is the first time this object type (ID) is added in the list // create a new list of the instances, add in the object collection and create the object's metaobject // Create metaobject QString mname = obj->getName(); mname.append("Meta"); UAVMetaObject* mobj = new UAVMetaObject(obj->getObjID()+1, mname, obj); // Initialize object obj->initialize(0, mobj); // Add to list addObject(obj); addObject(mobj); return true; } void UAVObjectManager::addObject(UAVObject* obj) { // Add to list QList list; list.append(obj); objects.append(list); emit newObject(obj); } /** * Get all objects. A two dimentional QList is returned. Objects are grouped by * instances of the same object type. */ QList< QList > UAVObjectManager::getObjects() { QMutexLocker locker(mutex); return objects; } /** * Same as getObjects() but will only return DataObjects. */ QList< QList > UAVObjectManager::getDataObjects() { QMutexLocker locker(mutex); QList< QList > dObjects; // 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); } } } // Done return dObjects; } /** * Same as getObjects() but will only return MetaObjects. */ QList > UAVObjectManager::getMetaObjects() { QMutexLocker locker(mutex); QList< QList > mObjects; // 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); } } } // Done return mObjects; } /** * Get a specific object given its name and instance ID * @returns The object is found or NULL if not */ UAVObject* UAVObjectManager::getObject(const QString& name, quint32 instId) { return getObject(&name, 0, instId); } /** * Get a specific object given its object and instance ID * @returns The object is found or NULL if not */ UAVObject* UAVObjectManager::getObject(quint32 objId, quint32 instId) { return getObject(NULL, objId, instId); } /** * Helper function for the public getObject() functions. */ UAVObject* UAVObjectManager::getObject(const QString* name, quint32 objId, quint32 instId) { QMutexLocker locker(mutex); // Check if this object type is already in the list for (int objidx = 0; objidx < objects.length(); ++objidx) { // Check if the object ID is in the list if (objects[objidx].length() > 0) { if ( (name != NULL && objects[objidx][0]->getName().compare(name) == 0) || (name == NULL && objects[objidx][0]->getObjID() == objId) ) { // Look for the requested instance ID for (int instidx = 0; instidx < objects[objidx].length(); ++instidx) { if (objects[objidx][instidx]->getInstID() == instId) { return objects[objidx][instidx]; } } } } } // If this point is reached then the requested object could not be found return NULL; } /** * Get all the instances of the object specified by name */ QList UAVObjectManager::getObjectInstances(const QString& name) { return getObjectInstances(&name, 0); } /** * Get all the instances of the object specified by its ID */ QList UAVObjectManager::getObjectInstances(quint32 objId) { return getObjectInstances(NULL, objId); } /** * Helper function for the public getObjectInstances() */ QList UAVObjectManager::getObjectInstances(const QString* name, quint32 objId) { QMutexLocker locker(mutex); // Check if this object type is already in the list for (int objidx = 0; objidx < objects.length(); ++objidx) { // Check if the object ID is in the list if (objects[objidx].length() > 0) { if ( (name != NULL && objects[objidx][0]->getName().compare(name) == 0) || (name == NULL && objects[objidx][0]->getObjID() == objId) ) { return objects[objidx]; } } } // If this point is reached then the requested object could not be found return QList(); } /** * Get the number of instances for an object given its name */ qint32 UAVObjectManager::getNumInstances(const QString& name) { return getNumInstances(&name, 0); } /** * Get the number of instances for an object given its ID */ qint32 UAVObjectManager::getNumInstances(quint32 objId) { return getNumInstances(NULL, objId); } /** * Helper function for public getNumInstances */ qint32 UAVObjectManager::getNumInstances(const QString* name, quint32 objId) { QMutexLocker locker(mutex); // Check if this object type is already in the list for (int objidx = 0; objidx < objects.length(); ++objidx) { // Check if the object ID is in the list if (objects[objidx].length() > 0) { if ( (name != NULL && objects[objidx][0]->getName().compare(name) == 0) || (name == NULL && objects[objidx][0]->getObjID() == objId) ) { return objects[objidx].length(); } } } // If this point is reached then the requested object could not be found return -1; }