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