1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-10 00:54:15 +01:00
m_thread b0e337c540 OP-1222 Added UUID to template file for identification.
Implemented the code to apply the template settings.
Fixed tab order in template export dialog.
Extended support for parsing and applying json data in uavobjectmanager.
2014-09-25 23:16:13 +02:00

378 lines
13 KiB
C++

/**
******************************************************************************
*
* @file uavobjectmanager.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @see The GNU Public License (GPL) Version 3
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVObjectsPlugin UAVObjects Plugin
* @{
* @brief The UAVUObjects GCS plugin
*****************************************************************************/
/*
* 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"
#include <QtWidgetsDepends>
/**
* 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);
getObject(cobj->getObjID())->emitNewInstance(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);
getObject(obj->getObjID())->emitNewInstance(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];
}
}
}
}
}
// qWarning("UAVObjectManager::getObject: Object not found. Probably a bug or mismatched GCS/flight versions.");
// 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);
}
void UAVObjectManager::toJson(QJsonObject &jsonObject, UAVObjectManager::JSON_EXPORT_OPTION what)
{
QList<UAVObject *> objects;
QList< QList<UAVObject *> > allObjects = getObjects();
foreach(QList<UAVObject *> instances, allObjects) {
foreach(UAVObject * object, instances) {
if (what == JSON_EXPORT_ALL ||
(what == JSON_EXPORT_DATA && !object->isSettingsObject()) ||
(what == JSON_EXPORT_SETTINGS && object->isSettingsObject()) ||
(what == JSON_EXPORT_SETTINGS && object->isMetaDataObject())) {
objects << object;
}
}
}
toJson(jsonObject, objects);
}
void UAVObjectManager::toJson(QJsonObject &jsonObject, const QList<QString> &objectsToExport)
{
QList<UAVObject *> objects;
foreach(QString objectName, objectsToExport) {
QList<UAVObject *> instances = getObjectInstances(objectName);
foreach(UAVObject * object, instances) {
objects << object;
}
}
toJson(jsonObject, objects);
}
void UAVObjectManager::toJson(QJsonObject &jsonObject, const QList<UAVObject *> &objectsToExport)
{
QJsonArray jObjects;
foreach(UAVObject * object, objectsToExport) {
QJsonObject jObject;
object->toJson(jObject);
jObjects.append(jObject);
}
jsonObject["objects"] = jObjects;
}
void UAVObjectManager::fromJson(const QJsonObject &jsonObject, QList<UAVObject *> *updatedObjects)
{
QJsonArray jObjects = jsonObject["objects"].toArray();
for (int i = 0; i < jObjects.size(); i++) {
QJsonObject jObject = jObjects.at(i).toObject();
UAVObject *object = getObject(jObject["name"].toString(), jObject["instance"].toInt());
if (object != NULL) {
object->fromJson(jObject);
if (updatedObjects != NULL) {
updatedObjects->append(object);
}
}
}
}
/**
* 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;
}