add readable and writable traits for signal-like structs
This commit is contained in:
1 parent
93adb35cfa
commit
51d7133ca5
17 files changed
+756
-673
No files matched your search
@@ -198,36 +198,6 @@ impl<T, S> Clone for GenerationalBox<T, S> {
|
||||
|
||||
/// A trait for a storage backing type. (RefCell, RwLock, etc.)
|
||||
pub trait Storage<Data = ()>: AnyStorage + 'static {
|
||||
/// The reference this storage type returns.
|
||||
type Ref<T: ?Sized + 'static>: Deref<Target = T>;
|
||||
/// The mutable reference this storage type returns.
|
||||
type Mut<T: ?Sized + 'static>: DerefMut<Target = T>;
|
||||
|
||||
/// Try to map the mutable ref.
|
||||
fn try_map_mut<T, U: ?Sized + 'static>(
|
||||
mut_ref: Self::Mut<T>,
|
||||
f: impl FnOnce(&mut T) -> Option<&mut U>,
|
||||
) -> Option<Self::Mut<U>>;
|
||||
|
||||
/// Map the mutable ref.
|
||||
fn map_mut<T, U: ?Sized + 'static>(
|
||||
mut_ref: Self::Mut<T>,
|
||||
f: impl FnOnce(&mut T) -> &mut U,
|
||||
) -> Self::Mut<U> {
|
||||
Self::try_map_mut(mut_ref, |v| Some(f(v))).unwrap()
|
||||
}
|
||||
|
||||
/// Try to map the ref.
|
||||
fn try_map<T, U: ?Sized + 'static>(
|
||||
ref_: Self::Ref<T>,
|
||||
f: impl FnOnce(&T) -> Option<&U>,
|
||||
) -> Option<Self::Ref<U>>;
|
||||
|
||||
/// Map the ref.
|
||||
fn map<T, U: ?Sized + 'static>(ref_: Self::Ref<T>, f: impl FnOnce(&T) -> &U) -> Self::Ref<U> {
|
||||
Self::try_map(ref_, |v| Some(f(v))).unwrap()
|
||||
}
|
||||
|
||||
/// Try to read the value. Returns None if the value is no longer valid.
|
||||
fn try_read(
|
||||
&'static self,
|
||||
@@ -246,6 +216,36 @@ pub trait Storage<Data = ()>: AnyStorage + 'static {
|
||||
|
||||
/// A trait for any storage backing type.
|
||||
pub trait AnyStorage: Default {
|
||||
/// The reference this storage type returns.
|
||||
type Ref<T: ?Sized + 'static>: Deref<Target = T>;
|
||||
/// The mutable reference this storage type returns.
|
||||
type Mut<T: ?Sized + 'static>: DerefMut<Target = T>;
|
||||
|
||||
/// Try to map the mutable ref.
|
||||
fn try_map_mut<T: ?Sized, U: ?Sized + 'static>(
|
||||
mut_ref: Self::Mut<T>,
|
||||
f: impl FnOnce(&mut T) -> Option<&mut U>,
|
||||
) -> Option<Self::Mut<U>>;
|
||||
|
||||
/// Map the mutable ref.
|
||||
fn map_mut<T: ?Sized, U: ?Sized + 'static>(
|
||||
mut_ref: Self::Mut<T>,
|
||||
f: impl FnOnce(&mut T) -> &mut U,
|
||||
) -> Self::Mut<U> {
|
||||
Self::try_map_mut(mut_ref, |v| Some(f(v))).unwrap()
|
||||
}
|
||||
|
||||
/// Try to map the ref.
|
||||
fn try_map<T, U: ?Sized + 'static>(
|
||||
ref_: Self::Ref<T>,
|
||||
f: impl FnOnce(&T) -> Option<&U>,
|
||||
) -> Option<Self::Ref<U>>;
|
||||
|
||||
/// Map the ref.
|
||||
fn map<T, U: ?Sized + 'static>(ref_: Self::Ref<T>, f: impl FnOnce(&T) -> &U) -> Self::Ref<U> {
|
||||
Self::try_map(ref_, |v| Some(f(v))).unwrap()
|
||||
}
|
||||
|
||||
/// Get the data pointer. No guarantees are made about the data pointer. It should only be used for debugging.
|
||||
fn data_ptr(&self) -> *const ();
|
||||
|
||||
|
||||
@@ -20,6 +20,54 @@ fn sync_runtime() -> &'static Arc<Mutex<Vec<MemoryLocation<SyncStorage>>>> {
|
||||
}
|
||||
|
||||
impl AnyStorage for SyncStorage {
|
||||
type Ref<R: ?Sized + 'static> = GenerationalRef<MappedRwLockReadGuard<'static, R>>;
|
||||
type Mut<W: ?Sized + 'static> = GenerationalRefMut<MappedRwLockWriteGuard<'static, W>>;
|
||||
|
||||
fn try_map<I, U: ?Sized + 'static>(
|
||||
ref_: Self::Ref<I>,
|
||||
f: impl FnOnce(&I) -> Option<&U>,
|
||||
) -> Option<Self::Ref<U>> {
|
||||
let GenerationalRef {
|
||||
inner,
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
borrow,
|
||||
..
|
||||
} = ref_;
|
||||
MappedRwLockReadGuard::try_map(inner, f)
|
||||
.ok()
|
||||
.map(|inner| GenerationalRef {
|
||||
inner,
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
borrow: crate::GenerationalRefBorrowInfo {
|
||||
borrowed_at: borrow.borrowed_at,
|
||||
borrowed_from: borrow.borrowed_from,
|
||||
created_at: borrow.created_at,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn try_map_mut<I: ?Sized, U: ?Sized + 'static>(
|
||||
mut_ref: Self::Mut<I>,
|
||||
f: impl FnOnce(&mut I) -> Option<&mut U>,
|
||||
) -> Option<Self::Mut<U>> {
|
||||
let GenerationalRefMut {
|
||||
inner,
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
borrow,
|
||||
..
|
||||
} = mut_ref;
|
||||
MappedRwLockWriteGuard::try_map(inner, f)
|
||||
.ok()
|
||||
.map(|inner| GenerationalRefMut {
|
||||
inner,
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
borrow: crate::GenerationalRefMutBorrowInfo {
|
||||
borrowed_from: borrow.borrowed_from,
|
||||
created_at: borrow.created_at,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn data_ptr(&self) -> *const () {
|
||||
self.0.data_ptr() as *const ()
|
||||
}
|
||||
@@ -49,9 +97,6 @@ impl AnyStorage for SyncStorage {
|
||||
}
|
||||
|
||||
impl<T: Sync + Send + 'static> Storage<T> for SyncStorage {
|
||||
type Ref<R: ?Sized + 'static> = GenerationalRef<MappedRwLockReadGuard<'static, R>>;
|
||||
type Mut<W: ?Sized + 'static> = GenerationalRefMut<MappedRwLockWriteGuard<'static, W>>;
|
||||
|
||||
fn try_read(
|
||||
&'static self,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
@@ -117,49 +162,4 @@ impl<T: Sync + Send + 'static> Storage<T> for SyncStorage {
|
||||
fn set(&self, value: T) {
|
||||
*self.0.write() = Some(Box::new(value));
|
||||
}
|
||||
|
||||
fn try_map<I, U: ?Sized + 'static>(
|
||||
ref_: Self::Ref<I>,
|
||||
f: impl FnOnce(&I) -> Option<&U>,
|
||||
) -> Option<Self::Ref<U>> {
|
||||
let GenerationalRef {
|
||||
inner,
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
borrow,
|
||||
..
|
||||
} = ref_;
|
||||
MappedRwLockReadGuard::try_map(inner, f)
|
||||
.ok()
|
||||
.map(|inner| GenerationalRef {
|
||||
inner,
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
borrow: crate::GenerationalRefBorrowInfo {
|
||||
borrowed_at: borrow.borrowed_at,
|
||||
borrowed_from: borrow.borrowed_from,
|
||||
created_at: borrow.created_at,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn try_map_mut<I, U: ?Sized + 'static>(
|
||||
mut_ref: Self::Mut<I>,
|
||||
f: impl FnOnce(&mut I) -> Option<&mut U>,
|
||||
) -> Option<Self::Mut<U>> {
|
||||
let GenerationalRefMut {
|
||||
inner,
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
borrow,
|
||||
..
|
||||
} = mut_ref;
|
||||
MappedRwLockWriteGuard::try_map(inner, f)
|
||||
.ok()
|
||||
.map(|inner| GenerationalRefMut {
|
||||
inner,
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
borrow: crate::GenerationalRefMutBorrowInfo {
|
||||
borrowed_from: borrow.borrowed_from,
|
||||
created_at: borrow.created_at,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,6 @@ use std::cell::{Ref, RefCell, RefMut};
|
||||
pub struct UnsyncStorage(RefCell<Option<Box<dyn std::any::Any>>>);
|
||||
|
||||
impl<T: 'static> Storage<T> for UnsyncStorage {
|
||||
type Ref<R: ?Sized + 'static> = GenerationalRef<Ref<'static, R>>;
|
||||
type Mut<W: ?Sized + 'static> = GenerationalRefMut<RefMut<'static, W>>;
|
||||
|
||||
fn try_read(
|
||||
&'static self,
|
||||
|
||||
@@ -78,6 +75,15 @@ impl<T: 'static> Storage<T> for UnsyncStorage {
|
||||
fn set(&self, value: T) {
|
||||
*self.0.borrow_mut() = Some(Box::new(value));
|
||||
}
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static UNSYNC_RUNTIME: RefCell<Vec<MemoryLocation<UnsyncStorage>>> = RefCell::new(Vec::new());
|
||||
}
|
||||
|
||||
impl AnyStorage for UnsyncStorage {
|
||||
type Ref<R: ?Sized + 'static> = GenerationalRef<Ref<'static, R>>;
|
||||
type Mut<W: ?Sized + 'static> = GenerationalRefMut<RefMut<'static, W>>;
|
||||
|
||||
fn try_map<I, U: ?Sized + 'static>(
|
||||
_self: Self::Ref<I>,
|
||||
@@ -96,7 +102,7 @@ impl<T: 'static> Storage<T> for UnsyncStorage {
|
||||
})
|
||||
}
|
||||
|
||||
fn try_map_mut<I, U: ?Sized + 'static>(
|
||||
fn try_map_mut<I: ?Sized, U: ?Sized + 'static>(
|
||||
mut_ref: Self::Mut<I>,
|
||||
f: impl FnOnce(&mut I) -> Option<&mut U>,
|
||||
) -> Option<Self::Mut<U>> {
|
||||
@@ -117,13 +123,7 @@ impl<T: 'static> Storage<T> for UnsyncStorage {
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static UNSYNC_RUNTIME: RefCell<Vec<MemoryLocation<UnsyncStorage>>> = RefCell::new(Vec::new());
|
||||
}
|
||||
|
||||
impl AnyStorage for UnsyncStorage {
|
||||
fn data_ptr(&self) -> *const () {
|
||||
self.0.as_ptr() as *const ()
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user