Make it possible to send signals from rust threads
parent
e3d9df5813
commit
5a52613025
|
@ -5,6 +5,7 @@ use std::fs::read_dir;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
pub struct Hello {
|
pub struct Hello {
|
||||||
emit: HelloEmitter,
|
emit: HelloEmitter,
|
||||||
|
@ -105,6 +106,10 @@ impl<T: Item> RGeneralItemModel<T> {
|
||||||
};
|
};
|
||||||
if self.entries[p].children.is_none() {
|
if self.entries[p].children.is_none() {
|
||||||
self.retrieve(p);
|
self.retrieve(p);
|
||||||
|
let emit = self.emit.clone();
|
||||||
|
thread::spawn(move || {
|
||||||
|
emit.new_data_ready();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
|
@ -150,6 +155,9 @@ impl<T: Item> RItemModelTrait<T> for RGeneralItemModel<T> {
|
||||||
entries: vec![none, root]
|
entries: vec![none, root]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn emit(&self) -> &RItemModelEmitter {
|
||||||
|
&self.emit
|
||||||
|
}
|
||||||
fn column_count(&mut self, _: QModelIndex) -> c_int {
|
fn column_count(&mut self, _: QModelIndex) -> c_int {
|
||||||
2
|
2
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use libc::{c_int, uint16_t, size_t, c_void};
|
use libc::{c_int, uint16_t, size_t, c_void};
|
||||||
use types::*;
|
use types::*;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::ptr::null;
|
||||||
|
|
||||||
use implementation::*;
|
use implementation::*;
|
||||||
|
|
||||||
|
@ -53,17 +55,32 @@ pub extern fn hello_get(ptr: *mut Hello) -> QString {
|
||||||
QString::from(hello.get_hello())
|
QString::from(hello.get_hello())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct RItemModelQObject {}
|
pub struct RItemModelQObject {}
|
||||||
|
|
||||||
|
#[derive (Clone)]
|
||||||
pub struct RItemModelEmitter {
|
pub struct RItemModelEmitter {
|
||||||
qobject: *const RItemModelQObject
|
qobject: Arc<Mutex<*const RItemModelQObject>>,
|
||||||
|
new_data_ready: fn (*const RItemModelQObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for RItemModelEmitter {}
|
||||||
|
|
||||||
impl RItemModelEmitter {
|
impl RItemModelEmitter {
|
||||||
|
pub fn new_data_ready(&self) {
|
||||||
|
let ptr = *self.qobject.lock().unwrap();
|
||||||
|
if !ptr.is_null() {
|
||||||
|
(self.new_data_ready)(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn clear(&self) {
|
||||||
|
*self.qobject.lock().unwrap() = null();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait RItemModelTrait<T> {
|
pub trait RItemModelTrait<T> {
|
||||||
fn create(emit: RItemModelEmitter, root: T) -> Self;
|
fn create(emit: RItemModelEmitter, root: T) -> Self;
|
||||||
|
fn emit(&self) -> &RItemModelEmitter;
|
||||||
fn column_count(&mut self, parent: QModelIndex) -> c_int;
|
fn column_count(&mut self, parent: QModelIndex) -> c_int;
|
||||||
fn row_count(&mut self, parent: QModelIndex) -> c_int;
|
fn row_count(&mut self, parent: QModelIndex) -> c_int;
|
||||||
fn index(&mut self, row: c_int, column: c_int, parent: QModelIndex) -> QModelIndex;
|
fn index(&mut self, row: c_int, column: c_int, parent: QModelIndex) -> QModelIndex;
|
||||||
|
@ -72,9 +89,10 @@ pub trait RItemModelTrait<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn ritemmodel_new(qobject: *const RItemModelQObject) -> *mut RItemModel {
|
pub extern fn ritemmodel_new(qobject: *const RItemModelQObject, new_data_ready: fn(*const RItemModelQObject)) -> *mut RItemModel {
|
||||||
let emit = RItemModelEmitter {
|
let emit = RItemModelEmitter {
|
||||||
qobject: qobject
|
qobject: Arc::new(Mutex::new(qobject)),
|
||||||
|
new_data_ready: new_data_ready
|
||||||
};
|
};
|
||||||
let ritemmodel = RItemModel::create(emit, DirEntry::create("/"));
|
let ritemmodel = RItemModel::create(emit, DirEntry::create("/"));
|
||||||
Box::into_raw(Box::new(ritemmodel))
|
Box::into_raw(Box::new(ritemmodel))
|
||||||
|
@ -82,8 +100,8 @@ pub extern fn ritemmodel_new(qobject: *const RItemModelQObject) -> *mut RItemMod
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn ritemmodel_free(ptr: *mut RItemModel) {
|
pub extern fn ritemmodel_free(ptr: *mut RItemModel) {
|
||||||
if ptr.is_null() { return }
|
let ritemmodel = unsafe { Box::from_raw(ptr) };
|
||||||
unsafe { Box::from_raw(ptr); }
|
ritemmodel.emit().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
typedef struct {
|
struct qbytearray_t {
|
||||||
private:
|
private:
|
||||||
const char* data;
|
const char* data;
|
||||||
int len;
|
int len;
|
||||||
|
@ -13,7 +13,7 @@ namespace {
|
||||||
operator QByteArray() const {
|
operator QByteArray() const {
|
||||||
return QByteArray(data, len);
|
return QByteArray(data, len);
|
||||||
}
|
}
|
||||||
} qbytearray_t;
|
};
|
||||||
struct qstring_t {
|
struct qstring_t {
|
||||||
private:
|
private:
|
||||||
const char* data;
|
const char* data;
|
||||||
|
@ -23,16 +23,18 @@ namespace {
|
||||||
return QString::fromUtf8(data, len);
|
return QString::fromUtf8(data, len);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
typedef struct {
|
struct qmodelindex_t {
|
||||||
int row;
|
int row;
|
||||||
int column;
|
int column;
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
} qmodelindex_t;
|
qmodelindex_t(const QModelIndex& m):
|
||||||
typedef struct qvariant_t {
|
row(m.row()), column(m.column()), id(m.internalId()) {}
|
||||||
|
};
|
||||||
|
struct qvariant_t {
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
int value;
|
int value;
|
||||||
const char* data;
|
const char* data;
|
||||||
} qvariant_t;
|
};
|
||||||
QVariant variant(const qvariant_t& v) {
|
QVariant variant(const qvariant_t& v) {
|
||||||
switch (v.type) {
|
switch (v.type) {
|
||||||
case QVariant::Bool: return QVariant((bool)v.value);
|
case QVariant::Bool: return QVariant((bool)v.value);
|
||||||
|
@ -67,7 +69,7 @@ extern "C" {
|
||||||
void hello_set(RMailObjectInterface*, const uint16_t *, size_t);
|
void hello_set(RMailObjectInterface*, const uint16_t *, size_t);
|
||||||
qstring_t hello_get(RMailObjectInterface*);
|
qstring_t hello_get(RMailObjectInterface*);
|
||||||
|
|
||||||
RItemModelInterface* ritemmodel_new(void*);
|
RItemModelInterface* ritemmodel_new(void*, void (*)(RItemModel*));
|
||||||
void ritemmodel_free(RItemModelInterface*);
|
void ritemmodel_free(RItemModelInterface*);
|
||||||
int ritemmodel_column_count(RItemModelInterface*, qmodelindex_t parent);
|
int ritemmodel_column_count(RItemModelInterface*, qmodelindex_t parent);
|
||||||
int ritemmodel_row_count(RItemModelInterface*, qmodelindex_t parent);
|
int ritemmodel_row_count(RItemModelInterface*, qmodelindex_t parent);
|
||||||
|
@ -111,31 +113,30 @@ RMailObject::setTree(const QVariantMap& tree) {
|
||||||
|
|
||||||
RItemModel::RItemModel(QObject *parent):
|
RItemModel::RItemModel(QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
d(ritemmodel_new(this))
|
d(ritemmodel_new(this,
|
||||||
|
[](RItemModel* o) { emit o->newDataReady(); }
|
||||||
|
))
|
||||||
{
|
{
|
||||||
|
connect(this, &RItemModel::newDataReady, this, &RItemModel::handleNewData,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
qDebug() << sizeof(QObject) << sizeof(RItemModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
RItemModel::~RItemModel() {
|
RItemModel::~RItemModel() {
|
||||||
ritemmodel_free(d);
|
ritemmodel_free(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RItemModel::handleNewData() {
|
||||||
|
qDebug() << "new data!";
|
||||||
|
}
|
||||||
|
|
||||||
int RItemModel::columnCount(const QModelIndex &parent) const
|
int RItemModel::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
const qmodelindex_t p = {
|
return ritemmodel_column_count(d, parent);
|
||||||
.row = parent.row(),
|
|
||||||
.column = parent.column(),
|
|
||||||
.id = parent.internalId()
|
|
||||||
};
|
|
||||||
return ritemmodel_column_count(d, p);
|
|
||||||
}
|
}
|
||||||
int RItemModel::rowCount(const QModelIndex &parent) const
|
int RItemModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
const qmodelindex_t p = {
|
return ritemmodel_row_count(d, parent);
|
||||||
.row = parent.row(),
|
|
||||||
.column = parent.column(),
|
|
||||||
.id = parent.internalId()
|
|
||||||
};
|
|
||||||
return ritemmodel_row_count(d, p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_variant(void* v, qvariant_t* val) {
|
void set_variant(void* v, qvariant_t* val) {
|
||||||
|
@ -144,23 +145,13 @@ void set_variant(void* v, qvariant_t* val) {
|
||||||
|
|
||||||
QVariant RItemModel::data(const QModelIndex &index, int role) const
|
QVariant RItemModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
const qmodelindex_t i = {
|
|
||||||
.row = index.row(),
|
|
||||||
.column = index.column(),
|
|
||||||
.id = index.internalId()
|
|
||||||
};
|
|
||||||
QVariant v;
|
QVariant v;
|
||||||
ritemmodel_data(d, i, role, &v, set_variant);
|
ritemmodel_data(d, index, role, &v, set_variant);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
QModelIndex RItemModel::index(int row, int column, const QModelIndex &parent) const
|
QModelIndex RItemModel::index(int row, int column, const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
const qmodelindex_t p = {
|
const qmodelindex_t i = ritemmodel_index(d, row, column, parent);
|
||||||
.row = parent.row(),
|
|
||||||
.column = parent.column(),
|
|
||||||
.id = parent.internalId()
|
|
||||||
};
|
|
||||||
const qmodelindex_t i = ritemmodel_index(d, row, column, p);
|
|
||||||
return i.id ?createIndex(i.row, i.column, i.id) :QModelIndex();
|
return i.id ?createIndex(i.row, i.column, i.id) :QModelIndex();
|
||||||
}
|
}
|
||||||
QModelIndex RItemModel::parent(const QModelIndex &index) const
|
QModelIndex RItemModel::parent(const QModelIndex &index) const
|
||||||
|
@ -168,11 +159,6 @@ QModelIndex RItemModel::parent(const QModelIndex &index) const
|
||||||
if (!index.isValid()) {
|
if (!index.isValid()) {
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
const qmodelindex_t i = {
|
const qmodelindex_t parent = ritemmodel_parent(d, index);
|
||||||
.row = index.row(),
|
|
||||||
.column = index.column(),
|
|
||||||
.id = index.internalId()
|
|
||||||
};
|
|
||||||
const qmodelindex_t parent = ritemmodel_parent(d, i);
|
|
||||||
return parent.id ?createIndex(parent.row, parent.column, parent.id) :QModelIndex();
|
return parent.id ?createIndex(parent.row, parent.column, parent.id) :QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,12 @@ public:
|
||||||
QModelIndex index(int row, int column, const QModelIndex &parent) const;
|
QModelIndex index(int row, int column, const QModelIndex &parent) const;
|
||||||
QModelIndex parent(const QModelIndex &index) const;
|
QModelIndex parent(const QModelIndex &index) const;
|
||||||
int rowCount(const QModelIndex &parent) const;
|
int rowCount(const QModelIndex &parent) const;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleNewData();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void newDataReady();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RMAIL_OBJECT_H
|
#endif // RMAIL_OBJECT_H
|
||||||
|
|
Loading…
Reference in New Issue