mirror of
https://github.com/status-im/dotherside.git
synced 2025-02-11 20:16:47 +00:00
Closed #39 Add support for QVariantList
This adds support for marshalling arrays of QVariant (QVariantList) in/out from DosQVariant. We added the following 3 API: dos_qvariant_create_array dos_qvariant_setArray dos_qvariant_toArray Support for QVariantList in property definition of QObjects is already enabled. The end user should use the QVariantList metatype.
This commit is contained in:
parent
a86aa43a97
commit
819409fa94
@ -64,6 +64,9 @@ DOS_API void DOS_CALL dos_qqmlcontext_setcontextproperty(DosQQmlContext *vptr,
|
||||
/// @param ptr The string
|
||||
DOS_API void DOS_CALL dos_chararray_delete(char *ptr);
|
||||
|
||||
/// Delete a DosQVariantArray
|
||||
DOS_API void DOS_CALL dos_qvariantarray_delete(DosQVariantArray *ptr);
|
||||
|
||||
// QVariant
|
||||
DOS_API DosQVariant *DOS_CALL dos_qvariant_create();
|
||||
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_int(int value);
|
||||
@ -73,12 +76,14 @@ DOS_API DosQVariant *DOS_CALL dos_qvariant_create_qobject(DosQObject *value);
|
||||
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_qvariant(const DosQVariant *value);
|
||||
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_float(float value);
|
||||
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_double(double value);
|
||||
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_array(int size, DosQVariant** array);
|
||||
DOS_API void DOS_CALL dos_qvariant_setInt (DosQVariant *vptr, int value);
|
||||
DOS_API void DOS_CALL dos_qvariant_setBool (DosQVariant *vptr, bool value);
|
||||
DOS_API void DOS_CALL dos_qvariant_setFloat (DosQVariant *vptr, float value);
|
||||
DOS_API void DOS_CALL dos_qvariant_setDouble (DosQVariant *vptr, double value);
|
||||
DOS_API void DOS_CALL dos_qvariant_setString (DosQVariant *vptr, const char *value);
|
||||
DOS_API void DOS_CALL dos_qvariant_setQObject(DosQVariant *vptr, DosQObject *value);
|
||||
DOS_API void DOS_CALL dos_qvariant_setArray (DosQVariant *vptr, int size, DosQVariant** array);
|
||||
DOS_API bool DOS_CALL dos_qvariant_isnull (const DosQVariant *vptr);
|
||||
DOS_API void DOS_CALL dos_qvariant_delete (DosQVariant *vptr);
|
||||
DOS_API void DOS_CALL dos_qvariant_assign (DosQVariant *vptr, const DosQVariant *other);
|
||||
@ -87,6 +92,7 @@ DOS_API bool DOS_CALL dos_qvariant_toBool (const DosQVariant *vptr);
|
||||
DOS_API char *DOS_CALL dos_qvariant_toString (const DosQVariant *vptr);
|
||||
DOS_API float DOS_CALL dos_qvariant_toFloat (const DosQVariant *vptr);
|
||||
DOS_API double DOS_CALL dos_qvariant_toDouble (const DosQVariant *vptr);
|
||||
DOS_API DosQVariantArray* DOS_CALL dos_qvariant_toArray(const DosQVariant *vptr);
|
||||
DOS_API DosQObject *DOS_CALL dos_qvariant_toQObject(const DosQVariant *vptr);
|
||||
|
||||
// QMetaObject
|
||||
|
@ -62,6 +62,11 @@ typedef void (DOS_CALL *HeaderDataCallback) (void *self, int section, int orie
|
||||
typedef void (DOS_CALL *CreateDObject)(int, void *, void **, void **);
|
||||
typedef void (DOS_CALL *DeleteDObject)(int, void *);
|
||||
|
||||
struct DosQVariantArray {
|
||||
int size;
|
||||
DosQVariant** data;
|
||||
};
|
||||
|
||||
struct QmlRegisterType {
|
||||
int major;
|
||||
int minor;
|
||||
|
@ -179,6 +179,21 @@ void dos_chararray_delete(char *ptr)
|
||||
if (ptr) delete[] ptr;
|
||||
}
|
||||
|
||||
void dos_qvariantarray_delete(DosQVariantArray *ptr)
|
||||
{
|
||||
if (!ptr || !ptr->data)
|
||||
return;
|
||||
// Delete each variant
|
||||
for (int i = 0; i < ptr->size; ++i)
|
||||
dos_qvariant_delete(ptr->data[i]);
|
||||
// Delete the array
|
||||
delete[] ptr->data;
|
||||
ptr->data = nullptr;
|
||||
ptr->size = 0;
|
||||
// Delete the wrapped struct
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
char *dos_qqmlcontext_baseUrl(const ::DosQQmlContext *vptr)
|
||||
{
|
||||
auto context = static_cast<const QQmlContext *>(vptr);
|
||||
@ -239,6 +254,15 @@ void dos_qqmlcontext_setcontextproperty(::DosQQmlContext *vptr, const char *name
|
||||
return new QVariant(value);
|
||||
}
|
||||
|
||||
::DosQVariant *dos_qvariant_create_array(int size, ::DosQVariant** array)
|
||||
{
|
||||
QList<QVariant> data;
|
||||
data.reserve(size);
|
||||
for (int i = 0; i < size; ++i)
|
||||
data << *(static_cast<QVariant*>(array[i]));
|
||||
return new QVariant(data);
|
||||
}
|
||||
|
||||
bool dos_qvariant_isnull(const DosQVariant *vptr)
|
||||
{
|
||||
auto variant = static_cast<const QVariant *>(vptr);
|
||||
@ -288,6 +312,18 @@ char *dos_qvariant_toString(const DosQVariant *vptr)
|
||||
return convert_to_cstring(variant->toString());
|
||||
}
|
||||
|
||||
DosQVariantArray *dos_qvariant_toArray(const DosQVariant *vptr)
|
||||
{
|
||||
auto variant = static_cast<const QVariant *>(vptr);
|
||||
QVariantList data = variant->toList();
|
||||
auto result = new DosQVariantArray();
|
||||
result->size = data.size();
|
||||
result->data = new DosQVariant*[result->size];
|
||||
for (int i = 0; i < result->size; ++i)
|
||||
result->data[i] = new QVariant(data[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
::DosQObject *dos_qvariant_toQObject(const DosQVariant *vptr)
|
||||
{
|
||||
auto variant = static_cast<const QVariant *>(vptr);
|
||||
@ -331,6 +367,16 @@ void dos_qvariant_setQObject(::DosQVariant *vptr, ::DosQObject *value)
|
||||
variant->setValue<QObject *>(qobject);
|
||||
}
|
||||
|
||||
void dos_qvariant_setArray(::DosQVariant *vptr, int size, ::DosQVariant **array)
|
||||
{
|
||||
auto variant = static_cast<QVariant *>(vptr);
|
||||
QVariantList data;
|
||||
data.reserve(size);
|
||||
for (int i = 0; i < size; ++i)
|
||||
data << *(static_cast<QVariant *>(array[i]));
|
||||
variant->setValue(data);
|
||||
}
|
||||
|
||||
::DosQMetaObject *dos_qobject_qmetaobject()
|
||||
{
|
||||
return new DOS::DosIQMetaObjectHolder(std::make_shared<DOS::DosQObjectMetaObject>());
|
||||
|
@ -14,19 +14,28 @@ namespace {
|
||||
{
|
||||
void* superClassMetaObject = dos_qobject_qmetaobject();
|
||||
// Signals
|
||||
::SignalDefinition signalDefinitionArray[1];
|
||||
::SignalDefinition signalDefinitionArray[2];
|
||||
|
||||
// nameChanged
|
||||
signalDefinitionArray[0].name = "nameChanged";
|
||||
signalDefinitionArray[0].parametersCount = 1;
|
||||
int nameChanged[1];
|
||||
nameChanged[0] = QMetaType::QString;
|
||||
signalDefinitionArray[0].parametersMetaTypes = nameChanged;
|
||||
|
||||
// arrayPropertyChanged
|
||||
signalDefinitionArray[1].name = "arrayPropertyChanged";
|
||||
signalDefinitionArray[1].parametersCount = 1;
|
||||
int arrayPropertyChanged[1];
|
||||
arrayPropertyChanged[0] = QMetaType::QVariantList;
|
||||
signalDefinitionArray[1].parametersMetaTypes = arrayPropertyChanged;
|
||||
|
||||
::SignalDefinitions signalDefinitions;
|
||||
signalDefinitions.count = 1;
|
||||
signalDefinitions.count = 2;
|
||||
signalDefinitions.definitions = signalDefinitionArray;
|
||||
|
||||
// Slots
|
||||
::SlotDefinition slotDefinitionArray[2];
|
||||
::SlotDefinition slotDefinitionArray[4];
|
||||
|
||||
slotDefinitionArray[0].name = "name";
|
||||
slotDefinitionArray[0].returnMetaType = QMetaType::QString;
|
||||
@ -40,20 +49,38 @@ namespace {
|
||||
slotDefinitionArray[1].parametersCount = 1;
|
||||
slotDefinitionArray[1].parametersMetaTypes = setNameParameters;
|
||||
|
||||
slotDefinitionArray[2].name = "arrayProperty";
|
||||
slotDefinitionArray[2].returnMetaType = QMetaType::QVariantList;
|
||||
slotDefinitionArray[2].parametersCount = 0;
|
||||
slotDefinitionArray[2].parametersMetaTypes = nullptr;
|
||||
|
||||
slotDefinitionArray[3].name = "setArrayProperty";
|
||||
slotDefinitionArray[3].returnMetaType = QMetaType::Void;
|
||||
int setArrayPropertyParameters[1];
|
||||
setArrayPropertyParameters[0] = QMetaType::QVariantList;
|
||||
slotDefinitionArray[3].parametersCount = 1;
|
||||
slotDefinitionArray[3].parametersMetaTypes = setArrayPropertyParameters;
|
||||
|
||||
::SlotDefinitions slotDefinitions;
|
||||
slotDefinitions.count = 2;
|
||||
slotDefinitions.count = 4;
|
||||
slotDefinitions.definitions = slotDefinitionArray;
|
||||
|
||||
// Properties
|
||||
::PropertyDefinition propertyDefinitionArray[1];
|
||||
::PropertyDefinition propertyDefinitionArray[2];
|
||||
propertyDefinitionArray[0].name = "name";
|
||||
propertyDefinitionArray[0].notifySignal = "nameChanged";
|
||||
propertyDefinitionArray[0].propertyMetaType = QMetaType::QString;
|
||||
propertyDefinitionArray[0].readSlot = "name";
|
||||
propertyDefinitionArray[0].writeSlot = "setName";
|
||||
|
||||
propertyDefinitionArray[1].name = "arrayProperty";
|
||||
propertyDefinitionArray[1].notifySignal = "arrayPropertyChanged";
|
||||
propertyDefinitionArray[1].propertyMetaType = QMetaType::QVariantList;
|
||||
propertyDefinitionArray[1].readSlot = "arrayProperty";
|
||||
propertyDefinitionArray[1].writeSlot = "setArrayProperty";
|
||||
|
||||
::PropertyDefinitions propertyDefinitions;
|
||||
propertyDefinitions.count = 1;
|
||||
propertyDefinitions.count = 2;
|
||||
propertyDefinitions.definitions = propertyDefinitionArray;
|
||||
|
||||
return VoidPointer(dos_qmetaobject_create(superClassMetaObject, "MockQObject", &signalDefinitions, &slotDefinitions, &propertyDefinitions),
|
||||
@ -64,6 +91,7 @@ namespace {
|
||||
|
||||
MockQObject::MockQObject()
|
||||
: m_vptr(dos_qobject_create(this, metaObject(), &onSlotCalled), &dos_qobject_delete)
|
||||
, m_arrayProperty({10, 5.3, false})
|
||||
{}
|
||||
|
||||
MockQObject::~MockQObject() = default;
|
||||
@ -122,6 +150,35 @@ void MockQObject::nameChanged(const string &name)
|
||||
dos_qvariant_delete(argv[0]);
|
||||
}
|
||||
|
||||
std::tuple<int, double, bool> MockQObject::arrayProperty() const
|
||||
{
|
||||
return m_arrayProperty;
|
||||
}
|
||||
|
||||
void MockQObject::setArrayProperty(std::tuple<int, double, bool> value)
|
||||
{
|
||||
if (m_arrayProperty == value)
|
||||
return;
|
||||
m_arrayProperty = std::move(value);
|
||||
arrayPropertyChanged(value);
|
||||
}
|
||||
|
||||
void MockQObject::arrayPropertyChanged(const std::tuple<int, double, bool> &value)
|
||||
{
|
||||
std::vector<DosQVariant*> valueAsDosQVariant ({
|
||||
dos_qvariant_create_int(std::get<0>(value)),
|
||||
dos_qvariant_create_double(std::get<1>(value)),
|
||||
dos_qvariant_create_bool(std::get<2>(value))
|
||||
});
|
||||
|
||||
int argc = 1;
|
||||
DosQVariant* argv[1];
|
||||
argv[0] = dos_qvariant_create_array(valueAsDosQVariant.size(), &valueAsDosQVariant[0]);
|
||||
dos_qobject_signal_emit(m_vptr.get(), "arrayPropertyChanged", argc, argv);
|
||||
dos_qvariant_delete(argv[0]);
|
||||
std::for_each(valueAsDosQVariant.begin(), valueAsDosQVariant.end(), &dos_qvariant_delete);
|
||||
}
|
||||
|
||||
void MockQObject::onSlotCalled(void *selfVPtr, DosQVariant *dosSlotNameVariant, int dosSlotArgc, DosQVariant **dosSlotArgv) {
|
||||
MockQObject* self = static_cast<MockQObject*>(selfVPtr);
|
||||
|
||||
@ -136,4 +193,29 @@ void MockQObject::onSlotCalled(void *selfVPtr, DosQVariant *dosSlotNameVariant,
|
||||
self->setName(toStringFromQVariant(dosSlotArgv[1]));
|
||||
return;
|
||||
}
|
||||
|
||||
if (slotName == "arrayProperty") {
|
||||
auto value = self->arrayProperty();
|
||||
|
||||
std::vector<DosQVariant*> data {
|
||||
dos_qvariant_create_int(std::get<0>(value)),
|
||||
dos_qvariant_create_double(std::get<1>(value)),
|
||||
dos_qvariant_create_bool(std::get<2>(value))
|
||||
};
|
||||
VoidPointer arrayProperty(dos_qvariant_create_array(data.size(), &data[0]), &dos_qvariant_delete);
|
||||
dos_qvariant_assign(dosSlotArgv[0], arrayProperty.get());
|
||||
std::for_each(data.begin(), data.end(), &dos_qvariant_delete);
|
||||
return;
|
||||
}
|
||||
|
||||
if (slotName == "setArrayProperty") {
|
||||
std::tuple<int, double, bool> value;
|
||||
DosQVariantArray* array = dos_qvariant_toArray(dosSlotArgv[1]);
|
||||
std::get<0>(value) = dos_qvariant_toInt(array->data[0]);
|
||||
std::get<1>(value) = dos_qvariant_toDouble(array->data[1]);
|
||||
std::get<2>(value) = dos_qvariant_toBool(array->data[2]);
|
||||
dos_qvariantarray_delete(array);
|
||||
self->setArrayProperty(std::move(value));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <Global.h>
|
||||
|
||||
class MockQObject
|
||||
@ -21,9 +22,14 @@ public:
|
||||
void setName(const std::string& name);
|
||||
void nameChanged(const std::string& name);
|
||||
|
||||
std::tuple<int, double, bool> arrayProperty() const;
|
||||
void setArrayProperty(std::tuple<int, double, bool> value);
|
||||
void arrayPropertyChanged(const std::tuple<int, double, bool>& value);
|
||||
|
||||
private:
|
||||
static void onSlotCalled(void *selfVPtr, DosQVariant *dosSlotNameVariant, int dosSlotArgc, DosQVariant **dosSlotArgv);
|
||||
|
||||
VoidPointer m_vptr;
|
||||
std::string m_name;
|
||||
std::tuple<int, double, bool> m_arrayProperty;
|
||||
};
|
||||
|
@ -29,4 +29,14 @@ QtObject {
|
||||
testObject.name = "bar"
|
||||
return result
|
||||
}
|
||||
|
||||
function testArrayProperty() {
|
||||
if (!testObject)
|
||||
return false
|
||||
var values = testObject.arrayProperty
|
||||
if (values[0] != 10 || values[1] != 5.3 || values[2] != false)
|
||||
return false
|
||||
testObject.arrayProperty = [404, 6.3, true]
|
||||
return values[0] != 404 || values[1] != 6.3 || values[2] != true
|
||||
}
|
||||
}
|
||||
|
@ -184,6 +184,26 @@ private slots:
|
||||
QVERIFY(value == nullptr);
|
||||
}
|
||||
|
||||
void testArray() {
|
||||
std::vector<DosQVariant*> data ({
|
||||
dos_qvariant_create_int(10),
|
||||
dos_qvariant_create_double(4.3),
|
||||
dos_qvariant_create_bool(false),
|
||||
dos_qvariant_create_string("FooBar")
|
||||
});
|
||||
|
||||
VoidPointer variant (dos_qvariant_create_array(data.size(), &data[0]), &dos_qvariant_delete);
|
||||
|
||||
DosQVariantArray* array = dos_qvariant_toArray(variant.get());
|
||||
QVERIFY(array);
|
||||
QCOMPARE(int(data.size()), array->size);
|
||||
QCOMPARE(dos_qvariant_toInt(array->data[0]), int(10));
|
||||
QCOMPARE(dos_qvariant_toDouble(array->data[1]), double(4.3));
|
||||
QCOMPARE(dos_qvariant_toBool(array->data[2]), false);
|
||||
dos_qvariantarray_delete(array);
|
||||
|
||||
std::for_each(data.begin(), data.end(), &dos_qvariant_delete);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@ -388,6 +408,15 @@ private slots:
|
||||
QVERIFY(result.toBool());
|
||||
}
|
||||
|
||||
void testArrayProperty() {
|
||||
QObject* testCase = engine->rootObjects().first();
|
||||
QVERIFY(testCase);
|
||||
QVariant result;
|
||||
QVERIFY(QMetaObject::invokeMethod(testCase, "testArrayProperty", Q_RETURN_ARG(QVariant, result)));
|
||||
QVERIFY(result.type() == QVariant::Bool);
|
||||
QVERIFY(result.toBool());
|
||||
}
|
||||
|
||||
private:
|
||||
QString value;
|
||||
unique_ptr<MockQObject> testObject;
|
||||
|
Loading…
x
Reference in New Issue
Block a user