Rich pointer prototype #149
-
use std::ops::Deref;
// defined in library
pub trait CxxQtRustObj {
type FFI;
}
struct MyObjectFFI {}
impl MyObjectFFI {
pub fn emit(&self) {}
}
struct MyObject {
// #[property]
prop: Vec<i32>,
}
// generated by CXX-Qt
// so that we can instantiate a Qt<'a, MyObject>
impl CxxQtRustObj for MyObject {
type FFI = MyObjectFFI;
}
mod qt {
// defined in library
pub struct Qt<'a, T>
where
T: super::CxxQtRustObj,
{
rust: &'a mut T,
cpp: &'a mut T::FFI,
}
impl<'a, T> Qt<'a, T>
where
T: super::CxxQtRustObj,
{
pub fn new(rust: &'a mut T, cpp: &'a mut T::FFI) -> Self {
Self { rust, cpp }
}
pub fn cpp(&self) -> &T::FFI {
&self.cpp
}
pub fn rust(&self) -> &T {
&self.rust
}
pub unsafe fn rust_mut(&mut self) -> &mut T {
&mut self.rust
}
}
}
// impl Drop for Qt<'a, T> // destructs cpp
// generated by CXX-Qt
impl<'a> qt::Qt<'a, MyObject> {
pub fn prop(&self) -> &Vec<i32> {
&self.rust().prop
}
pub fn set_prop(&mut self, new_value: Vec<i32>) {
unsafe {
self.rust_mut().prop = new_value;
}
self.cpp().emit();
}
}
impl<'a> qt::Qt<'a, MyObject> {
// #[invokable]
fn my_invokable(&self) -> i32 {
self.prop()[0]
}
fn another_invokable(&mut self) {
let mut rusty = MyObject {
prop: vec![3, 4, 5],
};
// self.rust_mut().prop = vec![3, 4, 5];
}
}
fn main() {
use std::cell::UnsafeCell;
let x = vec![1, 2, 3];
let cell: UnsafeCell<Vec<i32>> = x.into();
let r = cell.get();
let r_mut = unsafe { &mut *r };
let another_r_mut = unsafe { &mut *r };
}
// generated cxx
// extern "Rust" {
// type MyObject;
// unsafe fn my_invokable(self: &MyObject, cpp: &MyObject::FFI>) {
// let rust = unsafe { self as *mut MyObject as &mut MyObject };
// let cpp = unsafe { self as *mut MyObject::FFI as &mut MyObject::FFI };
// let fat_pointer = Qt::new(rust, cpp);
// }
// }
// fn main() {
// let mut rustobj = RustObj { x: vec![1, 2, 3] };
// let mutable = QtMut { rust: &mut rustobj };
// } |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 1 reply
-
For the |
Beta Was this translation helpful? Give feedback.
-
V2: use std::ops::Deref;
// defined in library
pub trait CxxQtRustObj {
type FFIRef;
type FFI;
}
struct MyObjectFFI {}
impl MyObjectFFI {
pub fn emit(&mut self) {}
}
struct MyObject {
// #[property]
prop: Vec<i32>,
}
// generated by CXX-Qt
// so that we can instantiate a Qt<'a, MyObject>
impl<'a> CxxQtRustObj for &'a MyObject {
type FFIRef = &'a MyObjectFFI;
type FFI = MyObjectFFI;
}
impl<'a> CxxQtRustObj for &'a mut MyObject {
type FFIRef = &'a mut MyObjectFFI;
type FFI = &'a mut MyObjectFFI;
}
mod qt {
use std::ops::Deref;
use std::ops::DerefMut;
// defined in library
pub struct Qt<T>
where
T: super::CxxQtRustObj,
{
rust: T,
cpp: T::FFIRef,
}
impl<T> Qt<T>
where
T: super::CxxQtRustObj,
{
pub fn new(rust: T, cpp: T::FFIRef) -> Self {
Self { rust, cpp }
}
}
impl<T> Qt<T>
where
T: super::CxxQtRustObj,
{
pub fn cpp(self) -> T::FFIRef {
self.cpp
}
pub fn rust(self) -> T {
self.rust
}
}
use std::borrow::BorrowMut;
impl<'a, T> Qt<&'a mut T>
where
&'a mut T: super::CxxQtRustObj,
<&'a mut T as super::CxxQtRustObj>::FFIRef:
BorrowMut<<&'a mut T as super::CxxQtRustObj>::FFI>,
{
// This function is unsafe, so that you can't accidentally change a property without using "unsafe".
pub unsafe fn rust_mut(&mut self) -> &mut T {
self.rust
}
pub fn cpp_mut(&mut self) -> &mut <&'a mut T as super::CxxQtRustObj>::FFI {
self.cpp.borrow_mut()
}
}
impl<T> Clone for Qt<T>
where
T: super::CxxQtRustObj + Clone,
<T as super::CxxQtRustObj>::FFIRef: Clone,
{
fn clone(&self) -> Self {
Self {
rust: self.rust.clone(),
cpp: self.cpp.clone(),
}
}
}
impl<T> Copy for Qt<T>
where
T: super::CxxQtRustObj + Copy,
<T as super::CxxQtRustObj>::FFIRef: Copy,
{
}
}
// impl Drop for Qt<'a, T> // destructs cpp
// generated by CXX-Qt
impl qt::Qt<&MyObject> {
pub fn prop(&self) -> &Vec<i32> {
&self.rust().prop
}
}
impl qt::Qt<&mut MyObject> {
pub fn set_prop(&mut self, new_value: Vec<i32>) {
unsafe {
self.rust_mut().prop = new_value;
}
self.cpp_mut().emit();
}
}
impl qt::Qt<&MyObject> {
// #[invokable]
fn my_invokable(&self) -> i32 {
self.prop()[0]
}
}
impl qt::Qt<&mut MyObject> {
fn another_invokable(&mut self) {
self.set_prop(vec![3, 4, 5]);
}
}
// fn invokable(rust: &MyObject, cpp: &MyObjectFFI) {
// let mut rich_pointer = qt::Qt::new(rust, cpp);
// rich_pointer.another_invokable();
// }
fn another_invokable(rust: &mut MyObject, cpp: &mut MyObjectFFI) {
let mut rich_pointer = qt::Qt::new(rust, cpp);
rich_pointer.another_invokable();
}
fn main() {} |
Beta Was this translation helpful? Give feedback.
-
Another random idea: Possible unsafety:
|
Beta Was this translation helpful? Give feedback.
-
Deprecated in favor of #156 |
Beta Was this translation helpful? Give feedback.
Deprecated in favor of #156