Initial version

This commit is contained in:
Filippo Cucchetto 2015-02-04 23:02:26 +01:00
parent 23c73e4e75
commit e6e67e07b4
20 changed files with 1109 additions and 1001 deletions

View File

@ -1,3 +1,3 @@
add_subdirectory(DOtherSide)
add_subdirectory(DynamicQObject)
add_subdirectory(IntegrationTest)
#add_subdirectory(DynamicQObject)
#add_subdirectory(IntegrationTest)

View File

@ -1,82 +0,0 @@
#include "BaseQAbstractListModel.h"
BaseQAbstractListModel::BaseQAbstractListModel(void* modelObject,
RowCountCallback rowCountCallback,
DataCallback dataCallback,
RoleNamesCallback roleNamesCallback)
: m_modelObject(modelObject)
, m_rowCountCallback(rowCountCallback)
, m_dataCallback(dataCallback)
, m_roleNamesCallback(roleNamesCallback)
{
}
int BaseQAbstractListModel::rowCount(const QModelIndex& index) const
{
auto newIndex = new QModelIndex();
*newIndex = index;
int result;
m_rowCountCallback(m_modelObject, newIndex, &result);
return result;
}
QVariant BaseQAbstractListModel::data(const QModelIndex& index, int role) const
{
auto newIndex = new QModelIndex();
*newIndex = index;
QVariant result;
m_dataCallback(m_modelObject, newIndex, role, &result);
return result;
}
void* BaseQAbstractListModel::modelObject()
{
return m_modelObject;
}
QHash<int, QByteArray> BaseQAbstractListModel::roleNames() const
{
QHash<int, QByteArray> result;
m_roleNamesCallback(m_modelObject, &result);
return result;
}
void BaseQAbstractListModel::publicBeginInsertRows(const QModelIndex& index, int first, int last)
{
beginInsertRows(index, first, last);
}
void BaseQAbstractListModel::publicEndInsertRows()
{
return endInsertRows();
}
void BaseQAbstractListModel::publicBeginRemoveRows(const QModelIndex& index, int first, int last)
{
beginRemoveRows(index, first, last);
}
void BaseQAbstractListModel::publicEndRemoveRows()
{
return endRemoveRows();
}
void BaseQAbstractListModel::publicBeginResetModel()
{
beginResetModel();
}
void BaseQAbstractListModel::publicEndResetModel()
{
endResetModel();
}
void BaseQAbstractListModel::publicDataChanged(const QModelIndex& topLeft,
const QModelIndex& bottomRight,
const QVector<int>& roles)
{
emit dataChanged(topLeft, bottomRight, roles);
}

View File

@ -1,10 +1,12 @@
#pragma once
#ifndef BASEQABSTRACTLISTMODEL_H
#define BASEQABSTRACTLISTMODEL_H
#include "DOtherSideTypes.h"
#include "DynamicQObject.h"
#include <QAbstractListModel>
/// This class act as a base class for D and Nim QAbstractListModel
class BaseQAbstractListModel : public QAbstractListModel
class BaseQAbstractListModel : public DynamicQObject<QAbstractListModel>
{
public:
/// Constructor
@ -27,30 +29,110 @@ public:
/// Expose beginInsertRows
void publicBeginInsertRows(const QModelIndex& index, int first, int last);
/// Expose endInsertRows
void publicEndInsertRows();
/// Expose beginRemoveRows
void publicBeginRemoveRows(const QModelIndex& index, int first, int last);
/// Expose endInsertRows
void publicEndRemoveRows();
/// Expose beginResetModel
void publicBeginResetModel();
/// Expose endResetModel
void publicEndResetModel();
/// Expose dataChanged
void publicDataChanged(const QModelIndex& topLeft,
const QModelIndex& bottomRight,
void publicDataChanged(const QModelIndex& topLeft,
const QModelIndex& bottomRight,
const QVector<int>& roles = QVector<int>());
private:
void* m_modelObject;
RowCountCallback m_rowCountCallback;
DataCallback m_dataCallback;
RoleNamesCallback m_roleNamesCallback;
};
BaseQAbstractListModel::BaseQAbstractListModel(void* modelObject,
RowCountCallback rowCountCallback,
DataCallback dataCallback,
RoleNamesCallback roleNamesCallback)
: m_modelObject(modelObject)
, m_rowCountCallback(rowCountCallback)
, m_dataCallback(dataCallback)
, m_roleNamesCallback(roleNamesCallback)
{
}
int BaseQAbstractListModel::rowCount(const QModelIndex& index) const
{
auto newIndex = new QModelIndex();
*newIndex = index;
int result;
m_rowCountCallback(m_modelObject, newIndex, &result);
return result;
}
QVariant BaseQAbstractListModel::data(const QModelIndex& index, int role) const
{
auto newIndex = new QModelIndex();
*newIndex = index;
QVariant result;
m_dataCallback(m_modelObject, newIndex, role, &result);
return result;
}
void* BaseQAbstractListModel::modelObject()
{
return m_modelObject;
}
QHash<int, QByteArray> BaseQAbstractListModel::roleNames() const
{
QHash<int, QByteArray> result;
m_roleNamesCallback(m_modelObject, &result);
return result;
}
void BaseQAbstractListModel::publicBeginInsertRows(const QModelIndex& index, int first, int last)
{
beginInsertRows(index, first, last);
}
void BaseQAbstractListModel::publicEndInsertRows()
{
return endInsertRows();
}
void BaseQAbstractListModel::publicBeginRemoveRows(const QModelIndex& index, int first, int last)
{
beginRemoveRows(index, first, last);
}
void BaseQAbstractListModel::publicEndRemoveRows()
{
return endRemoveRows();
}
void BaseQAbstractListModel::publicBeginResetModel()
{
beginResetModel();
}
void BaseQAbstractListModel::publicEndResetModel()
{
endResetModel();
}
void BaseQAbstractListModel::publicDataChanged(const QModelIndex& topLeft,
const QModelIndex& bottomRight,
const QVector<int>& roles)
{
emit dataChanged(topLeft, bottomRight, roles);
}
#endif

View File

@ -0,0 +1,8 @@
#ifndef BASEQOBJECT_H
#define BASEQOBJECT_H
#include "DynamicQObject.h"
class BaseQObject : public DynamicQObject<QObject> {};
#endif

View File

@ -12,14 +12,15 @@ find_package(Qt5Widgets)
set(HEADERS_LIST
DOtherSide.h
DOtherSideTypes.h
BaseQAbstractListModel.h
BaseQObject.h
)
set(SRC_LIST
DOtherSide.cpp
BaseQAbstractListModel.cpp
)
add_library(${PROJECT_NAME} SHARED ${SRC_LIST} ${HEADERS_LIST})
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Qml Qt5::Quick DynamicQObject)
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Qml Qt5::Quick)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../DynamicQObject)

View File

@ -1,5 +1,7 @@
#include "DOtherSide.h"
#include <iostream>
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtCore/QModelIndex>
@ -8,10 +10,10 @@
#include <QtQml/QQmlApplicationEngine>
#include <QtQuick/QQuickView>
#include <QtWidgets/QApplication>
#include <iostream>
#include "DynamicQObject.h"
#include "BaseQAbstractListModel.h"
#include "BaseQObject.h"
void convert_to_cstring(const QString& source, char** destination, int* length)
{
@ -307,7 +309,7 @@ void dos_qvariant_setQAbstractListModel(void* vptr, void* value)
void dos_qobject_create(void** vptr, void* dObjectPointer, DObjectCallback dObjectCallback)
{
auto dynamicQObject = new DynamicQObject();
auto dynamicQObject = new DynamicQObject<QObject>();
QQmlEngine::setObjectOwnership(dynamicQObject, QQmlEngine::CppOwnership);
dynamicQObject->setDObjectPointer(dObjectPointer);
dynamicQObject->setDObjectCallback(dObjectCallback);
@ -316,7 +318,7 @@ void dos_qobject_create(void** vptr, void* dObjectPointer, DObjectCallback dObje
void dos_qobject_delete(void* vptr)
{
auto dynamicQObject = reinterpret_cast<DynamicQObject*>(vptr);
auto dynamicQObject = reinterpret_cast<DynamicQObject<QObject>*>(vptr);
dynamicQObject->disconnect();
delete dynamicQObject;
}
@ -326,7 +328,7 @@ void dos_qobject_slot_create(void* vptr, const char* name, int parametersCount,
if (parametersCount <= 0)
return;
auto dynamicQObject = reinterpret_cast<DynamicQObject*>(vptr);
auto dynamicQObject = reinterpret_cast<DynamicQObject<QObject>*>(vptr);
QMetaType::Type returnType = static_cast<QMetaType::Type>(parametersMetaTypes[0]);
QList<QMetaType::Type> argumentsTypes;
@ -341,7 +343,7 @@ void dos_qobject_signal_create(void* vptr, const char* name, int parametersCount
if (parametersCount <= 0)
return;
auto dynamicQObject = reinterpret_cast<DynamicQObject*>(vptr);
auto dynamicQObject = reinterpret_cast<DynamicQObject<QObject>*>(vptr);
QList<QMetaType::Type> argumentsTypes;
for (int i = 0; i < parametersCount; ++i)
@ -352,7 +354,7 @@ void dos_qobject_signal_create(void* vptr, const char* name, int parametersCount
void dos_qobject_signal_emit(void* vptr, const char* name, int parametersCount, void** parameters)
{
auto dynamicQObject = reinterpret_cast<DynamicQObject*>(vptr);
auto dynamicQObject = reinterpret_cast<DynamicQObject<QObject>*>(vptr);
QVariantList arguments;
for (int i = 0; i < parametersCount; ++i)
arguments << *(reinterpret_cast<QVariant*>(parameters[i]));
@ -366,7 +368,7 @@ void dos_qobject_property_create(void* vptr,
const char* writeSlot,
const char* notifySignal)
{
auto dynamicQObject = reinterpret_cast<DynamicQObject*>(vptr);
auto dynamicQObject = reinterpret_cast<DynamicQObject<QObject>*>(vptr);
dynamicQObject->registerProperty(QString(name),
QMetaType::Type(type),
QString(readSlot),
@ -489,8 +491,8 @@ void dos_qabstractlistmodel_endResetModel(void* vptr)
model->publicEndResetModel();
}
void dos_qabstractlistmodel_dataChanged(void* vptr,
QModelIndexVoidPtr topLeftIndex,
void dos_qabstractlistmodel_dataChanged(void* vptr,
QModelIndexVoidPtr topLeftIndex,
QModelIndexVoidPtr bottomRightIndex,
int* rolesArrayPtr,
int rolesArrayLength)

View File

@ -125,19 +125,19 @@ void dos_qabstractlistmodel_create(void** vptr,
RowCountCallback rowCountCallback,
DataCallback dataCallback,
RoleNamesCallback roleNamesCallback);
void dos_qabstractlistmodel_beginInsertRows(void* vptr,
QModelIndexVoidPtr parentIndex,
int first,
int last);
void dos_qabstractlistmodel_beginInsertRows(void* vptr,
QModelIndexVoidPtr parentIndex,
int first,
int last);
void dos_qabstractlistmodel_endInsertRows(void* vptr);
void dos_qabstractlistmodel_beginRemoveRows(void* vptr,
QModelIndexVoidPtr parentIndex,
int first,
int last);
void dos_qabstractlistmodel_beginRemoveRows(void* vptr,
QModelIndexVoidPtr parentIndex,
int first,
int last);
void dos_qabstractlistmodel_endRemoveRows(void* vptr);
void dos_qabstractlistmodel_beginResetModel(void* vptr);
void dos_qabstractlistmodel_endResetModel(void* vptr);
void dos_qabstractlistmodel_dataChanged(void* vptr,
void dos_qabstractlistmodel_dataChanged(void* vptr,
QModelIndexVoidPtr topLeftIndex,
QModelIndexVoidPtr bottomRightIndex,
int* rolesArrayPtr,

View File

@ -15,7 +15,6 @@ set(HEADERS_LIST
set(SRC_LIST
DynamicProperty.cpp
DynamicQObject.cpp
DynamicSignal.cpp
DynamicSlot.cpp
)

View File

@ -1,113 +0,0 @@
#include "DynamicProperty.h"
#include <QtCore/QString>
struct PropertyData
{
PropertyData(const QString& name,
QMetaType::Type type,
const QString& readSlotName,
const QString& writeSlotName,
const QString& notifySignalName)
: name(name)
, type(type)
, readSlotName(readSlotName)
, writeSlotName(writeSlotName)
, notifySignalName(notifySignalName)
{}
PropertyData(const PropertyData& other)
: name(other.name)
, type(other.type)
, readSlotName(other.readSlotName)
, writeSlotName(other.writeSlotName)
, notifySignalName(other.notifySignalName)
{}
PropertyData& operator=(const PropertyData& other)
{
name = other.name;
type = other.type;
readSlotName = other.readSlotName;
writeSlotName = other.writeSlotName;
notifySignalName = other.notifySignalName;
return *this;
}
QString name;
QMetaType::Type type;
QString readSlotName;
QString writeSlotName;
QString notifySignalName;
};
DynamicProperty::DynamicProperty()
: d(nullptr)
{}
DynamicProperty::DynamicProperty(const QString& name, QMetaType::Type type, const QString& readSlotName, const QString& writeSlotName, const QString& notifySignalName)
: d(new PropertyData(name, type, readSlotName, writeSlotName, notifySignalName))
{
}
DynamicProperty::DynamicProperty(const DynamicProperty& other)
: d(nullptr)
{
if (other.d)
d.reset(new PropertyData(*other.d));
}
DynamicProperty& DynamicProperty::operator=(const DynamicProperty& other)
{
if (!other.d && d)
d.reset();
else if (other.d && !d)
d.reset(new PropertyData(*other.d));
else if (other.d && d)
*d = *other.d;
return *this;
}
DynamicProperty::~DynamicProperty()
{}
QString DynamicProperty::name() const
{
return d->name;
}
QMetaType::Type DynamicProperty::type() const
{
return d->type;
}
bool DynamicProperty::isReadable() const
{
return !d->readSlotName.isEmpty();
}
bool DynamicProperty::isWriteable() const
{
return !d->writeSlotName.isEmpty();
}
bool DynamicProperty::hasNotifySignal() const
{
return !d->notifySignalName.isEmpty();
}
QString DynamicProperty::readSlot() const
{
return d->readSlotName;
}
QString DynamicProperty::writeSlot() const
{
return d->writeSlotName;
}
QString DynamicProperty::notifySignal() const
{
return d->notifySignalName;
}

View File

@ -1,10 +1,10 @@
#pragma once
#ifndef DYNAMICPROPERTY_H
#define DYNAMICPROPERTY_H
#include <memory>
#include <QtCore/QString>
#include <QtCore/QMetaType>
#include <memory>
class QString;
class PropertyData;
class DynamicProperty
@ -38,3 +38,115 @@ public:
private:
std::unique_ptr<PropertyData> d;
};
struct PropertyData
{
PropertyData(const QString& name,
QMetaType::Type type,
const QString& readSlotName,
const QString& writeSlotName,
const QString& notifySignalName)
: name(name)
, type(type)
, readSlotName(readSlotName)
, writeSlotName(writeSlotName)
, notifySignalName(notifySignalName)
{}
PropertyData(const PropertyData& other)
: name(other.name)
, type(other.type)
, readSlotName(other.readSlotName)
, writeSlotName(other.writeSlotName)
, notifySignalName(other.notifySignalName)
{}
PropertyData& operator=(const PropertyData& other)
{
name = other.name;
type = other.type;
readSlotName = other.readSlotName;
writeSlotName = other.writeSlotName;
notifySignalName = other.notifySignalName;
return *this;
}
QString name;
QMetaType::Type type;
QString readSlotName;
QString writeSlotName;
QString notifySignalName;
};
DynamicProperty::DynamicProperty()
: d(nullptr)
{}
DynamicProperty::DynamicProperty(const QString& name, QMetaType::Type type, const QString& readSlotName, const QString& writeSlotName, const QString& notifySignalName)
: d(new PropertyData(name, type, readSlotName, writeSlotName, notifySignalName))
{
}
DynamicProperty::DynamicProperty(const DynamicProperty& other)
: d(nullptr)
{
if (other.d)
d.reset(new PropertyData(*other.d));
}
DynamicProperty& DynamicProperty::operator=(const DynamicProperty& other)
{
if (!other.d && d)
d.reset();
else if (other.d && !d)
d.reset(new PropertyData(*other.d));
else if (other.d && d)
*d = *other.d;
return *this;
}
DynamicProperty::~DynamicProperty()
{}
QString DynamicProperty::name() const
{
return d->name;
}
QMetaType::Type DynamicProperty::type() const
{
return d->type;
}
bool DynamicProperty::isReadable() const
{
return !d->readSlotName.isEmpty();
}
bool DynamicProperty::isWriteable() const
{
return !d->writeSlotName.isEmpty();
}
bool DynamicProperty::hasNotifySignal() const
{
return !d->notifySignalName.isEmpty();
}
QString DynamicProperty::readSlot() const
{
return d->readSlotName;
}
QString DynamicProperty::writeSlot() const
{
return d->writeSlotName;
}
QString DynamicProperty::notifySignal() const
{
return d->notifySignalName;
}
#endif

View File

@ -1,347 +0,0 @@
#include "DynamicQObject.h"
#include <QDebug>
#include <memory>
#include <array>
#include "private/qmetaobjectbuilder_p.h"
DynamicQObject::DynamicQObject()
: m_dObjectPointer(nullptr)
, m_dObjectCallback(nullptr)
{
QMetaObjectBuilder builder;
builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
builder.setClassName("DynamicQObject");
builder.setSuperClass(&QObject::staticMetaObject);
m_metaObject.reset(builder.toMetaObject());
}
DynamicQObject::~DynamicQObject() = default;
bool DynamicQObject::registerSlot(const QString& name,
const QMetaType::Type returnType,
const QList<QMetaType::Type>& argumentsTypes,
int& slotIndex)
{
DynamicSlot slot(name, returnType, argumentsTypes);
if (m_slotsBySignature.contains(slot.signature()))
return false;
m_slotsByName.insertMulti(slot.name(), slot);
m_slotsBySignature[slot.signature()] = slot;
auto afterSignalAdded = [](QMetaObjectBuilder&) {};
auto afterPropertyAdded = afterSignalAdded;
auto afterSlotAdded = [&slot, returnType](QMetaObjectBuilder & metaObjectBuilder) {
QMetaMethodBuilder methodBuilder = metaObjectBuilder.addSlot(slot.signature());
methodBuilder.setReturnType(QMetaType::typeName(returnType));
methodBuilder.setAttributes(QMetaMethod::Scriptable);
};
auto newMetaObject = recreateMetaObjectBuilder(m_metaObject.data()
, afterSignalAdded
, afterSlotAdded
, afterPropertyAdded);
m_metaObject.reset(newMetaObject);
slotIndex = m_metaObject->indexOfSlot(QMetaObject::normalizedSignature(slot.signature()));
return slotIndex != -1;
}
bool DynamicQObject::registerSignal(const QString& name, const QList<QMetaType::Type>& arguments, int& signalIndex)
{
DynamicSignal signal(name, arguments);
if (m_signalsBySignature.contains(signal.signature()))
return false;
m_signalsByName.insertMulti(signal.name(), signal);
m_signalsBySignature[signal.signature()] = signal;
auto afterSignalAdded = [&signal](QMetaObjectBuilder & metaObjectBuilder) {
QMetaMethodBuilder methodBuilder = metaObjectBuilder.addSignal(signal.signature());
methodBuilder.setReturnType(QMetaType::typeName(QMetaType::Void));
methodBuilder.setAccess(QMetaMethod::Public);
};
auto afterSlotAdded = [](QMetaObjectBuilder&) { };
auto afterPropertyAdded = afterSlotAdded;
auto newMetaObject = recreateMetaObjectBuilder(m_metaObject.data()
, afterSignalAdded
, afterSlotAdded
, afterPropertyAdded);
m_metaObject.reset(newMetaObject);
signalIndex = m_metaObject->indexOfSignal(QMetaObject::normalizedSignature(signal.signature()));
return signalIndex != -1;
}
bool DynamicQObject::registerProperty(const QString& name,
QMetaType::Type type,
const QString& readSlotName,
const QString& writeSlotName,
const QString& notifySignalName)
{
DynamicProperty property(name, type, readSlotName, writeSlotName, notifySignalName);
DynamicSignal notifySignal;
if (!notifySignalName.isEmpty())
{
notifySignal = m_signalsByName.value(notifySignalName, DynamicSignal());
if (!notifySignal.isValid())
return false;
}
m_propertiesByName.insert(name.toUtf8(), property);
auto afterSignalAdded = [](QMetaObjectBuilder & metaObjectBuilder) {};
auto afterSlotAdded = [](QMetaObjectBuilder & metaObjectBuilder) {};
auto afterPropertyAdded = [name, type, notifySignal](QMetaObjectBuilder & metaObjectBuilder)
{
int signalIndex = -1;
if (notifySignal.isValid())
{
for (int i = 0; i < metaObjectBuilder.methodCount(); ++i)
{
QMetaMethodBuilder methodBuilder = metaObjectBuilder.method(i);
if (methodBuilder.methodType() == QMetaMethod::Signal)
{
if (methodBuilder.signature() == QMetaObject::normalizedSignature(notifySignal.signature()));
{
signalIndex = i;
break;
}
}
}
}
auto typeName = QMetaType::typeName(type);
auto builder = metaObjectBuilder.addProperty(name.toUtf8(),
QMetaObject::normalizedType(typeName),
signalIndex);
if (signalIndex == -1)
builder.setConstant(true);
};
auto newMetaObject = recreateMetaObjectBuilder(m_metaObject.data()
, afterSignalAdded
, afterSlotAdded
, afterPropertyAdded);
m_metaObject.reset(newMetaObject);
return true;
}
bool DynamicQObject::emitSignal(const QString& name, const QList<QVariant>& args)
{
DynamicSignal signal;
for (DynamicSignal currentSignal : m_signalsByName.values(name))
{
if (currentSignal.validate(args))
{
signal = currentSignal;
break;
}
}
if (!signal.isValid())
return false;
int index = m_metaObject->indexOfSignal(QMetaObject::normalizedSignature(signal.signature()));
if (index < 0)
return false;
QVariantList argsCopy = args;
QVector<void*> arguments(argsCopy.size() + 1 , 0);
arguments[0] = 0;
for (int i = 0; i < argsCopy.size(); ++i)
arguments[i + 1] = &argsCopy[i];
QMetaObject::activate(this, index, arguments.data());
return true;
}
const QMetaObject* DynamicQObject::metaObject() const
{
return m_metaObject.data();
}
bool DynamicQObject::executeSlot(const DynamicSlot& slot, void** args)
{
if (!slot.isValid())
return false;
QList<QVariant> arguments;
for (int i = 0; i < slot.argumentsTypes().count(); ++i)
arguments << QVariant(slot.argumentTypeAt(i), args[i + 1]);
QVariant result = executeSlot(slot, arguments);
if (slot.returnType() != QMetaType::Void && result.isValid())
{
QMetaType metatype(slot.returnType());
metatype.construct(args[0], result.constData());
}
return true;
}
QVariant DynamicQObject::executeSlot(const DynamicSlot& slot, const QList<QVariant>& args)
{
QVariant slotName(slot.name());
const int numParametersPlusReturn = slot.argumentsTypes().count() + 1;
std::vector<QVariant> argumentsAsVariants(numParametersPlusReturn);
std::vector<void*> argumentsAsVoidPointers(numParametersPlusReturn);
for (int i = 0; i < numParametersPlusReturn; ++i) {
argumentsAsVariants[i] = i == 0 ? QVariant() : args[i - 1];
argumentsAsVoidPointers[i] = &argumentsAsVariants[i];
}
if (m_dObjectCallback && m_dObjectPointer)
m_dObjectCallback(m_dObjectPointer, &slotName, numParametersPlusReturn, &argumentsAsVoidPointers[0]);
return argumentsAsVariants[0];
}
bool DynamicQObject::readProperty(const DynamicProperty& property, void** args)
{
if (!property.isValid())
return false;
if (!property.isReadable())
return false;
DynamicSlot readSlot = m_slotsByName.value(property.readSlot(), DynamicSlot());
if (!readSlot.isValid())
return false;
if (readSlot.argumentsTypes().count() > 0)
return false;
if (readSlot.returnType() != property.type())
return false;
return executeSlot(readSlot, args);
}
bool DynamicQObject::writeProperty(const DynamicProperty& property, void** args)
{
if (!property.isValid())
return false;
if (!property.isWriteable())
return false;
DynamicSlot writeSlot = m_slotsByName.value(property.writeSlot(), DynamicSlot());
if (!writeSlot.isValid())
return false;
if (writeSlot.argumentsTypes().count() != 1)
return false;
if (writeSlot.returnType() != QMetaType::Void)
return false;
QVariant newValue(writeSlot.argumentTypeAt(0), args[0]);
executeSlot(writeSlot, {newValue});
}
int DynamicQObject::qt_metacall(QMetaObject::Call callType, int index, void** args)
{
if (callType == QMetaObject::InvokeMetaMethod)
{
QMetaMethod method = m_metaObject->method(index);
if (!method.isValid())
return -1;
DynamicSlot slot = m_slotsBySignature[method.methodSignature()];
return executeSlot(slot, args) ? 1 : -1;
}
else if (callType == QMetaObject::ReadProperty)
{
QMetaProperty metaProperty = m_metaObject->property(index);
if (!metaProperty.isValid())
return -1;
DynamicProperty dynamicProperty = m_propertiesByName.value(metaProperty.name(), DynamicProperty());
return readProperty(dynamicProperty, args) ? 1 : -1;
}
else if (callType == QMetaObject::WriteProperty)
{
QMetaProperty metaProperty = m_metaObject->property(index);
if (!metaProperty.isValid())
return -1;
DynamicProperty dynamicProperty = m_propertiesByName.value(metaProperty.name(), DynamicProperty());
return writeProperty(dynamicProperty, args) ? 1 : -1;
}
return -1;
}
QMetaObject* DynamicQObject::recreateMetaObjectBuilder(QMetaObject* currentMetaObject,
const std::function<void(QMetaObjectBuilder&)>& afterSignalAdded,
const std::function<void(QMetaObjectBuilder&)>& afterSlotAdded,
const std::function<void(QMetaObjectBuilder&)>& afterPropertyAdded)
{
// Collect the current methods and signals
QList<QMetaMethod> signalsList;
QList<QMetaMethod> methodsList;
QList<QMetaProperty> propertiesList;
for (int i = currentMetaObject->methodOffset(); i < currentMetaObject->methodCount(); ++i)
{
QMetaMethod method = currentMetaObject->method(i);
if (method.methodType() == QMetaMethod::Signal)
signalsList.append(method);
else
methodsList.append(method);
}
for (int i = currentMetaObject->propertyOffset(); i < currentMetaObject->propertyCount(); ++i)
{
QMetaProperty property = currentMetaObject->property(i);
propertiesList.append(property);
}
QMetaObjectBuilder metaObjectBuilder;
metaObjectBuilder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
metaObjectBuilder.setClassName(currentMetaObject->className());
metaObjectBuilder.setSuperClass(currentMetaObject->superClass());
foreach (auto& method, signalsList)
metaObjectBuilder.addMethod(method);
// Call custom code to be executed after signal have been added
afterSignalAdded(metaObjectBuilder);
foreach (auto& method, methodsList)
metaObjectBuilder.addMethod(method);
// Call custom code to be executed after slots have been added
afterSlotAdded(metaObjectBuilder);
foreach (auto& property, propertiesList)
metaObjectBuilder.addProperty(property);
afterPropertyAdded(metaObjectBuilder);
return metaObjectBuilder.toMetaObject();
}

View File

@ -1,16 +1,21 @@
#pragma once
#ifndef DYNAMICQOBJECT_H
#define DYNAMICQOBJECT_H
#include <QObject>
#include <QScopedPointer>
#include <memory>
#include <array>
#include <QtCore/QObject>
#include <QtCore/QScopedPointer>
#include <QtCore/QDebug>
#include "private/qmetaobjectbuilder_p.h"
#include "DynamicSignal.h"
#include "DynamicSlot.h"
#include "DynamicProperty.h"
class QMetaObjectBuilder;
#include "IDynamicQObject.h"
/// This class implements a QObject to which signals, slots and properties can be added dynamically
class DynamicQObject : public QObject
template <class T>
class DynamicQObject : public T
{
typedef void (*Callback)(void*, void*, int, void**);
@ -22,35 +27,35 @@ public:
virtual ~DynamicQObject();
/// Sets the function to be called from C++ to D or Nimrod
void setDObjectCallback(Callback callback) {
virtual void setDObjectCallback(Callback callback) {
m_dObjectCallback = callback;
}
/// Sets the D or Nimrod object that owns this DynamicQObject
void setDObjectPointer(void* dObjectPointer) {
virtual void setDObjectPointer(void* dObjectPointer) {
m_dObjectPointer = dObjectPointer;
}
/// Register a new signal
bool registerSignal(const QString& name,
const QList<QMetaType::Type>& argumentsTypes,
int& signalIndex);
virtual bool registerSignal(const QString& name,
const QList<QMetaType::Type>& argumentsTypes,
int& signalIndex);
/// Register a new slot
bool registerSlot(const QString& name,
const QMetaType::Type returnType,
const QList<QMetaType::Type>& argumentsTypes,
int& slotIndex);
virtual bool registerSlot(const QString& name,
const QMetaType::Type returnType,
const QList<QMetaType::Type>& argumentsTypes,
int& slotIndex);
/// Register a new property
bool registerProperty(const QString& name,
QMetaType::Type type,
const QString& readSlotName,
const QString& writeSlotName = "",
const QString& notifySignalName = "");
virtual bool registerProperty(const QString& name,
QMetaType::Type type,
const QString& readSlotName,
const QString& writeSlotName = "",
const QString& notifySignalName = "");
/// Emit the signal with the given name and arguments
bool emitSignal(const QString& name, const QList<QVariant>& argumentsValues);
virtual bool emitSignal(const QString& name, const QList<QVariant>& argumentsValues);
/// Return the QMetaObject for this DynamicQObject
virtual const QMetaObject* metaObject() const;
@ -84,3 +89,361 @@ private:
void* m_dObjectPointer;
Callback m_dObjectCallback;
};
template <typename T>
DynamicQObject<T>::DynamicQObject()
: T()
, m_dObjectPointer(nullptr)
, m_dObjectCallback(nullptr)
{
QMetaObjectBuilder builder;
builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
builder.setClassName("DynamicQObject");
builder.setSuperClass(&T::staticMetaObject);
m_metaObject.reset(builder.toMetaObject());
}
template <typename T>
DynamicQObject<T>::~DynamicQObject() = default;
template <typename T>
bool DynamicQObject<T>::registerSlot(const QString& name,
const QMetaType::Type returnType,
const QList<QMetaType::Type>& argumentsTypes,
int& slotIndex)
{
DynamicSlot slot(name, returnType, argumentsTypes);
if (m_slotsBySignature.contains(slot.signature()))
return false;
m_slotsByName.insertMulti(slot.name(), slot);
m_slotsBySignature[slot.signature()] = slot;
auto afterSignalAdded = [](QMetaObjectBuilder&) {};
auto afterPropertyAdded = afterSignalAdded;
auto afterSlotAdded = [&slot, returnType](QMetaObjectBuilder & metaObjectBuilder) {
QMetaMethodBuilder methodBuilder = metaObjectBuilder.addSlot(slot.signature());
methodBuilder.setReturnType(QMetaType::typeName(returnType));
methodBuilder.setAttributes(QMetaMethod::Scriptable);
};
auto newMetaObject = recreateMetaObjectBuilder(m_metaObject.data()
, afterSignalAdded
, afterSlotAdded
, afterPropertyAdded);
m_metaObject.reset(newMetaObject);
slotIndex = m_metaObject->indexOfSlot(QMetaObject::normalizedSignature(slot.signature()));
return slotIndex != -1;
}
template <typename T>
bool DynamicQObject<T>::registerSignal(const QString& name, const QList<QMetaType::Type>& arguments, int& signalIndex)
{
DynamicSignal signal(name, arguments);
if (m_signalsBySignature.contains(signal.signature()))
return false;
m_signalsByName.insertMulti(signal.name(), signal);
m_signalsBySignature[signal.signature()] = signal;
auto afterSignalAdded = [&signal](QMetaObjectBuilder & metaObjectBuilder) {
QMetaMethodBuilder methodBuilder = metaObjectBuilder.addSignal(signal.signature());
methodBuilder.setReturnType(QMetaType::typeName(QMetaType::Void));
methodBuilder.setAccess(QMetaMethod::Public);
};
auto afterSlotAdded = [](QMetaObjectBuilder&) { };
auto afterPropertyAdded = afterSlotAdded;
auto newMetaObject = recreateMetaObjectBuilder(m_metaObject.data()
, afterSignalAdded
, afterSlotAdded
, afterPropertyAdded);
m_metaObject.reset(newMetaObject);
signalIndex = m_metaObject->indexOfSignal(QMetaObject::normalizedSignature(signal.signature()));
return signalIndex != -1;
}
template <typename T>
bool DynamicQObject<T>::registerProperty(const QString& name,
QMetaType::Type type,
const QString& readSlotName,
const QString& writeSlotName,
const QString& notifySignalName)
{
DynamicProperty property(name, type, readSlotName, writeSlotName, notifySignalName);
DynamicSignal notifySignal;
if (!notifySignalName.isEmpty())
{
notifySignal = m_signalsByName.value(notifySignalName, DynamicSignal());
if (!notifySignal.isValid())
return false;
}
m_propertiesByName.insert(name.toUtf8(), property);
auto afterSignalAdded = [](QMetaObjectBuilder & metaObjectBuilder) {};
auto afterSlotAdded = [](QMetaObjectBuilder & metaObjectBuilder) {};
auto afterPropertyAdded = [name, type, notifySignal](QMetaObjectBuilder & metaObjectBuilder)
{
int signalIndex = -1;
if (notifySignal.isValid())
{
for (int i = 0; i < metaObjectBuilder.methodCount(); ++i)
{
QMetaMethodBuilder methodBuilder = metaObjectBuilder.method(i);
if (methodBuilder.methodType() == QMetaMethod::Signal)
{
if (methodBuilder.signature() == QMetaObject::normalizedSignature(notifySignal.signature()));
{
signalIndex = i;
break;
}
}
}
}
auto typeName = QMetaType::typeName(type);
auto builder = metaObjectBuilder.addProperty(name.toUtf8(),
QMetaObject::normalizedType(typeName),
signalIndex);
if (signalIndex == -1)
builder.setConstant(true);
};
auto newMetaObject = recreateMetaObjectBuilder(m_metaObject.data()
, afterSignalAdded
, afterSlotAdded
, afterPropertyAdded);
m_metaObject.reset(newMetaObject);
return true;
}
template <typename T>
bool DynamicQObject<T>::emitSignal(const QString& name, const QList<QVariant>& args)
{
DynamicSignal signal;
for (DynamicSignal currentSignal : m_signalsByName.values(name))
{
if (currentSignal.validate(args))
{
signal = currentSignal;
break;
}
}
if (!signal.isValid())
return false;
int index = m_metaObject->indexOfSignal(QMetaObject::normalizedSignature(signal.signature()));
if (index < 0)
return false;
QVariantList argsCopy = args;
QVector<void*> arguments(argsCopy.size() + 1 , 0);
arguments[0] = 0;
for (int i = 0; i < argsCopy.size(); ++i)
arguments[i + 1] = &argsCopy[i];
QMetaObject::activate(this, index, arguments.data());
return true;
}
template <typename T>
const QMetaObject* DynamicQObject<T>::metaObject() const
{
return m_metaObject.data();
}
template <typename T>
bool DynamicQObject<T>::executeSlot(const DynamicSlot& slot, void** args)
{
if (!slot.isValid())
return false;
QList<QVariant> arguments;
for (int i = 0; i < slot.argumentsTypes().count(); ++i)
arguments << QVariant(slot.argumentTypeAt(i), args[i + 1]);
QVariant result = executeSlot(slot, arguments);
if (slot.returnType() != QMetaType::Void && result.isValid())
{
QMetaType metatype(slot.returnType());
metatype.construct(args[0], result.constData());
}
return true;
}
template <typename T>
QVariant DynamicQObject<T>::executeSlot(const DynamicSlot& slot, const QList<QVariant>& args)
{
QVariant slotName(slot.name());
const int numParametersPlusReturn = slot.argumentsTypes().count() + 1;
std::vector<QVariant> argumentsAsVariants(numParametersPlusReturn);
std::vector<void*> argumentsAsVoidPointers(numParametersPlusReturn);
for (int i = 0; i < numParametersPlusReturn; ++i) {
argumentsAsVariants[i] = i == 0 ? QVariant() : args[i - 1];
argumentsAsVoidPointers[i] = &argumentsAsVariants[i];
}
if (m_dObjectCallback && m_dObjectPointer)
m_dObjectCallback(m_dObjectPointer, &slotName, numParametersPlusReturn, &argumentsAsVoidPointers[0]);
return argumentsAsVariants[0];
}
template <typename T>
bool DynamicQObject<T>::readProperty(const DynamicProperty& property, void** args)
{
if (!property.isValid())
return false;
if (!property.isReadable())
return false;
DynamicSlot readSlot = m_slotsByName.value(property.readSlot(), DynamicSlot());
if (!readSlot.isValid())
return false;
if (readSlot.argumentsTypes().count() > 0)
return false;
if (readSlot.returnType() != property.type())
return false;
return executeSlot(readSlot, args);
}
template <typename T>
bool DynamicQObject<T>::writeProperty(const DynamicProperty& property, void** args)
{
if (!property.isValid())
return false;
if (!property.isWriteable())
return false;
DynamicSlot writeSlot = m_slotsByName.value(property.writeSlot(), DynamicSlot());
if (!writeSlot.isValid())
return false;
if (writeSlot.argumentsTypes().count() != 1)
return false;
if (writeSlot.returnType() != QMetaType::Void)
return false;
QVariant newValue(writeSlot.argumentTypeAt(0), args[0]);
executeSlot(writeSlot, {newValue});
}
template <typename T>
int DynamicQObject<T>::qt_metacall(QMetaObject::Call callType, int index, void** args)
{
if (callType == QMetaObject::InvokeMetaMethod)
{
QMetaMethod method = m_metaObject->method(index);
if (!method.isValid())
return -1;
DynamicSlot slot = m_slotsBySignature[method.methodSignature()];
return executeSlot(slot, args) ? 1 : -1;
}
else if (callType == QMetaObject::ReadProperty)
{
QMetaProperty metaProperty = m_metaObject->property(index);
if (!metaProperty.isValid())
return -1;
DynamicProperty dynamicProperty = m_propertiesByName.value(metaProperty.name(), DynamicProperty());
return readProperty(dynamicProperty, args) ? 1 : -1;
}
else if (callType == QMetaObject::WriteProperty)
{
QMetaProperty metaProperty = m_metaObject->property(index);
if (!metaProperty.isValid())
return -1;
DynamicProperty dynamicProperty = m_propertiesByName.value(metaProperty.name(), DynamicProperty());
return writeProperty(dynamicProperty, args) ? 1 : -1;
}
return -1;
}
template <typename T>
QMetaObject* DynamicQObject<T>::recreateMetaObjectBuilder(QMetaObject* currentMetaObject,
const std::function<void(QMetaObjectBuilder&)>& afterSignalAdded,
const std::function<void(QMetaObjectBuilder&)>& afterSlotAdded,
const std::function<void(QMetaObjectBuilder&)>& afterPropertyAdded)
{
// Collect the current methods and signals
QList<QMetaMethod> signalsList;
QList<QMetaMethod> methodsList;
QList<QMetaProperty> propertiesList;
for (int i = currentMetaObject->methodOffset(); i < currentMetaObject->methodCount(); ++i)
{
QMetaMethod method = currentMetaObject->method(i);
if (method.methodType() == QMetaMethod::Signal)
signalsList.append(method);
else
methodsList.append(method);
}
for (int i = currentMetaObject->propertyOffset(); i < currentMetaObject->propertyCount(); ++i)
{
QMetaProperty property = currentMetaObject->property(i);
propertiesList.append(property);
}
QMetaObjectBuilder metaObjectBuilder;
metaObjectBuilder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
metaObjectBuilder.setClassName(currentMetaObject->className());
metaObjectBuilder.setSuperClass(currentMetaObject->superClass());
foreach (auto& method, signalsList)
metaObjectBuilder.addMethod(method);
// Call custom code to be executed after signal have been added
afterSignalAdded(metaObjectBuilder);
foreach (auto& method, methodsList)
metaObjectBuilder.addMethod(method);
// Call custom code to be executed after slots have been added
afterSlotAdded(metaObjectBuilder);
foreach (auto& property, propertiesList)
metaObjectBuilder.addProperty(property);
afterPropertyAdded(metaObjectBuilder);
return metaObjectBuilder.toMetaObject();
}
#endif

View File

@ -1,90 +0,0 @@
#include "DynamicSignal.h"
#include "DynamicQObject.h"
struct SignalData
{
QString name;
QList<QMetaType::Type> argumentsTypes;
QByteArray signature;
};
DynamicSignal::DynamicSignal()
: d(nullptr)
{
}
DynamicSignal::DynamicSignal(const QString& name, const QList<QMetaType::Type>& arguments)
: d(new SignalData())
{
d->name = name;
d->signature = QByteArray();
d->argumentsTypes = arguments;
_initSignature();
}
DynamicSignal::DynamicSignal(const DynamicSignal& signal)
{
if (signal.isValid())
{
d.reset(new SignalData());
*d = *signal.d;
}
else
d.reset(nullptr);
}
DynamicSignal& DynamicSignal::operator=(const DynamicSignal& signal)
{
if (signal.isValid())
{
d.reset(new SignalData());
*d = *signal.d;
}
else
d.reset(nullptr);
return *this;
}
DynamicSignal::~DynamicSignal()
{
}
bool DynamicSignal::isValid() const
{
return d != nullptr;
}
QString DynamicSignal::name() const
{
return isValid() ? d->name : QString();
}
QByteArray DynamicSignal::signature() const
{
return isValid() ? d->signature : QByteArray();
}
bool DynamicSignal::validate(const QVariantList& arguments)
{
return true;
}
bool DynamicSignal::validate(const QList<QMetaType::Type>& argumentsTypes, const QVariantList& argumentsValues)
{
return true;
}
void DynamicSignal::_initSignature()
{
QString signature("%1(%2)");
QString arguments;
for (int i = 0; i < d->argumentsTypes.size(); ++i)
{
if (i != 0)
arguments += ',';
arguments += QMetaType::typeName(d->argumentsTypes[i]);
}
d->signature = signature.arg(d->name, arguments).toUtf8();
}

View File

@ -1,10 +1,14 @@
#pragma once
#ifndef DYNAMICSIGNAL_H
#define DYNAMICSIGNAL_H
#include <QtCore/QMetaType>
#include <memory>
#include <QtCore/QMetaType>
#include <QtCore/QString>
#include <QtCore/QMetaType>
#include <QtCore/QList>
class SignalData;
class DynamicQObject;
class DynamicSignal
{
@ -28,3 +32,93 @@ private:
std::unique_ptr<SignalData> d;
};
struct SignalData
{
QString name;
QList<QMetaType::Type> argumentsTypes;
QByteArray signature;
};
DynamicSignal::DynamicSignal()
: d(nullptr)
{
}
DynamicSignal::DynamicSignal(const QString& name, const QList<QMetaType::Type>& arguments)
: d(new SignalData())
{
d->name = name;
d->signature = QByteArray();
d->argumentsTypes = arguments;
_initSignature();
}
DynamicSignal::DynamicSignal(const DynamicSignal& signal)
{
if (signal.isValid())
{
d.reset(new SignalData());
*d = *signal.d;
}
else
d.reset(nullptr);
}
DynamicSignal& DynamicSignal::operator=(const DynamicSignal& signal)
{
if (signal.isValid())
{
d.reset(new SignalData());
*d = *signal.d;
}
else
d.reset(nullptr);
return *this;
}
DynamicSignal::~DynamicSignal()
{
}
bool DynamicSignal::isValid() const
{
return d != nullptr;
}
QString DynamicSignal::name() const
{
return isValid() ? d->name : QString();
}
QByteArray DynamicSignal::signature() const
{
return isValid() ? d->signature : QByteArray();
}
bool DynamicSignal::validate(const QVariantList& arguments)
{
return true;
}
bool DynamicSignal::validate(const QList<QMetaType::Type>& argumentsTypes, const QVariantList& argumentsValues)
{
return true;
}
void DynamicSignal::_initSignature()
{
QString signature("%1(%2)");
QString arguments;
for (int i = 0; i < d->argumentsTypes.size(); ++i)
{
if (i != 0)
arguments += ',';
arguments += QMetaType::typeName(d->argumentsTypes[i]);
}
d->signature = signature.arg(d->name, arguments).toUtf8();
}
#endif

View File

@ -1,109 +0,0 @@
#include "DynamicSlot.h"
#include <QtCore/QDebug>
#include <QtCore/QString>
#include <QtCore/QVariant>
#include <QtCore/QMetaType>
#include <functional>
#include "private/qmetaobjectbuilder_p.h"
struct SlotData
{
QString name;
QMetaType::Type returnType;
QList<QMetaType::Type> argumentsTypes;
QByteArray signature;
};
DynamicSlot::DynamicSlot()
: d(nullptr)
{
}
DynamicSlot::DynamicSlot(const QString& name,
QMetaType::Type returnType,
const QList<QMetaType::Type>& argumentsTypes)
: d(new SlotData())
{
d->name = name;
d->returnType = returnType;
d->argumentsTypes = argumentsTypes;
_initSignature();
}
DynamicSlot::DynamicSlot(const DynamicSlot& slot)
{
if (slot.isValid())
{
d.reset(new SlotData());
*d = *slot.d;
}
else
d.reset(nullptr);
}
DynamicSlot& DynamicSlot::operator=(const DynamicSlot& slot)
{
if (slot.isValid())
{
d.reset(new SlotData());
*d = *slot.d;
}
else
d.reset(nullptr);
return *this;
}
DynamicSlot::~DynamicSlot()
{
}
QString DynamicSlot::name() const
{
return isValid() ? d->name : QString();
}
bool DynamicSlot::isValid() const
{
return d != nullptr;
}
QByteArray DynamicSlot::signature() const
{
return isValid() ? d->signature : QByteArray();
}
bool DynamicSlot::validate(const QVariantList& argumentsValues)
{
return true;
}
QMetaType::Type DynamicSlot::returnType() const
{
return isValid() ? d->returnType : QMetaType::UnknownType;
}
QList<QMetaType::Type> DynamicSlot::argumentsTypes() const
{
return isValid() ? d->argumentsTypes : QList<QMetaType::Type>();
}
QMetaType::Type DynamicSlot::argumentTypeAt(int i) const
{
return isValid() ? d->argumentsTypes.at(i) : QMetaType::UnknownType;
}
void DynamicSlot::_initSignature()
{
QString signature("%1(%2)");
QString arguments = "";
for (int i = 0; i < d->argumentsTypes.size(); ++i)
{
if (i != 0)
arguments += ',';
arguments += QMetaType::typeName(d->argumentsTypes[i]);
}
d->signature = signature.arg(d->name, arguments).toUtf8();
}

View File

@ -1,4 +1,5 @@
#pragma once
#ifndef DYNAMICSLOT_H
#define DYNAMICSLOT_H
#include <memory>
#include <functional>
@ -6,6 +7,12 @@
#include <QtCore/QList>
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
#include <QtCore/QDebug>
#include <QtCore/QString>
#include <QtCore/QVariant>
#include <QtCore/QMetaType>
#include "private/qmetaobjectbuilder_p.h"
class SlotData;
class QString;
@ -34,3 +41,107 @@ private:
std::unique_ptr<SlotData> d;
};
struct SlotData
{
QString name;
QMetaType::Type returnType;
QList<QMetaType::Type> argumentsTypes;
QByteArray signature;
};
DynamicSlot::DynamicSlot()
: d(nullptr)
{
}
DynamicSlot::DynamicSlot(const QString& name,
QMetaType::Type returnType,
const QList<QMetaType::Type>& argumentsTypes)
: d(new SlotData())
{
d->name = name;
d->returnType = returnType;
d->argumentsTypes = argumentsTypes;
_initSignature();
}
DynamicSlot::DynamicSlot(const DynamicSlot& slot)
{
if (slot.isValid())
{
d.reset(new SlotData());
*d = *slot.d;
}
else
d.reset(nullptr);
}
DynamicSlot& DynamicSlot::operator=(const DynamicSlot& slot)
{
if (slot.isValid())
{
d.reset(new SlotData());
*d = *slot.d;
}
else
d.reset(nullptr);
return *this;
}
DynamicSlot::~DynamicSlot()
{
}
QString DynamicSlot::name() const
{
return isValid() ? d->name : QString();
}
bool DynamicSlot::isValid() const
{
return d != nullptr;
}
QByteArray DynamicSlot::signature() const
{
return isValid() ? d->signature : QByteArray();
}
bool DynamicSlot::validate(const QVariantList& argumentsValues)
{
return true;
}
QMetaType::Type DynamicSlot::returnType() const
{
return isValid() ? d->returnType : QMetaType::UnknownType;
}
QList<QMetaType::Type> DynamicSlot::argumentsTypes() const
{
return isValid() ? d->argumentsTypes : QList<QMetaType::Type>();
}
QMetaType::Type DynamicSlot::argumentTypeAt(int i) const
{
return isValid() ? d->argumentsTypes.at(i) : QMetaType::UnknownType;
}
void DynamicSlot::_initSignature()
{
QString signature("%1(%2)");
QString arguments = "";
for (int i = 0; i < d->argumentsTypes.size(); ++i)
{
if (i != 0)
arguments += ',';
arguments += QMetaType::typeName(d->argumentsTypes[i]);
}
d->signature = signature.arg(d->name, arguments).toUtf8();
}
#endif

View File

@ -0,0 +1,40 @@
#ifndef IDYNAMICQOBJECT_H
#define IDYNAMICQOBJECT_H
class IDynamicQObject
{
public:
typedef void (*Callback)(void*, void*, int, void**);
/// Destructor
virtual ~IDynamicQObject() = default;
/// Sets the function to be called from C++ to D or Nimrod
virtual void setDObjectCallback(Callback callback) = 0;
/// Sets the D or Nimrod object that owns this DynamicQObject
virtual void setDObjectPointer(void* dObjectPointer) = 0;
/// Register a new signal
virtual bool registerSignal(const QString& name,
const QList<QMetaType::Type>& argumentsTypes,
int& signalIndex) = 0;
/// Register a new slot
virtual bool registerSlot(const QString& name,
const QMetaType::Type returnType,
const QList<QMetaType::Type>& argumentsTypes,
int& slotIndex) = 0;
/// Register a new property
virtual bool registerProperty(const QString& name,
QMetaType::Type type,
const QString& readSlotName,
const QString& writeSlotName = "",
const QString& notifySignalName = "") = 0;
/// Emit the signal with the given name and arguments
virtual bool emitSignal(const QString& name, const QList<QVariant>& argumentsValues) = 0;
};
#endif

View File

@ -114,7 +114,7 @@ enum MetaDataFlags {
TypeNameIndexMask = 0x7FFFFFFF
};
extern int qMetaTypeTypeInternal(const char *);
extern int qMetaTypeTypeInternal(const char*);
class QArgumentType
{
@ -122,21 +122,23 @@ public:
QArgumentType(int type)
: _type(type)
{}
QArgumentType(const QByteArray &name)
QArgumentType(const QByteArray& name)
: _type(qMetaTypeTypeInternal(name.constData())), _name(name)
{}
QArgumentType()
: _type(0)
{}
int type() const
{ return _type; }
{
return _type;
}
QByteArray name() const
{
if (_type && _name.isEmpty())
const_cast<QArgumentType *>(this)->_name = QMetaType::typeName(_type);
const_cast<QArgumentType*>(this)->_name = QMetaType::typeName(_type);
return _name;
}
bool operator==(const QArgumentType &other) const
bool operator==(const QArgumentType& other) const
{
if (_type)
return _type == other._type;
@ -145,7 +147,7 @@ public:
else
return _name == other._name;
}
bool operator!=(const QArgumentType &other) const
bool operator!=(const QArgumentType& other) const
{
if (_type)
return _type != other._type;
@ -182,55 +184,57 @@ struct QMetaObjectPrivate
// revision 6 added qt_static_metacall as a member of each Q_OBJECT and inside QMetaObject itself
// revision 7 is Qt 5
static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
{ return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
static inline const QMetaObjectPrivate* get(const QMetaObject* metaobject)
{
return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data);
}
static int originalClone(const QMetaObject *obj, int local_method_index);
static int originalClone(const QMetaObject* obj, int local_method_index);
static QByteArray decodeMethodSignature(const char *signature,
QArgumentTypeArray &types);
static int indexOfSignalRelative(const QMetaObject **baseObject,
const QByteArray &name, int argc,
const QArgumentType *types);
static int indexOfSlotRelative(const QMetaObject **m,
const QByteArray &name, int argc,
const QArgumentType *types);
static int indexOfSignal(const QMetaObject *m, const QByteArray &name,
int argc, const QArgumentType *types);
static int indexOfSlot(const QMetaObject *m, const QByteArray &name,
int argc, const QArgumentType *types);
static int indexOfMethod(const QMetaObject *m, const QByteArray &name,
int argc, const QArgumentType *types);
static int indexOfConstructor(const QMetaObject *m, const QByteArray &name,
int argc, const QArgumentType *types);
Q_CORE_EXPORT static QMetaMethod signal(const QMetaObject *m, int signal_index);
Q_CORE_EXPORT static int signalOffset(const QMetaObject *m);
Q_CORE_EXPORT static int absoluteSignalCount(const QMetaObject *m);
Q_CORE_EXPORT static int signalIndex(const QMetaMethod &m);
static bool checkConnectArgs(int signalArgc, const QArgumentType *signalTypes,
int methodArgc, const QArgumentType *methodTypes);
static bool checkConnectArgs(const QMetaMethodPrivate *signal,
const QMetaMethodPrivate *method);
static QByteArray decodeMethodSignature(const char* signature,
QArgumentTypeArray& types);
static int indexOfSignalRelative(const QMetaObject** baseObject,
const QByteArray& name, int argc,
const QArgumentType* types);
static int indexOfSlotRelative(const QMetaObject** m,
const QByteArray& name, int argc,
const QArgumentType* types);
static int indexOfSignal(const QMetaObject* m, const QByteArray& name,
int argc, const QArgumentType* types);
static int indexOfSlot(const QMetaObject* m, const QByteArray& name,
int argc, const QArgumentType* types);
static int indexOfMethod(const QMetaObject* m, const QByteArray& name,
int argc, const QArgumentType* types);
static int indexOfConstructor(const QMetaObject* m, const QByteArray& name,
int argc, const QArgumentType* types);
Q_CORE_EXPORT static QMetaMethod signal(const QMetaObject* m, int signal_index);
Q_CORE_EXPORT static int signalOffset(const QMetaObject* m);
Q_CORE_EXPORT static int absoluteSignalCount(const QMetaObject* m);
Q_CORE_EXPORT static int signalIndex(const QMetaMethod& m);
static bool checkConnectArgs(int signalArgc, const QArgumentType* signalTypes,
int methodArgc, const QArgumentType* methodTypes);
static bool checkConnectArgs(const QMetaMethodPrivate* signal,
const QMetaMethodPrivate* method);
static QList<QByteArray> parameterTypeNamesFromSignature(const char *signature);
static QList<QByteArray> parameterTypeNamesFromSignature(const char* signature);
#ifndef QT_NO_QOBJECT
//defined in qobject.cpp
enum DisconnectType { DisconnectAll, DisconnectOne };
static void memberIndexes(const QObject *obj, const QMetaMethod &member,
int *signalIndex, int *methodIndex);
static QObjectPrivate::Connection *connect(const QObject *sender, int signal_index,
const QMetaObject *smeta,
const QObject *receiver, int method_index_relative,
const QMetaObject *rmeta = 0,
int type = 0, int *types = 0);
static bool disconnect(const QObject *sender, int signal_index,
const QMetaObject *smeta,
const QObject *receiver, int method_index, void **slot,
static void memberIndexes(const QObject* obj, const QMetaMethod& member,
int* signalIndex, int* methodIndex);
static QObjectPrivate::Connection* connect(const QObject* sender, int signal_index,
const QMetaObject* smeta,
const QObject* receiver, int method_index_relative,
const QMetaObject* rmeta = 0,
int type = 0, int* types = 0);
static bool disconnect(const QObject* sender, int signal_index,
const QMetaObject* smeta,
const QObject* receiver, int method_index, void** slot,
DisconnectType = DisconnectAll);
static inline bool disconnectHelper(QObjectPrivate::Connection *c,
const QObject *receiver, int method_index, void **slot,
QMutex *senderMutex, DisconnectType = DisconnectAll);
static inline bool disconnectHelper(QObjectPrivate::Connection* c,
const QObject* receiver, int method_index, void** slot,
QMutex* senderMutex, DisconnectType = DisconnectAll);
#endif
};
@ -246,7 +250,7 @@ static inline bool is_ident_char(char s)
|| (s >= 'A' && s <= 'Z')
|| (s >= '0' && s <= '9')
|| s == '_'
);
);
}
static inline bool is_space(char s)

View File

@ -100,14 +100,14 @@ public:
Q_DECLARE_FLAGS(MetaObjectFlags, MetaObjectFlag)
QMetaObjectBuilder();
explicit QMetaObjectBuilder(const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members = AllMembers);
explicit QMetaObjectBuilder(const QMetaObject* prototype, QMetaObjectBuilder::AddMembers members = AllMembers);
virtual ~QMetaObjectBuilder();
QByteArray className() const;
void setClassName(const QByteArray& name);
const QMetaObject *superClass() const;
void setSuperClass(const QMetaObject *meta);
const QMetaObject* superClass() const;
void setSuperClass(const QMetaObject* meta);
MetaObjectFlags flags() const;
void setFlags(MetaObjectFlags);
@ -129,7 +129,7 @@ public:
QMetaMethodBuilder addConstructor(const QByteArray& signature);
QMetaMethodBuilder addConstructor(const QMetaMethod& prototype);
QMetaPropertyBuilder addProperty(const QByteArray& name, const QByteArray& type, int notifierId=-1);
QMetaPropertyBuilder addProperty(const QByteArray& name, const QByteArray& type, int notifierId = -1);
QMetaPropertyBuilder addProperty(const QMetaProperty& prototype);
QMetaEnumBuilder addEnumerator(const QByteArray& name);
@ -137,15 +137,15 @@ public:
int addClassInfo(const QByteArray& name, const QByteArray& value);
int addRelatedMetaObject(const QMetaObject *meta);
int addRelatedMetaObject(const QMetaObject* meta);
void addMetaObject(const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members = AllMembers);
void addMetaObject(const QMetaObject* prototype, QMetaObjectBuilder::AddMembers members = AllMembers);
QMetaMethodBuilder method(int index) const;
QMetaMethodBuilder constructor(int index) const;
QMetaPropertyBuilder property(int index) const;
QMetaEnumBuilder enumerator(int index) const;
const QMetaObject *relatedMetaObject(int index) const;
const QMetaObject* relatedMetaObject(int index) const;
QByteArray classInfoName(int index) const;
QByteArray classInfoValue(int index) const;
@ -165,26 +165,26 @@ public:
int indexOfEnumerator(const QByteArray& name);
int indexOfClassInfo(const QByteArray& name);
typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
typedef void (*StaticMetacallFunction)(QObject*, QMetaObject::Call, int, void**);
QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction() const;
void setStaticMetacallFunction(QMetaObjectBuilder::StaticMetacallFunction value);
QMetaObject *toMetaObject() const;
QByteArray toRelocatableData(bool * = 0) const;
static void fromRelocatableData(QMetaObject *, const QMetaObject *, const QByteArray &);
QMetaObject* toMetaObject() const;
QByteArray toRelocatableData(bool* = 0) const;
static void fromRelocatableData(QMetaObject*, const QMetaObject*, const QByteArray&);
#ifndef QT_NO_DATASTREAM
void serialize(QDataStream& stream) const;
void deserialize
(QDataStream& stream,
const QMap<QByteArray, const QMetaObject *>& references);
(QDataStream& stream,
const QMap<QByteArray, const QMetaObject*>& references);
#endif
private:
Q_DISABLE_COPY(QMetaObjectBuilder)
QMetaObjectBuilderPrivate *d;
QMetaObjectBuilderPrivate* d;
friend class QMetaMethodBuilder;
friend class QMetaPropertyBuilder;
@ -221,16 +221,16 @@ public:
void setRevision(int revision);
private:
const QMetaObjectBuilder *_mobj;
const QMetaObjectBuilder* _mobj;
int _index;
friend class QMetaObjectBuilder;
friend class QMetaPropertyBuilder;
QMetaMethodBuilder(const QMetaObjectBuilder *mobj, int index)
QMetaMethodBuilder(const QMetaObjectBuilder* mobj, int index)
: _mobj(mobj), _index(index) {}
QMetaMethodBuilderPrivate *d_func() const;
QMetaMethodBuilderPrivate* d_func() const;
};
class Q_CORE_EXPORT QMetaPropertyBuilder
@ -238,7 +238,9 @@ class Q_CORE_EXPORT QMetaPropertyBuilder
public:
QMetaPropertyBuilder() : _mobj(0), _index(0) {}
int index() const { return _index; }
int index() const {
return _index;
}
QByteArray name() const;
QByteArray type() const;
@ -278,15 +280,15 @@ public:
void setRevision(int revision);
private:
const QMetaObjectBuilder *_mobj;
const QMetaObjectBuilder* _mobj;
int _index;
friend class QMetaObjectBuilder;
QMetaPropertyBuilder(const QMetaObjectBuilder *mobj, int index)
QMetaPropertyBuilder(const QMetaObjectBuilder* mobj, int index)
: _mobj(mobj), _index(index) {}
QMetaPropertyBuilderPrivate *d_func() const;
QMetaPropertyBuilderPrivate* d_func() const;
};
class Q_CORE_EXPORT QMetaEnumBuilder
@ -294,7 +296,9 @@ class Q_CORE_EXPORT QMetaEnumBuilder
public:
QMetaEnumBuilder() : _mobj(0), _index(0) {}
int index() const { return _index; }
int index() const {
return _index;
}
QByteArray name() const;
@ -309,27 +313,27 @@ public:
void removeKey(int index);
private:
const QMetaObjectBuilder *_mobj;
const QMetaObjectBuilder* _mobj;
int _index;
friend class QMetaObjectBuilder;
QMetaEnumBuilder(const QMetaObjectBuilder *mobj, int index)
QMetaEnumBuilder(const QMetaObjectBuilder* mobj, int index)
: _mobj(mobj), _index(index) {}
QMetaEnumBuilderPrivate *d_func() const;
QMetaEnumBuilderPrivate* d_func() const;
};
class Q_CORE_EXPORT QMetaStringTable
{
public:
explicit QMetaStringTable(const QByteArray &className);
explicit QMetaStringTable(const QByteArray& className);
int enter(const QByteArray &value);
int enter(const QByteArray& value);
static int preferredAlignment();
int blobSize() const;
void writeBlob(char *out) const;
void writeBlob(char* out) const;
private:
typedef QHash<QByteArray, int> Entries; // string --> index mapping

View File

@ -68,19 +68,21 @@ QT_BEGIN_NAMESPACE
class QVariant;
class QThreadData;
class QObjectConnectionListVector;
namespace QtSharedPointer { struct ExternalRefCountData; }
namespace QtSharedPointer {
struct ExternalRefCountData;
}
/* for Qt Test */
struct QSignalSpyCallbackSet
{
typedef void (*BeginCallback)(QObject *caller, int signal_or_method_index, void **argv);
typedef void (*EndCallback)(QObject *caller, int signal_or_method_index);
typedef void (*BeginCallback)(QObject* caller, int signal_or_method_index, void** argv);
typedef void (*EndCallback)(QObject* caller, int signal_or_method_index);
BeginCallback signal_begin_callback,
slot_begin_callback;
slot_begin_callback;
EndCallback signal_end_callback,
slot_end_callback;
};
void Q_CORE_EXPORT qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set);
void Q_CORE_EXPORT qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet& callback_set);
extern QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set;
@ -89,19 +91,19 @@ enum { QObjectPrivateVersion = QT_VERSION };
class Q_CORE_EXPORT QAbstractDeclarativeData
{
public:
static void (*destroyed)(QAbstractDeclarativeData *, QObject *);
static void (*destroyed_qml1)(QAbstractDeclarativeData *, QObject *);
static void (*parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *);
static void (*signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **);
static int (*receivers)(QAbstractDeclarativeData *, const QObject *, int);
static bool (*isSignalConnected)(QAbstractDeclarativeData *, const QObject *, int);
static void (*destroyed)(QAbstractDeclarativeData*, QObject*);
static void (*destroyed_qml1)(QAbstractDeclarativeData*, QObject*);
static void (*parentChanged)(QAbstractDeclarativeData*, QObject*, QObject*);
static void (*signalEmitted)(QAbstractDeclarativeData*, QObject*, int, void**);
static int (*receivers)(QAbstractDeclarativeData*, const QObject*, int);
static bool (*isSignalConnected)(QAbstractDeclarativeData*, const QObject*, int);
};
// This is an implementation of QAbstractDeclarativeData that is identical with
// the implementation in QtDeclarative and QtQml for the first bit
struct QAbstractDeclarativeDataImpl : public QAbstractDeclarativeData
{
quint32 ownedByQml1:1;
quint32 ownedByQml1: 1;
quint32 unused: 31;
};
@ -113,9 +115,9 @@ public:
struct ExtraData
{
ExtraData() {}
#ifndef QT_NO_USERDATA
QVector<QObjectUserData *> userData;
#endif
#ifndef QT_NO_USERDATA
QVector<QObjectUserData*> userData;
#endif
QList<QByteArray> propertyNames;
QList<QVariant> propertyValues;
QVector<int> runningTimers;
@ -123,20 +125,20 @@ public:
QString objectName;
};
typedef void (*StaticMetaCallFunction)(QObject *, QMetaObject::Call, int, void **);
typedef void (*StaticMetaCallFunction)(QObject*, QMetaObject::Call, int, void**);
struct Connection
{
QObject *sender;
QObject *receiver;
QObject* sender;
QObject* receiver;
union {
StaticMetaCallFunction callFunction;
QtPrivate::QSlotObjectBase *slotObj;
QtPrivate::QSlotObjectBase* slotObj;
};
// The next pointer for the singly-linked ConnectionList
Connection *nextConnectionList;
Connection* nextConnectionList;
//senders linked list
Connection *next;
Connection **prev;
Connection* next;
Connection** prev;
QAtomicPointer<const int> argumentTypes;
QAtomicInt ref_;
ushort method_offset;
@ -149,8 +151,12 @@ public:
//ref_ is 2 for the use in the internal lists, and for the use in QMetaObject::Connection
}
~Connection();
int method() const { return method_offset + method_relative; }
void ref() { ref_.ref(); }
int method() const {
return method_offset + method_relative;
}
void ref() {
ref_.ref();
}
void deref() {
if (!ref_.deref()) {
Q_ASSERT(!receiver);
@ -161,13 +167,13 @@ public:
// ConnectionList is a singly-linked list
struct ConnectionList {
ConnectionList() : first(0), last(0) {}
Connection *first;
Connection *last;
Connection* first;
Connection* last;
};
struct Sender
{
QObject *sender;
QObject* sender;
int signal;
int ref;
};
@ -177,64 +183,64 @@ public:
virtual ~QObjectPrivate();
void deleteChildren();
void setParent_helper(QObject *);
void setParent_helper(QObject*);
void moveToThread_helper();
void setThreadData_helper(QThreadData *currentData, QThreadData *targetData);
void _q_reregisterTimers(void *pointer);
void setThreadData_helper(QThreadData* currentData, QThreadData* targetData);
void _q_reregisterTimers(void* pointer);
bool isSender(const QObject *receiver, const char *signal) const;
QObjectList receiverList(const char *signal) const;
bool isSender(const QObject* receiver, const char* signal) const;
QObjectList receiverList(const char* signal) const;
QObjectList senderList() const;
void addConnection(int signal, Connection *c);
void addConnection(int signal, Connection* c);
void cleanConnectionLists();
static inline Sender *setCurrentSender(QObject *receiver,
Sender *sender);
static inline void resetCurrentSender(QObject *receiver,
Sender *currentSender,
Sender *previousSender);
static inline Sender* setCurrentSender(QObject* receiver,
Sender* sender);
static inline void resetCurrentSender(QObject* receiver,
Sender* currentSender,
Sender* previousSender);
static QObjectPrivate *get(QObject *o) {
static QObjectPrivate* get(QObject* o) {
return o->d_func();
}
int signalIndex(const char *signalName, const QMetaObject **meta = 0) const;
int signalIndex(const char* signalName, const QMetaObject** meta = 0) const;
inline bool isSignalConnected(uint signalIdx) const;
// To allow abitrary objects to call connectNotify()/disconnectNotify() without making
// the API public in QObject. This is used by QQmlNotifierEndpoint.
inline void connectNotify(const QMetaMethod &signal);
inline void disconnectNotify(const QMetaMethod &signal);
inline void connectNotify(const QMetaMethod& signal);
inline void disconnectNotify(const QMetaMethod& signal);
template <typename Func1, typename Func2>
static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot,
Qt::ConnectionType type = Qt::AutoConnection);
static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object* sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object* receiverPrivate, Func2 slot,
Qt::ConnectionType type = Qt::AutoConnection);
template <typename Func1, typename Func2>
static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot);
static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object* sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object* receiverPrivate, Func2 slot);
static QMetaObject::Connection connectImpl(const QObject *sender, int signal_index,
const QObject *receiver, void **slot,
QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
const int *types, const QMetaObject *senderMetaObject);
static QMetaObject::Connection connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type);
static bool disconnect(const QObject *sender, int signal_index, void **slot);
static QMetaObject::Connection connectImpl(const QObject* sender, int signal_index,
const QObject* receiver, void** slot,
QtPrivate::QSlotObjectBase* slotObj, Qt::ConnectionType type,
const int* types, const QMetaObject* senderMetaObject);
static QMetaObject::Connection connect(const QObject* sender, int signal_index, QtPrivate::QSlotObjectBase* slotObj, Qt::ConnectionType type);
static bool disconnect(const QObject* sender, int signal_index, void** slot);
public:
ExtraData *extraData; // extra data set by the user
QThreadData *threadData; // id of the thread that owns the object
ExtraData* extraData; // extra data set by the user
QThreadData* threadData; // id of the thread that owns the object
QObjectConnectionListVector *connectionLists;
QObjectConnectionListVector* connectionLists;
Connection *senders; // linked list of connections connected to this object
Sender *currentSender; // object currently activating the object
Connection* senders; // linked list of connections connected to this object
Sender* currentSender; // object currently activating the object
mutable quint32 connectedSignals[2];
union {
QObject *currentChildBeingDeleted;
QAbstractDeclarativeData *declarativeData; //extra data used by the declarative module
QObject* currentChildBeingDeleted;
QAbstractDeclarativeData* declarativeData; //extra data used by the declarative module
};
// these objects are all used to indicate that a QObject was deleted
@ -254,22 +260,22 @@ public:
inline bool QObjectPrivate::isSignalConnected(uint signal_index) const
{
return signal_index >= sizeof(connectedSignals) * 8
|| (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f))
|| (declarativeData && QAbstractDeclarativeData::isSignalConnected
&& QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index)));
|| (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f))
|| (declarativeData && QAbstractDeclarativeData::isSignalConnected
&& QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index)));
}
inline QObjectPrivate::Sender *QObjectPrivate::setCurrentSender(QObject *receiver,
Sender *sender)
inline QObjectPrivate::Sender* QObjectPrivate::setCurrentSender(QObject* receiver,
Sender* sender)
{
Sender *previousSender = receiver->d_func()->currentSender;
Sender* previousSender = receiver->d_func()->currentSender;
receiver->d_func()->currentSender = sender;
return previousSender;
}
inline void QObjectPrivate::resetCurrentSender(QObject *receiver,
Sender *currentSender,
Sender *previousSender)
inline void QObjectPrivate::resetCurrentSender(QObject* receiver,
Sender* currentSender,
Sender* previousSender)
{
// ref is set to zero when this object is deleted during the metacall
if (currentSender->ref == 1)
@ -279,46 +285,47 @@ inline void QObjectPrivate::resetCurrentSender(QObject *receiver,
previousSender->ref = currentSender->ref;
}
inline void QObjectPrivate::connectNotify(const QMetaMethod &signal)
inline void QObjectPrivate::connectNotify(const QMetaMethod& signal)
{
q_ptr->connectNotify(signal);
}
inline void QObjectPrivate::disconnectNotify(const QMetaMethod &signal)
inline void QObjectPrivate::disconnectNotify(const QMetaMethod& signal)
{
q_ptr->disconnectNotify(signal);
}
namespace QtPrivate {
template<typename Func, typename Args, typename R> class QPrivateSlotObject : public QSlotObjectBase
{
typedef QtPrivate::FunctionPointer<Func> FuncType;
Func function;
static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret)
template<typename Func, typename Args, typename R> class QPrivateSlotObject : public QSlotObjectBase
{
switch (which) {
typedef QtPrivate::FunctionPointer<Func> FuncType;
Func function;
static void impl(int which, QSlotObjectBase* this_, QObject* r, void** a, bool* ret)
{
switch (which) {
case Destroy:
delete static_cast<QPrivateSlotObject*>(this_);
break;
case Call:
FuncType::template call<Args, R>(static_cast<QPrivateSlotObject*>(this_)->function,
static_cast<typename FuncType::Object *>(QObjectPrivate::get(r)), a);
static_cast<typename FuncType::Object*>(QObjectPrivate::get(r)), a);
break;
case Compare:
*ret = *reinterpret_cast<Func *>(a) == static_cast<QPrivateSlotObject*>(this_)->function;
*ret = *reinterpret_cast<Func*>(a) == static_cast<QPrivateSlotObject*>(this_)->function;
break;
case NumOperations: ;
case NumOperations:
;
}
}
}
public:
explicit QPrivateSlotObject(Func f) : QSlotObjectBase(&impl), function(f) {}
};
public:
explicit QPrivateSlotObject(Func f) : QSlotObjectBase(&impl), function(f) {}
};
} //namespace QtPrivate
template <typename Func1, typename Func2>
inline QMetaObject::Connection QObjectPrivate::connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot,
Qt::ConnectionType type)
inline QMetaObject::Connection QObjectPrivate::connect(const typename QtPrivate::FunctionPointer<Func1>::Object* sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object* receiverPrivate, Func2 slot,
Qt::ConnectionType type)
{
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
@ -333,15 +340,15 @@ inline QMetaObject::Connection QObjectPrivate::connect(const typename QtPrivate:
Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
"Return type of the slot is not compatible with the return type of the signal.");
const int *types = 0;
const int* types = 0;
if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
return QObject::connectImpl(sender, reinterpret_cast<void **>(&signal),
receiverPrivate->q_ptr, reinterpret_cast<void **>(&slot),
new QtPrivate::QPrivateSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
type, types, &SignalType::Object::staticMetaObject);
return QObject::connectImpl(sender, reinterpret_cast<void**>(&signal),
receiverPrivate->q_ptr, reinterpret_cast<void**>(&slot),
new QtPrivate::QPrivateSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
type, types, &SignalType::Object::staticMetaObject);
}
template <typename Func1, typename Func2>
@ -355,9 +362,9 @@ bool QObjectPrivate::disconnect(const typename QtPrivate::FunctionPointer< Func1
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
"Signal and slot arguments are not compatible.");
return QObject::disconnectImpl(sender, reinterpret_cast<void **>(&signal),
receiverPrivate->q_ptr, reinterpret_cast<void **>(&slot),
&SignalType::Object::staticMetaObject);
return QObject::disconnectImpl(sender, reinterpret_cast<void**>(&signal),
receiverPrivate->q_ptr, reinterpret_cast<void**>(&slot),
&SignalType::Object::staticMetaObject);
}
Q_DECLARE_TYPEINFO(QObjectPrivate::Connection, Q_MOVABLE_TYPE);
@ -367,31 +374,39 @@ class QSemaphore;
class Q_CORE_EXPORT QMetaCallEvent : public QEvent
{
public:
QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction , const QObject *sender, int signalId,
int nargs = 0, int *types = 0, void **args = 0, QSemaphore *semaphore = 0);
QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction , const QObject* sender, int signalId,
int nargs = 0, int* types = 0, void** args = 0, QSemaphore* semaphore = 0);
/*! \internal
\a signalId is in the signal index range (see QObjectPrivate::signalIndex()).
*/
QMetaCallEvent(QtPrivate::QSlotObjectBase *slotObj, const QObject *sender, int signalId,
int nargs = 0, int *types = 0, void **args = 0, QSemaphore *semaphore = 0);
QMetaCallEvent(QtPrivate::QSlotObjectBase* slotObj, const QObject* sender, int signalId,
int nargs = 0, int* types = 0, void** args = 0, QSemaphore* semaphore = 0);
~QMetaCallEvent();
inline int id() const { return method_offset_ + method_relative_; }
inline const QObject *sender() const { return sender_; }
inline int signalId() const { return signalId_; }
inline void **args() const { return args_; }
inline int id() const {
return method_offset_ + method_relative_;
}
inline const QObject* sender() const {
return sender_;
}
inline int signalId() const {
return signalId_;
}
inline void** args() const {
return args_;
}
virtual void placeMetaCall(QObject *object);
virtual void placeMetaCall(QObject* object);
private:
QtPrivate::QSlotObjectBase *slotObj_;
const QObject *sender_;
QtPrivate::QSlotObjectBase* slotObj_;
const QObject* sender_;
int signalId_;
int nargs_;
int *types_;
void **args_;
QSemaphore *semaphore_;
int* types_;
void** args_;
QSemaphore* semaphore_;
QObjectPrivate::StaticMetaCallFunction callFunction_;
ushort method_offset_;
ushort method_relative_;
@ -401,32 +416,46 @@ class QBoolBlocker
{
Q_DISABLE_COPY(QBoolBlocker)
public:
explicit inline QBoolBlocker(bool &b, bool value=true):block(b), reset(b){block = value;}
inline ~QBoolBlocker(){block = reset; }
explicit inline QBoolBlocker(bool& b, bool value = true): block(b), reset(b) {
block = value;
}
inline ~QBoolBlocker() {
block = reset;
}
private:
bool &block;
bool& block;
bool reset;
};
void Q_CORE_EXPORT qDeleteInEventHandler(QObject *o);
void Q_CORE_EXPORT qDeleteInEventHandler(QObject* o);
struct QAbstractDynamicMetaObject;
struct Q_CORE_EXPORT QDynamicMetaObjectData
{
virtual ~QDynamicMetaObjectData() {}
virtual void objectDestroyed(QObject *) { delete this; }
virtual void objectDestroyed(QObject*) {
delete this;
}
virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) = 0;
virtual int metaCall(QObject *, QMetaObject::Call, int _id, void **) = 0;
virtual QAbstractDynamicMetaObject* toDynamicMetaObject(QObject*) = 0;
virtual int metaCall(QObject*, QMetaObject::Call, int _id, void**) = 0;
};
struct Q_CORE_EXPORT QAbstractDynamicMetaObject : public QDynamicMetaObjectData, public QMetaObject
{
virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) { return this; }
virtual int createProperty(const char *, const char *) { return -1; }
virtual int metaCall(QObject *, QMetaObject::Call c, int _id, void **a)
{ return metaCall(c, _id, a); }
virtual int metaCall(QMetaObject::Call, int _id, void **) { return _id; } // Compat overload
virtual QAbstractDynamicMetaObject* toDynamicMetaObject(QObject*) {
return this;
}
virtual int createProperty(const char*, const char*) {
return -1;
}
virtual int metaCall(QObject*, QMetaObject::Call c, int _id, void** a)
{
return metaCall(c, _id, a);
}
virtual int metaCall(QMetaObject::Call, int _id, void**) {
return _id; // Compat overload
}
};
QT_END_NAMESPACE