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_assign(void* vptr, void* other);
// QObjectFactory
DOS_API void dos_qmetaobject_create(void** vptr, void *superClassMetaObject, const char *className,
// QMetaObject
DOS_API void dos_qmetaobject_create(void** vptr,
void *superClassMetaObject,
const char *className,
SignalDefinitions signalDefinitions,
SlotDefinitions slotDefinitions,
PropertyDefinitions propertyDefinitions);

View File

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

View File

@ -536,9 +536,13 @@ void dos_qmetaobject_create(void **vptr,
::SlotDefinitions slotDefinitions,
::PropertyDefinitions propertyDefinitions)
{
Q_ASSERT(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),
toVector(signalDefinitions),
toVector(slotDefinitions),

View File

@ -23,10 +23,18 @@ QByteArray createSignature(const T& functionDefinition)
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()
{
QMetaObjectBuilder builder;
builder.setClassName("DynamicQObject");
builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
builder.setSuperClass(&QObject::staticMetaObject);
return builder.toMetaObject();
}
@ -34,6 +42,7 @@ QMetaObject* createDynamicQObjectMetaObject()
QMetaObject* createDynamicQAbstractListModelMetaObject()
{
QMetaObjectBuilder builder;
builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
builder.setClassName("DynamicQAbstractListModel");
builder.setSuperClass(&QAbstractListModel::staticMetaObject);
return builder.toMetaObject();
@ -57,8 +66,9 @@ DosQMetaObject::DosQMetaObject(const IDosQMetaObject &superClassMetaObject,
const SignalDefinitions& signalDefinitions,
const SlotDefinitions& slotDefinitions,
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,
@ -69,37 +79,36 @@ QMetaObject *DosQMetaObject::createMetaObject(const IDosQMetaObject &superClassM
{
QMetaObjectBuilder builder;
builder.setClassName(className.toUtf8());
builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
builder.setSuperClass(superClassMetaObject.metaObject());
m_signalIndexByName.reserve(signalDefinitions.size());
for (const SignalDefinition& signal : signalDefinitions)
{
QMetaMethodBuilder signalBuilder = builder.addSignal(::createSignature(signal));
signalBuilder.setReturnType(QMetaType::typeName(QMetaType::Void));
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)
{
QMetaMethodBuilder methodBuilder = builder.addSlot(::createSignature(slot));
methodBuilder.setReturnType(QMetaType::typeName(slot.returnType));
methodBuilder.setAttributes(QMetaMethod::Scriptable);
methodIndexByName[slot.name] = methodBuilder.index();
methodIndexByName[slot.name.toStdString()] = methodBuilder.index();
}
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 typeName = QMetaObject::normalizedType(QMetaType::typeName(property.type));
QMetaPropertyBuilder propertyBuilder = builder.addProperty(name, typeName, notifier);
if (notifier == -1)
propertyBuilder.setConstant(true);
m_propertySlots[propertyBuilder.name()] = { methodIndexByName.value(property.readSlot, -1)
, methodIndexByName.value(property.writeSlot, -1)};
m_propertySlots[propertyBuilder.name().toStdString()] = std::make_pair(::valueOrDefault(methodIndexByName, property.readSlot.toStdString(), -1),
::valueOrDefault(methodIndexByName, property.writeSlot.toStdString(), -1));
}
return builder.toMetaObject();
@ -107,17 +116,22 @@ QMetaObject *DosQMetaObject::createMetaObject(const IDosQMetaObject &superClassM
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
{
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
{
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