mirror of
https://github.com/status-im/dotherside.git
synced 2025-02-21 08:58:16 +00:00
100 lines
3.1 KiB
C++
100 lines
3.1 KiB
C++
#include "DOtherSide/DynamicQObject.h"
|
|
#include "DOtherSide/DynamicQObjectFactory.h"
|
|
#include <QtCore/QMetaMethod>
|
|
#include <QtCore/QDebug>
|
|
|
|
namespace DOS
|
|
{
|
|
|
|
DynamicQObject::DynamicQObject(const DynamicQObjectFactory *factory,
|
|
OnSlotExecuted handler)
|
|
: m_factory(factory)
|
|
, m_handler(std::move(handler))
|
|
{}
|
|
|
|
bool DynamicQObject::emitSignal(const QString &name, const std::vector<QVariant> &args)
|
|
{
|
|
const int index = metaObject()->methodOffset() + m_factory->signalSlotIndex(name);
|
|
const QMetaMethod method = metaObject()->method(index);
|
|
if (!method.isValid()) {
|
|
qDebug() << "Cannot emit signal from invalid method";
|
|
return false;
|
|
}
|
|
Q_ASSERT(name.toUtf8() == method.name());
|
|
|
|
std::vector<void*> arguments(args.size() + 1, nullptr);
|
|
arguments.front() = nullptr;
|
|
auto func = [](const QVariant& arg) -> void* { return (void*)(&arg); };
|
|
std::transform(args.begin(), args.end(), arguments.begin() + 1, func);
|
|
QMetaObject::activate(this, method.methodIndex(), arguments.data());
|
|
return true;
|
|
}
|
|
|
|
const QMetaObject *DynamicQObject::metaObject() const
|
|
{
|
|
return m_factory->metaObject();
|
|
}
|
|
|
|
int DynamicQObject::qt_metacall(QMetaObject::Call callType, int index, void** args)
|
|
{
|
|
switch (callType)
|
|
{
|
|
case QMetaObject::InvokeMetaMethod:
|
|
return executeSlot(index, args) ? 1 : -1;
|
|
case QMetaObject::ReadProperty:
|
|
return readProperty(index, args) ? 1 : -1;
|
|
case QMetaObject::WriteProperty:
|
|
return writeProperty(index, args) ? 1 : -1;
|
|
default:
|
|
return QObject::qt_metacall(callType, index, args);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
bool DynamicQObject::executeSlot(int index, void **args)
|
|
{
|
|
const QMetaMethod method = metaObject()->method(index);
|
|
if (!method.isValid()) {
|
|
qDebug() << "Cannot execute invalid method";
|
|
return false;
|
|
}
|
|
|
|
std::vector<QVariant> arguments;
|
|
arguments.reserve(method.parameterCount());
|
|
for (int i = 0; i < method.parameterCount(); ++i) {
|
|
QVariant argument(method.parameterType(i), args[i + 1]);
|
|
arguments.emplace_back(std::move(argument));
|
|
}
|
|
|
|
QVariant result = m_handler(method.name(), arguments); // Execute method
|
|
|
|
if (method.returnType() != QMetaType::Void && result.isValid()) {
|
|
QMetaType::construct(method.returnType(), args[0], result.constData());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool DynamicQObject::readProperty(int index, void **args)
|
|
{
|
|
const QMetaProperty property = metaObject()->property(index);
|
|
if (!property.isValid() || !property.isReadable()) {
|
|
qDebug() << "Cannot read invalid or unreadable property ";
|
|
return false;
|
|
}
|
|
return executeSlot(m_factory->readSlotIndex(property.name()), args);
|
|
}
|
|
|
|
bool DynamicQObject::writeProperty(int index, void **args)
|
|
{
|
|
const QMetaProperty property = metaObject()->property(index);
|
|
if (!property.isValid() || !property.isWritable()) {
|
|
qDebug() << "Cannot write invalid or unwritable property ";
|
|
return false;
|
|
}
|
|
return executeSlot(m_factory->writeSlotIndex(property.name()), args);
|
|
}
|
|
|
|
} // namespace DOS
|