From c5164093266261aba64b3a2302f14d6166a7c7c1 Mon Sep 17 00:00:00 2001 From: Jos van den Oever Date: Mon, 28 Aug 2017 09:28:48 +0200 Subject: [PATCH] A few fixes for deeply nested objects This is still broken according to the test test_objects. --- demo/rust/Cargo.toml | 2 +- demo/src/Fibonacci.cpp | 18 +++-- demo/src/Fibonacci.h | 3 + demo/src/Processes.cpp | 9 ++- demo/src/Processes.h | 2 + demo/src/TimeSeries.cpp | 9 ++- demo/src/TimeSeries.h | 2 + demo/src/Tree.cpp | 9 ++- demo/src/Tree.h | 2 + src/cpp.cpp | 70 +++++++++++++------ src/parseJson.cpp | 14 ++-- src/rust.cpp | 2 +- tests/rust_list/src/implementation.rs | 1 + tests/rust_object/src/implementation.rs | 1 + tests/rust_object_types/src/implementation.rs | 1 + tests/rust_objects/src/implementation.rs | 25 +++++++ tests/rust_objects/src/interface.rs | 55 +++++++++++++++ tests/rust_tree/src/implementation.rs | 1 + tests/test_list_rust.cpp | 9 ++- tests/test_list_rust.h | 2 + tests/test_object_rust.cpp | 9 ++- tests/test_object_rust.h | 2 + tests/test_object_types_rust.cpp | 9 ++- tests/test_object_types_rust.h | 2 + tests/test_objects.cpp | 41 +++++++++-- tests/test_objects.json | 8 +++ tests/test_objects_rust.cpp | 58 +++++++++++++-- tests/test_objects_rust.h | 26 ++++++- tests/test_tree_rust.cpp | 9 ++- tests/test_tree_rust.h | 2 + 30 files changed, 342 insertions(+), 61 deletions(-) diff --git a/demo/rust/Cargo.toml b/demo/rust/Cargo.toml index 3e77ca8..c08b1e8 100644 --- a/demo/rust/Cargo.toml +++ b/demo/rust/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" [dependencies] libc = "*" -sysinfo = "0.3" +sysinfo = "0.3.16" [lib] name = "rust" diff --git a/demo/src/Fibonacci.cpp b/demo/src/Fibonacci.cpp index bf4bce4..270d5a0 100644 --- a/demo/src/Fibonacci.cpp +++ b/demo/src/Fibonacci.cpp @@ -69,6 +69,7 @@ extern "C" { void fibonacci_input_set(Fibonacci::Private*, uint); quint64 fibonacci_result_get(const Fibonacci::Private*); }; + extern "C" { quint64 fibonacci_list_data_result(const FibonacciList::Private*, int); void fibonacci_list_sort(FibonacciList::Private*, unsigned char column, Qt::SortOrder order = Qt::AscendingOrder); @@ -168,16 +169,21 @@ extern "C" { void (*)(FibonacciList*)); void fibonacci_list_free(FibonacciList::Private*); }; + Fibonacci::Fibonacci(bool /*owned*/, QObject *parent): QObject(parent), m_d(0), - m_ownsPrivate(false) {} + m_ownsPrivate(false) +{ +} + Fibonacci::Fibonacci(QObject *parent): QObject(parent), m_d(fibonacci_new(this, fibonacciInputChanged, fibonacciResultChanged)), - m_ownsPrivate(true) { + m_ownsPrivate(true) +{ } Fibonacci::~Fibonacci() { @@ -199,7 +205,10 @@ quint64 Fibonacci::result() const FibonacciList::FibonacciList(bool /*owned*/, QObject *parent): QAbstractItemModel(parent), m_d(0), - m_ownsPrivate(false) {} + m_ownsPrivate(false) +{ +} + FibonacciList::FibonacciList(QObject *parent): QAbstractItemModel(parent), m_d(fibonacci_list_new(this, @@ -225,7 +234,8 @@ FibonacciList::FibonacciList(QObject *parent): o->endRemoveRows(); } )), - m_ownsPrivate(true) { + m_ownsPrivate(true) +{ connect(this, &FibonacciList::newDataReady, this, [this](const QModelIndex& i) { fetchMore(i); }, Qt::QueuedConnection); diff --git a/demo/src/Fibonacci.h b/demo/src/Fibonacci.h index 0dd97a3..94d37b0 100644 --- a/demo/src/Fibonacci.h +++ b/demo/src/Fibonacci.h @@ -5,6 +5,9 @@ #include #include +class Fibonacci; +class FibonacciList; + class Fibonacci : public QObject { Q_OBJECT diff --git a/demo/src/Processes.cpp b/demo/src/Processes.cpp index 923b05d..bf841e5 100644 --- a/demo/src/Processes.cpp +++ b/demo/src/Processes.cpp @@ -220,10 +220,14 @@ extern "C" { void (*)(Processes*)); void processes_free(Processes::Private*); }; + Processes::Processes(bool /*owned*/, QObject *parent): QAbstractItemModel(parent), m_d(0), - m_ownsPrivate(false) {} + m_ownsPrivate(false) +{ +} + Processes::Processes(QObject *parent): QAbstractItemModel(parent), m_d(processes_new(this, @@ -264,7 +268,8 @@ Processes::Processes(QObject *parent): o->endRemoveRows(); } )), - m_ownsPrivate(true) { + m_ownsPrivate(true) +{ connect(this, &Processes::newDataReady, this, [this](const QModelIndex& i) { fetchMore(i); }, Qt::QueuedConnection); diff --git a/demo/src/Processes.h b/demo/src/Processes.h index 0600132..29a0c31 100644 --- a/demo/src/Processes.h +++ b/demo/src/Processes.h @@ -5,6 +5,8 @@ #include #include +class Processes; + class Processes : public QAbstractItemModel { Q_OBJECT diff --git a/demo/src/TimeSeries.cpp b/demo/src/TimeSeries.cpp index 4d58b55..0cfac34 100644 --- a/demo/src/TimeSeries.cpp +++ b/demo/src/TimeSeries.cpp @@ -189,10 +189,14 @@ extern "C" { void (*)(TimeSeries*)); void time_series_free(TimeSeries::Private*); }; + TimeSeries::TimeSeries(bool /*owned*/, QObject *parent): QAbstractItemModel(parent), m_d(0), - m_ownsPrivate(false) {} + m_ownsPrivate(false) +{ +} + TimeSeries::TimeSeries(QObject *parent): QAbstractItemModel(parent), m_d(time_series_new(this, @@ -218,7 +222,8 @@ TimeSeries::TimeSeries(QObject *parent): o->endRemoveRows(); } )), - m_ownsPrivate(true) { + m_ownsPrivate(true) +{ connect(this, &TimeSeries::newDataReady, this, [this](const QModelIndex& i) { fetchMore(i); }, Qt::QueuedConnection); diff --git a/demo/src/TimeSeries.h b/demo/src/TimeSeries.h index 756cfac..81d727d 100644 --- a/demo/src/TimeSeries.h +++ b/demo/src/TimeSeries.h @@ -5,6 +5,8 @@ #include #include +class TimeSeries; + class TimeSeries : public QAbstractItemModel { Q_OBJECT diff --git a/demo/src/Tree.cpp b/demo/src/Tree.cpp index 1bd65e0..2c10052 100644 --- a/demo/src/Tree.cpp +++ b/demo/src/Tree.cpp @@ -240,10 +240,14 @@ extern "C" { void tree_path_set(Tree::Private*, qstring_t); void tree_path_set_none(Tree::Private*); }; + Tree::Tree(bool /*owned*/, QObject *parent): QAbstractItemModel(parent), m_d(0), - m_ownsPrivate(false) {} + m_ownsPrivate(false) +{ +} + Tree::Tree(QObject *parent): QAbstractItemModel(parent), m_d(tree_new(this, @@ -285,7 +289,8 @@ Tree::Tree(QObject *parent): o->endRemoveRows(); } )), - m_ownsPrivate(true) { + m_ownsPrivate(true) +{ connect(this, &Tree::newDataReady, this, [this](const QModelIndex& i) { fetchMore(i); }, Qt::QueuedConnection); diff --git a/demo/src/Tree.h b/demo/src/Tree.h index cfb2378..dc9e8ec 100644 --- a/demo/src/Tree.h +++ b/demo/src/Tree.h @@ -5,6 +5,8 @@ #include #include +class Tree; + class Tree : public QAbstractItemModel { Q_OBJECT diff --git a/src/cpp.cpp b/src/cpp.cpp index e56efea..d7302b6 100644 --- a/src/cpp.cpp +++ b/src/cpp.cpp @@ -325,7 +325,7 @@ class %1 : public %3 Q_OBJEC%2 )").arg(o.name, "T", baseType(o)); for (auto object: conf.objects) { - if (object.containsObject()) { + if (object.containsObject() && o.name != object.name) { h << " friend class " << object.name << ";\n"; } } @@ -414,12 +414,13 @@ QString changedF(const Object& o, const Property& p) { return lowerInitial(o.name) + upperInitial(p.name) + "Changed"; } -void constructorArgs(QTextStream& cpp, const Object& o, const Configuration& conf) { +void constructorArgs(QTextStream& cpp, const QString& prefix, const Object& o, const Configuration& conf) { const QString lcname(snakeCase(o.name)); for (const Property& p: o.properties) { if (p.type.type == BindingType::Object) { - cpp << ", m_" << p.name; - constructorArgs(cpp, conf.findObject(p.type.name), conf); + cpp << ", " << prefix << "m_" << p.name; + constructorArgs(cpp, "m_" + p.name + "->", + conf.findObject(p.type.name), conf); } else { cpp << ",\n " << changedF(o, p); } @@ -521,6 +522,40 @@ void writeObjectCDecl(QTextStream& cpp, const Object& o, const Configuration& co } } +void initializeMembersEmpty(QTextStream& cpp, const Object& o, const Configuration& conf) +{ + for (const Property& p: o.properties) { + if (p.type.type == BindingType::Object) { + initializeMembersEmpty(cpp, conf.findObject(p.type.name), conf); + cpp << QString(" %1m_%2(new %3(false, this)),\n") + .arg(p.name, p.type.name); + } + } +} + + +void initializeMembersZero(QTextStream& cpp, const Object& o, const Configuration& conf) +{ + for (const Property& p: o.properties) { + if (p.type.type == BindingType::Object) { + cpp << QString(" m_%1(new %2(false, this)),\n") + .arg(p.name, p.type.name); + } + } +} + +void initializeMembers(QTextStream& cpp, const QString& prefix, const Object& o, const Configuration& conf) +{ + for (const Property& p: o.properties) { + if (p.type.type == BindingType::Object) { + initializeMembers(cpp, "m_" + p.name + "->", + conf.findObject(p.type.name), conf); + cpp << QString(" %1m_%2->m_d = %3_%2_get(%1m_d);\n") + .arg(prefix, p.name, snakeCase(o.name)); + } + } +} + void writeCppObject(QTextStream& cpp, const Object& o, const Configuration& conf) { const QString lcname(snakeCase(o.name)); cpp << QString("%1::%1(bool /*owned*/, QObject *parent):\n %2(parent),") @@ -531,24 +566,14 @@ void writeCppObject(QTextStream& cpp, const Object& o, const Configuration& conf .arg(p.name, p.type.name); } } - cpp << " m_d(0),\n m_ownsPrivate(false) {}\n"; + cpp << " m_d(0),\n m_ownsPrivate(false)\n{\n}\n\n"; cpp << QString("%1::%1(QObject *parent):\n %2(parent),") .arg(o.name, baseType(o)) << endl; - for (const Property& p: o.properties) { - if (p.type.type == BindingType::Object) { - cpp << QString(" m_%1(new %2(false, this)),\n") - .arg(p.name, p.type.name); - } - } + initializeMembersZero(cpp, o, conf); cpp << QString(" m_d(%1_new(this").arg(lcname); - constructorArgs(cpp, o, conf); - cpp << ")),\n m_ownsPrivate(true) {\n"; - for (const Property& p: o.properties) { - if (p.type.type == BindingType::Object) { - cpp << QString(" m_%1->m_d = %2_%1_get(this->m_d);\n") - .arg(p.name, snakeCase(o.name)); - } - } + constructorArgs(cpp, "", o, conf); + cpp << ")),\n m_ownsPrivate(true)\n{\n"; + initializeMembers(cpp, "", o, conf); if (o.type != ObjectType::Object) { cpp << QString(R"( connect(this, &%1::newDataReady, this, [this](const QModelIndex& i) { fetchMore(i); @@ -612,12 +637,11 @@ void writeHeader(const Configuration& conf) { #include #include + )").arg(guard); for (auto object: conf.objects) { - if (object.containsObject()) { - h << "class " << object.name << ";\n"; - } + h << "class " << object.name << ";\n"; } for (auto object: conf.objects) { writeHeaderObject(h, object, conf); @@ -706,7 +730,7 @@ void set_qbytearray(QByteArray* v, qbytearray_t* val) { cpp << "extern \"C\" {\n"; writeObjectCDecl(cpp, object, conf); - cpp << "};" << endl; + cpp << "};\n" << endl; } for (auto object: conf.objects) { diff --git a/src/parseJson.cpp b/src/parseJson.cpp index ca2b87a..5141099 100644 --- a/src/parseJson.cpp +++ b/src/parseJson.cpp @@ -204,17 +204,19 @@ parseConfiguration(const QString& path) { c.hFile = QFileInfo(c.cppFile.dir(), c.cppFile.completeBaseName() + ".h"); const QJsonObject& object = o.value("objects").toObject(); for (const QString& key: object.keys()) { - Object o = parseObject(key, object[key].toObject()); - c.objects.append(o); bindingTypeProperties().append({ .type = BindingType::Object, - .name = o.name, - .cppSetType = o.name, - .cSetType = o.name, - .rustType = o.name, + .name = key, + .cppSetType = key, + .cSetType = key, + .rustType = key, .rustTypeInit = "", }); } + for (const QString& key: object.keys()) { + Object o = parseObject(key, object[key].toObject()); + c.objects.append(o); + } const QJsonObject rust = o.value("rust").toObject(); c.rustdir = QDir(base.filePath(rust.value("dir").toString())); c.interfaceModule = rust.value("interfaceModule").toString(); diff --git a/src/rust.cpp b/src/rust.cpp index 1382529..4980cff 100644 --- a/src/rust.cpp +++ b/src/rust.cpp @@ -767,7 +767,7 @@ void writeRustImplementationObject(QTextStream& r, const Object& o) { } } } - r << "}\n"; + r << "}\n\n"; } void writeRustImplementation(const Configuration& conf) { diff --git a/tests/rust_list/src/implementation.rs b/tests/rust_list/src/implementation.rs index bf9fd4d..e3c893e 100644 --- a/tests/rust_list/src/implementation.rs +++ b/tests/rust_list/src/implementation.rs @@ -36,3 +36,4 @@ impl PersonsTrait for Persons { true } } + diff --git a/tests/rust_object/src/implementation.rs b/tests/rust_object/src/implementation.rs index 44c0081..fe0f79c 100644 --- a/tests/rust_object/src/implementation.rs +++ b/tests/rust_object/src/implementation.rs @@ -26,3 +26,4 @@ impl PersonTrait for Person { self.emit.user_name_changed(); } } + diff --git a/tests/rust_object_types/src/implementation.rs b/tests/rust_object_types/src/implementation.rs index b36c5d8..2d1bbcb 100644 --- a/tests/rust_object_types/src/implementation.rs +++ b/tests/rust_object_types/src/implementation.rs @@ -89,3 +89,4 @@ impl ObjectTrait for Object { self.emit.uinteger_changed(); } } + diff --git a/tests/rust_objects/src/implementation.rs b/tests/rust_objects/src/implementation.rs index a7b2264..f2d35f8 100644 --- a/tests/rust_objects/src/implementation.rs +++ b/tests/rust_objects/src/implementation.rs @@ -3,6 +3,29 @@ #![allow(dead_code)] use interface::*; +pub struct Group { + emit: GroupEmitter, + person: Person, +} + +impl GroupTrait for Group { + fn create(emit: GroupEmitter, person: Person) -> Group { + Group { + emit: emit, + person: person, + } + } + fn emit(&self) -> &GroupEmitter { + &self.emit + } + fn get_person(&self) -> &Person { + &self.person + } + fn get_mut_person(&mut self) -> &mut Person { + &mut self.person + } +} + pub struct InnerObject { emit: InnerObjectEmitter, description: String, @@ -26,6 +49,7 @@ impl InnerObjectTrait for InnerObject { self.emit.description_changed(); } } + pub struct Person { emit: PersonEmitter, object: InnerObject, @@ -48,3 +72,4 @@ impl PersonTrait for Person { &mut self.object } } + diff --git a/tests/rust_objects/src/interface.rs b/tests/rust_objects/src/interface.rs index 508244f..caa7238 100644 --- a/tests/rust_objects/src/interface.rs +++ b/tests/rust_objects/src/interface.rs @@ -38,6 +38,61 @@ impl<'a> From<&'a String> for QString { } } +pub struct GroupQObject {} + +#[derive (Clone)] +pub struct GroupEmitter { + qobject: Arc>, +} + +unsafe impl Send for GroupEmitter {} + +impl GroupEmitter { + fn clear(&self) { + *self.qobject.lock().unwrap() = null(); + } +} + +pub trait GroupTrait { + fn create(emit: GroupEmitter, + person: Person) -> Self; + fn emit(&self) -> &GroupEmitter; + fn get_person(&self) -> &Person; + fn get_mut_person(&mut self) -> &mut Person; +} + +#[no_mangle] +pub extern "C" fn group_new(group: *mut GroupQObject, person: *mut PersonQObject, object: *mut InnerObjectQObject, + description_changed: fn(*const InnerObjectQObject)) + -> *mut Group { + let object_emit = InnerObjectEmitter { + qobject: Arc::new(Mutex::new(object)), + description_changed: description_changed, + }; + let d_object = InnerObject::create(object_emit); + let person_emit = PersonEmitter { + qobject: Arc::new(Mutex::new(person)), + }; + let d_person = Person::create(person_emit, + d_object); + let group_emit = GroupEmitter { + qobject: Arc::new(Mutex::new(group)), + }; + let d_group = Group::create(group_emit, + d_person); + Box::into_raw(Box::new(d_group)) +} + +#[no_mangle] +pub unsafe extern "C" fn group_free(ptr: *mut Group) { + Box::from_raw(ptr).emit().clear(); +} + +#[no_mangle] +pub unsafe extern "C" fn group_person_get(ptr: *mut Group) -> *mut Person { + (&mut *ptr).get_mut_person() +} + pub struct InnerObjectQObject {} #[derive (Clone)] diff --git a/tests/rust_tree/src/implementation.rs b/tests/rust_tree/src/implementation.rs index 128a529..5018b86 100644 --- a/tests/rust_tree/src/implementation.rs +++ b/tests/rust_tree/src/implementation.rs @@ -45,3 +45,4 @@ impl PersonsTrait for Persons { true } } + diff --git a/tests/test_list_rust.cpp b/tests/test_list_rust.cpp index 4297a03..c73991c 100644 --- a/tests/test_list_rust.cpp +++ b/tests/test_list_rust.cpp @@ -164,10 +164,14 @@ extern "C" { void (*)(Persons*)); void persons_free(Persons::Private*); }; + Persons::Persons(bool /*owned*/, QObject *parent): QAbstractItemModel(parent), m_d(0), - m_ownsPrivate(false) {} + m_ownsPrivate(false) +{ +} + Persons::Persons(QObject *parent): QAbstractItemModel(parent), m_d(persons_new(this, @@ -193,7 +197,8 @@ Persons::Persons(QObject *parent): o->endRemoveRows(); } )), - m_ownsPrivate(true) { + m_ownsPrivate(true) +{ connect(this, &Persons::newDataReady, this, [this](const QModelIndex& i) { fetchMore(i); }, Qt::QueuedConnection); diff --git a/tests/test_list_rust.h b/tests/test_list_rust.h index bcd1448..c9f7c69 100644 --- a/tests/test_list_rust.h +++ b/tests/test_list_rust.h @@ -5,6 +5,8 @@ #include #include +class Persons; + class Persons : public QAbstractItemModel { Q_OBJECT diff --git a/tests/test_object_rust.cpp b/tests/test_object_rust.cpp index 127304f..bbd6987 100644 --- a/tests/test_object_rust.cpp +++ b/tests/test_object_rust.cpp @@ -64,15 +64,20 @@ extern "C" { void person_user_name_get(const Person::Private*, QString*, qstring_set); void person_user_name_set(Person::Private*, qstring_t); }; + Person::Person(bool /*owned*/, QObject *parent): QObject(parent), m_d(0), - m_ownsPrivate(false) {} + m_ownsPrivate(false) +{ +} + Person::Person(QObject *parent): QObject(parent), m_d(person_new(this, personUserNameChanged)), - m_ownsPrivate(true) { + m_ownsPrivate(true) +{ } Person::~Person() { diff --git a/tests/test_object_rust.h b/tests/test_object_rust.h index e6c378d..361937e 100644 --- a/tests/test_object_rust.h +++ b/tests/test_object_rust.h @@ -5,6 +5,8 @@ #include #include +class Person; + class Person : public QObject { Q_OBJECT diff --git a/tests/test_object_types_rust.cpp b/tests/test_object_types_rust.cpp index faac038..779053e 100644 --- a/tests/test_object_types_rust.cpp +++ b/tests/test_object_types_rust.cpp @@ -108,10 +108,14 @@ extern "C" { quint32 object_uinteger_get(const Object::Private*); void object_uinteger_set(Object::Private*, uint); }; + Object::Object(bool /*owned*/, QObject *parent): QObject(parent), m_d(0), - m_ownsPrivate(false) {} + m_ownsPrivate(false) +{ +} + Object::Object(QObject *parent): QObject(parent), m_d(object_new(this, @@ -123,7 +127,8 @@ Object::Object(QObject *parent): objectStringChanged, objectU64Changed, objectUintegerChanged)), - m_ownsPrivate(true) { + m_ownsPrivate(true) +{ } Object::~Object() { diff --git a/tests/test_object_types_rust.h b/tests/test_object_types_rust.h index 8252cce..95aeb59 100644 --- a/tests/test_object_types_rust.h +++ b/tests/test_object_types_rust.h @@ -5,6 +5,8 @@ #include #include +class Object; + class Object : public QObject { Q_OBJECT diff --git a/tests/test_objects.cpp b/tests/test_objects.cpp index a0eb95e..9e9bb31 100644 --- a/tests/test_objects.cpp +++ b/tests/test_objects.cpp @@ -6,23 +6,26 @@ class TestRustObjects : public QObject { Q_OBJECT private slots: - void testConstructor(); - void testStringGetter(); - void testStringSetter(); + void testOneLevelConstructor(); + void testOneLevelStringGetter(); + void testOneLevelStringSetter(); + void testTwoLevelsConstructor(); + void testTwoLevelsStringGetter(); + void testTwoLevelsStringSetter(); }; -void TestRustObjects::testConstructor() +void TestRustObjects::testOneLevelConstructor() { Person person; } -void TestRustObjects::testStringGetter() +void TestRustObjects::testOneLevelStringGetter() { Person person; person.object()->setDescription("Konqi"); } -void TestRustObjects::testStringSetter() +void TestRustObjects::testOneLevelStringSetter() { // GIVEN Person person; @@ -37,5 +40,31 @@ void TestRustObjects::testStringSetter() QCOMPARE(person.object()->description(), QString("Konqi")); } +void TestRustObjects::testTwoLevelsConstructor() +{ + Group group; +} + +void TestRustObjects::testTwoLevelsStringGetter() +{ + Group group; + group.person()->object()->setDescription("Konqi"); +} + +void TestRustObjects::testTwoLevelsStringSetter() +{ + // GIVEN + Group group; + QSignalSpy spy(group.person()->object(), &InnerObject::descriptionChanged); + + // WHEN + group.person()->object()->setDescription("Konqi"); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(spy.count(), 1); + QCOMPARE(group.person()->object()->description(), QString("Konqi")); +} + QTEST_MAIN(TestRustObjects) #include "test_objects.moc" diff --git a/tests/test_objects.json b/tests/test_objects.json index 1daac94..fd0a1be 100644 --- a/tests/test_objects.json +++ b/tests/test_objects.json @@ -23,6 +23,14 @@ "type": "InnerObject" } } + }, + "Group": { + "type": "Object", + "properties": { + "person": { + "type": "Person" + } + } } } } diff --git a/tests/test_objects_rust.cpp b/tests/test_objects_rust.cpp index 9abefc9..ea73ee1 100644 --- a/tests/test_objects_rust.cpp +++ b/tests/test_objects_rust.cpp @@ -58,26 +58,70 @@ typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*); void set_qbytearray(QByteArray* v, qbytearray_t* val) { *v = *val; } +extern "C" { + Group::Private* group_new(Group*, Person*, InnerObject*, void (*)(InnerObject*)); + void group_free(Group::Private*); + Person::Private* group_person_get(const Group::Private*); +}; + extern "C" { InnerObject::Private* inner_object_new(InnerObject*, void (*)(InnerObject*)); void inner_object_free(InnerObject::Private*); void inner_object_description_get(const InnerObject::Private*, QString*, qstring_set); void inner_object_description_set(InnerObject::Private*, qstring_t); }; + extern "C" { Person::Private* person_new(Person*, InnerObject*, void (*)(InnerObject*)); void person_free(Person::Private*); InnerObject::Private* person_object_get(const Person::Private*); }; + +Group::Group(bool /*owned*/, QObject *parent): + QObject(parent), + m_person(new Person(false, this)), + m_d(0), + m_ownsPrivate(false) +{ +} + +Group::Group(QObject *parent): + QObject(parent), + m_person(new Person(false, this)), + m_d(group_new(this, m_person, m_person->m_object, + innerObjectDescriptionChanged)), + m_ownsPrivate(true) +{ + m_person->m_object->m_d = person_object_get(m_person->m_d); + m_person->m_d = group_person_get(m_d); +} + +Group::~Group() { + if (m_ownsPrivate) { + group_free(m_d); + } +} +const Person* Group::person() const +{ + return m_person; +} +Person* Group::person() +{ + return m_person; +} InnerObject::InnerObject(bool /*owned*/, QObject *parent): QObject(parent), m_d(0), - m_ownsPrivate(false) {} + m_ownsPrivate(false) +{ +} + InnerObject::InnerObject(QObject *parent): QObject(parent), m_d(inner_object_new(this, innerObjectDescriptionChanged)), - m_ownsPrivate(true) { + m_ownsPrivate(true) +{ } InnerObject::~InnerObject() { @@ -98,14 +142,18 @@ Person::Person(bool /*owned*/, QObject *parent): QObject(parent), m_object(new InnerObject(false, this)), m_d(0), - m_ownsPrivate(false) {} + m_ownsPrivate(false) +{ +} + Person::Person(QObject *parent): QObject(parent), m_object(new InnerObject(false, this)), m_d(person_new(this, m_object, innerObjectDescriptionChanged)), - m_ownsPrivate(true) { - m_object->m_d = person_object_get(this->m_d); + m_ownsPrivate(true) +{ + m_object->m_d = person_object_get(m_d); } Person::~Person() { diff --git a/tests/test_objects_rust.h b/tests/test_objects_rust.h index 2de6252..747f0ac 100644 --- a/tests/test_objects_rust.h +++ b/tests/test_objects_rust.h @@ -4,11 +4,35 @@ #include #include + +class Group; +class InnerObject; class Person; +class Group : public QObject +{ + Q_OBJECT + friend class Person; +public: + class Private; +private: + Person* const m_person; + Private * m_d; + bool m_ownsPrivate; + Q_PROPERTY(Person* person READ person FINAL) + explicit Group(bool owned, QObject *parent); +public: + explicit Group(QObject *parent = nullptr); + ~Group(); + const Person* person() const; + Person* person(); +signals: +}; + class InnerObject : public QObject { Q_OBJECT + friend class Group; friend class Person; public: class Private; @@ -29,7 +53,7 @@ signals: class Person : public QObject { Q_OBJECT - friend class Person; + friend class Group; public: class Private; private: diff --git a/tests/test_tree_rust.cpp b/tests/test_tree_rust.cpp index aaff5e4..fa55c1c 100644 --- a/tests/test_tree_rust.cpp +++ b/tests/test_tree_rust.cpp @@ -182,10 +182,14 @@ extern "C" { void (*)(Persons*)); void persons_free(Persons::Private*); }; + Persons::Persons(bool /*owned*/, QObject *parent): QAbstractItemModel(parent), m_d(0), - m_ownsPrivate(false) {} + m_ownsPrivate(false) +{ +} + Persons::Persons(QObject *parent): QAbstractItemModel(parent), m_d(persons_new(this, @@ -226,7 +230,8 @@ Persons::Persons(QObject *parent): o->endRemoveRows(); } )), - m_ownsPrivate(true) { + m_ownsPrivate(true) +{ connect(this, &Persons::newDataReady, this, [this](const QModelIndex& i) { fetchMore(i); }, Qt::QueuedConnection); diff --git a/tests/test_tree_rust.h b/tests/test_tree_rust.h index 1beeb5a..fe703dc 100644 --- a/tests/test_tree_rust.h +++ b/tests/test_tree_rust.h @@ -5,6 +5,8 @@ #include #include +class Persons; + class Persons : public QAbstractItemModel { Q_OBJECT