2010-06-23 04:33:53 +02:00
|
|
|
/**
|
|
|
|
******************************************************************************
|
|
|
|
*
|
2010-07-16 20:07:13 +02:00
|
|
|
* @file uavobjectmanager.cpp
|
2010-06-23 04:33:53 +02:00
|
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
|
|
* @see The GNU Public License (GPL) Version 3
|
2010-07-16 19:32:18 +02:00
|
|
|
* @addtogroup GCSPlugins GCS Plugins
|
|
|
|
* @{
|
|
|
|
* @addtogroup UAVObjectsPlugin UAVObjects Plugin
|
2010-06-23 04:33:53 +02:00
|
|
|
* @{
|
2010-07-16 20:07:13 +02:00
|
|
|
* @brief The UAVUObjects GCS plugin
|
2010-06-23 04:33:53 +02:00
|
|
|
*****************************************************************************/
|
2010-07-16 19:32:18 +02:00
|
|
|
/*
|
2010-06-23 04:33:53 +02:00
|
|
|
* 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<UAVDataObject*>(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<UAVObject*> 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<UAVObject*> > UAVObjectManager::getObjects()
|
|
|
|
{
|
|
|
|
QMutexLocker locker(mutex);
|
|
|
|
return objects;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Same as getObjects() but will only return DataObjects.
|
|
|
|
*/
|
|
|
|
QList< QList<UAVDataObject*> > UAVObjectManager::getDataObjects()
|
|
|
|
{
|
|
|
|
QMutexLocker locker(mutex);
|
|
|
|
QList< QList<UAVDataObject*> > 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<UAVDataObject*>(objects[objidx][0]);
|
|
|
|
if (obj != NULL)
|
|
|
|
{
|
|
|
|
// Create instance list
|
|
|
|
QList<UAVDataObject*> 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<UAVDataObject*>(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 <QList<UAVMetaObject*> > UAVObjectManager::getMetaObjects()
|
|
|
|
{
|
|
|
|
QMutexLocker locker(mutex);
|
|
|
|
QList< QList<UAVMetaObject*> > 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<UAVMetaObject*>(objects[objidx][0]);
|
|
|
|
if (obj != NULL)
|
|
|
|
{
|
|
|
|
// Create instance list
|
|
|
|
QList<UAVMetaObject*> 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<UAVMetaObject*>(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];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-09-16 08:20:49 +02:00
|
|
|
//qWarning("UAVObjectManager::getObject: Object not found. Probably a bug or mismatched GCS/flight versions.");
|
2010-06-23 04:33:53 +02:00
|
|
|
// 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<UAVObject*> UAVObjectManager::getObjectInstances(const QString& name)
|
|
|
|
{
|
|
|
|
return getObjectInstances(&name, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get all the instances of the object specified by its ID
|
|
|
|
*/
|
|
|
|
QList<UAVObject*> UAVObjectManager::getObjectInstances(quint32 objId)
|
|
|
|
{
|
|
|
|
return getObjectInstances(NULL, objId);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper function for the public getObjectInstances()
|
|
|
|
*/
|
|
|
|
QList<UAVObject*> 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<UAVObject*>();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
}
|