Merge branch 'unclone' into 'master'
util: C-wrapped data don't need to be cloneable See merge request Librem5/squeekboard!213
This commit is contained in:
@ -10,6 +10,7 @@ use ::action::Action;
|
|||||||
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::iter::{ FromIterator, IntoIterator };
|
use std::iter::{ FromIterator, IntoIterator };
|
||||||
|
use ::util::CloneOwned;
|
||||||
|
|
||||||
/// Gathers stuff defined in C or called by C
|
/// Gathers stuff defined in C or called by C
|
||||||
pub mod c {
|
pub mod c {
|
||||||
@ -48,13 +49,13 @@ pub mod c {
|
|||||||
pub extern "C"
|
pub extern "C"
|
||||||
fn squeek_key_is_pressed(key: CKeyState) -> u32 {
|
fn squeek_key_is_pressed(key: CKeyState) -> u32 {
|
||||||
//let key = unsafe { Rc::from_raw(key.0) };
|
//let key = unsafe { Rc::from_raw(key.0) };
|
||||||
return key.to_owned().pressed as u32;
|
return key.clone_owned().pressed as u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C"
|
pub extern "C"
|
||||||
fn squeek_key_is_locked(key: CKeyState) -> u32 {
|
fn squeek_key_is_locked(key: CKeyState) -> u32 {
|
||||||
return key.to_owned().locked as u32;
|
return key.clone_owned().locked as u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@ -27,6 +27,8 @@ use ::action::Action;
|
|||||||
use ::float_ord::FloatOrd;
|
use ::float_ord::FloatOrd;
|
||||||
use ::keyboard::*;
|
use ::keyboard::*;
|
||||||
|
|
||||||
|
use ::util::CloneOwned;
|
||||||
|
|
||||||
/// Gathers stuff defined in C or called by C
|
/// Gathers stuff defined in C or called by C
|
||||||
pub mod c {
|
pub mod c {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -270,7 +272,7 @@ pub mod c {
|
|||||||
) {
|
) {
|
||||||
let layout = unsafe { &mut *layout };
|
let layout = unsafe { &mut *layout };
|
||||||
|
|
||||||
let view_name = match key.to_owned().action {
|
let view_name = match key.clone_owned().action {
|
||||||
Action::SetLevel(name) => {
|
Action::SetLevel(name) => {
|
||||||
Some(name.clone())
|
Some(name.clone())
|
||||||
},
|
},
|
||||||
|
|||||||
33
src/util.rs
33
src/util.rs
@ -4,6 +4,8 @@ use std::collections::HashMap;
|
|||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
pub mod c {
|
pub mod c {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ffi::{ CStr, CString };
|
use std::ffi::{ CStr, CString };
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
@ -63,7 +65,7 @@ pub mod c {
|
|||||||
/// RefCell will enforce them dynamically (only 1 writer/many readers)
|
/// RefCell will enforce them dynamically (only 1 writer/many readers)
|
||||||
/// Rc is implied and will ensure timely dropping
|
/// Rc is implied and will ensure timely dropping
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Wrapped<T: Clone>(*const RefCell<T>);
|
pub struct Wrapped<T>(*const RefCell<T>);
|
||||||
|
|
||||||
// It would be nice to implement `Borrow`
|
// It would be nice to implement `Borrow`
|
||||||
// directly on the raw pointer to avoid one conversion call,
|
// directly on the raw pointer to avoid one conversion call,
|
||||||
@ -73,7 +75,7 @@ pub mod c {
|
|||||||
// Unfortunately, that needs a `Ref` struct with self-referential fields,
|
// Unfortunately, that needs a `Ref` struct with self-referential fields,
|
||||||
// which is a bit too complex for now.
|
// which is a bit too complex for now.
|
||||||
|
|
||||||
impl<T: Clone> Wrapped<T> {
|
impl<T> Wrapped<T> {
|
||||||
pub fn wrap(state: Rc<RefCell<T>>) -> Wrapped<T> {
|
pub fn wrap(state: Rc<RefCell<T>>) -> Wrapped<T> {
|
||||||
Wrapped(Rc::into_raw(state))
|
Wrapped(Rc::into_raw(state))
|
||||||
}
|
}
|
||||||
@ -91,20 +93,31 @@ pub mod c {
|
|||||||
Rc::into_raw(used_rc); // prevent dropping the original reference
|
Rc::into_raw(used_rc); // prevent dropping the original reference
|
||||||
rc
|
rc
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Clone for Wrapped<T> {
|
||||||
|
fn clone(&self) -> Wrapped<T> {
|
||||||
|
Wrapped::wrap(self.clone_ref())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ToOwned won't work here
|
||||||
|
/// because it's really difficult to implement Borrow on Wrapped<T>
|
||||||
|
/// with the Rc<RefCell<>> chain on the way to the data
|
||||||
|
impl<T: Clone> CloneOwned for Wrapped<T> {
|
||||||
|
type Owned = T;
|
||||||
|
|
||||||
/// Create a copy of the underlying data
|
fn clone_owned(&self) -> T {
|
||||||
pub fn to_owned(&self) -> T {
|
|
||||||
let rc = self.clone_ref();
|
let rc = self.clone_ref();
|
||||||
let r = rc.borrow();
|
let r = rc.borrow();
|
||||||
r.to_owned()
|
r.to_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
impl<T: Clone> Clone for Wrapped<T> {
|
|
||||||
fn clone(&self) -> Wrapped<T> {
|
pub trait CloneOwned {
|
||||||
Wrapped::wrap(self.clone_ref())
|
type Owned;
|
||||||
}
|
fn clone_owned(&self) -> Self::Owned;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash_map_map<K, V, F, K1, V1>(map: HashMap<K, V>, mut f: F)
|
pub fn hash_map_map<K, V, F, K1, V1>(map: HashMap<K, V>, mut f: F)
|
||||||
|
|||||||
Reference in New Issue
Block a user