mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-20 10:54:14 +01:00
LP-599 Make cloned fields as typedef's of parent types in flight & ground (c, c++) uavobjgenerators.
This commit is contained in:
parent
9e9c9c8975
commit
8dbf25edc2
@ -40,6 +40,7 @@
|
||||
#ifndef $(NAMEUC)_H
|
||||
#define $(NAMEUC)_H
|
||||
#include <stdbool.h>
|
||||
$(INCLUDE)
|
||||
/* Object constants */
|
||||
#define $(NAMEUC)_OBJID $(OBJIDHEX)
|
||||
#define $(NAMEUC)_ISSINGLEINST $(ISSINGLEINST)
|
||||
|
@ -35,6 +35,7 @@
|
||||
#define $(NAMEUC)_H
|
||||
|
||||
#include "uavdataobject.h"
|
||||
$(INCLUDE)
|
||||
|
||||
class UAVObjectManager;
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <QSet>
|
||||
#include "uavobjectgeneratorflight.h"
|
||||
|
||||
using namespace std;
|
||||
@ -169,52 +170,91 @@ bool UAVObjectGeneratorFlight::process_object(ObjectInfo *info)
|
||||
enums.append(QString("/* Field %1 information */\n").arg(info->fields[n]->name));
|
||||
// Only for enum types
|
||||
if (info->fields[n]->type == FIELDTYPE_ENUM) {
|
||||
enums.append(QString("\n// Enumeration options for field %1\n").arg(info->fields[n]->name));
|
||||
enums.append("typedef enum __attribute__ ((__packed__)) {\n");
|
||||
// Go through each option
|
||||
QStringList options = info->fields[n]->options;
|
||||
for (int m = 0; m < options.length(); ++m) {
|
||||
QString s = (m == (options.length() - 1)) ? " %1_%2_%3=%4\n" : " %1_%2_%3=%4,\n";
|
||||
enums.append(s
|
||||
.arg(info->name.toUpper())
|
||||
.arg(info->fields[n]->name.toUpper())
|
||||
.arg(options[m].toUpper().replace(QRegExp(ENUM_SPECIAL_CHARS), ""))
|
||||
.arg(m));
|
||||
if (info->fields[n]->parentObjectName.length() > 0) {
|
||||
enums.append(QString("typedef %1%2Options %3%4Options;\n")
|
||||
.arg(info->fields[n]->parentObjectName)
|
||||
.arg(info->fields[n]->parentFieldName)
|
||||
.arg(info->name)
|
||||
.arg(info->fields[n]->name));
|
||||
} else {
|
||||
enums.append(QString("\n// Enumeration options for field %1\n").arg(info->fields[n]->name));
|
||||
enums.append("typedef enum __attribute__ ((__packed__)) {\n");
|
||||
// Go through each option
|
||||
QStringList options = info->fields[n]->options;
|
||||
for (int m = 0; m < options.length(); ++m) {
|
||||
QString s = (m == (options.length() - 1)) ? " %1_%2_%3=%4\n" : " %1_%2_%3=%4,\n";
|
||||
enums.append(s
|
||||
.arg(info->name.toUpper())
|
||||
.arg(info->fields[n]->name.toUpper())
|
||||
.arg(options[m].toUpper().replace(QRegExp(ENUM_SPECIAL_CHARS), ""))
|
||||
.arg(m));
|
||||
}
|
||||
enums.append(QString("} %1%2Options;\n")
|
||||
.arg(info->name)
|
||||
.arg(info->fields[n]->name));
|
||||
}
|
||||
enums.append(QString("} %1%2Options;\n")
|
||||
.arg(info->name)
|
||||
.arg(info->fields[n]->name));
|
||||
}
|
||||
// Generate element names (only if field has more than one element)
|
||||
if (info->fields[n]->numElements > 1 && !info->fields[n]->defaultElementNames) {
|
||||
enums.append(QString("\n// Array element names for field %1\n").arg(info->fields[n]->name));
|
||||
enums.append("typedef enum {\n");
|
||||
// Go through the element names
|
||||
QStringList elemNames = info->fields[n]->elementNames;
|
||||
for (int m = 0; m < elemNames.length(); ++m) {
|
||||
QString s = (m != (elemNames.length() - 1)) ? " %1_%2_%3=%4,\n" : " %1_%2_%3=%4\n";
|
||||
enums.append(s
|
||||
.arg(info->name.toUpper())
|
||||
.arg(info->fields[n]->name.toUpper())
|
||||
.arg(elemNames[m].toUpper())
|
||||
.arg(m));
|
||||
if (info->fields[n]->parentObjectName.length() > 0) {
|
||||
enums.append(QString("typedef %1%2Elem %3%4Elem;\n")
|
||||
.arg(info->fields[n]->parentObjectName)
|
||||
.arg(info->fields[n]->parentFieldName)
|
||||
.arg(info->name)
|
||||
.arg(info->fields[n]->name));
|
||||
} else {
|
||||
enums.append(QString("\n// Array element names for field %1\n").arg(info->fields[n]->name));
|
||||
enums.append("typedef enum {\n");
|
||||
// Go through the element names
|
||||
QStringList elemNames = info->fields[n]->elementNames;
|
||||
for (int m = 0; m < elemNames.length(); ++m) {
|
||||
QString s = (m != (elemNames.length() - 1)) ? " %1_%2_%3=%4,\n" : " %1_%2_%3=%4\n";
|
||||
enums.append(s
|
||||
.arg(info->name.toUpper())
|
||||
.arg(info->fields[n]->name.toUpper())
|
||||
.arg(elemNames[m].toUpper())
|
||||
.arg(m));
|
||||
}
|
||||
enums.append(QString("} %1%2Elem;\n")
|
||||
.arg(info->name)
|
||||
.arg(info->fields[n]->name));
|
||||
}
|
||||
enums.append(QString("} %1%2Elem;\n")
|
||||
.arg(info->name)
|
||||
.arg(info->fields[n]->name));
|
||||
}
|
||||
// Generate array information
|
||||
if (info->fields[n]->numElements > 1) {
|
||||
enums.append(QString("\n// Number of elements for field %1\n").arg(info->fields[n]->name));
|
||||
enums.append(QString("#define %1_%2_NUMELEM %3\n")
|
||||
.arg(info->name.toUpper())
|
||||
.arg(info->fields[n]->name.toUpper())
|
||||
.arg(info->fields[n]->numElements));
|
||||
if (info->fields[n]->parentObjectName.length() > 0) {
|
||||
enums.append(QString("#define %1_%2_NUMELEM %3_%4_NUMELEM\n")
|
||||
.arg(info->name.toUpper())
|
||||
.arg(info->fields[n]->name.toUpper())
|
||||
.arg(info->fields[n]->parentObjectName.toUpper())
|
||||
.arg(info->fields[n]->parentFieldName.toUpper()));
|
||||
} else {
|
||||
enums.append(QString("#define %1_%2_NUMELEM %3\n")
|
||||
.arg(info->name.toUpper())
|
||||
.arg(info->fields[n]->name.toUpper())
|
||||
.arg(info->fields[n]->numElements));
|
||||
}
|
||||
}
|
||||
|
||||
enums.append(QString("\n"));
|
||||
}
|
||||
|
||||
QString includes;
|
||||
QSet<QString> parentObjects;
|
||||
|
||||
for (int n = 0; n < info->fields.length(); ++n) {
|
||||
if (info->fields[n]->parentObjectName.length() > 0) {
|
||||
parentObjects.insert(info->fields[n]->parentObjectName);
|
||||
}
|
||||
}
|
||||
|
||||
foreach(const QString &objectName, parentObjects) {
|
||||
includes.append("#include \"" + objectName.toLower() + ".h\"\n");
|
||||
}
|
||||
|
||||
outInclude.replace(QString("$(DATAFIELDINFO)"), enums);
|
||||
outInclude.replace(QString("$(INCLUDE)"), includes);
|
||||
|
||||
// Replace the $(INITFIELDS) tag
|
||||
QString initfields;
|
||||
|
@ -24,7 +24,7 @@
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <QSet>
|
||||
#include "uavobjectgeneratorgcs.h"
|
||||
|
||||
#define VERBOSE false
|
||||
@ -52,27 +52,32 @@ void info(ObjectInfo *object, QString msg)
|
||||
}
|
||||
|
||||
struct Context {
|
||||
ObjectInfo *object;
|
||||
ObjectInfo *object;
|
||||
// parent objects
|
||||
QSet<QString> parentObjects;
|
||||
// enums
|
||||
QString enums;
|
||||
QString enumsCount;
|
||||
QString registerImpl;
|
||||
QString enums;
|
||||
QString enumsCount;
|
||||
QString registerImpl;
|
||||
// interface
|
||||
QString fields;
|
||||
QString fieldsInfo;
|
||||
QString properties;
|
||||
QString deprecatedProperties;
|
||||
QString getters;
|
||||
QString setters;
|
||||
QString notifications;
|
||||
QString fields;
|
||||
QString fieldsInfo;
|
||||
QString properties;
|
||||
QString deprecatedProperties;
|
||||
QString getters;
|
||||
QString setters;
|
||||
QString notifications;
|
||||
// implementation
|
||||
QString fieldsInit;
|
||||
QString fieldsDefault;
|
||||
QString propertiesImpl;
|
||||
QString notificationsImpl;
|
||||
QString fieldsInit;
|
||||
QString fieldsDefault;
|
||||
QString propertiesImpl;
|
||||
QString notificationsImpl;
|
||||
};
|
||||
|
||||
struct FieldContext {
|
||||
FieldContext(FieldInfo *fieldInfo, ObjectInfo *object);
|
||||
FieldContext(const FieldContext &fieldContext);
|
||||
|
||||
FieldInfo *field;
|
||||
// field
|
||||
QString fieldName;
|
||||
@ -82,6 +87,10 @@ struct FieldContext {
|
||||
QString ucPropName;
|
||||
QString propType;
|
||||
QString propRefType;
|
||||
//
|
||||
QString parentClassName;
|
||||
QString parentFieldName;
|
||||
QString ucParentPropName;
|
||||
// deprecation
|
||||
bool hasDeprecatedProperty;
|
||||
bool hasDeprecatedGetter;
|
||||
@ -226,6 +235,10 @@ QString generate(Context &ctxt, FieldContext &fieldCtxt, const QString &fragment
|
||||
str.replace(":elementCount", QString::number(fieldCtxt.field->numElements));
|
||||
str.replace(":enumCount", QString::number(fieldCtxt.field->numOptions));
|
||||
|
||||
str.replace(":parentFieldName", fieldCtxt.parentFieldName);
|
||||
str.replace(":parentClassName", fieldCtxt.parentClassName);
|
||||
str.replace(":ParentPropName", fieldCtxt.ucParentPropName);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@ -234,34 +247,42 @@ void generateFieldInfo(Context &ctxt, FieldContext &fieldCtxt)
|
||||
ctxt.fieldsInfo += generate(ctxt, fieldCtxt, " // :fieldName\n");
|
||||
|
||||
if (fieldCtxt.field->type == FIELDTYPE_ENUM) {
|
||||
QStringList options = fieldCtxt.field->options;
|
||||
ctxt.fieldsInfo += " typedef enum { ";
|
||||
for (int m = 0; m < options.length(); ++m) {
|
||||
if (m > 0) {
|
||||
ctxt.fieldsInfo.append(", ");
|
||||
if (fieldCtxt.field->parentObjectName.length() > 0) {
|
||||
ctxt.fieldsInfo += generate(ctxt, fieldCtxt, " typedef :parentClassName:::parentFieldNameOptions :fieldNameOptions;\n");
|
||||
} else {
|
||||
QStringList options = fieldCtxt.field->options;
|
||||
ctxt.fieldsInfo += " typedef enum { ";
|
||||
for (int m = 0; m < options.length(); ++m) {
|
||||
if (m > 0) {
|
||||
ctxt.fieldsInfo.append(", ");
|
||||
}
|
||||
ctxt.fieldsInfo += generate(ctxt, fieldCtxt, "%1_%2=%3")
|
||||
.arg(fieldCtxt.field->name.toUpper())
|
||||
.arg(options[m].toUpper().replace(QRegExp(ENUM_SPECIAL_CHARS), ""))
|
||||
.arg(m);
|
||||
}
|
||||
ctxt.fieldsInfo += generate(ctxt, fieldCtxt, "%1_%2=%3")
|
||||
.arg(fieldCtxt.field->name.toUpper())
|
||||
.arg(options[m].toUpper().replace(QRegExp(ENUM_SPECIAL_CHARS), ""))
|
||||
.arg(m);
|
||||
ctxt.fieldsInfo += generate(ctxt, fieldCtxt, " } :fieldNameOptions;\n");
|
||||
}
|
||||
ctxt.fieldsInfo += generate(ctxt, fieldCtxt, " } :fieldNameOptions;\n");
|
||||
}
|
||||
|
||||
// Generate element names (only if field has more than one element)
|
||||
if (fieldCtxt.field->numElements > 1 && !fieldCtxt.field->defaultElementNames) {
|
||||
QStringList elemNames = fieldCtxt.field->elementNames;
|
||||
ctxt.fieldsInfo += " typedef enum { ";
|
||||
for (int m = 0; m < elemNames.length(); ++m) {
|
||||
if (m > 0) {
|
||||
ctxt.fieldsInfo.append(", ");
|
||||
if (fieldCtxt.field->parentObjectName.length() > 0) {
|
||||
ctxt.fieldsInfo += generate(ctxt, fieldCtxt, " typedef :parentClassName:::parentFieldNameElem :fieldNameElem;\n");
|
||||
} else {
|
||||
QStringList elemNames = fieldCtxt.field->elementNames;
|
||||
ctxt.fieldsInfo += " typedef enum { ";
|
||||
for (int m = 0; m < elemNames.length(); ++m) {
|
||||
if (m > 0) {
|
||||
ctxt.fieldsInfo.append(", ");
|
||||
}
|
||||
ctxt.fieldsInfo += QString("%1_%2=%3")
|
||||
.arg(fieldCtxt.field->name.toUpper())
|
||||
.arg(elemNames[m].toUpper())
|
||||
.arg(m);
|
||||
}
|
||||
ctxt.fieldsInfo += QString("%1_%2=%3")
|
||||
.arg(fieldCtxt.field->name.toUpper())
|
||||
.arg(elemNames[m].toUpper())
|
||||
.arg(m);
|
||||
ctxt.fieldsInfo += generate(ctxt, fieldCtxt, " } :fieldNameElem;\n");
|
||||
}
|
||||
ctxt.fieldsInfo += generate(ctxt, fieldCtxt, " } :fieldNameElem;\n");
|
||||
}
|
||||
|
||||
// Generate array information
|
||||
@ -341,6 +362,9 @@ void generateFieldDefault(Context &ctxt, FieldContext &fieldCtxt)
|
||||
|
||||
void generateField(Context &ctxt, FieldContext &fieldCtxt)
|
||||
{
|
||||
if (fieldCtxt.parentClassName.length() > 0) {
|
||||
ctxt.parentObjects.insert(fieldCtxt.parentClassName);
|
||||
}
|
||||
if (fieldCtxt.field->numElements > 1) {
|
||||
ctxt.fields += generate(ctxt, fieldCtxt, " :fieldType :fieldName[:elementCount];\n");
|
||||
} else {
|
||||
@ -355,20 +379,24 @@ void generateEnum(Context &ctxt, FieldContext &fieldCtxt)
|
||||
{
|
||||
Q_ASSERT(fieldCtxt.field->type == FIELDTYPE_ENUM);
|
||||
|
||||
QString enumStringList = toEnumStringList(ctxt.object, fieldCtxt.field);
|
||||
if (fieldCtxt.field->parentObjectName.length() > 0) {
|
||||
ctxt.enums += generate(ctxt, fieldCtxt, "typedef :parentClassName_:ParentPropName :ClassName_:PropName;\n\n");
|
||||
} else {
|
||||
QString enumStringList = toEnumStringList(ctxt.object, fieldCtxt.field);
|
||||
|
||||
ctxt.enums += generate(ctxt, fieldCtxt,
|
||||
"class :ClassName_:PropName : public QObject {\n"
|
||||
" Q_OBJECT\n"
|
||||
"public:\n"
|
||||
" enum Enum { %1 };\n"
|
||||
" Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5\n"
|
||||
"};\n\n").arg(enumStringList);
|
||||
ctxt.enums += generate(ctxt, fieldCtxt,
|
||||
"class :ClassName_:PropName : public QObject {\n"
|
||||
" Q_OBJECT\n"
|
||||
"public:\n"
|
||||
" enum Enum { %1 };\n"
|
||||
" Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5\n"
|
||||
"};\n\n").arg(enumStringList);
|
||||
|
||||
ctxt.enumsCount += generate(ctxt, fieldCtxt, ":PropNameCount = :enumCount, ");
|
||||
ctxt.enumsCount += generate(ctxt, fieldCtxt, ":PropNameCount = :enumCount, ");
|
||||
|
||||
ctxt.registerImpl += generate(ctxt, fieldCtxt,
|
||||
" qmlRegisterType<:ClassName_:PropName>(\"%1.:ClassName\", 1, 0, \":PropName\");\n").arg("UAVTalk");
|
||||
ctxt.registerImpl += generate(ctxt, fieldCtxt,
|
||||
" qmlRegisterType<:ClassName_:PropName>(\"%1.:ClassName\", 1, 0, \":PropName\");\n").arg("UAVTalk");
|
||||
}
|
||||
}
|
||||
|
||||
void generateBaseProperty(Context &ctxt, FieldContext &fieldCtxt)
|
||||
@ -507,14 +535,10 @@ void generateIndexedProperty(Context &ctxt, FieldContext &fieldCtxt)
|
||||
sep = "_";
|
||||
}
|
||||
|
||||
FieldContext elementCtxt;
|
||||
elementCtxt.field = fieldCtxt.field;
|
||||
elementCtxt.fieldName = fieldCtxt.fieldName + "_" + elementName;
|
||||
elementCtxt.fieldType = fieldCtxt.fieldType;
|
||||
elementCtxt.propName = fieldCtxt.propName + sep + elementName;
|
||||
elementCtxt.ucPropName = fieldCtxt.ucPropName + sep + elementName;
|
||||
elementCtxt.propType = fieldCtxt.propType;
|
||||
elementCtxt.propRefType = fieldCtxt.propRefType;
|
||||
FieldContext elementCtxt(fieldCtxt);
|
||||
elementCtxt.fieldName = fieldCtxt.fieldName + "_" + elementName;
|
||||
elementCtxt.propName = fieldCtxt.propName + sep + elementName;
|
||||
elementCtxt.ucPropName = fieldCtxt.ucPropName + sep + elementName;
|
||||
// deprecation
|
||||
elementCtxt.hasDeprecatedProperty = (elementCtxt.fieldName != elementCtxt.propName) && DEPRECATED;
|
||||
elementCtxt.hasDeprecatedGetter = DEPRECATED;
|
||||
@ -593,6 +617,44 @@ bool UAVObjectGeneratorGCS::generate(UAVObjectParser *parser, QString templatepa
|
||||
return true;
|
||||
}
|
||||
|
||||
FieldContext::FieldContext(const FieldContext &fieldContext)
|
||||
{
|
||||
*this = fieldContext;
|
||||
}
|
||||
|
||||
FieldContext::FieldContext(FieldInfo *fieldInfo, ObjectInfo *object)
|
||||
{
|
||||
field = fieldInfo;
|
||||
|
||||
// field properties
|
||||
fieldName = field->name;
|
||||
fieldType = fieldTypeStrCPP(field->type);
|
||||
|
||||
parentClassName = field->parentObjectName;
|
||||
parentFieldName = field->parentFieldName;
|
||||
ucParentPropName = toPropertyName(field->parentFieldName);
|
||||
|
||||
ucPropName = toPropertyName(field->name);
|
||||
propName = toLowerCamelCase(ucPropName);
|
||||
propType = fieldType;
|
||||
if (field->type == FIELDTYPE_INT8) {
|
||||
propType = fieldTypeStrCPP(FIELDTYPE_INT16);
|
||||
} else if (field->type == FIELDTYPE_UINT8) {
|
||||
propType = fieldTypeStrCPP(FIELDTYPE_UINT16);
|
||||
} else if (field->type == FIELDTYPE_ENUM) {
|
||||
QString enumClassName = object->name + "_" + ucPropName;
|
||||
propType = enumClassName + "::Enum";
|
||||
}
|
||||
// reference type
|
||||
propRefType = propType;
|
||||
|
||||
// deprecation
|
||||
hasDeprecatedProperty = (fieldName != propName) && DEPRECATED;
|
||||
hasDeprecatedGetter = DEPRECATED;
|
||||
hasDeprecatedSetter = ((fieldName != ucPropName) || (fieldType != propType)) && DEPRECATED;
|
||||
hasDeprecatedNotification = ((fieldName != propName) || (fieldType != propType)) && DEPRECATED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the GCS object files
|
||||
*
|
||||
@ -634,32 +696,7 @@ bool UAVObjectGeneratorGCS::process_object(ObjectInfo *object)
|
||||
FieldInfo *field = object->fields[n];
|
||||
|
||||
// field context
|
||||
FieldContext fieldCtxt;
|
||||
fieldCtxt.field = field;
|
||||
|
||||
// field properties
|
||||
fieldCtxt.fieldName = field->name;
|
||||
fieldCtxt.fieldType = fieldTypeStrCPP(field->type);
|
||||
|
||||
fieldCtxt.ucPropName = toPropertyName(field->name);
|
||||
fieldCtxt.propName = toLowerCamelCase(fieldCtxt.ucPropName);
|
||||
fieldCtxt.propType = fieldCtxt.fieldType;
|
||||
if (field->type == FIELDTYPE_INT8) {
|
||||
fieldCtxt.propType = fieldTypeStrCPP(FIELDTYPE_INT16);
|
||||
} else if (field->type == FIELDTYPE_UINT8) {
|
||||
fieldCtxt.propType = fieldTypeStrCPP(FIELDTYPE_UINT16);
|
||||
} else if (field->type == FIELDTYPE_ENUM) {
|
||||
QString enumClassName = object->name + "_" + fieldCtxt.ucPropName;
|
||||
fieldCtxt.propType = enumClassName + "::Enum";
|
||||
}
|
||||
// reference type
|
||||
fieldCtxt.propRefType = fieldCtxt.propType;
|
||||
|
||||
// deprecation
|
||||
fieldCtxt.hasDeprecatedProperty = (fieldCtxt.fieldName != fieldCtxt.propName) && DEPRECATED;
|
||||
fieldCtxt.hasDeprecatedGetter = DEPRECATED;
|
||||
fieldCtxt.hasDeprecatedSetter = ((fieldCtxt.fieldName != fieldCtxt.ucPropName) || (fieldCtxt.fieldType != fieldCtxt.propType)) && DEPRECATED;
|
||||
fieldCtxt.hasDeprecatedNotification = ((fieldCtxt.fieldName != fieldCtxt.propName) || (fieldCtxt.fieldType != fieldCtxt.propType)) && DEPRECATED;
|
||||
FieldContext fieldCtxt(field, object);
|
||||
|
||||
generateField(ctxt, fieldCtxt);
|
||||
|
||||
@ -671,6 +708,12 @@ bool UAVObjectGeneratorGCS::process_object(ObjectInfo *object)
|
||||
generateProperty(ctxt, fieldCtxt);
|
||||
}
|
||||
|
||||
QString includes;
|
||||
foreach(const QString &objectName, ctxt.parentObjects) {
|
||||
includes.append("#include \"" + objectName.toLower() + ".h\"\n");
|
||||
}
|
||||
|
||||
outInclude.replace("$(INCLUDE)", includes);
|
||||
outInclude.replace("$(ENUMS)", ctxt.enums);
|
||||
outInclude.replace("$(ENUMS_COUNT)", ctxt.enumsCount);
|
||||
outInclude.replace("$(DATAFIELDS)", ctxt.fields);
|
||||
|
Loading…
x
Reference in New Issue
Block a user