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]
|
[dependencies]
|
||||||
libc = "*"
|
libc = "*"
|
||||||
sysinfo = "0.3"
|
sysinfo = "0.3.16"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "rust"
|
name = "rust"
|
||||||
|
|
|
@ -69,6 +69,7 @@ extern "C" {
|
||||||
void fibonacci_input_set(Fibonacci::Private*, uint);
|
void fibonacci_input_set(Fibonacci::Private*, uint);
|
||||||
quint64 fibonacci_result_get(const Fibonacci::Private*);
|
quint64 fibonacci_result_get(const Fibonacci::Private*);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
quint64 fibonacci_list_data_result(const FibonacciList::Private*, int);
|
quint64 fibonacci_list_data_result(const FibonacciList::Private*, int);
|
||||||
void fibonacci_list_sort(FibonacciList::Private*, unsigned char column, Qt::SortOrder order = Qt::AscendingOrder);
|
void fibonacci_list_sort(FibonacciList::Private*, unsigned char column, Qt::SortOrder order = Qt::AscendingOrder);
|
||||||
|
@ -168,16 +169,21 @@ extern "C" {
|
||||||
void (*)(FibonacciList*));
|
void (*)(FibonacciList*));
|
||||||
void fibonacci_list_free(FibonacciList::Private*);
|
void fibonacci_list_free(FibonacciList::Private*);
|
||||||
};
|
};
|
||||||
|
|
||||||
Fibonacci::Fibonacci(bool /*owned*/, QObject *parent):
|
Fibonacci::Fibonacci(bool /*owned*/, QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_d(0),
|
m_d(0),
|
||||||
m_ownsPrivate(false) {}
|
m_ownsPrivate(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Fibonacci::Fibonacci(QObject *parent):
|
Fibonacci::Fibonacci(QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_d(fibonacci_new(this,
|
m_d(fibonacci_new(this,
|
||||||
fibonacciInputChanged,
|
fibonacciInputChanged,
|
||||||
fibonacciResultChanged)),
|
fibonacciResultChanged)),
|
||||||
m_ownsPrivate(true) {
|
m_ownsPrivate(true)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Fibonacci::~Fibonacci() {
|
Fibonacci::~Fibonacci() {
|
||||||
|
@ -199,7 +205,10 @@ quint64 Fibonacci::result() const
|
||||||
FibonacciList::FibonacciList(bool /*owned*/, QObject *parent):
|
FibonacciList::FibonacciList(bool /*owned*/, QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
m_d(0),
|
m_d(0),
|
||||||
m_ownsPrivate(false) {}
|
m_ownsPrivate(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
FibonacciList::FibonacciList(QObject *parent):
|
FibonacciList::FibonacciList(QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
m_d(fibonacci_list_new(this,
|
m_d(fibonacci_list_new(this,
|
||||||
|
@ -225,7 +234,8 @@ FibonacciList::FibonacciList(QObject *parent):
|
||||||
o->endRemoveRows();
|
o->endRemoveRows();
|
||||||
}
|
}
|
||||||
)),
|
)),
|
||||||
m_ownsPrivate(true) {
|
m_ownsPrivate(true)
|
||||||
|
{
|
||||||
connect(this, &FibonacciList::newDataReady, this, [this](const QModelIndex& i) {
|
connect(this, &FibonacciList::newDataReady, this, [this](const QModelIndex& i) {
|
||||||
fetchMore(i);
|
fetchMore(i);
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
class Fibonacci;
|
||||||
|
class FibonacciList;
|
||||||
|
|
||||||
class Fibonacci : public QObject
|
class Fibonacci : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -220,10 +220,14 @@ extern "C" {
|
||||||
void (*)(Processes*));
|
void (*)(Processes*));
|
||||||
void processes_free(Processes::Private*);
|
void processes_free(Processes::Private*);
|
||||||
};
|
};
|
||||||
|
|
||||||
Processes::Processes(bool /*owned*/, QObject *parent):
|
Processes::Processes(bool /*owned*/, QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
m_d(0),
|
m_d(0),
|
||||||
m_ownsPrivate(false) {}
|
m_ownsPrivate(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Processes::Processes(QObject *parent):
|
Processes::Processes(QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
m_d(processes_new(this,
|
m_d(processes_new(this,
|
||||||
|
@ -264,7 +268,8 @@ Processes::Processes(QObject *parent):
|
||||||
o->endRemoveRows();
|
o->endRemoveRows();
|
||||||
}
|
}
|
||||||
)),
|
)),
|
||||||
m_ownsPrivate(true) {
|
m_ownsPrivate(true)
|
||||||
|
{
|
||||||
connect(this, &Processes::newDataReady, this, [this](const QModelIndex& i) {
|
connect(this, &Processes::newDataReady, this, [this](const QModelIndex& i) {
|
||||||
fetchMore(i);
|
fetchMore(i);
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
class Processes;
|
||||||
|
|
||||||
class Processes : public QAbstractItemModel
|
class Processes : public QAbstractItemModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -189,10 +189,14 @@ extern "C" {
|
||||||
void (*)(TimeSeries*));
|
void (*)(TimeSeries*));
|
||||||
void time_series_free(TimeSeries::Private*);
|
void time_series_free(TimeSeries::Private*);
|
||||||
};
|
};
|
||||||
|
|
||||||
TimeSeries::TimeSeries(bool /*owned*/, QObject *parent):
|
TimeSeries::TimeSeries(bool /*owned*/, QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
m_d(0),
|
m_d(0),
|
||||||
m_ownsPrivate(false) {}
|
m_ownsPrivate(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
TimeSeries::TimeSeries(QObject *parent):
|
TimeSeries::TimeSeries(QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
m_d(time_series_new(this,
|
m_d(time_series_new(this,
|
||||||
|
@ -218,7 +222,8 @@ TimeSeries::TimeSeries(QObject *parent):
|
||||||
o->endRemoveRows();
|
o->endRemoveRows();
|
||||||
}
|
}
|
||||||
)),
|
)),
|
||||||
m_ownsPrivate(true) {
|
m_ownsPrivate(true)
|
||||||
|
{
|
||||||
connect(this, &TimeSeries::newDataReady, this, [this](const QModelIndex& i) {
|
connect(this, &TimeSeries::newDataReady, this, [this](const QModelIndex& i) {
|
||||||
fetchMore(i);
|
fetchMore(i);
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
class TimeSeries;
|
||||||
|
|
||||||
class TimeSeries : public QAbstractItemModel
|
class TimeSeries : public QAbstractItemModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -240,10 +240,14 @@ extern "C" {
|
||||||
void tree_path_set(Tree::Private*, qstring_t);
|
void tree_path_set(Tree::Private*, qstring_t);
|
||||||
void tree_path_set_none(Tree::Private*);
|
void tree_path_set_none(Tree::Private*);
|
||||||
};
|
};
|
||||||
|
|
||||||
Tree::Tree(bool /*owned*/, QObject *parent):
|
Tree::Tree(bool /*owned*/, QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
m_d(0),
|
m_d(0),
|
||||||
m_ownsPrivate(false) {}
|
m_ownsPrivate(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Tree::Tree(QObject *parent):
|
Tree::Tree(QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
m_d(tree_new(this,
|
m_d(tree_new(this,
|
||||||
|
@ -285,7 +289,8 @@ Tree::Tree(QObject *parent):
|
||||||
o->endRemoveRows();
|
o->endRemoveRows();
|
||||||
}
|
}
|
||||||
)),
|
)),
|
||||||
m_ownsPrivate(true) {
|
m_ownsPrivate(true)
|
||||||
|
{
|
||||||
connect(this, &Tree::newDataReady, this, [this](const QModelIndex& i) {
|
connect(this, &Tree::newDataReady, this, [this](const QModelIndex& i) {
|
||||||
fetchMore(i);
|
fetchMore(i);
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
class Tree;
|
||||||
|
|
||||||
class Tree : public QAbstractItemModel
|
class Tree : public QAbstractItemModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
70
src/cpp.cpp
70
src/cpp.cpp
|
@ -325,7 +325,7 @@ class %1 : public %3
|
||||||
Q_OBJEC%2
|
Q_OBJEC%2
|
||||||
)").arg(o.name, "T", baseType(o));
|
)").arg(o.name, "T", baseType(o));
|
||||||
for (auto object: conf.objects) {
|
for (auto object: conf.objects) {
|
||||||
if (object.containsObject()) {
|
if (object.containsObject() && o.name != object.name) {
|
||||||
h << " friend class " << object.name << ";\n";
|
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";
|
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));
|
const QString lcname(snakeCase(o.name));
|
||||||
for (const Property& p: o.properties) {
|
for (const Property& p: o.properties) {
|
||||||
if (p.type.type == BindingType::Object) {
|
if (p.type.type == BindingType::Object) {
|
||||||
cpp << ", m_" << p.name;
|
cpp << ", " << prefix << "m_" << p.name;
|
||||||
constructorArgs(cpp, conf.findObject(p.type.name), conf);
|
constructorArgs(cpp, "m_" + p.name + "->",
|
||||||
|
conf.findObject(p.type.name), conf);
|
||||||
} else {
|
} else {
|
||||||
cpp << ",\n " << changedF(o, p);
|
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) {
|
void writeCppObject(QTextStream& cpp, const Object& o, const Configuration& conf) {
|
||||||
const QString lcname(snakeCase(o.name));
|
const QString lcname(snakeCase(o.name));
|
||||||
cpp << QString("%1::%1(bool /*owned*/, QObject *parent):\n %2(parent),")
|
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);
|
.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),")
|
cpp << QString("%1::%1(QObject *parent):\n %2(parent),")
|
||||||
.arg(o.name, baseType(o)) << endl;
|
.arg(o.name, baseType(o)) << endl;
|
||||||
for (const Property& p: o.properties) {
|
initializeMembersZero(cpp, o, conf);
|
||||||
if (p.type.type == BindingType::Object) {
|
|
||||||
cpp << QString(" m_%1(new %2(false, this)),\n")
|
|
||||||
.arg(p.name, p.type.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cpp << QString(" m_d(%1_new(this").arg(lcname);
|
cpp << QString(" m_d(%1_new(this").arg(lcname);
|
||||||
constructorArgs(cpp, o, conf);
|
constructorArgs(cpp, "", o, conf);
|
||||||
cpp << ")),\n m_ownsPrivate(true) {\n";
|
cpp << ")),\n m_ownsPrivate(true)\n{\n";
|
||||||
for (const Property& p: o.properties) {
|
initializeMembers(cpp, "", o, conf);
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (o.type != ObjectType::Object) {
|
if (o.type != ObjectType::Object) {
|
||||||
cpp << QString(R"( connect(this, &%1::newDataReady, this, [this](const QModelIndex& i) {
|
cpp << QString(R"( connect(this, &%1::newDataReady, this, [this](const QModelIndex& i) {
|
||||||
fetchMore(i);
|
fetchMore(i);
|
||||||
|
@ -612,12 +637,11 @@ void writeHeader(const Configuration& conf) {
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
)").arg(guard);
|
)").arg(guard);
|
||||||
|
|
||||||
for (auto object: conf.objects) {
|
for (auto object: conf.objects) {
|
||||||
if (object.containsObject()) {
|
h << "class " << object.name << ";\n";
|
||||||
h << "class " << object.name << ";\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (auto object: conf.objects) {
|
for (auto object: conf.objects) {
|
||||||
writeHeaderObject(h, object, conf);
|
writeHeaderObject(h, object, conf);
|
||||||
|
@ -706,7 +730,7 @@ void set_qbytearray(QByteArray* v, qbytearray_t* val) {
|
||||||
|
|
||||||
cpp << "extern \"C\" {\n";
|
cpp << "extern \"C\" {\n";
|
||||||
writeObjectCDecl(cpp, object, conf);
|
writeObjectCDecl(cpp, object, conf);
|
||||||
cpp << "};" << endl;
|
cpp << "};\n" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto object: conf.objects) {
|
for (auto object: conf.objects) {
|
||||||
|
|
|
@ -204,17 +204,19 @@ parseConfiguration(const QString& path) {
|
||||||
c.hFile = QFileInfo(c.cppFile.dir(), c.cppFile.completeBaseName() + ".h");
|
c.hFile = QFileInfo(c.cppFile.dir(), c.cppFile.completeBaseName() + ".h");
|
||||||
const QJsonObject& object = o.value("objects").toObject();
|
const QJsonObject& object = o.value("objects").toObject();
|
||||||
for (const QString& key: object.keys()) {
|
for (const QString& key: object.keys()) {
|
||||||
Object o = parseObject(key, object[key].toObject());
|
|
||||||
c.objects.append(o);
|
|
||||||
bindingTypeProperties().append({
|
bindingTypeProperties().append({
|
||||||
.type = BindingType::Object,
|
.type = BindingType::Object,
|
||||||
.name = o.name,
|
.name = key,
|
||||||
.cppSetType = o.name,
|
.cppSetType = key,
|
||||||
.cSetType = o.name,
|
.cSetType = key,
|
||||||
.rustType = o.name,
|
.rustType = key,
|
||||||
.rustTypeInit = "",
|
.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();
|
const QJsonObject rust = o.value("rust").toObject();
|
||||||
c.rustdir = QDir(base.filePath(rust.value("dir").toString()));
|
c.rustdir = QDir(base.filePath(rust.value("dir").toString()));
|
||||||
c.interfaceModule = rust.value("interfaceModule").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) {
|
void writeRustImplementation(const Configuration& conf) {
|
||||||
|
|
|
@ -36,3 +36,4 @@ impl PersonsTrait for Persons {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,3 +26,4 @@ impl PersonTrait for Person {
|
||||||
self.emit.user_name_changed();
|
self.emit.user_name_changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,3 +89,4 @@ impl ObjectTrait for Object {
|
||||||
self.emit.uinteger_changed();
|
self.emit.uinteger_changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,29 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use interface::*;
|
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 {
|
pub struct InnerObject {
|
||||||
emit: InnerObjectEmitter,
|
emit: InnerObjectEmitter,
|
||||||
description: String,
|
description: String,
|
||||||
|
@ -26,6 +49,7 @@ impl InnerObjectTrait for InnerObject {
|
||||||
self.emit.description_changed();
|
self.emit.description_changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Person {
|
pub struct Person {
|
||||||
emit: PersonEmitter,
|
emit: PersonEmitter,
|
||||||
object: InnerObject,
|
object: InnerObject,
|
||||||
|
@ -48,3 +72,4 @@ impl PersonTrait for Person {
|
||||||
&mut self.object
|
&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 {}
|
pub struct InnerObjectQObject {}
|
||||||
|
|
||||||
#[derive (Clone)]
|
#[derive (Clone)]
|
||||||
|
|
|
@ -45,3 +45,4 @@ impl PersonsTrait for Persons {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,10 +164,14 @@ extern "C" {
|
||||||
void (*)(Persons*));
|
void (*)(Persons*));
|
||||||
void persons_free(Persons::Private*);
|
void persons_free(Persons::Private*);
|
||||||
};
|
};
|
||||||
|
|
||||||
Persons::Persons(bool /*owned*/, QObject *parent):
|
Persons::Persons(bool /*owned*/, QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
m_d(0),
|
m_d(0),
|
||||||
m_ownsPrivate(false) {}
|
m_ownsPrivate(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Persons::Persons(QObject *parent):
|
Persons::Persons(QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
m_d(persons_new(this,
|
m_d(persons_new(this,
|
||||||
|
@ -193,7 +197,8 @@ Persons::Persons(QObject *parent):
|
||||||
o->endRemoveRows();
|
o->endRemoveRows();
|
||||||
}
|
}
|
||||||
)),
|
)),
|
||||||
m_ownsPrivate(true) {
|
m_ownsPrivate(true)
|
||||||
|
{
|
||||||
connect(this, &Persons::newDataReady, this, [this](const QModelIndex& i) {
|
connect(this, &Persons::newDataReady, this, [this](const QModelIndex& i) {
|
||||||
fetchMore(i);
|
fetchMore(i);
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
class Persons;
|
||||||
|
|
||||||
class Persons : public QAbstractItemModel
|
class Persons : public QAbstractItemModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -64,15 +64,20 @@ extern "C" {
|
||||||
void person_user_name_get(const Person::Private*, QString*, qstring_set);
|
void person_user_name_get(const Person::Private*, QString*, qstring_set);
|
||||||
void person_user_name_set(Person::Private*, qstring_t);
|
void person_user_name_set(Person::Private*, qstring_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
Person::Person(bool /*owned*/, QObject *parent):
|
Person::Person(bool /*owned*/, QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_d(0),
|
m_d(0),
|
||||||
m_ownsPrivate(false) {}
|
m_ownsPrivate(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Person::Person(QObject *parent):
|
Person::Person(QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_d(person_new(this,
|
m_d(person_new(this,
|
||||||
personUserNameChanged)),
|
personUserNameChanged)),
|
||||||
m_ownsPrivate(true) {
|
m_ownsPrivate(true)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Person::~Person() {
|
Person::~Person() {
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
class Person;
|
||||||
|
|
||||||
class Person : public QObject
|
class Person : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -108,10 +108,14 @@ extern "C" {
|
||||||
quint32 object_uinteger_get(const Object::Private*);
|
quint32 object_uinteger_get(const Object::Private*);
|
||||||
void object_uinteger_set(Object::Private*, uint);
|
void object_uinteger_set(Object::Private*, uint);
|
||||||
};
|
};
|
||||||
|
|
||||||
Object::Object(bool /*owned*/, QObject *parent):
|
Object::Object(bool /*owned*/, QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_d(0),
|
m_d(0),
|
||||||
m_ownsPrivate(false) {}
|
m_ownsPrivate(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Object::Object(QObject *parent):
|
Object::Object(QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_d(object_new(this,
|
m_d(object_new(this,
|
||||||
|
@ -123,7 +127,8 @@ Object::Object(QObject *parent):
|
||||||
objectStringChanged,
|
objectStringChanged,
|
||||||
objectU64Changed,
|
objectU64Changed,
|
||||||
objectUintegerChanged)),
|
objectUintegerChanged)),
|
||||||
m_ownsPrivate(true) {
|
m_ownsPrivate(true)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::~Object() {
|
Object::~Object() {
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
class Object;
|
||||||
|
|
||||||
class Object : public QObject
|
class Object : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -6,23 +6,26 @@ class TestRustObjects : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private slots:
|
private slots:
|
||||||
void testConstructor();
|
void testOneLevelConstructor();
|
||||||
void testStringGetter();
|
void testOneLevelStringGetter();
|
||||||
void testStringSetter();
|
void testOneLevelStringSetter();
|
||||||
|
void testTwoLevelsConstructor();
|
||||||
|
void testTwoLevelsStringGetter();
|
||||||
|
void testTwoLevelsStringSetter();
|
||||||
};
|
};
|
||||||
|
|
||||||
void TestRustObjects::testConstructor()
|
void TestRustObjects::testOneLevelConstructor()
|
||||||
{
|
{
|
||||||
Person person;
|
Person person;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRustObjects::testStringGetter()
|
void TestRustObjects::testOneLevelStringGetter()
|
||||||
{
|
{
|
||||||
Person person;
|
Person person;
|
||||||
person.object()->setDescription("Konqi");
|
person.object()->setDescription("Konqi");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRustObjects::testStringSetter()
|
void TestRustObjects::testOneLevelStringSetter()
|
||||||
{
|
{
|
||||||
// GIVEN
|
// GIVEN
|
||||||
Person person;
|
Person person;
|
||||||
|
@ -37,5 +40,31 @@ void TestRustObjects::testStringSetter()
|
||||||
QCOMPARE(person.object()->description(), QString("Konqi"));
|
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)
|
QTEST_MAIN(TestRustObjects)
|
||||||
#include "test_objects.moc"
|
#include "test_objects.moc"
|
||||||
|
|
|
@ -23,6 +23,14 @@
|
||||||
"type": "InnerObject"
|
"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) {
|
void set_qbytearray(QByteArray* v, qbytearray_t* val) {
|
||||||
*v = *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" {
|
extern "C" {
|
||||||
InnerObject::Private* inner_object_new(InnerObject*, void (*)(InnerObject*));
|
InnerObject::Private* inner_object_new(InnerObject*, void (*)(InnerObject*));
|
||||||
void inner_object_free(InnerObject::Private*);
|
void inner_object_free(InnerObject::Private*);
|
||||||
void inner_object_description_get(const InnerObject::Private*, QString*, qstring_set);
|
void inner_object_description_get(const InnerObject::Private*, QString*, qstring_set);
|
||||||
void inner_object_description_set(InnerObject::Private*, qstring_t);
|
void inner_object_description_set(InnerObject::Private*, qstring_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
Person::Private* person_new(Person*, InnerObject*, void (*)(InnerObject*));
|
Person::Private* person_new(Person*, InnerObject*, void (*)(InnerObject*));
|
||||||
void person_free(Person::Private*);
|
void person_free(Person::Private*);
|
||||||
InnerObject::Private* person_object_get(const 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):
|
InnerObject::InnerObject(bool /*owned*/, QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_d(0),
|
m_d(0),
|
||||||
m_ownsPrivate(false) {}
|
m_ownsPrivate(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
InnerObject::InnerObject(QObject *parent):
|
InnerObject::InnerObject(QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_d(inner_object_new(this,
|
m_d(inner_object_new(this,
|
||||||
innerObjectDescriptionChanged)),
|
innerObjectDescriptionChanged)),
|
||||||
m_ownsPrivate(true) {
|
m_ownsPrivate(true)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
InnerObject::~InnerObject() {
|
InnerObject::~InnerObject() {
|
||||||
|
@ -98,14 +142,18 @@ Person::Person(bool /*owned*/, QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_object(new InnerObject(false, this)),
|
m_object(new InnerObject(false, this)),
|
||||||
m_d(0),
|
m_d(0),
|
||||||
m_ownsPrivate(false) {}
|
m_ownsPrivate(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Person::Person(QObject *parent):
|
Person::Person(QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_object(new InnerObject(false, this)),
|
m_object(new InnerObject(false, this)),
|
||||||
m_d(person_new(this, m_object,
|
m_d(person_new(this, m_object,
|
||||||
innerObjectDescriptionChanged)),
|
innerObjectDescriptionChanged)),
|
||||||
m_ownsPrivate(true) {
|
m_ownsPrivate(true)
|
||||||
m_object->m_d = person_object_get(this->m_d);
|
{
|
||||||
|
m_object->m_d = person_object_get(m_d);
|
||||||
}
|
}
|
||||||
|
|
||||||
Person::~Person() {
|
Person::~Person() {
|
||||||
|
|
|
@ -4,11 +4,35 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
class Group;
|
||||||
|
class InnerObject;
|
||||||
class Person;
|
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
|
class InnerObject : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
friend class Group;
|
||||||
friend class Person;
|
friend class Person;
|
||||||
public:
|
public:
|
||||||
class Private;
|
class Private;
|
||||||
|
@ -29,7 +53,7 @@ signals:
|
||||||
class Person : public QObject
|
class Person : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
friend class Person;
|
friend class Group;
|
||||||
public:
|
public:
|
||||||
class Private;
|
class Private;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -182,10 +182,14 @@ extern "C" {
|
||||||
void (*)(Persons*));
|
void (*)(Persons*));
|
||||||
void persons_free(Persons::Private*);
|
void persons_free(Persons::Private*);
|
||||||
};
|
};
|
||||||
|
|
||||||
Persons::Persons(bool /*owned*/, QObject *parent):
|
Persons::Persons(bool /*owned*/, QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
m_d(0),
|
m_d(0),
|
||||||
m_ownsPrivate(false) {}
|
m_ownsPrivate(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Persons::Persons(QObject *parent):
|
Persons::Persons(QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
m_d(persons_new(this,
|
m_d(persons_new(this,
|
||||||
|
@ -226,7 +230,8 @@ Persons::Persons(QObject *parent):
|
||||||
o->endRemoveRows();
|
o->endRemoveRows();
|
||||||
}
|
}
|
||||||
)),
|
)),
|
||||||
m_ownsPrivate(true) {
|
m_ownsPrivate(true)
|
||||||
|
{
|
||||||
connect(this, &Persons::newDataReady, this, [this](const QModelIndex& i) {
|
connect(this, &Persons::newDataReady, this, [this](const QModelIndex& i) {
|
||||||
fetchMore(i);
|
fetchMore(i);
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
class Persons;
|
||||||
|
|
||||||
class Persons : public QAbstractItemModel
|
class Persons : public QAbstractItemModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
Loading…
Reference in New Issue