mirror of
https://github.com/status-im/dotherside.git
synced 2025-02-12 04:26:43 +00:00
Added QMetaObjectFactory
This commit is contained in:
parent
2ed13a3238
commit
3c63201936
@ -22,14 +22,16 @@ set(HEADERS_LIST
|
||||
include/DOtherSide/DynamicQObjectFactory.h
|
||||
include/DOtherSide/DynamicQObject.h
|
||||
include/DOtherSide/Utils.h
|
||||
include/DOtherSide/QMetaObjectFactory.h
|
||||
)
|
||||
|
||||
set(SRC_LIST
|
||||
set(SRC_LIST
|
||||
src/DOtherSide.cpp
|
||||
src/OnSlotExecutedHandler.cpp
|
||||
src/DynamicQObjectFactory.cpp
|
||||
src/DynamicQObject.cpp
|
||||
src/DOtherSideTypesCpp.cpp
|
||||
src/QMetaObjectFactory.cpp
|
||||
)
|
||||
|
||||
include_directories(include include/Qt)
|
||||
|
@ -4,7 +4,7 @@
|
||||
#ifdef WIN32
|
||||
#define DOS_API __declspec( dllexport )
|
||||
#else
|
||||
#define DOS_API
|
||||
#define DOS_API
|
||||
#endif
|
||||
|
||||
#include <DOtherSide/DOtherSideTypes.h>
|
||||
@ -48,7 +48,7 @@ DOS_API void dos_qquickview_set_source(void* vptr, const char* filename);
|
||||
DOS_API void dos_qquickview_set_resize_mode(void* vptr, int resizeMode);
|
||||
DOS_API void dos_qquickview_delete(void* vptr);
|
||||
DOS_API void dos_qquickview_rootContext(void* vptr, void** result);
|
||||
|
||||
|
||||
// QQmlContext
|
||||
DOS_API void dos_qqmlcontext_baseUrl(void* vptr, char** result);
|
||||
DOS_API void dos_qqmlcontext_setcontextproperty(void* vptr, const char* name, void* value);
|
||||
@ -87,15 +87,11 @@ DOS_API void dos_qvariant_delete(void* vptr);
|
||||
DOS_API void dos_qvariant_assign(void* vptr, void* other);
|
||||
|
||||
// QObjectFactory
|
||||
DOS_API void dos_qobjectfactory_create(void** vptr,
|
||||
DOS_API void dos_qmetaobjectfactory_create(void** vptr,
|
||||
SignalDefinitions signalDefinitions,
|
||||
SlotDefinitions slotDefinitions,
|
||||
PropertyDefinitions propertyDefinitions);
|
||||
DOS_API void dos_qobjectfactory_delete(void* vptr);
|
||||
DOS_API void dos_qobjectfactory_create_qobject(void* vptr,
|
||||
void* dObjectPointer,
|
||||
DObjectCallback dObjectCallback,
|
||||
void** result);
|
||||
DOS_API void dos_qmetaobjectfactory_delete(void* vptr);
|
||||
|
||||
// QObject
|
||||
DOS_API void dos_qobject_signal_emit(void* vptr,
|
||||
|
@ -22,9 +22,8 @@ struct SignalDefinition
|
||||
SignalDefinition(::SignalDefinition cType)
|
||||
: name(QString::fromUtf8(cType.name))
|
||||
{
|
||||
auto wrapped = wrap_array(cType.parametersMetaTypes, cType.parametersCount);
|
||||
auto conversion = [](int type)->QMetaType::Type { return static_cast<QMetaType::Type>(type);};
|
||||
std::transform(wrapped.begin(), wrapped.end(), parameterTypes.begin(), conversion);
|
||||
for (int type : wrap_array(cType.parametersMetaTypes, cType.parametersCount))
|
||||
parameterTypes.emplace_back(QMetaType::Type(type));
|
||||
}
|
||||
|
||||
QString name;
|
||||
@ -43,11 +42,10 @@ struct SlotDefinition
|
||||
|
||||
SlotDefinition(::SlotDefinition cType)
|
||||
: name(QString::fromUtf8(cType.name))
|
||||
, returnType(static_cast<QMetaType::Type>(cType.returnMetaType))
|
||||
, returnType(QMetaType::Type(cType.returnMetaType))
|
||||
{
|
||||
auto wrapped = wrap_array(cType.parametersMetaTypes, cType.parametersCount);
|
||||
auto conversion = [](int type)->QMetaType::Type { return static_cast<QMetaType::Type>(type);};
|
||||
std::transform(wrapped.begin(), wrapped.end(), parameterTypes.begin(), conversion);
|
||||
for (int type : wrap_array(cType.parametersMetaTypes, cType.parametersCount))
|
||||
parameterTypes.emplace_back(QMetaType::Type(type));
|
||||
}
|
||||
|
||||
QString name;
|
||||
|
52
lib/include/DOtherSide/QMetaObjectFactory.h
Normal file
52
lib/include/DOtherSide/QMetaObjectFactory.h
Normal file
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <tuple>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QHash>
|
||||
|
||||
#include "DOtherSide/DOtherSideTypesCpp.h"
|
||||
|
||||
namespace DOS
|
||||
{
|
||||
class QMetaObjectFactory
|
||||
{
|
||||
public:
|
||||
QMetaObjectFactory(SignalDefinitions signalDefinitions,
|
||||
SlotDefinitions slotDefinitions,
|
||||
PropertyDefinitions propertyDefinitions);
|
||||
|
||||
inline const QMetaObject* metaObject() const;
|
||||
inline int signalSlotIndex(const QString& signalName) const;
|
||||
inline int readSlotIndex(const char* propertyName) const;
|
||||
inline int writeSlotIndex(const char* propertyName) const;
|
||||
|
||||
private:
|
||||
SafeQMetaObjectPtr m_metaObject;
|
||||
QHash<QByteArray, int> m_signalIndexByName;
|
||||
QHash<QByteArray, QPair<int,int>> m_propertySlots;
|
||||
};
|
||||
|
||||
const QMetaObject *QMetaObjectFactory::metaObject() const
|
||||
{
|
||||
return m_metaObject;
|
||||
}
|
||||
|
||||
inline int QMetaObjectFactory::signalSlotIndex(const QString &signalName) const
|
||||
{
|
||||
return m_signalIndexByName.value(signalName.toUtf8(), -1);
|
||||
}
|
||||
|
||||
inline int QMetaObjectFactory::readSlotIndex(const char *propertyName) const
|
||||
{
|
||||
return m_propertySlots.value(propertyName, {-1,-1}).first;
|
||||
}
|
||||
|
||||
inline int QMetaObjectFactory::writeSlotIndex(const char *propertyName) const
|
||||
{
|
||||
return m_propertySlots.value(propertyName, {-1,-1}).second;
|
||||
}
|
||||
} // namespace DOS
|
@ -29,7 +29,8 @@ std::vector<T> toVector(G* first, std::ptrdiff_t size) noexcept
|
||||
{
|
||||
const wrapped_array<G> array = wrap_array(first, size);
|
||||
std::vector<T> result;
|
||||
std::copy(array.begin(), array.end(), result.begin());
|
||||
for (auto it = array.begin(); it != array.end(); ++it)
|
||||
result.emplace_back(T(*it));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -38,7 +39,8 @@ std::vector<R> toVector(T* first, std::ptrdiff_t size, K f) noexcept
|
||||
{
|
||||
wrapped_array<T> array = wrap_array<T>(first, size);
|
||||
std::vector<R> result;
|
||||
std::transform(array.begin(), array.end(), result.begin(), f);
|
||||
for (auto it = array.begin(); it != array.end(); ++it)
|
||||
result.emplace_back(R(f(*it)));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -514,7 +514,7 @@ void dos_qurl_to_string(void* vptr, char** result)
|
||||
}
|
||||
|
||||
|
||||
void dos_qobjectfactory_create(void **vptr,
|
||||
void dos_qmetaobjectfactory_create(void **vptr,
|
||||
SignalDefinitions signalDefinitions,
|
||||
SlotDefinitions slotDefinitions,
|
||||
PropertyDefinitions propertyDefinitions)
|
||||
@ -524,14 +524,8 @@ void dos_qobjectfactory_create(void **vptr,
|
||||
DOS::toVector(propertyDefinitions));
|
||||
}
|
||||
|
||||
void dos_qobjectfactory_delete(void *vptr)
|
||||
void dos_qmetaobjectfactory_delete(void *vptr)
|
||||
{
|
||||
auto factory = reinterpret_cast<DOS::DynamicQObjectFactory*>(vptr);
|
||||
delete factory;
|
||||
}
|
||||
|
||||
void dos_qobjectfactory_create_qobject(void *vptr, void* dObjectPointer, DObjectCallback dObjectCallback, void **result)
|
||||
{
|
||||
auto factory = reinterpret_cast<DOS::DynamicQObjectFactory*>(vptr);
|
||||
*result = factory->create(DOS::OnSlotExecutedHandler(dObjectPointer, dObjectCallback));
|
||||
}
|
||||
|
71
lib/src/QMetaObjectFactory.cpp
Normal file
71
lib/src/QMetaObjectFactory.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include "DOtherSide/QMetaObjectFactory.h"
|
||||
#include "private/qmetaobjectbuilder_p.h"
|
||||
#include "private/qmetaobject_p.h"
|
||||
#include "private/qobject_p.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
template<class T>
|
||||
QByteArray createSignature(const T& functionDefinition)
|
||||
{
|
||||
QString signature("%1(%2)");
|
||||
QString arguments;
|
||||
|
||||
for (int type : functionDefinition.parameterTypes) {
|
||||
if (type != functionDefinition.parameterTypes.front())
|
||||
arguments += QLatin1Char(',');
|
||||
arguments += QMetaType::typeName(type);
|
||||
}
|
||||
|
||||
return signature.arg(functionDefinition.name, arguments).toUtf8();
|
||||
}
|
||||
}
|
||||
|
||||
namespace DOS
|
||||
{
|
||||
|
||||
QMetaObjectFactory::QMetaObjectFactory(SignalDefinitions signalDefinitions,
|
||||
SlotDefinitions slotDefinitions,
|
||||
PropertyDefinitions propertyDefinitions)
|
||||
: m_metaObject(nullptr)
|
||||
{
|
||||
QMetaObjectBuilder builder;
|
||||
builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
|
||||
builder.setClassName("DynamicQObject");
|
||||
builder.setSuperClass(&QObject::staticMetaObject);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
QHash<QString, 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();
|
||||
}
|
||||
|
||||
for (const PropertyDefinition& property : propertyDefinitions)
|
||||
{
|
||||
const int notifier = m_signalIndexByName.value(property.notifySignal.toUtf8(), -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_metaObject.reset(builder.toMetaObject());
|
||||
}
|
||||
|
||||
} // namespace DOS
|
Loading…
x
Reference in New Issue
Block a user