Bug fixing

This commit is contained in:
Filippo Cucchetto 2016-01-07 13:24:52 +01:00
parent 56306f8403
commit e5457adc85
4 changed files with 40 additions and 18 deletions

View File

@ -86,8 +86,10 @@ DOS_API void dos_qvariant_isnull(void* vptr, bool* result);
DOS_API void dos_qvariant_delete(void* vptr); DOS_API void dos_qvariant_delete(void* vptr);
DOS_API void dos_qvariant_assign(void* vptr, void* other); DOS_API void dos_qvariant_assign(void* vptr, void* other);
// QObjectFactory // QMetaObject
DOS_API void dos_qmetaobject_create(void** vptr, void *superClassMetaObject, const char *className, DOS_API void dos_qmetaobject_create(void** vptr,
void *superClassMetaObject,
const char *className,
SignalDefinitions signalDefinitions, SignalDefinitions signalDefinitions,
SlotDefinitions slotDefinitions, SlotDefinitions slotDefinitions,
PropertyDefinitions propertyDefinitions); PropertyDefinitions propertyDefinitions);

View File

@ -56,7 +56,7 @@ public:
}; };
/// This the generic version used by subclasses of QObject or QAbstractListModels /// This the generic version used by subclasses of QObject or QAbstractListModels
class DosQMetaObject : public BaseDosQMetaObject class DosQMetaObject : public IDosQMetaObject
{ {
public: public:
DosQMetaObject(const IDosQMetaObject& superClassMetaObject, DosQMetaObject(const IDosQMetaObject& superClassMetaObject,
@ -68,6 +68,7 @@ public:
int signalSlotIndex(const QString& signalName) const override; int signalSlotIndex(const QString& signalName) const override;
int readSlotIndex(const char* propertyName) const override; int readSlotIndex(const char* propertyName) const override;
int writeSlotIndex(const char* propertyName) const override; int writeSlotIndex(const char* propertyName) const override;
const QMetaObject *metaObject() const override;
private: private:
QMetaObject *createMetaObject(const IDosQMetaObject &superClassMetaObject, QMetaObject *createMetaObject(const IDosQMetaObject &superClassMetaObject,
@ -76,8 +77,9 @@ private:
const SlotDefinitions &slotDefinitions, const SlotDefinitions &slotDefinitions,
const PropertyDefinitions &propertyDefinitions); const PropertyDefinitions &propertyDefinitions);
QHash<QByteArray, int> m_signalIndexByName; SafeQMetaObjectPtr m_metaObject;
QHash<QByteArray, QPair<int,int>> m_propertySlots; std::unordered_map<std::string, int> m_signalIndexByName;
std::unordered_map<std::string, std::pair<int,int>> m_propertySlots;
}; };
/// This class simply holds a ptr to a IDosQMetaObject /// This class simply holds a ptr to a IDosQMetaObject

View File

@ -536,9 +536,13 @@ void dos_qmetaobject_create(void **vptr,
::SlotDefinitions slotDefinitions, ::SlotDefinitions slotDefinitions,
::PropertyDefinitions propertyDefinitions) ::PropertyDefinitions propertyDefinitions)
{ {
Q_ASSERT(superClassVPtr);
auto superClassHolder = static_cast<DosIQMetaObjectHolder*>(superClassVPtr); auto superClassHolder = static_cast<DosIQMetaObjectHolder*>(superClassVPtr);
Q_ASSERT(superClassHolder);
auto data = superClassHolder->data();
Q_ASSERT(data);
auto metaObject = std::make_shared<DosQMetaObject>(*superClassHolder->data(), auto metaObject = std::make_shared<DosQMetaObject>(*data,
QString::fromUtf8(className), QString::fromUtf8(className),
toVector(signalDefinitions), toVector(signalDefinitions),
toVector(slotDefinitions), toVector(slotDefinitions),

View File

@ -23,10 +23,18 @@ QByteArray createSignature(const T& functionDefinition)
return signature.arg(functionDefinition.name, arguments).toUtf8(); return signature.arg(functionDefinition.name, arguments).toUtf8();
} }
template<class Key, class Value>
Value valueOrDefault(std::unordered_map<Key,Value> const& map, const Key& k, Value value)
{
auto it = map.find(k);
return it != std::end(map) ? it->second : std::move(value);
}
QMetaObject* createDynamicQObjectMetaObject() QMetaObject* createDynamicQObjectMetaObject()
{ {
QMetaObjectBuilder builder; QMetaObjectBuilder builder;
builder.setClassName("DynamicQObject"); builder.setClassName("DynamicQObject");
builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
builder.setSuperClass(&QObject::staticMetaObject); builder.setSuperClass(&QObject::staticMetaObject);
return builder.toMetaObject(); return builder.toMetaObject();
} }
@ -34,6 +42,7 @@ QMetaObject* createDynamicQObjectMetaObject()
QMetaObject* createDynamicQAbstractListModelMetaObject() QMetaObject* createDynamicQAbstractListModelMetaObject()
{ {
QMetaObjectBuilder builder; QMetaObjectBuilder builder;
builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
builder.setClassName("DynamicQAbstractListModel"); builder.setClassName("DynamicQAbstractListModel");
builder.setSuperClass(&QAbstractListModel::staticMetaObject); builder.setSuperClass(&QAbstractListModel::staticMetaObject);
return builder.toMetaObject(); return builder.toMetaObject();
@ -57,8 +66,9 @@ DosQMetaObject::DosQMetaObject(const IDosQMetaObject &superClassMetaObject,
const SignalDefinitions& signalDefinitions, const SignalDefinitions& signalDefinitions,
const SlotDefinitions& slotDefinitions, const SlotDefinitions& slotDefinitions,
const PropertyDefinitions& propertyDefinitions) const PropertyDefinitions& propertyDefinitions)
: BaseDosQMetaObject(createMetaObject(superClassMetaObject, className, signalDefinitions, slotDefinitions, propertyDefinitions)) : m_metaObject(nullptr)
{ {
m_metaObject.reset(createMetaObject(superClassMetaObject, className, signalDefinitions, slotDefinitions, propertyDefinitions));
} }
QMetaObject *DosQMetaObject::createMetaObject(const IDosQMetaObject &superClassMetaObject, QMetaObject *DosQMetaObject::createMetaObject(const IDosQMetaObject &superClassMetaObject,
@ -69,37 +79,36 @@ QMetaObject *DosQMetaObject::createMetaObject(const IDosQMetaObject &superClassM
{ {
QMetaObjectBuilder builder; QMetaObjectBuilder builder;
builder.setClassName(className.toUtf8()); builder.setClassName(className.toUtf8());
builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
builder.setSuperClass(superClassMetaObject.metaObject()); builder.setSuperClass(superClassMetaObject.metaObject());
m_signalIndexByName.reserve(signalDefinitions.size());
for (const SignalDefinition& signal : signalDefinitions) for (const SignalDefinition& signal : signalDefinitions)
{ {
QMetaMethodBuilder signalBuilder = builder.addSignal(::createSignature(signal)); QMetaMethodBuilder signalBuilder = builder.addSignal(::createSignature(signal));
signalBuilder.setReturnType(QMetaType::typeName(QMetaType::Void)); signalBuilder.setReturnType(QMetaType::typeName(QMetaType::Void));
signalBuilder.setAccess(QMetaMethod::Public); signalBuilder.setAccess(QMetaMethod::Public);
m_signalIndexByName[signal.name.toUtf8()] = signalBuilder.index(); m_signalIndexByName[signal.name.toStdString()] = signalBuilder.index();
} }
QHash<QString, int> methodIndexByName; std::unordered_map<std::string, int> methodIndexByName;
for (const SlotDefinition& slot : slotDefinitions) for (const SlotDefinition& slot : slotDefinitions)
{ {
QMetaMethodBuilder methodBuilder = builder.addSlot(::createSignature(slot)); QMetaMethodBuilder methodBuilder = builder.addSlot(::createSignature(slot));
methodBuilder.setReturnType(QMetaType::typeName(slot.returnType)); methodBuilder.setReturnType(QMetaType::typeName(slot.returnType));
methodBuilder.setAttributes(QMetaMethod::Scriptable); methodBuilder.setAttributes(QMetaMethod::Scriptable);
methodIndexByName[slot.name] = methodBuilder.index(); methodIndexByName[slot.name.toStdString()] = methodBuilder.index();
} }
for (const PropertyDefinition& property : propertyDefinitions) for (const PropertyDefinition& property : propertyDefinitions)
{ {
const int notifier = m_signalIndexByName.value(property.notifySignal.toUtf8(), -1); const int notifier = ::valueOrDefault(m_signalIndexByName, property.notifySignal.toStdString(), -1);
const QByteArray name = property.name.toUtf8(); const QByteArray name = property.name.toUtf8();
const QByteArray typeName = QMetaObject::normalizedType(QMetaType::typeName(property.type)); const QByteArray typeName = QMetaObject::normalizedType(QMetaType::typeName(property.type));
QMetaPropertyBuilder propertyBuilder = builder.addProperty(name, typeName, notifier); QMetaPropertyBuilder propertyBuilder = builder.addProperty(name, typeName, notifier);
if (notifier == -1) if (notifier == -1)
propertyBuilder.setConstant(true); propertyBuilder.setConstant(true);
m_propertySlots[propertyBuilder.name()] = { methodIndexByName.value(property.readSlot, -1) m_propertySlots[propertyBuilder.name().toStdString()] = std::make_pair(::valueOrDefault(methodIndexByName, property.readSlot.toStdString(), -1),
, methodIndexByName.value(property.writeSlot, -1)}; ::valueOrDefault(methodIndexByName, property.writeSlot.toStdString(), -1));
} }
return builder.toMetaObject(); return builder.toMetaObject();
@ -107,17 +116,22 @@ QMetaObject *DosQMetaObject::createMetaObject(const IDosQMetaObject &superClassM
int DosQMetaObject::signalSlotIndex(const QString &signalName) const int DosQMetaObject::signalSlotIndex(const QString &signalName) const
{ {
return metaObject()->methodOffset() + m_signalIndexByName.value(signalName.toUtf8(), -1); return metaObject()->methodOffset() + ::valueOrDefault(m_signalIndexByName, signalName.toStdString(), -1);
} }
int DosQMetaObject::readSlotIndex(const char *propertyName) const int DosQMetaObject::readSlotIndex(const char *propertyName) const
{ {
return metaObject()->methodOffset() + m_propertySlots.value(propertyName, {-1,-1}).first; return metaObject()->methodOffset() + ::valueOrDefault(m_propertySlots, std::string(propertyName), std::make_pair(-1,-1)).first;
} }
int DosQMetaObject::writeSlotIndex(const char *propertyName) const int DosQMetaObject::writeSlotIndex(const char *propertyName) const
{ {
return metaObject()->methodOffset() + m_propertySlots.value(propertyName, {-1,-1}).second; return metaObject()->methodOffset() + valueOrDefault(m_propertySlots, std::string(propertyName), std::make_pair(-1,-1)).second;
}
const QMetaObject *DosQMetaObject::metaObject() const
{
return m_metaObject;
} }
} // namespace DOS } // namespace DOS