mirror of
https://github.com/status-im/dotherside.git
synced 2025-02-12 04:26:43 +00:00
Merge remote-tracking branch 'origin/feature/QAbstractItemModels' into develop
This commit is contained in:
commit
a91b4f59e7
3
.gitignore
vendored
3
.gitignore
vendored
@ -4,4 +4,5 @@ build
|
||||
*.o
|
||||
.directory
|
||||
#*#
|
||||
nimcache
|
||||
nimcache
|
||||
*.kdev4
|
@ -1,3 +1,3 @@
|
||||
add_subdirectory(DOtherSide)
|
||||
add_subdirectory(DynamicQObject)
|
||||
add_subdirectory(IntegrationTest)
|
||||
#add_subdirectory(DynamicQObject)
|
||||
#add_subdirectory(IntegrationTest)
|
202
DOtherSide/DOtherSide/BaseQAbstractListModel.h
Normal file
202
DOtherSide/DOtherSide/BaseQAbstractListModel.h
Normal file
@ -0,0 +1,202 @@
|
||||
#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 DynamicQObject<QAbstractListModel>
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
BaseQAbstractListModel(void* modelObject,
|
||||
RowCountCallback rowCountCallback,
|
||||
ColumnCountCallback columnCountCallback,
|
||||
DataCallback dataCallback,
|
||||
SetDataCallback setDataCallback,
|
||||
RoleNamesCallback roleNamesCallback,
|
||||
FlagsCallback flagsCallback,
|
||||
HeaderDataCallback headerDataCallback);
|
||||
|
||||
/// Return the model's row count
|
||||
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
|
||||
/// Return the model's column count
|
||||
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
|
||||
/// Return the QVariant at the given index
|
||||
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
/// Sets the QVariant value at the given index and role
|
||||
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
|
||||
|
||||
/// Return the item flags for the given index
|
||||
virtual Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
|
||||
/// Return the data for the given role and section in the header with the specified orientation
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
/// Return the dModelPointer
|
||||
void* modelObject();
|
||||
|
||||
/// Return the roleNames
|
||||
virtual QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
/// 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,
|
||||
const QVector<int>& roles = QVector<int>());
|
||||
|
||||
private:
|
||||
void* m_modelObject;
|
||||
RowCountCallback m_rowCountCallback;
|
||||
ColumnCountCallback m_columnCountCallback;
|
||||
DataCallback m_dataCallback;
|
||||
SetDataCallback m_setDataCallback;
|
||||
RoleNamesCallback m_roleNamesCallback;
|
||||
FlagsCallback m_flagsCallback;
|
||||
HeaderDataCallback m_headerDataCallback;
|
||||
};
|
||||
|
||||
BaseQAbstractListModel::BaseQAbstractListModel(void* modelObject,
|
||||
RowCountCallback rowCountCallback,
|
||||
ColumnCountCallback columnCountCallback,
|
||||
DataCallback dataCallback,
|
||||
SetDataCallback setDataCallback,
|
||||
RoleNamesCallback roleNamesCallback,
|
||||
FlagsCallback flagsCallback,
|
||||
HeaderDataCallback headerDataCallback)
|
||||
: m_modelObject(modelObject)
|
||||
, m_rowCountCallback(rowCountCallback)
|
||||
, m_columnCountCallback(columnCountCallback)
|
||||
, m_dataCallback(dataCallback)
|
||||
, m_setDataCallback(setDataCallback)
|
||||
, m_roleNamesCallback(roleNamesCallback)
|
||||
, m_flagsCallback(flagsCallback)
|
||||
, m_headerDataCallback(headerDataCallback)
|
||||
{
|
||||
}
|
||||
|
||||
int BaseQAbstractListModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
auto parentIndex = new QModelIndex();
|
||||
*parentIndex = parent;
|
||||
int result;
|
||||
m_rowCountCallback(m_modelObject, parentIndex, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int BaseQAbstractListModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
auto parentIndex = new QModelIndex();
|
||||
*parentIndex = parent;
|
||||
int result;
|
||||
m_columnCountCallback(m_modelObject, parentIndex, &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;
|
||||
}
|
||||
|
||||
bool BaseQAbstractListModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||
{
|
||||
auto newIndex = new QModelIndex(index);
|
||||
*newIndex = index;
|
||||
auto newValue = new QVariant();
|
||||
*newValue = value;
|
||||
bool result = false;
|
||||
m_setDataCallback(m_modelObject, newIndex, newValue, role, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Qt::ItemFlags BaseQAbstractListModel::flags(const QModelIndex& index) const
|
||||
{
|
||||
auto newIndex = new QModelIndex(index);
|
||||
*newIndex = index;
|
||||
int result;
|
||||
m_flagsCallback(m_modelObject, newIndex, &result);
|
||||
return Qt::ItemFlags(result);
|
||||
}
|
||||
|
||||
QVariant BaseQAbstractListModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
QVariant result;
|
||||
m_headerDataCallback(m_modelObject, section, orientation, 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
|
8
DOtherSide/DOtherSide/BaseQObject.h
Normal file
8
DOtherSide/DOtherSide/BaseQObject.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef BASEQOBJECT_H
|
||||
#define BASEQOBJECT_H
|
||||
|
||||
#include "DynamicQObject.h"
|
||||
|
||||
class BaseQObject : public DynamicQObject<QObject> {};
|
||||
|
||||
#endif
|
@ -12,6 +12,9 @@ find_package(Qt5Widgets)
|
||||
|
||||
set(HEADERS_LIST
|
||||
DOtherSide.h
|
||||
DOtherSideTypes.h
|
||||
BaseQAbstractListModel.h
|
||||
BaseQObject.h
|
||||
)
|
||||
|
||||
set(SRC_LIST
|
||||
@ -19,5 +22,5 @@ set(SRC_LIST
|
||||
)
|
||||
|
||||
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)
|
@ -1,20 +1,25 @@
|
||||
#include "DOtherSide.h"
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtQuick/QQuickView>
|
||||
#include <QtQml/QQmlContext>
|
||||
#include <iostream>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QModelIndex>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtQml/QQmlContext>
|
||||
#include <QtQml/QQmlApplicationEngine>
|
||||
#include <QtQuick/QQuickView>
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
#include "DynamicQObject.h"
|
||||
#include "BaseQAbstractListModel.h"
|
||||
#include "BaseQObject.h"
|
||||
|
||||
void convert_to_cstring(const QString& source, CharPtr& destination, int& length)
|
||||
void convert_to_cstring(const QString& source, char** destination, int* length)
|
||||
{
|
||||
QByteArray array = source.toUtf8();
|
||||
destination = qstrdup(array.data());
|
||||
length = qstrlen(array.data());
|
||||
*destination = qstrdup(array.data());
|
||||
*length = qstrlen(array.data());
|
||||
}
|
||||
|
||||
void dos_qguiapplication_create()
|
||||
@ -63,12 +68,12 @@ void dos_qapplication_quit()
|
||||
qApp->quit();
|
||||
}
|
||||
|
||||
void dos_qqmlapplicationengine_create(void **vptr)
|
||||
void dos_qqmlapplicationengine_create(void** vptr)
|
||||
{
|
||||
*vptr = new QQmlApplicationEngine();
|
||||
}
|
||||
|
||||
void dos_qqmlapplicationengine_load(void *vptr, const char *filename)
|
||||
void dos_qqmlapplicationengine_load(void* vptr, const char* filename)
|
||||
{
|
||||
QQmlApplicationEngine* engine = reinterpret_cast<QQmlApplicationEngine*>(vptr);
|
||||
engine->load(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + QDir::separator() + QString(filename)));
|
||||
@ -104,7 +109,7 @@ void dos_qquickview_delete(void* vptr)
|
||||
delete view;
|
||||
}
|
||||
|
||||
void dos_qquickview_source(void *vptr, CharPtr& result, int& length)
|
||||
void dos_qquickview_source(void* vptr, char** result, int* length)
|
||||
{
|
||||
QQuickView* view = reinterpret_cast<QQuickView*>(vptr);
|
||||
QUrl url = view->source();
|
||||
@ -123,25 +128,25 @@ void dos_qquickview_rootContext(void* vptr, void** context)
|
||||
*context = view->rootContext();
|
||||
}
|
||||
|
||||
void dos_chararray_create(CharPtr& ptr)
|
||||
void dos_chararray_create(char** ptr)
|
||||
{
|
||||
ptr = 0;
|
||||
*ptr = 0;
|
||||
}
|
||||
|
||||
void dos_chararray_create(CharPtr& ptr, int size)
|
||||
void dos_chararray_create(char** ptr, int size)
|
||||
{
|
||||
if (size > 0)
|
||||
ptr = new char[size];
|
||||
*ptr = new char[size];
|
||||
else
|
||||
ptr = 0;
|
||||
*ptr = 0;
|
||||
}
|
||||
|
||||
void dos_chararray_delete(CharPtr ptr)
|
||||
void dos_chararray_delete(char* ptr)
|
||||
{
|
||||
if (ptr) delete[] ptr;
|
||||
}
|
||||
|
||||
void dos_qqmlcontext_baseUrl(void* vptr, CharPtr& result, int& length)
|
||||
void dos_qqmlcontext_baseUrl(void* vptr, char** result, int* length)
|
||||
{
|
||||
QQmlContext* context = reinterpret_cast<QQmlContext*>(vptr);
|
||||
QUrl url = context->baseUrl();
|
||||
@ -155,17 +160,17 @@ void dos_qqmlcontext_setcontextproperty(void* vptr, const char* name, void* valu
|
||||
context->setContextProperty(QString::fromUtf8(name), *variant);
|
||||
}
|
||||
|
||||
void dos_qvariant_create(void **vptr)
|
||||
void dos_qvariant_create(void** vptr)
|
||||
{
|
||||
*vptr = new QVariant();
|
||||
}
|
||||
|
||||
void dos_qvariant_create_int(void **vptr, int value)
|
||||
void dos_qvariant_create_int(void** vptr, int value)
|
||||
{
|
||||
*vptr = new QVariant(value);
|
||||
}
|
||||
|
||||
void dos_qvariant_create_bool(void **vptr, bool value)
|
||||
void dos_qvariant_create_bool(void** vptr, bool value)
|
||||
{
|
||||
*vptr = new QVariant(value);
|
||||
}
|
||||
@ -177,13 +182,13 @@ void dos_qvariant_create_string(void** vptr, const char* value)
|
||||
|
||||
void dos_qvariant_create_qvariant(void** vptr, void* other)
|
||||
{
|
||||
auto newQVariant = new QVariant();
|
||||
auto otherQVariant = reinterpret_cast<QVariant*>(other);
|
||||
*newQVariant = *otherQVariant;
|
||||
*vptr = newQVariant;
|
||||
auto newQVariant = new QVariant();
|
||||
auto otherQVariant = reinterpret_cast<QVariant*>(other);
|
||||
*newQVariant = *otherQVariant;
|
||||
*vptr = newQVariant;
|
||||
}
|
||||
|
||||
void dos_qvariant_create_qobject(void **vptr, void* value)
|
||||
void dos_qvariant_create_qobject(void** vptr, void* value)
|
||||
{
|
||||
auto qobject = reinterpret_cast<QObject*>(value);
|
||||
auto variant = new QVariant();
|
||||
@ -201,13 +206,21 @@ void dos_qvariant_create_double(void** vptr, double value)
|
||||
*vptr = new QVariant(value);
|
||||
}
|
||||
|
||||
void dos_qvariant_isnull(void* vptr, bool& isNull)
|
||||
void dos_qvariant_create_qabstractlistmodel(void** vptr, void* value)
|
||||
{
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
isNull = variant->isNull();
|
||||
auto qobject = reinterpret_cast<QObject*>(value);
|
||||
auto variant = new QVariant();
|
||||
variant->setValue<QObject*>(qobject);
|
||||
*vptr = variant;
|
||||
}
|
||||
|
||||
void dos_qvariant_delete(void *vptr)
|
||||
void dos_qvariant_isnull(void* vptr, bool* isNull)
|
||||
{
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
*isNull = variant->isNull();
|
||||
}
|
||||
|
||||
void dos_qvariant_delete(void* vptr)
|
||||
{
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
delete variant;
|
||||
@ -215,36 +228,36 @@ void dos_qvariant_delete(void *vptr)
|
||||
|
||||
void dos_qvariant_assign(void* vptr, void* other)
|
||||
{
|
||||
auto leftQVariant = reinterpret_cast<QVariant*>(vptr);
|
||||
auto rightQVariant = reinterpret_cast<QVariant*>(other);
|
||||
*leftQVariant = *rightQVariant;
|
||||
auto leftQVariant = reinterpret_cast<QVariant*>(vptr);
|
||||
auto rightQVariant = reinterpret_cast<QVariant*>(other);
|
||||
*leftQVariant = *rightQVariant;
|
||||
}
|
||||
|
||||
void dos_qvariant_toInt(void* vptr, int& value)
|
||||
void dos_qvariant_toInt(void* vptr, int* value)
|
||||
{
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
value = variant->toInt();
|
||||
*value = variant->toInt();
|
||||
}
|
||||
|
||||
void dos_qvariant_toBool(void* vptr, bool& value)
|
||||
void dos_qvariant_toBool(void* vptr, bool* value)
|
||||
{
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
value = variant->toBool();
|
||||
*value = variant->toBool();
|
||||
}
|
||||
|
||||
void dos_qvariant_toFloat(void* vptr, float& value)
|
||||
void dos_qvariant_toFloat(void* vptr, float* value)
|
||||
{
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
value = variant->toFloat();
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
*value = variant->toFloat();
|
||||
}
|
||||
|
||||
void dos_qvariant_toDouble(void* vptr, double& value)
|
||||
void dos_qvariant_toDouble(void* vptr, double* value)
|
||||
{
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
value = variant->toDouble();
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
*value = variant->toDouble();
|
||||
}
|
||||
|
||||
void dos_qvariant_toString(void* vptr, CharPtr& ptr, int& size)
|
||||
void dos_qvariant_toString(void* vptr, char** ptr, int* size)
|
||||
{
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
convert_to_cstring(variant->toString(), ptr, size);
|
||||
@ -282,23 +295,30 @@ void dos_qvariant_setString(void* vptr, const char* value)
|
||||
|
||||
void dos_qvariant_setQObject(void* vptr, void* value)
|
||||
{
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
auto qobject = reinterpret_cast<QObject*>(value);
|
||||
variant->setValue<QObject*>(qobject);
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
auto qobject = reinterpret_cast<QObject*>(value);
|
||||
variant->setValue<QObject*>(qobject);
|
||||
}
|
||||
|
||||
void dos_qvariant_setQAbstractListModel(void* vptr, void* value)
|
||||
{
|
||||
auto variant = reinterpret_cast<QVariant*>(vptr);
|
||||
auto qobject = reinterpret_cast<QObject*>(value);
|
||||
variant->setValue<QObject*>(qobject);
|
||||
}
|
||||
|
||||
void dos_qobject_create(void** vptr, void* dObjectPointer, DObjectCallback dObjectCallback)
|
||||
{
|
||||
auto dynamicQObject = new DynamicQObject();
|
||||
auto dynamicQObject = new BaseQObject();
|
||||
QQmlEngine::setObjectOwnership(dynamicQObject, QQmlEngine::CppOwnership);
|
||||
dynamicQObject->setDObjectPointer(dObjectPointer);
|
||||
dynamicQObject->setDObjectCallback(dObjectCallback);
|
||||
*vptr = dynamicQObject;
|
||||
}
|
||||
|
||||
void dos_qobject_delete(void *vptr)
|
||||
void dos_qobject_delete(void* vptr)
|
||||
{
|
||||
auto dynamicQObject = reinterpret_cast<DynamicQObject*>(vptr);
|
||||
auto dynamicQObject = reinterpret_cast<BaseQObject*>(vptr);
|
||||
dynamicQObject->disconnect();
|
||||
delete dynamicQObject;
|
||||
}
|
||||
@ -308,7 +328,8 @@ void dos_qobject_slot_create(void* vptr, const char* name, int parametersCount,
|
||||
if (parametersCount <= 0)
|
||||
return;
|
||||
|
||||
auto dynamicQObject = reinterpret_cast<DynamicQObject*>(vptr);
|
||||
auto qobject = reinterpret_cast<QObject*>(vptr);
|
||||
auto dynamicQObject = dynamic_cast<IDynamicQObject*>(qobject);
|
||||
|
||||
QMetaType::Type returnType = static_cast<QMetaType::Type>(parametersMetaTypes[0]);
|
||||
QList<QMetaType::Type> argumentsTypes;
|
||||
@ -323,7 +344,8 @@ void dos_qobject_signal_create(void* vptr, const char* name, int parametersCount
|
||||
if (parametersCount <= 0)
|
||||
return;
|
||||
|
||||
auto dynamicQObject = reinterpret_cast<DynamicQObject*>(vptr);
|
||||
auto qobject = reinterpret_cast<QObject*>(vptr);
|
||||
auto dynamicQObject = dynamic_cast<IDynamicQObject*>(qobject);
|
||||
|
||||
QList<QMetaType::Type> argumentsTypes;
|
||||
for (int i = 0; i < parametersCount; ++i)
|
||||
@ -334,14 +356,16 @@ 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 qobject = reinterpret_cast<QObject*>(vptr);
|
||||
auto dynamicQObject = dynamic_cast<IDynamicQObject*>(qobject);
|
||||
|
||||
QVariantList arguments;
|
||||
for (int i = 0; i < parametersCount; ++i)
|
||||
arguments << *(reinterpret_cast<QVariant*>(parameters[i]));
|
||||
|
||||
dynamicQObject->emitSignal(QString::fromStdString(name), arguments);
|
||||
}
|
||||
|
||||
|
||||
void dos_qobject_property_create(void* vptr,
|
||||
const char* name,
|
||||
int type,
|
||||
@ -349,10 +373,175 @@ void dos_qobject_property_create(void* vptr,
|
||||
const char* writeSlot,
|
||||
const char* notifySignal)
|
||||
{
|
||||
auto dynamicQObject = reinterpret_cast<DynamicQObject*>(vptr);
|
||||
auto qobject = reinterpret_cast<QObject*>(vptr);
|
||||
auto dynamicQObject = dynamic_cast<IDynamicQObject*>(qobject);
|
||||
dynamicQObject->registerProperty(QString(name),
|
||||
QMetaType::Type(type),
|
||||
QString(readSlot),
|
||||
QString(writeSlot),
|
||||
QString(notifySignal));
|
||||
}
|
||||
|
||||
void dos_qmodelindex_create(void** vptr)
|
||||
{
|
||||
auto index = new QModelIndex();
|
||||
*vptr = index;
|
||||
}
|
||||
|
||||
void dos_qmodelindex_delete(void* vptr)
|
||||
{
|
||||
auto index = reinterpret_cast<QModelIndex*>(vptr);
|
||||
delete index;
|
||||
}
|
||||
|
||||
void dos_qmodelindex_row(void* vptr, int* row)
|
||||
{
|
||||
auto index = reinterpret_cast<QModelIndex*>(vptr);
|
||||
*row = index->row();
|
||||
}
|
||||
|
||||
void dos_qmodelindex_column(void* vptr, int* column)
|
||||
{
|
||||
auto index = reinterpret_cast<QModelIndex*>(vptr);
|
||||
*column = index->column();
|
||||
}
|
||||
|
||||
void dos_qmodelindex_isValid(void* vptr, bool* isValid)
|
||||
{
|
||||
auto index = reinterpret_cast<QModelIndex*>(vptr);
|
||||
*isValid = index->isValid();
|
||||
}
|
||||
|
||||
void dos_qmodelindex_data(void* vptr, int role, void* data)
|
||||
{
|
||||
auto index = reinterpret_cast<QModelIndex*>(vptr);
|
||||
auto result = reinterpret_cast<QVariant*>(data);
|
||||
*result = index->data(role);
|
||||
}
|
||||
|
||||
void dos_qmodelindex_parent(void* vptr, void* parent)
|
||||
{
|
||||
auto index = reinterpret_cast<QModelIndex*>(vptr);
|
||||
auto parentIndex = reinterpret_cast<QModelIndex*>(parent);
|
||||
*parentIndex = index->parent();
|
||||
}
|
||||
|
||||
void dos_qmodelindex_child(void* vptr, int row, int column, void* child)
|
||||
{
|
||||
auto index = reinterpret_cast<QModelIndex*>(vptr);
|
||||
auto childIndex = reinterpret_cast<QModelIndex*>(child);
|
||||
*childIndex = index->child(row, column);
|
||||
}
|
||||
|
||||
void dos_qmodelindex_sibling(void* vptr, int row, int column, void* sibling)
|
||||
{
|
||||
auto index = reinterpret_cast<QModelIndex*>(vptr);
|
||||
auto siblingIndex = reinterpret_cast<QModelIndex*>(sibling);
|
||||
*siblingIndex = index->sibling(row, column);
|
||||
}
|
||||
|
||||
void dos_qabstractlistmodel_create(void** vptr,
|
||||
void* modelObject,
|
||||
DObjectCallback dObjectCallback,
|
||||
RowCountCallback rowCountCallback,
|
||||
ColumnCountCallback columnCountCallback,
|
||||
DataCallback dataCallback,
|
||||
SetDataCallback setDataCallback,
|
||||
RoleNamesCallback roleNamesCallaback,
|
||||
FlagsCallback flagsCallback,
|
||||
HeaderDataCallback headerDataCallback)
|
||||
{
|
||||
auto model = new BaseQAbstractListModel(modelObject,
|
||||
rowCountCallback,
|
||||
columnCountCallback,
|
||||
dataCallback,
|
||||
setDataCallback,
|
||||
roleNamesCallaback,
|
||||
flagsCallback,
|
||||
headerDataCallback);
|
||||
model->setDObjectPointer(modelObject);
|
||||
model->setDObjectCallback(dObjectCallback);
|
||||
*vptr = model;
|
||||
}
|
||||
|
||||
void dos_qabstractlistmodel_delete(void* vptr)
|
||||
{
|
||||
auto model = reinterpret_cast<BaseQAbstractListModel*>(vptr);
|
||||
delete model;
|
||||
}
|
||||
|
||||
void dos_qabstractlistmodel_beginInsertRows(void* vptr, QModelIndexVoidPtr parentIndex, int first, int last)
|
||||
{
|
||||
auto model = reinterpret_cast<BaseQAbstractListModel*>(vptr);
|
||||
auto index = reinterpret_cast<QModelIndex*>(parentIndex);
|
||||
model->publicBeginInsertRows(*index, first, last);
|
||||
}
|
||||
|
||||
void dos_qabstractlistmodel_endInsertRows(void* vptr)
|
||||
{
|
||||
auto model = reinterpret_cast<BaseQAbstractListModel*>(vptr);
|
||||
model->publicEndInsertRows();
|
||||
}
|
||||
|
||||
void dos_qabstractlistmodel_beginRemoveRows(void* vptr, QModelIndexVoidPtr parentIndex, int first, int last)
|
||||
{
|
||||
auto model = reinterpret_cast<BaseQAbstractListModel*>(vptr);
|
||||
auto index = reinterpret_cast<QModelIndex*>(parentIndex);
|
||||
model->publicBeginRemoveRows(*index, first, last);
|
||||
}
|
||||
|
||||
void dos_qabstractlistmodel_endRemoveRows(void* vptr)
|
||||
{
|
||||
auto model = reinterpret_cast<BaseQAbstractListModel*>(vptr);
|
||||
model->publicEndRemoveRows();
|
||||
}
|
||||
|
||||
void dos_qabstractlistmodel_beginResetModel(void* vptr)
|
||||
{
|
||||
auto model = reinterpret_cast<BaseQAbstractListModel*>(vptr);
|
||||
model->publicBeginResetModel();
|
||||
}
|
||||
|
||||
void dos_qabstractlistmodel_endResetModel(void* vptr)
|
||||
{
|
||||
auto model = reinterpret_cast<BaseQAbstractListModel*>(vptr);
|
||||
model->publicEndResetModel();
|
||||
}
|
||||
|
||||
void dos_qabstractlistmodel_dataChanged(void* vptr,
|
||||
QModelIndexVoidPtr topLeftIndex,
|
||||
QModelIndexVoidPtr bottomRightIndex,
|
||||
int* rolesArrayPtr,
|
||||
int rolesArrayLength)
|
||||
{
|
||||
auto model = reinterpret_cast<BaseQAbstractListModel*>(vptr);
|
||||
auto topLeft = reinterpret_cast<QModelIndex*>(topLeftIndex);
|
||||
auto bottomRight = reinterpret_cast<QModelIndex*>(bottomRightIndex);
|
||||
auto roles = QVector<int>::fromStdVector(std::vector<int>(rolesArrayPtr, rolesArrayPtr + rolesArrayLength));
|
||||
model->publicDataChanged(*topLeft, *bottomRight, roles);
|
||||
}
|
||||
|
||||
void dos_qhash_int_qbytearray_create(QHashIntQByteArrayVoidPtr* vptr)
|
||||
{
|
||||
*vptr = new QHash<int, QByteArray>();
|
||||
}
|
||||
|
||||
void dos_qhash_int_qbytearray_delete(QHashIntQByteArrayVoidPtr vptr)
|
||||
{
|
||||
auto qHash = reinterpret_cast<QHash<int, QByteArray>*>(vptr);
|
||||
delete qHash;
|
||||
}
|
||||
|
||||
void dos_qhash_int_qbytearray_insert(QHashIntQByteArrayVoidPtr vptr, int key, const char* value)
|
||||
{
|
||||
auto qHash = reinterpret_cast<QHash<int, QByteArray>*>(vptr);
|
||||
qHash->insert(key, QByteArray(value));
|
||||
}
|
||||
|
||||
void dos_qhash_int_qbytearray_value(QHashIntQByteArrayVoidPtr vptr, int key, char** result)
|
||||
{
|
||||
auto qHash = reinterpret_cast<QHash<int, QByteArray>*>(vptr);
|
||||
QByteArray value = qHash->value(key);
|
||||
*result = qstrdup(value.data());
|
||||
}
|
||||
|
||||
|
@ -1,102 +1,154 @@
|
||||
#ifndef DOTHERSIDE_H
|
||||
#define DOTHERSIDE_H
|
||||
|
||||
#include "DOtherSideTypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef char* CharPtr;
|
||||
typedef void(*Function)(void*);
|
||||
typedef void(*DObjectCallback)(void*, void*, int, void**);
|
||||
typedef char* CharPtr;
|
||||
typedef void(*Function)(void*);
|
||||
typedef void(*DObjectCallback)(void*, void*, int, void**);
|
||||
|
||||
// QGuiApplication
|
||||
void dos_qguiapplication_create();
|
||||
void dos_qguiapplication_exec();
|
||||
void dos_qguiapplication_quit();
|
||||
void dos_qguiapplication_delete();
|
||||
// QGuiApplication
|
||||
void dos_qguiapplication_create();
|
||||
void dos_qguiapplication_exec();
|
||||
void dos_qguiapplication_quit();
|
||||
void dos_qguiapplication_delete();
|
||||
|
||||
// QApplication
|
||||
void dos_qapplication_create();
|
||||
void dos_qapplication_exec();
|
||||
void dos_qapplication_quit();
|
||||
void dos_qapplication_delete();
|
||||
|
||||
// QQmlApplicationEngine
|
||||
void dos_qqmlapplicationengine_create(void** vptr);
|
||||
void dos_qqmlapplicationengine_load(void* vptr, const char* filename);
|
||||
void dos_qqmlapplicationengine_context(void* vptr, void** context);
|
||||
void dos_qqmlapplicationengine_delete(void* vptr);
|
||||
// QApplication
|
||||
void dos_qapplication_create();
|
||||
void dos_qapplication_exec();
|
||||
void dos_qapplication_quit();
|
||||
void dos_qapplication_delete();
|
||||
|
||||
// QQuickView
|
||||
void dos_qquickview_create(void** vptr);
|
||||
void dos_qquickview_show(void* vptr);
|
||||
void dos_qquickview_source(void* vptr, CharPtr& result, int& length);
|
||||
void dos_qquickview_set_source(void* vptr, const char* filename);
|
||||
void dos_qquickview_delete(void* vptr);
|
||||
void dos_qquickview_rootContext(void* vptr, void** context);
|
||||
// QQmlApplicationEngine
|
||||
void dos_qqmlapplicationengine_create(void** vptr);
|
||||
void dos_qqmlapplicationengine_load(void* vptr, const char* filename);
|
||||
void dos_qqmlapplicationengine_context(void* vptr, void** context);
|
||||
void dos_qqmlapplicationengine_delete(void* vptr);
|
||||
|
||||
// QQmlContext
|
||||
void dos_qqmlcontext_baseUrl(void* vptr, CharPtr& result, int& length);
|
||||
void dos_qqmlcontext_setcontextproperty(void* vptr, const char* name, void* value);
|
||||
// QQuickView
|
||||
void dos_qquickview_create(void** vptr);
|
||||
void dos_qquickview_show(void* vptr);
|
||||
void dos_qquickview_source(void* vptr, char** result, int* length);
|
||||
void dos_qquickview_set_source(void* vptr, const char* filename);
|
||||
void dos_qquickview_delete(void* vptr);
|
||||
void dos_qquickview_rootContext(void* vptr, void** context);
|
||||
|
||||
// CharArray
|
||||
void dos_chararray_create(CharPtr& ptr, int size);
|
||||
void dos_chararray_delete(CharPtr ptr);
|
||||
// QQmlContext
|
||||
void dos_qqmlcontext_baseUrl(void* vptr, char** result, int* length);
|
||||
void dos_qqmlcontext_setcontextproperty(void* vptr, const char* name, void* value);
|
||||
|
||||
// QVariant
|
||||
void dos_qvariant_create(void **vptr);
|
||||
void dos_qvariant_create_int(void **vptr, int value);
|
||||
void dos_qvariant_create_bool(void **vptr, bool value);
|
||||
void dos_qvariant_create_string(void **vptr, const char* value);
|
||||
void dos_qvariant_create_qobject(void **vptr, void* value);
|
||||
void dos_qvariant_create_qvariant(void **vptr, void* value);
|
||||
void dos_qvariant_create_float(void **vptr, float value);
|
||||
void dos_qvariant_create_double(void **vptr, double value);
|
||||
void dos_qvariant_toInt(void* vptr, int& value);
|
||||
void dos_qvariant_setInt(void* vptr, int value);
|
||||
void dos_qvariant_toBool(void* vptr, bool& value);
|
||||
void dos_qvariant_setBool(void* vptr, bool value);
|
||||
void dos_qvariant_toFloat(void* vptr, float& value);
|
||||
void dos_qvariant_setFloat(void* vptr, float value);
|
||||
void dos_qvariant_toDouble(void* vptr, double& value);
|
||||
void dos_qvariant_setDouble(void* vptr, double value);
|
||||
void dos_qvariant_toString(void* vptr, CharPtr& ptr, int& size);
|
||||
void dos_qvariant_setString(void* vptr, const char* value);
|
||||
void dos_qvariant_setQObject(void* vptr, void* value);
|
||||
void dos_qvariant_isnull(void *vptr, bool& isNull);
|
||||
void dos_qvariant_delete(void *vptr);
|
||||
void dos_qvariant_assign(void* vptr, void* other);
|
||||
// CharArray
|
||||
void dos_chararray_create(char** ptr, int size);
|
||||
void dos_chararray_delete(char* ptr);
|
||||
|
||||
// QObject
|
||||
void dos_qobject_create(void **vptr,
|
||||
void *dObjectPointer,
|
||||
DObjectCallback dObjectCallback);
|
||||
// QVariant
|
||||
void dos_qvariant_create(void** vptr);
|
||||
void dos_qvariant_create_int(void** vptr, int value);
|
||||
void dos_qvariant_create_bool(void** vptr, bool value);
|
||||
void dos_qvariant_create_string(void** vptr, const char* value);
|
||||
void dos_qvariant_create_qobject(void** vptr, void* value);
|
||||
void dos_qvariant_create_qvariant(void** vptr, void* value);
|
||||
void dos_qvariant_create_float(void** vptr, float value);
|
||||
void dos_qvariant_create_double(void** vptr, double value);
|
||||
void dos_qvariant_create_qabstractlistmodel(void** vptr, void* value);
|
||||
void dos_qvariant_toInt(void* vptr, int* value);
|
||||
void dos_qvariant_setInt(void* vptr, int value);
|
||||
void dos_qvariant_toBool(void* vptr, bool* value);
|
||||
void dos_qvariant_setBool(void* vptr, bool value);
|
||||
void dos_qvariant_toFloat(void* vptr, float* value);
|
||||
void dos_qvariant_setFloat(void* vptr, float value);
|
||||
void dos_qvariant_toDouble(void* vptr, double* value);
|
||||
void dos_qvariant_setDouble(void* vptr, double value);
|
||||
void dos_qvariant_toString(void* vptr, char** ptr, int* size);
|
||||
void dos_qvariant_setString(void* vptr, const char* value);
|
||||
void dos_qvariant_setQObject(void* vptr, void* value);
|
||||
void dos_qvariant_setQAbstractListModel(void* vptr, void* value);
|
||||
void dos_qvariant_isnull(void* vptr, bool* isNull);
|
||||
void dos_qvariant_delete(void* vptr);
|
||||
void dos_qvariant_assign(void* vptr, void* other);
|
||||
|
||||
void dos_qobject_slot_create(void* vptr,
|
||||
const char* name,
|
||||
int parametersCount,
|
||||
int* parametersMetaTypes,
|
||||
int* slotIndex);
|
||||
// QObject
|
||||
void dos_qobject_create(void** vptr,
|
||||
void* dObjectPointer,
|
||||
DObjectCallback dObjectCallback);
|
||||
|
||||
void dos_qobject_signal_create(void* vptr,
|
||||
const char* name,
|
||||
int parametersCount,
|
||||
int* parametersMetaTypes,
|
||||
int* signalIndex);
|
||||
void dos_qobject_slot_create(void* vptr,
|
||||
const char* name,
|
||||
int parametersCount,
|
||||
int* parametersMetaTypes,
|
||||
int* slotIndex);
|
||||
|
||||
void dos_qobject_signal_emit(void* vptr,
|
||||
const char* name,
|
||||
int parametersCount,
|
||||
void** parameters);
|
||||
void dos_qobject_signal_create(void* vptr,
|
||||
const char* name,
|
||||
int parametersCount,
|
||||
int* parametersMetaTypes,
|
||||
int* signalIndex);
|
||||
|
||||
void dos_qobject_property_create(void* vptr,
|
||||
const char* name,
|
||||
int propertyMetaType,
|
||||
const char* readSlot,
|
||||
const char* writeSlot,
|
||||
const char* notifySignal);
|
||||
void dos_qobject_delete(void *vptr);
|
||||
void dos_qobject_signal_emit(void* vptr,
|
||||
const char* name,
|
||||
int parametersCount,
|
||||
void** parameters);
|
||||
|
||||
void dos_qobject_property_create(void* vptr,
|
||||
const char* name,
|
||||
int propertyMetaType,
|
||||
const char* readSlot,
|
||||
const char* writeSlot,
|
||||
const char* notifySignal);
|
||||
void dos_qobject_delete(void* vptr);
|
||||
|
||||
// QModelIndex
|
||||
void dos_qmodelindex_create(void** vptr);
|
||||
void dos_qmodelindex_delete(void* vptr);
|
||||
void dos_qmodelindex_row(void* vptr, int* row);
|
||||
void dos_qmodelindex_column(void* vptr, int* column);
|
||||
void dos_qmodelindex_isValid(void* vptr, bool* isValid);
|
||||
void dos_qmodelindex_data(void* vptr, int role, void* data);
|
||||
void dos_qmodelindex_parent(void* vptr, void* parent);
|
||||
void dos_qmodelindex_child(void* vptr, int row, int column, void* child);
|
||||
void dos_qmodelindex_sibling(void* vptr, int row, int column, void* sibling);
|
||||
|
||||
// QHash<int, QByteArray>
|
||||
void dos_qhash_int_qbytearray_create(QHashIntQByteArrayVoidPtr* vptr);
|
||||
void dos_qhash_int_qbytearray_delete(QHashIntQByteArrayVoidPtr vptr);
|
||||
void dos_qhash_int_qbytearray_insert(QHashIntQByteArrayVoidPtr vptr, int key, const char* value);
|
||||
void dos_qhash_int_qbytearray_value(QHashIntQByteArrayVoidPtr vptr, int key, char** result);
|
||||
|
||||
// QAbstractListModel
|
||||
void dos_qabstractlistmodel_create(void** vptr,
|
||||
void* callbackObject,
|
||||
DObjectCallback dObjectCallback,
|
||||
RowCountCallback rowCountCallback,
|
||||
ColumnCountCallback columnCountCallback,
|
||||
DataCallback dataCallback,
|
||||
SetDataCallback setDataCallback,
|
||||
RoleNamesCallback roleNamesCallback,
|
||||
FlagsCallback flagsCallback,
|
||||
HeaderDataCallback headerDataCallback);
|
||||
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_endRemoveRows(void* vptr);
|
||||
void dos_qabstractlistmodel_beginResetModel(void* vptr);
|
||||
void dos_qabstractlistmodel_endResetModel(void* vptr);
|
||||
void dos_qabstractlistmodel_dataChanged(void* vptr,
|
||||
QModelIndexVoidPtr topLeftIndex,
|
||||
QModelIndexVoidPtr bottomRightIndex,
|
||||
int* rolesArrayPtr,
|
||||
int rolesArrayLength);
|
||||
|
||||
void dos_qabstractlistmodel_delete(void* vptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
27
DOtherSide/DOtherSide/DOtherSideTypes.h
Normal file
27
DOtherSide/DOtherSide/DOtherSideTypes.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef DOTHERSIDETYPES_H
|
||||
#define DOTHERSIDETYPES_H
|
||||
|
||||
// Raw data types
|
||||
typedef bool* BoolPtr;
|
||||
typedef int* IntPtr;
|
||||
typedef char* CharPtr;
|
||||
typedef const char* ConstCharPtr;
|
||||
typedef void* QVariantVoidPtr;
|
||||
typedef void* QModelIndexVoidPtr;
|
||||
typedef void* QAbstractListModelVoidPtr;
|
||||
typedef void* QQmlApplicationEngineVoidPtr;
|
||||
typedef void* QQuickViewVoidPtr;
|
||||
typedef void* QQmlContextVoidPtr;
|
||||
typedef void* QHashIntQByteArrayVoidPtr;
|
||||
|
||||
// Raw function types
|
||||
typedef void (*Function)(void*);
|
||||
typedef void (*DObjectCallback)(void*, void*, int, void**);
|
||||
typedef void (*RowCountCallback)(void* model, QModelIndexVoidPtr index, IntPtr result);
|
||||
typedef void (*ColumnCountCallback)(void* model, QModelIndexVoidPtr index, IntPtr result);
|
||||
typedef void (*DataCallback)(void* model, QModelIndexVoidPtr index, int role, QVariantVoidPtr result);
|
||||
typedef void (*SetDataCallback) (void* model, QModelIndexVoidPtr index, QVariantVoidPtr value, int role, BoolPtr result);
|
||||
typedef void (*RoleNamesCallback)(void* model, QHashIntQByteArrayVoidPtr result);
|
||||
typedef void (*FlagsCallback) (void* model, QModelIndexVoidPtr index, IntPtr result);
|
||||
typedef void (*HeaderDataCallback) (void* model, int section, int orientation, int role, QVariantVoidPtr result);
|
||||
#endif
|
@ -15,7 +15,6 @@ set(HEADERS_LIST
|
||||
|
||||
set(SRC_LIST
|
||||
DynamicProperty.cpp
|
||||
DynamicQObject.cpp
|
||||
DynamicSignal.cpp
|
||||
DynamicSlot.cpp
|
||||
)
|
||||
|
@ -1,119 +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;
|
||||
}
|
||||
|
@ -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
|
||||
@ -23,7 +23,9 @@ public:
|
||||
QString name() const;
|
||||
QMetaType::Type type() const;
|
||||
|
||||
bool isValid() const { return d != nullptr; }
|
||||
bool isValid() const {
|
||||
return d != nullptr;
|
||||
}
|
||||
|
||||
bool isReadable() const;
|
||||
bool isWriteable() const;
|
||||
@ -36,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
|
@ -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();
|
||||
}
|
@ -1,19 +1,22 @@
|
||||
#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, public IDynamicQObject
|
||||
{
|
||||
typedef void (*Callback)(void*, void*, int, void **);
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
DynamicQObject();
|
||||
@ -22,37 +25,37 @@ public:
|
||||
virtual ~DynamicQObject();
|
||||
|
||||
/// Sets the function to be called from C++ to D or Nimrod
|
||||
void setDObjectCallback(Callback callback) { m_dObjectCallback = callback; }
|
||||
virtual void setDObjectCallback(IDynamicQObject::Callback callback) override;
|
||||
|
||||
/// Sets the D or Nimrod object that owns this DynamicQObject
|
||||
void setDObjectPointer(void* dObjectPointer) { m_dObjectPointer = dObjectPointer; }
|
||||
virtual void setDObjectPointer(void* dObjectPointer) override;
|
||||
|
||||
/// 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) override;
|
||||
|
||||
/// 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) override;
|
||||
|
||||
/// 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 = "") override;
|
||||
|
||||
/// 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) override;
|
||||
|
||||
/// Return the QMetaObject for this DynamicQObject
|
||||
virtual const QMetaObject *metaObject() const;
|
||||
virtual const QMetaObject* metaObject() const;
|
||||
|
||||
/// The qt metacall. Called from Qt when a signals, slot or property is invoked
|
||||
int qt_metacall(QMetaObject::Call, int, void **);
|
||||
int qt_metacall(QMetaObject::Call, int, void**);
|
||||
|
||||
private:
|
||||
bool executeSlot(const DynamicSlot& slot, void** args);
|
||||
@ -67,9 +70,9 @@ private:
|
||||
/// The creation is customizable by injecting custom code after signals and slots have
|
||||
/// been added
|
||||
static QMetaObject* recreateMetaObjectBuilder(QMetaObject* currentMetaObject,
|
||||
const std::function<void(QMetaObjectBuilder&)>& afterSignalAdded,
|
||||
const std::function<void(QMetaObjectBuilder&)>& afterSlotAdded,
|
||||
const std::function<void(QMetaObjectBuilder&)>& afterPropertyAdded);
|
||||
const std::function<void(QMetaObjectBuilder&)>& afterSignalAdded,
|
||||
const std::function<void(QMetaObjectBuilder&)>& afterSlotAdded,
|
||||
const std::function<void(QMetaObjectBuilder&)>& afterPropertyAdded);
|
||||
|
||||
QHash<QString, DynamicSignal> m_signalsByName;
|
||||
QHash<QByteArray, DynamicSignal> m_signalsBySignature;
|
||||
@ -78,5 +81,380 @@ private:
|
||||
QHash<QByteArray, DynamicProperty> m_propertiesByName;
|
||||
QScopedPointer<QMetaObject> m_metaObject;
|
||||
void* m_dObjectPointer;
|
||||
Callback m_dObjectCallback;
|
||||
IDynamicQObject::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>
|
||||
void DynamicQObject<T>::setDObjectCallback(IDynamicQObject::Callback callback)
|
||||
{
|
||||
m_dObjectCallback = callback;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DynamicQObject<T>::setDObjectPointer(void* dObjectPointer)
|
||||
{
|
||||
m_dObjectPointer = dObjectPointer;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
switch (callType)
|
||||
{
|
||||
case 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;
|
||||
}
|
||||
|
||||
case 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;
|
||||
}
|
||||
|
||||
case 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;
|
||||
}
|
||||
|
||||
default:
|
||||
return T::qt_metacall(callType, index, args);
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
for (auto& method : signalsList)
|
||||
metaObjectBuilder.addMethod(method);
|
||||
|
||||
// Call custom code to be executed after signal have been added
|
||||
afterSignalAdded(metaObjectBuilder);
|
||||
|
||||
for (auto& method : methodsList)
|
||||
metaObjectBuilder.addMethod(method);
|
||||
|
||||
// Call custom code to be executed after slots have been added
|
||||
afterSlotAdded(metaObjectBuilder);
|
||||
|
||||
for (auto& property : propertiesList)
|
||||
metaObjectBuilder.addProperty(property);
|
||||
|
||||
afterPropertyAdded(metaObjectBuilder);
|
||||
|
||||
return metaObjectBuilder.toMetaObject();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -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();
|
||||
}
|
@ -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
|
@ -1,111 +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();
|
||||
|
||||
qDebug() << "C++: slot signature is " << d->signature;
|
||||
}
|
@ -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
|
40
DOtherSide/DynamicQObject/IDynamicQObject.h
Normal file
40
DOtherSide/DynamicQObject/IDynamicQObject.h
Normal 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
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 █
|
||||
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
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <DynamicQObject.h>
|
||||
#include <QDebug>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
|
2
Nim/Examples/AbstractItemModel/CMakeLists.txt
Normal file
2
Nim/Examples/AbstractItemModel/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/main.qml DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_nim_executable(TARGET AbstractItemModel SOURCES main.nim PATHS ../../NimQml)
|
64
Nim/Examples/AbstractItemModel/main.nim
Normal file
64
Nim/Examples/AbstractItemModel/main.nim
Normal file
@ -0,0 +1,64 @@
|
||||
import NimQml
|
||||
import macros
|
||||
import typeinfo
|
||||
import tables
|
||||
|
||||
type
|
||||
Roles {.pure.} = enum
|
||||
Name = cint(0)
|
||||
|
||||
MyQAbstractListModel = ref object of QAbstractListModel
|
||||
m_roleNames: Table[int, cstring]
|
||||
m_names: seq[string]
|
||||
|
||||
proc create(self: MyQAbstractListModel) =
|
||||
var qAbstractListModel = self.QAbstractListModel
|
||||
qAbstractListModel.create
|
||||
self.m_names = @["John", "Max", "Paul", "Anna"]
|
||||
self.m_roleNames = initTable[int, cstring]()
|
||||
self.m_roleNames[0] = "name"
|
||||
|
||||
proc delete(self: MyQAbstractListModel) =
|
||||
var qAbstractListModel = self.QAbstractListModel
|
||||
qAbstractListModel.delete
|
||||
|
||||
proc newMyQAbstractListModel(): MyQAbstractListModel =
|
||||
new(result, delete)
|
||||
result.create
|
||||
|
||||
method rowCount(self: MyQAbstractListModel, index: QModelIndex): cint =
|
||||
return self.m_names.len.cint
|
||||
|
||||
method data(self: MyQAbstractListModel, index: QModelIndex, role: cint): QVariant =
|
||||
if not index.isValid:
|
||||
return
|
||||
if index.row < 0 or index.row >= self.m_names.len:
|
||||
return
|
||||
if role == Roles.Name.cint:
|
||||
return newQVariant(self.m_names[index.row])
|
||||
|
||||
method roleNames(self: MyQAbstractListModel): Table[int, cstring] =
|
||||
return self.m_roleNames
|
||||
|
||||
proc mainProc() =
|
||||
var app = newQApplication()
|
||||
defer: app.delete
|
||||
|
||||
var myListModel = newMyQAbstractListModel()
|
||||
defer: myListModel.delete
|
||||
|
||||
var engine = newQQmlApplicationEngine()
|
||||
defer: engine.delete
|
||||
|
||||
var variant = newQVariant(myListModel)
|
||||
defer: variant.delete
|
||||
|
||||
engine.rootContext.setContextProperty("myListModel", variant)
|
||||
engine.load("main.qml")
|
||||
|
||||
app.exec()
|
||||
|
||||
when isMainModule:
|
||||
mainProc()
|
||||
GC_fullcollect()
|
||||
|
25
Nim/Examples/AbstractItemModel/main.qml
Normal file
25
Nim/Examples/AbstractItemModel/main.qml
Normal file
@ -0,0 +1,25 @@
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
ApplicationWindow
|
||||
{
|
||||
width: 400
|
||||
height: 300
|
||||
title: "AbstractItemModel"
|
||||
Component.onCompleted: visible = true
|
||||
|
||||
Component
|
||||
{
|
||||
id: myListModelDelegate
|
||||
Label { text: "Name:" + name }
|
||||
}
|
||||
|
||||
ListView
|
||||
{
|
||||
anchors.fill: parent
|
||||
model: myListModel
|
||||
delegate: myListModelDelegate
|
||||
}
|
||||
}
|
@ -2,4 +2,5 @@ add_subdirectory(HelloWorld)
|
||||
add_subdirectory(SimpleData)
|
||||
add_subdirectory(SlotsAndProperties)
|
||||
add_subdirectory(QtObjectMacro)
|
||||
add_subdirectory(ContactApp)
|
||||
add_subdirectory(ContactApp)
|
||||
add_subdirectory(AbstractItemModel)
|
@ -1,44 +1,62 @@
|
||||
## Please note we are using templates where ordinarily we would like to use procedures
|
||||
## due to bug: https://github.com/Araq/Nim/issues/1821
|
||||
import NimQml, NimQmlMacros, Contact
|
||||
import NimQml, NimQmlMacros, Contact, Tables
|
||||
|
||||
QtObject:
|
||||
type ContactList* = ref object of QObject
|
||||
contacts*: seq[Contact]
|
||||
type
|
||||
ContactList* = ref object of QAbstractListModel
|
||||
contacts*: seq[Contact]
|
||||
ContactRoles {.pure.} = enum
|
||||
FirstName = 0
|
||||
Surname = 1
|
||||
|
||||
proc delete*(self: ContactList) =
|
||||
let qobject = self.QObject
|
||||
qobject.delete
|
||||
converter toCInt(value: ContactRoles): cint = return value.cint
|
||||
converter toCInt(value: int): cint = return value.cint
|
||||
converter toInt(value: ContactRoles): int = return value.int
|
||||
converter toInt(value: cint): int = return value.int
|
||||
converter toQVariant(value: string): QVariant = return value.newQVariant
|
||||
|
||||
proc delete(self: ContactList) =
|
||||
let model = self.QAbstractListModel
|
||||
model.delete
|
||||
for contact in self.contacts:
|
||||
contact.delete
|
||||
self.contacts = @[]
|
||||
|
||||
proc newContactList*(): ContactList =
|
||||
new(result)
|
||||
new(result, delete)
|
||||
result.contacts = @[]
|
||||
result.create()
|
||||
|
||||
method getCount(self: ContactList): int {.slot.} =
|
||||
result.create
|
||||
|
||||
method rowCount(self: ContactList, index: QModelIndex = nil): cint =
|
||||
return self.contacts.len
|
||||
|
||||
method countChanged(self: ContactList) {.signal.}
|
||||
method data(self: ContactList, index: QModelIndex, role: cint): QVariant =
|
||||
if not index.isValid:
|
||||
return
|
||||
if index.row < 0 or index.row >= self.contacts.len:
|
||||
return
|
||||
let contact = self.contacts[index.row]
|
||||
let contactRole = role.ContactRoles
|
||||
case contactRole:
|
||||
of ContactRoles.FirstName: return contact.firstName
|
||||
of ContactRoles.Surname: return contact.surname
|
||||
else: return
|
||||
|
||||
method roleNames(self: ContactList): Table[cint, cstring] =
|
||||
result = initTable[cint, cstring]()
|
||||
result[ContactRoles.FirstName] = "firstName"
|
||||
result[ContactRoles.Surname] = "surname"
|
||||
|
||||
method add*(self: ContactList, name: string, surname: string) {.slot.} =
|
||||
let contact = newContact()
|
||||
contact.firstName = name
|
||||
contact.surname = surname
|
||||
self.beginInsertRows(newQModelIndex(), self.contacts.len, self.contacts.len)
|
||||
self.contacts.add(contact)
|
||||
self.countChanged()
|
||||
self.endInsertRows()
|
||||
|
||||
method get*(self: ContactList, index: int): QObject {.slot.} =
|
||||
if index < 0 or index >= self.contacts.len:
|
||||
return nil
|
||||
result = self.contacts[index].QObject
|
||||
|
||||
method del*(self: ContactList, index: int) {.slot.} =
|
||||
self.contacts.del(index)
|
||||
self.countChanged()
|
||||
|
||||
QtProperty[int] count:
|
||||
read = getCount
|
||||
notify = countChanged
|
||||
method del*(self: ContactList, pos: int) {.slot.} =
|
||||
if pos < 0 or pos >= self.contacts.len:
|
||||
return
|
||||
self.beginRemoveRows(newQModelIndex(), pos, pos)
|
||||
self.contacts.del(pos)
|
||||
self.endRemoveRows
|
||||
|
@ -3,50 +3,91 @@ import QtQuick.Controls 1.2
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
ApplicationWindow
|
||||
{
|
||||
width: 400
|
||||
ApplicationWindow {
|
||||
|
||||
width: 500
|
||||
height: 300
|
||||
title: "ContactApp"
|
||||
visible: true
|
||||
|
||||
menuBar: MenuBar {
|
||||
Menu
|
||||
{
|
||||
Menu {
|
||||
title: "&File"
|
||||
MenuItem { text: "Load"; onTriggered: logic.onLoadTriggered() }
|
||||
MenuItem { text: "Save"; onTriggered: logic.onSaveTriggered() }
|
||||
MenuItem { text: "Exit"; onTriggered: logic.onExitTriggered() }
|
||||
MenuItem { text: "&Load"; onTriggered: logic.onLoadTriggered() }
|
||||
MenuItem { text: "&Save"; onTriggered: logic.onSaveTriggered() }
|
||||
MenuItem { text: "&Exit"; onTriggered: logic.onExitTriggered() }
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
ListView
|
||||
{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
model: logic.contactList.count
|
||||
spacing: 5
|
||||
delegate: RowLayout {
|
||||
width: ListView.view.width
|
||||
property QtObject contact: logic.contactList.get(index)
|
||||
TextField { Layout.fillWidth: true; text: contact.firstName }
|
||||
TextField { Layout.fillWidth: true; text: contact.surname }
|
||||
Button { text: "Save" }
|
||||
Button { text: "Delete"; onClicked: logic.contactList.del(index) }
|
||||
|
||||
Component {
|
||||
id: tableTextDelegate
|
||||
Label {
|
||||
id: tableTextDelegateInstance
|
||||
property var styleData: undefined
|
||||
states: State {
|
||||
when: styleData !== undefined
|
||||
PropertyChanges {
|
||||
target: tableTextDelegateInstance;
|
||||
text: styleData.value;
|
||||
color: styleData.textColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout
|
||||
{
|
||||
Component {
|
||||
id: tableButtonDelegate
|
||||
Button {
|
||||
id: tableButtonDelegateInstance
|
||||
property var styleData: undefined
|
||||
text: "Delete"
|
||||
onClicked: logic.contactList.del(styleData.row)
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: tableItemDelegate
|
||||
Loader {
|
||||
id: tableItemDelegateInstance
|
||||
sourceComponent: {
|
||||
if (styleData.column === 0 || styleData.column === 1)
|
||||
return tableTextDelegate
|
||||
else if (styleData.column === 2)
|
||||
return tableButtonDelegate
|
||||
else
|
||||
return tableTextDelegate
|
||||
}
|
||||
Binding {
|
||||
target: tableItemDelegateInstance.item
|
||||
property: "styleData"
|
||||
value: styleData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TableView {
|
||||
model: logic.contactList
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
TableViewColumn { role: "firstName"; title: "FirstName"; width: 200 }
|
||||
TableViewColumn { role: "surname"; title: "Surname"; width: 200}
|
||||
TableViewColumn { width: 100; }
|
||||
itemDelegate: tableItemDelegate
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Label { text: "Name" }
|
||||
TextField { id: nameTextField; Layout.fillWidth: true; text: "" }
|
||||
Label { text: "Surname" }
|
||||
TextField { id: surnameTextField; Layout.fillWidth: true; text: "" }
|
||||
Button { text: "Add"; onClicked: logic.contactList.add(nameTextField.text, surnameTextField.text) }
|
||||
Button {
|
||||
text: "Add"
|
||||
onClicked: logic.contactList.add(nameTextField.text, surnameTextField.text)
|
||||
enabled: nameTextField.text !== "" && surnameTextField.text !== ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,22 +26,37 @@ type QMetaType* {.pure.} = enum ## \
|
||||
|
||||
var qobjectRegistry = initTable[ptr QObjectObj, bool]()
|
||||
|
||||
proc debugMsg(message: string) =
|
||||
echo "NimQml: ", message
|
||||
template debugMsg(message: string) =
|
||||
{.push warning[user]: off.} # workaround to remove warnings; this won't be needed soon
|
||||
when defined(debug):
|
||||
{.pop.}
|
||||
echo "NimQml: ", message
|
||||
else:
|
||||
{.pop.}
|
||||
|
||||
template debugMsg(typeName: string, procName: string) =
|
||||
{.push warning[user]: off.} # workaround to remove warnings; this won't be needed soon
|
||||
when defined(debug):
|
||||
{.pop.}
|
||||
var message = typeName
|
||||
message &= ": "
|
||||
message &= procName
|
||||
debugMsg(message)
|
||||
else:
|
||||
{.pop.}
|
||||
|
||||
proc debugMsg(typeName: string, procName: string) =
|
||||
var message = typeName
|
||||
message &= ": "
|
||||
message &= procName
|
||||
debugMsg(message)
|
||||
|
||||
proc debugMsg(typeName: string, procName: string, userMessage: string) =
|
||||
var message = typeName
|
||||
message &= ": "
|
||||
message &= procName
|
||||
message &= " "
|
||||
message &= userMessage
|
||||
debugMsg(message)
|
||||
template debugMsg(typeName: string, procName: string, userMessage: string) =
|
||||
{.push warning[user]: off.} # workaround to remove warnings; this won't be needed soon
|
||||
when defined(debug):
|
||||
{.pop.}
|
||||
var message = typeName
|
||||
message &= ": "
|
||||
message &= procName
|
||||
message &= " "
|
||||
message &= userMessage
|
||||
debugMsg(message)
|
||||
else:
|
||||
{.pop.}
|
||||
|
||||
template newWithCondFinalizer(variable: expr, finalizer: expr) =
|
||||
## calls ``new`` but only setting a finalizer when ``nimqml_use_finalizers``
|
||||
@ -101,7 +116,7 @@ proc create*(variant: QVariant, value: string) =
|
||||
|
||||
proc create*(variant: QVariant, value: QObject) =
|
||||
## Create a new QVariant given a QObject
|
||||
dos_qvariant_create_qobject(variant.data, value.data)
|
||||
dos_qvariant_create_qobject(variant.data, value.data.RawQObject)
|
||||
variant.deleted = false
|
||||
|
||||
proc create*(variant: QVariant, value: RawQVariant) =
|
||||
@ -225,8 +240,8 @@ proc `stringVal=`*(variant: QVariant, value: string) =
|
||||
|
||||
proc `qobjectVal=`*(variant: QVariant, value: QObject) =
|
||||
## Sets the QVariant qobject value
|
||||
dos_qvariant_setQObject(variant.data, value.data)
|
||||
|
||||
dos_qvariant_setQObject(variant.data, value.data.RawQObject)
|
||||
|
||||
proc assign*(leftValue: QVariant, rightValue: QVariant) =
|
||||
## Assign a QVariant with another. The inner value of the QVariant is copied
|
||||
dos_qvariant_assign(leftValue.data, rightValue.data)
|
||||
@ -491,3 +506,284 @@ proc newQQuickView*(): QQuickView =
|
||||
## Return a new QQuickView
|
||||
newWithCondFinalizer(result, delete)
|
||||
result.create()
|
||||
|
||||
# QModelIndex
|
||||
proc dos_qmodelindex_create(modelIndex: var RawQModelIndex) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qmodelindex_delete(modelIndex: RawQModelIndex) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qmodelindex_row(modelIndex: RawQModelIndex, row: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qmodelindex_column(modelIndex: RawQModelIndex, column: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qmodelindex_isValid(modelIndex: RawQModelIndex, column: var bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qmodelindex_data(modelIndex: RawQModelIndex, role: cint, data: RawQVariant) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qmodelindex_parent(modelIndex: RawQModelIndex, parent: RawQModelIndex) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qmodelindex_child(modelIndex: RawQModelIndex, row: cint, column: cint, parent: RawQModelIndex) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qmodelindex_sibling(modelIndex: RawQModelIndex, row: cint, column: cint, sibling: RawQModelIndex) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
|
||||
proc create*(modelIndex: var QModelIndex) =
|
||||
## Create a new QModelIndex
|
||||
dos_qmodelindex_create(modelIndex.data)
|
||||
modelIndex.deleted = false
|
||||
|
||||
proc create*(modelIndex: var QModelIndex, rawQModelIndex: RawQModelIndex) =
|
||||
## Create a new QModelIndex
|
||||
modelIndex.data = rawQModelIndex
|
||||
modelIndex.deleted = false
|
||||
|
||||
proc delete*(modelIndex: QModelIndex) =
|
||||
## Delete the given QModelIndex
|
||||
if not modelIndex.deleted:
|
||||
debugMsg("QModelIndex", "delete")
|
||||
dos_qmodelindex_delete(modelIndex.data)
|
||||
modelIndex.data = nil.RawQModelIndex
|
||||
modelIndex.deleted = true
|
||||
|
||||
proc newQModelIndex*(): QModelIndex =
|
||||
## Return a new QModelIndex
|
||||
newWithCondFinalizer(result, delete)
|
||||
result.create()
|
||||
|
||||
proc newQModelIndex*(rawQModelIndex: RawQModelIndex): QModelIndex =
|
||||
## Return a new QModelIndex given a raw index
|
||||
newWithCondFinalizer(result, delete)
|
||||
result.create(rawQModelIndex)
|
||||
|
||||
proc row*(modelIndex: QModelIndex): cint =
|
||||
## Return the index row
|
||||
dos_qmodelindex_row(modelIndex.data, result)
|
||||
|
||||
proc column*(modelIndex: QModelIndex): cint =
|
||||
## Return the index column
|
||||
dos_qmodelindex_column(modelIndex.data, result)
|
||||
|
||||
proc isValid*(modelIndex: QModelIndex): bool =
|
||||
## Return true if the index is valid, false otherwise
|
||||
dos_qmodelindex_isValid(modelIndex.data, result)
|
||||
|
||||
proc data*(modelIndex: QModelIndex, role: cint): QVariant =
|
||||
## Return the model data associated to the given role
|
||||
result = newQVariant()
|
||||
dos_qmodelindex_data(modelIndex.data, role, result.data)
|
||||
|
||||
proc parent*(modelIndex: QModelIndex): QModelIndex =
|
||||
## Return the parent index
|
||||
result = newQModelIndex()
|
||||
dos_qmodelindex_parent(modelIndex.data, result.data)
|
||||
|
||||
proc child*(modelIndex: QModelIndex, row: cint, column: cint): QModelIndex =
|
||||
## Return the child index associated to the given row and column
|
||||
result = newQModelIndex()
|
||||
dos_qmodelindex_child(modelIndex.data, row, column, result.data)
|
||||
|
||||
proc sibling*(modelIndex: QModelIndex, row: cint, column: cint): QModelIndex =
|
||||
## Return the sibling index associated to the given row and column
|
||||
result = newQModelIndex()
|
||||
dos_qmodelindex_sibling(modelIndex.data, row, column, result.data)
|
||||
|
||||
# QHashIntByteArray
|
||||
proc dos_qhash_int_qbytearray_create(qHash: var RawQHashIntByteArray) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qhash_int_qbytearray_delete(qHash: RawQHashIntByteArray) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qhash_int_qbytearray_insert(qHash: RawQHashIntByteArray, key: int, value: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qhash_int_qbytearray_value(qHash: RawQHashIntByteArray, key: int, value: var cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
|
||||
proc create*(qHash: var QHashIntByteArray) =
|
||||
## Create the QHash
|
||||
debugMsg("QHashIntByteArray", "create")
|
||||
dos_qhash_int_qbytearray_create(qHash.data)
|
||||
qHash.deleted = false
|
||||
|
||||
proc delete*(qHash: QHashIntByteArray) =
|
||||
## Delete the QHash
|
||||
if not qHash.deleted:
|
||||
debugMsg("QHashIntByteArray", "delete")
|
||||
dos_qhash_int_qbytearray_delete(qHash.data)
|
||||
qHash.deleted = true
|
||||
|
||||
proc insert*(qHash: QHashIntByteArray, key: int, value: cstring) =
|
||||
## Insert the value at the given key
|
||||
dos_qhash_int_qbytearray_insert(qHash.data, key, value)
|
||||
|
||||
proc value*(qHash: QHashIntByteArray, key: int): string =
|
||||
## Return the value associated at the given key
|
||||
var rawString: cstring
|
||||
dos_qhash_int_qbytearray_value(qHash.data, key, rawString)
|
||||
result = $rawString
|
||||
dos_chararray_delete(rawString)
|
||||
|
||||
proc newQHashIntQByteArray*(): QHashIntByteArray =
|
||||
## Create a new QHashIntQByteArray
|
||||
newWithCondFinalizer(result, delete)
|
||||
result.create()
|
||||
|
||||
# QAbstractListModel
|
||||
type
|
||||
RowCountCallback = proc(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, result: var cint) {.cdecl.}
|
||||
ColumnCountCallback = proc(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, result: var cint) {.cdecl.}
|
||||
DataCallback = proc(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, role: cint, result: RawQVariant) {.cdecl.}
|
||||
SetDataCallback = proc(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, value: RawQVariant, role: cint, result: var bool) {.cdecl.}
|
||||
RoleNamesCallback = proc(modelObject: ptr QAbstractListModelObj, result: RawQHashIntByteArray) {.cdecl.}
|
||||
FlagsCallback = proc(modelObject: ptr QAbstractListModelObj, index: RawQModelIndex, result: var cint) {.cdecl.}
|
||||
HeaderDataCallback = proc(modelObject: ptr QAbstractListModelObj, section: cint, orientation: cint, role: cint, result: RawQVariant) {.cdecl.}
|
||||
|
||||
proc dos_qabstractlistmodel_create(model: var RawQAbstractListModel,
|
||||
modelPtr: ptr QAbstractListModelObj,
|
||||
qobjectCallback: QObjectCallBack,
|
||||
rowCountCallback: RowCountCallback,
|
||||
columnCountCallback: ColumnCountCallback,
|
||||
dataCallback: DataCallback,
|
||||
setDataCallback: SetDataCallBack,
|
||||
roleNamesCallback: RoleNamesCallback,
|
||||
flagsCallback: FlagsCallback,
|
||||
headerDataCallback: HeaderDataCallback) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qabstractlistmodel_delete(model: RawQAbstractListModel) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qabstractlistmodel_beginInsertRows(model: RawQAbstractListModel,
|
||||
parentIndex: RawQModelIndex,
|
||||
first: cint,
|
||||
last: cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qabstractlistmodel_endInsertRows(model: RawQAbstractListModel) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qabstractlistmodel_beginRemoveRows(model: RawQAbstractListModel,
|
||||
parentIndex: RawQModelIndex,
|
||||
first: cint,
|
||||
last: cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qabstractlistmodel_endRemoveRows(model: RawQAbstractListModel) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qabstractlistmodel_beginResetModel(model: RawQAbstractListModel) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qabstractlistmodel_endResetModel(model: RawQAbstractListModel) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
proc dos_qabstractlistmodel_dataChanged(model: RawQAbstractListModel,
|
||||
parentLeft: RawQModelIndex,
|
||||
bottomRight: RawQModelIndex,
|
||||
rolesArrayPtr: ptr cint,
|
||||
rolesArrayLength: cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
|
||||
|
||||
method rowCount*(model: QAbstractListModel, index: QModelIndex): cint =
|
||||
## Return the model's row count
|
||||
return 0
|
||||
|
||||
proc rowCountCallback(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, result: var cint) {.cdecl, exportc.} =
|
||||
debugMsg("QAbstractListModel", "rowCountCallback")
|
||||
let model = cast[QAbstractListModel](modelObject)
|
||||
let index = newQModelIndex(rawIndex)
|
||||
result = model.rowCount(index)
|
||||
|
||||
method columnCount*(model: QAbstractListModel, index: QModelIndex): cint =
|
||||
## Return the model's column count
|
||||
return 1
|
||||
|
||||
proc columnCountCallback(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, result: var cint) {.cdecl, exportc.} =
|
||||
debugMsg("QAbstractListModel", "columnCountCallback")
|
||||
let model = cast[QAbstractListModel](modelObject)
|
||||
let index = newQModelIndex(rawIndex)
|
||||
result = model.columnCount(index)
|
||||
|
||||
method data*(model: QAbstractListModel, index: QModelIndex, role: cint): QVariant =
|
||||
## Return the data at the given model index and role
|
||||
return nil
|
||||
|
||||
proc dataCallback(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, role: cint, result: RawQVariant) {.cdecl, exportc.} =
|
||||
debugMsg("QAbstractListModel", "dataCallback")
|
||||
let model = cast[QAbstractListModel](modelObject)
|
||||
let index = newQModelIndex(rawIndex)
|
||||
let variant = data(model, index, role)
|
||||
if variant != nil:
|
||||
dos_qvariant_assign(result, variant.data)
|
||||
variant.delete
|
||||
|
||||
method setData*(model: QAbstractListModel, index: QModelIndex, value: QVariant, role: cint): bool =
|
||||
## Sets the data at the given index and role. Return true on success, false otherwise
|
||||
return false
|
||||
|
||||
proc setDataCallback(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, rawQVariant: RawQVariant, role: cint, result: var bool) {.cdecl, exportc.} =
|
||||
debugMsg("QAbstractListModel", "setDataCallback")
|
||||
let model = cast[QAbstractListModel](modelObject)
|
||||
let index = newQModelIndex(rawIndex)
|
||||
let variant = newQVariant(rawQVariant)
|
||||
result = model.setData(index, variant, role)
|
||||
|
||||
method roleNames*(model: QAbstractListModel): Table[cint, cstring] =
|
||||
## Return the model role names
|
||||
result = initTable[cint, cstring]()
|
||||
|
||||
proc roleNamesCallback(modelObject: ptr QAbstractListModelObj, hash: RawQHashIntByteArray) {.cdecl, exportc.} =
|
||||
debugMsg("QAbstractListModel", "roleNamesCallback")
|
||||
let model = cast[QAbstractListModel](modelObject)
|
||||
let table = model.roleNames()
|
||||
for pair in table.pairs:
|
||||
dos_qhash_int_qbytearray_insert(hash, pair.key, pair.val)
|
||||
|
||||
method flags*(model: QAbstractListModel, index: QModelIndex): QtItemFlag =
|
||||
## Return the item flags and the given index
|
||||
return QtItemFlag.None
|
||||
|
||||
proc flagsCallback(modelObject: ptr QAbstractListModelObj, rawIndex: RawQModelIndex, result: var cint) {.cdecl, exportc.} =
|
||||
debugMsg("QAbstractListModel", "flagsCallback")
|
||||
let model = cast[QAbstractListModel](modelObject)
|
||||
let index = newQModelIndex(rawIndex)
|
||||
result = model.flags(index).cint
|
||||
|
||||
method headerData*(model: QAbstractListModel, section: cint, orientation: QtOrientation, role: cint): QVariant =
|
||||
## Returns the data for the given role and section in the header with the specified orientation
|
||||
return nil
|
||||
|
||||
proc headerDataCallback(modelObject: ptr QAbstractListModelObj, section: cint, orientation: cint, role: cint, result: RawQVariant) {.cdecl, exportc.} =
|
||||
debugMsg("QAbstractListModel", "headerDataCallback")
|
||||
let model = cast[QAbstractListModel](modelObject)
|
||||
let variant = model.headerData(section, orientation.QtOrientation, role)
|
||||
if variant != nil:
|
||||
dos_qvariant_assign(result, variant.data)
|
||||
variant.delete
|
||||
|
||||
proc create*(model: var QAbstractListModel) =
|
||||
## Create a new QAbstractListModel
|
||||
debugMsg("QAbstractListModel", "create")
|
||||
model.slots = initTable[string,cint]()
|
||||
model.signals = initTable[string, cint]()
|
||||
model.properties = initTable[string, cint]()
|
||||
model.deleted = false
|
||||
let modelPtr = addr(model[])
|
||||
dos_qabstractlistmodel_create(model.data.RawQAbstractListModel, modelPtr, qobjectCallback, rowCountCallback, columnCountCallback, dataCallback, setDataCallback, roleNamesCallback, flagsCallback, headerDataCallback)
|
||||
qobjectRegistry[modelPtr] = true
|
||||
|
||||
proc delete*(model: QAbstractListModel) =
|
||||
## Delete the given QAbstractListModel
|
||||
if not model.deleted:
|
||||
debugMsg("QAbstractListModel", "delete")
|
||||
let modelPtr = addr(model[])
|
||||
qobjectRegistry.del modelPtr
|
||||
dos_qabstractlistmodel_delete(model.data.RawQAbstractListModel)
|
||||
model.data = nil.RawQObject
|
||||
model.deleted = true
|
||||
|
||||
proc newQAbstractListModel*(): QAbstractListModel =
|
||||
## Return a new QAbstractListModel
|
||||
newWithCondFinalizer(result, delete)
|
||||
result.create()
|
||||
|
||||
proc beginInsertRows*(model: QAbstractListModel, parentIndex: QModelIndex, first: int, last: int) =
|
||||
## Notify the view that the model is about to inserting the given number of rows
|
||||
dos_qabstractlistmodel_beginInsertRows(model.data.RawQAbstractListModel, parentIndex.data, first.cint, last.cint)
|
||||
|
||||
proc endInsertRows*(model: QAbstractListModel) =
|
||||
## Notify the view that the rows have been inserted
|
||||
dos_qabstractlistmodel_endInsertRows(model.data.RawQAbstractListModel)
|
||||
|
||||
proc beginRemoveRows*(model: QAbstractListModel, parentIndex: QModelIndex, first: int, last: int) =
|
||||
## Notify the view that the model is about to remove the given number of rows
|
||||
dos_qabstractlistmodel_beginRemoveRows(model.data.RawQAbstractListModel, parentIndex.data, first.cint, last.cint)
|
||||
|
||||
proc endRemoveRows*(model: QAbstractListModel) =
|
||||
## Notify the view that the rows have been removed
|
||||
dos_qabstractlistmodel_endRemoveRows(model.data.RawQAbstractListModel)
|
||||
|
||||
proc beginResetModel*(model: QAbstractListModel) =
|
||||
## Notify the view that the model is about to resetting
|
||||
dos_qabstractlistmodel_beginResetModel(model.data.RawQAbstractListModel)
|
||||
|
||||
proc endResetModel*(model: QAbstractListModel) =
|
||||
## Notify the view that model has finished resetting
|
||||
dos_qabstractlistmodel_endResetModel(model.data.RawQAbstractListModel)
|
||||
|
||||
proc dataChanged*(model: QAbstractListModel,
|
||||
topLeft: QModelIndex,
|
||||
bottomRight: QModelIndex,
|
||||
roles: seq[cint]) =
|
||||
## Notify the view that the model data changed
|
||||
var copy = roles
|
||||
dos_qabstractlistmodel_dataChanged(model.data.RawQAbstractListModel, topLeft.data, bottomRight.data, copy[0].addr, copy.len.cint)
|
||||
|
||||
|
@ -24,8 +24,16 @@ type
|
||||
signals: Table[string, cint]
|
||||
properties: Table[string, cint]
|
||||
deleted: bool
|
||||
QObject* = ref QObjectObj ## A QObject
|
||||
QObject* = ref QObjectObj
|
||||
|
||||
RawBaseQObjectObj = distinct pointer
|
||||
BaseQObjectObj = object of QObjectObj
|
||||
BaseQObject* = ref BaseQObjectObj ## A QObject
|
||||
|
||||
RawQAbstractListModel = distinct pointer
|
||||
QAbstractListModelObj = object of QObjectObj
|
||||
QAbstractListModel* = ref QAbstractListModelObj ## A QAbstractListModel
|
||||
|
||||
RawQQuickView = distinct pointer
|
||||
QQuickView = ref object of RootObj ## A QQuickView
|
||||
data: RawQQuickView
|
||||
@ -33,3 +41,28 @@ type
|
||||
|
||||
QQmlContext* = distinct pointer ## A QQmlContext
|
||||
|
||||
RawQModelIndex = distinct pointer
|
||||
QModelIndex* = ref object of RootObj ## A QModelIndex
|
||||
data: RawQModelIndex
|
||||
deleted: bool
|
||||
|
||||
RawQHashIntByteArray = distinct pointer
|
||||
QHashIntByteArrayObj = object of RootObj
|
||||
data: RawQHashIntByteArray
|
||||
deleted: bool
|
||||
QHashIntByteArray* = ref QHashIntByteArrayObj ## A QHash<int,QByteArray>
|
||||
|
||||
QtItemFlag* {.pure.} = enum
|
||||
None = 0.cint,
|
||||
IsSelectable = 1.cint,
|
||||
IsEditable = 2.cint,
|
||||
IsDragEnabled = 4.cint,
|
||||
IsDropEnabled = 8.cint,
|
||||
IsUserCheckable = 16.cint,
|
||||
IsEnabled = 32.cint,
|
||||
IsTristate = 64.cint,
|
||||
NeverHasChildren = 128.cint
|
||||
|
||||
QtOrientation {.pure.} = enum
|
||||
Horizontal = 1.cint,
|
||||
Vertical = 2.cint
|
||||
|
Loading…
x
Reference in New Issue
Block a user