A few fixes for deeply nested objects
This is still broken according to the test test_objects.master
parent
64bcac54f0
commit
c516409326
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
|||
|
||||
[dependencies]
|
||||
libc = "*"
|
||||
sysinfo = "0.3"
|
||||
sysinfo = "0.3.16"
|
||||
|
||||
[lib]
|
||||
name = "rust"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class Fibonacci;
|
||||
class FibonacciList;
|
||||
|
||||
class Fibonacci : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class Processes;
|
||||
|
||||
class Processes : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class TimeSeries;
|
||||
|
||||
class TimeSeries : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class Tree;
|
||||
|
||||
class Tree : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
70
src/cpp.cpp
70
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 <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
)").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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -767,7 +767,7 @@ void writeRustImplementationObject(QTextStream& r, const Object& o) {
|
|||
}
|
||||
}
|
||||
}
|
||||
r << "}\n";
|
||||
r << "}\n\n";
|
||||
}
|
||||
|
||||
void writeRustImplementation(const Configuration& conf) {
|
||||
|
|
|
@ -36,3 +36,4 @@ impl PersonsTrait for Persons {
|
|||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,3 +26,4 @@ impl PersonTrait for Person {
|
|||
self.emit.user_name_changed();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,3 +89,4 @@ impl ObjectTrait for Object {
|
|||
self.emit.uinteger_changed();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,61 @@ impl<'a> From<&'a String> for QString {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct GroupQObject {}
|
||||
|
||||
#[derive (Clone)]
|
||||
pub struct GroupEmitter {
|
||||
qobject: Arc<Mutex<*const GroupQObject>>,
|
||||
}
|
||||
|
||||
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)]
|
||||
|
|
|
@ -45,3 +45,4 @@ impl PersonsTrait for Persons {
|
|||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class Persons;
|
||||
|
||||
class Persons : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class Person;
|
||||
|
||||
class Person : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class Object;
|
||||
|
||||
class Object : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -23,6 +23,14 @@
|
|||
"type": "InnerObject"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Group": {
|
||||
"type": "Object",
|
||||
"properties": {
|
||||
"person": {
|
||||
"type": "Person"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -4,11 +4,35 @@
|
|||
|
||||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class Persons;
|
||||
|
||||
class Persons : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
Loading…
Reference in New Issue