use std::marker::PhantomData;
use std::rc::Rc;
use crate::context::{Compute, SlotId};
use crate::{Computed, Context, Source};
#[cfg(feature = "thread-safe")]
use crate::ThreadSafeContext;
#[cfg(feature = "thread-safe")]
use crate::{Read, Write};
pub struct TypedContext<Schema> {
inner: Context,
_schema: PhantomData<fn() -> Schema>,
}
pub struct TypedContextRef<'a, Schema> {
inner: &'a Context,
track: Option<SlotId>,
_schema: PhantomData<fn() -> Schema>,
}
pub struct TypedSlotHandle<Schema, T> {
raw: Computed<T>,
_schema: PhantomData<fn() -> Schema>,
}
pub struct TypedCellHandle<Schema, T> {
raw: Source<T>,
_schema: PhantomData<fn() -> Schema>,
}
pub trait TypedGet<Schema, Kind> {
type Output;
fn get_typed(self, ctx: &TypedContext<Schema>) -> Self::Output;
}
pub trait TypedGetRef<Schema, Kind> {
type Output;
fn get_typed_ref(self, ctx: &TypedContextRef<'_, Schema>) -> Self::Output;
}
pub trait TypedSet<Schema, T, Kind> {
fn set_typed(self, ctx: &TypedContext<Schema>, value: T);
}
pub trait TypedContextFamily {
type Schema: 'static;
}
pub struct TypedSlotHandleSource;
pub struct TypedCellHandleSource;
pub struct TypedSlotFactorySource;
pub struct TypedCellFactorySource;
pub trait TypedFactoryContext {
type Schema: 'static;
fn memoized_slot<K, T, F>(&self, compute: F) -> TypedSlotHandle<Self::Schema, T>
where
K: 'static,
T: 'static,
F: for<'a> Fn(&TypedContextRef<'a, Self::Schema>) -> T + 'static;
fn memoized_cell<K, T, F>(&self, init: F) -> TypedCellHandle<Self::Schema, T>
where
K: 'static,
T: PartialEq + 'static,
F: for<'a> FnOnce(&TypedContextRef<'a, Self::Schema>) -> T;
}
#[cfg(feature = "thread-safe")]
pub struct TypedThreadSafeContext<Schema> {
inner: ThreadSafeContext,
_schema: PhantomData<fn() -> Schema>,
}
#[cfg(feature = "thread-safe")]
pub struct TypedThreadSafeContextRef<'a, Schema> {
inner: &'a ThreadSafeContext,
_schema: PhantomData<fn() -> Schema>,
}
#[cfg(feature = "thread-safe")]
pub struct TypedThreadSafeSlotHandle<Schema, T> {
raw: Computed<T>,
_schema: PhantomData<fn() -> Schema>,
}
#[cfg(feature = "thread-safe")]
pub struct TypedThreadSafeCellHandle<Schema, T> {
raw: Source<T>,
_schema: PhantomData<fn() -> Schema>,
}
impl<Schema> TypedContext<Schema> {
pub fn new() -> Self {
Self {
inner: Context::new(),
_schema: PhantomData,
}
}
pub fn raw(&self) -> &Context {
&self.inner
}
pub fn as_ref(&self) -> TypedContextRef<'_, Schema> {
TypedContextRef::detached(&self.inner)
}
pub fn cell<T>(&self, value: T) -> TypedCellHandle<Schema, T>
where
T: PartialEq + 'static,
{
TypedCellHandle::new(self.inner.cell(value))
}
pub fn slot<T, F>(&self, compute: F) -> TypedSlotHandle<Schema, T>
where
T: 'static,
F: for<'a> Fn(&TypedContextRef<'a, Schema>) -> T + 'static,
{
let raw = self.inner.slot(move |ctx| {
let typed = TypedContextRef::from_compute(ctx);
compute(&typed)
});
TypedSlotHandle::new(raw)
}
pub fn computed<T, F>(&self, compute: F) -> TypedSlotHandle<Schema, T>
where
T: PartialEq + 'static,
F: for<'a> Fn(&TypedContextRef<'a, Schema>) -> T + 'static,
{
let raw = self.inner.computed(move |ctx| {
let typed = TypedContextRef::from_compute(ctx);
compute(&typed)
});
TypedSlotHandle::new(raw)
}
pub fn memoized_slot<K, T, F>(&self, compute: F) -> TypedSlotHandle<Schema, T>
where
K: 'static,
T: 'static,
F: for<'a> Fn(&TypedContextRef<'a, Schema>) -> T + 'static,
Schema: 'static,
{
<Self as TypedFactoryContext>::memoized_slot::<K, T, F>(self, compute)
}
pub fn memoized_cell<K, T, F>(&self, init: F) -> TypedCellHandle<Schema, T>
where
K: 'static,
T: PartialEq + 'static,
F: for<'a> FnOnce(&TypedContextRef<'a, Schema>) -> T,
Schema: 'static,
{
<Self as TypedFactoryContext>::memoized_cell::<K, T, F>(self, init)
}
pub fn get<S, Kind>(&self, source: S) -> S::Output
where
S: TypedGet<Schema, Kind>,
{
source.get_typed(self)
}
pub fn get_rc<T>(&self, handle: &TypedSlotHandle<Schema, T>) -> Rc<T>
where
T: 'static,
{
self.inner.get_rc(&handle.raw)
}
pub fn get_cell<T>(&self, handle: &TypedCellHandle<Schema, T>) -> T
where
T: Clone + 'static,
{
self.inner.get(&handle.raw)
}
pub fn get_cell_rc<T>(&self, handle: &TypedCellHandle<Schema, T>) -> Rc<T>
where
T: 'static,
{
self.inner.get_rc(&handle.raw)
}
pub fn set_cell<T>(&self, handle: &TypedCellHandle<Schema, T>, value: T)
where
T: PartialEq + 'static,
{
self.inner.set(&handle.raw, value);
}
pub fn set<S, T, Kind>(&self, source: S, value: T)
where
S: TypedSet<Schema, T, Kind>,
{
source.set_typed(self, value);
}
pub fn is_set<T>(&self, handle: &TypedSlotHandle<Schema, T>) -> bool
where
T: 'static,
{
self.inner.is_set(&handle.raw)
}
}
impl<Schema> Default for TypedContext<Schema> {
fn default() -> Self {
Self::new()
}
}
impl<Schema: 'static> TypedContextFamily for TypedContext<Schema> {
type Schema = Schema;
}
impl<Schema: 'static> TypedFactoryContext for TypedContext<Schema> {
type Schema = Schema;
fn memoized_slot<K, T, F>(&self, compute: F) -> TypedSlotHandle<Self::Schema, T>
where
K: 'static,
T: 'static,
F: for<'a> Fn(&TypedContextRef<'a, Self::Schema>) -> T + 'static,
{
let raw = self.inner.memoized_slot::<K, T, _>(move |ctx| {
let typed = TypedContextRef::from_compute(ctx);
compute(&typed)
});
TypedSlotHandle::new(raw)
}
fn memoized_cell<K, T, F>(&self, init: F) -> TypedCellHandle<Self::Schema, T>
where
K: 'static,
T: PartialEq + 'static,
F: for<'a> FnOnce(&TypedContextRef<'a, Self::Schema>) -> T,
{
let raw = self.inner.memoized_cell::<K, T, _>(move |ctx| {
let typed = TypedContextRef::from_compute(ctx);
init(&typed)
});
TypedCellHandle::new(raw)
}
}
impl<'a, Schema> TypedContextRef<'a, Schema> {
fn from_compute(cx: &Compute<'a>) -> Self {
Self {
inner: cx.untracked(),
track: Some(cx.slot_id()),
_schema: PhantomData,
}
}
fn detached(inner: &'a Context) -> Self {
Self {
inner,
track: None,
_schema: PhantomData,
}
}
fn ops(&self) -> Compute<'_> {
Compute::new(self.inner, self.track.unwrap_or(SlotId::DETACHED), 0)
}
pub fn raw(&self) -> &'a Context {
self.inner
}
pub fn get<S, Kind>(&self, source: S) -> S::Output
where
S: TypedGetRef<Schema, Kind>,
{
source.get_typed_ref(self)
}
pub fn get_rc<T>(&self, handle: &TypedSlotHandle<Schema, T>) -> Rc<T>
where
T: 'static,
{
self.ops().get_rc(&handle.raw)
}
pub fn get_cell<T>(&self, handle: &TypedCellHandle<Schema, T>) -> T
where
T: Clone + 'static,
{
handle.raw.get(&self.ops())
}
pub fn get_cell_rc<T>(&self, handle: &TypedCellHandle<Schema, T>) -> Rc<T>
where
T: 'static,
{
if let Some(node) = self.track {
self.inner.register_dependency(handle.raw.id, node);
}
self.inner.get_rc(&handle.raw)
}
pub fn memoized_slot<K, T, F>(&self, compute: F) -> TypedSlotHandle<Schema, T>
where
K: 'static,
T: 'static,
F: for<'b> Fn(&TypedContextRef<'b, Schema>) -> T + 'static,
Schema: 'static,
{
<Self as TypedFactoryContext>::memoized_slot::<K, T, F>(self, compute)
}
pub fn memoized_cell<K, T, F>(&self, init: F) -> TypedCellHandle<Schema, T>
where
K: 'static,
T: PartialEq + 'static,
F: for<'b> FnOnce(&TypedContextRef<'b, Schema>) -> T,
Schema: 'static,
{
<Self as TypedFactoryContext>::memoized_cell::<K, T, F>(self, init)
}
}
impl<Schema: 'static> TypedContextFamily for TypedContextRef<'_, Schema> {
type Schema = Schema;
}
impl<Schema: 'static> TypedFactoryContext for TypedContextRef<'_, Schema> {
type Schema = Schema;
fn memoized_slot<K, T, F>(&self, compute: F) -> TypedSlotHandle<Self::Schema, T>
where
K: 'static,
T: 'static,
F: for<'a> Fn(&TypedContextRef<'a, Self::Schema>) -> T + 'static,
{
let raw = self.inner.memoized_slot::<K, T, _>(move |ctx| {
let typed = TypedContextRef::from_compute(ctx);
compute(&typed)
});
TypedSlotHandle::new(raw)
}
fn memoized_cell<K, T, F>(&self, init: F) -> TypedCellHandle<Self::Schema, T>
where
K: 'static,
T: PartialEq + 'static,
F: for<'a> FnOnce(&TypedContextRef<'a, Self::Schema>) -> T,
{
let raw = self.inner.memoized_cell::<K, T, _>(move |ctx| {
let typed = TypedContextRef::from_compute(ctx);
init(&typed)
});
TypedCellHandle::new(raw)
}
}
impl<Schema, T> TypedGet<Schema, TypedSlotHandleSource> for &TypedSlotHandle<Schema, T>
where
T: Clone + 'static,
{
type Output = T;
fn get_typed(self, ctx: &TypedContext<Schema>) -> Self::Output {
ctx.inner.get(&self.raw)
}
}
impl<Schema, T> TypedGet<Schema, TypedSlotHandleSource> for TypedSlotHandle<Schema, T>
where
T: Clone + 'static,
{
type Output = T;
fn get_typed(self, ctx: &TypedContext<Schema>) -> Self::Output {
ctx.inner.get(&self.raw)
}
}
impl<Schema, T> TypedGetRef<Schema, TypedSlotHandleSource> for &TypedSlotHandle<Schema, T>
where
T: Clone + 'static,
{
type Output = T;
fn get_typed_ref(self, ctx: &TypedContextRef<'_, Schema>) -> Self::Output {
self.raw.get(&ctx.ops())
}
}
impl<Schema, T> TypedGetRef<Schema, TypedSlotHandleSource> for TypedSlotHandle<Schema, T>
where
T: Clone + 'static,
{
type Output = T;
fn get_typed_ref(self, ctx: &TypedContextRef<'_, Schema>) -> Self::Output {
self.raw.get(&ctx.ops())
}
}
impl<Schema, T> TypedGet<Schema, TypedCellHandleSource> for &TypedCellHandle<Schema, T>
where
T: Clone + 'static,
{
type Output = T;
fn get_typed(self, ctx: &TypedContext<Schema>) -> Self::Output {
ctx.inner.get(&self.raw)
}
}
impl<Schema, T> TypedGet<Schema, TypedCellHandleSource> for TypedCellHandle<Schema, T>
where
T: Clone + 'static,
{
type Output = T;
fn get_typed(self, ctx: &TypedContext<Schema>) -> Self::Output {
ctx.inner.get(&self.raw)
}
}
impl<Schema, T> TypedGetRef<Schema, TypedCellHandleSource> for &TypedCellHandle<Schema, T>
where
T: Clone + 'static,
{
type Output = T;
fn get_typed_ref(self, ctx: &TypedContextRef<'_, Schema>) -> Self::Output {
self.raw.get(&ctx.ops())
}
}
impl<Schema, T> TypedGetRef<Schema, TypedCellHandleSource> for TypedCellHandle<Schema, T>
where
T: Clone + 'static,
{
type Output = T;
fn get_typed_ref(self, ctx: &TypedContextRef<'_, Schema>) -> Self::Output {
self.raw.get(&ctx.ops())
}
}
impl<Schema: 'static, T, F> TypedGet<Schema, TypedSlotFactorySource> for F
where
T: Clone + 'static,
F: Fn(&TypedContext<Schema>) -> TypedSlotHandle<Schema, T>,
{
type Output = T;
fn get_typed(self, ctx: &TypedContext<Schema>) -> Self::Output {
let handle = self(ctx);
ctx.inner.get(&handle.raw)
}
}
impl<Schema: 'static, T, F> TypedGetRef<Schema, TypedSlotFactorySource> for F
where
T: Clone + 'static,
F: for<'a> Fn(&TypedContextRef<'a, Schema>) -> TypedSlotHandle<Schema, T>,
{
type Output = T;
fn get_typed_ref(self, ctx: &TypedContextRef<'_, Schema>) -> Self::Output {
let handle = self(ctx);
handle.raw.get(&ctx.ops())
}
}
impl<Schema: 'static, T, F> TypedGet<Schema, TypedCellFactorySource> for F
where
T: Clone + 'static,
F: Fn(&TypedContext<Schema>) -> TypedCellHandle<Schema, T>,
{
type Output = T;
fn get_typed(self, ctx: &TypedContext<Schema>) -> Self::Output {
let handle = self(ctx);
ctx.inner.get(&handle.raw)
}
}
impl<Schema: 'static, T, F> TypedGetRef<Schema, TypedCellFactorySource> for F
where
T: Clone + 'static,
F: for<'a> Fn(&TypedContextRef<'a, Schema>) -> TypedCellHandle<Schema, T>,
{
type Output = T;
fn get_typed_ref(self, ctx: &TypedContextRef<'_, Schema>) -> Self::Output {
let handle = self(ctx);
handle.raw.get(&ctx.ops())
}
}
impl<Schema, T> TypedSet<Schema, T, TypedCellHandleSource> for &TypedCellHandle<Schema, T>
where
T: PartialEq + 'static,
{
fn set_typed(self, ctx: &TypedContext<Schema>, value: T) {
ctx.inner.set(&self.raw, value);
}
}
impl<Schema, T> TypedSet<Schema, T, TypedCellHandleSource> for TypedCellHandle<Schema, T>
where
T: PartialEq + 'static,
{
fn set_typed(self, ctx: &TypedContext<Schema>, value: T) {
ctx.inner.set(&self.raw, value);
}
}
impl<Schema: 'static, T, F> TypedSet<Schema, T, TypedCellFactorySource> for F
where
T: PartialEq + 'static,
F: Fn(&TypedContext<Schema>) -> TypedCellHandle<Schema, T>,
{
fn set_typed(self, ctx: &TypedContext<Schema>, value: T) {
let handle = self(ctx);
ctx.inner.set(&handle.raw, value);
}
}
impl<Schema, T> TypedSlotHandle<Schema, T> {
fn new(raw: Computed<T>) -> Self {
Self {
raw,
_schema: PhantomData,
}
}
pub fn raw(&self) -> Computed<T> {
self.raw
}
pub fn get(&self, ctx: &TypedContext<Schema>) -> T
where
T: Clone + 'static,
{
ctx.get(self)
}
pub fn get_ref(&self, ctx: &TypedContextRef<'_, Schema>) -> T
where
T: Clone + 'static,
{
ctx.get(self)
}
pub fn clear(&self, ctx: &TypedContext<Schema>) {
ctx.inner.clear_slot(self.raw.id);
ctx.inner.flush_effects_after_invalidation();
}
}
impl<Schema, T> Clone for TypedSlotHandle<Schema, T> {
fn clone(&self) -> Self {
*self
}
}
impl<Schema, T> Copy for TypedSlotHandle<Schema, T> {}
impl<Schema, T> TypedCellHandle<Schema, T> {
fn new(raw: Source<T>) -> Self {
Self {
raw,
_schema: PhantomData,
}
}
pub fn raw(&self) -> Source<T> {
self.raw
}
pub fn get(&self, ctx: &TypedContext<Schema>) -> T
where
T: Clone + 'static,
{
ctx.get(self)
}
pub fn get_ref(&self, ctx: &TypedContextRef<'_, Schema>) -> T
where
T: Clone + 'static,
{
ctx.get(self)
}
pub fn set(&self, ctx: &TypedContext<Schema>, value: T)
where
T: PartialEq + 'static,
{
ctx.set(self, value);
}
pub fn clear_dependents(&self, ctx: &TypedContext<Schema>) {
ctx.inner.clear_cell_dependents(self.raw.id);
}
}
impl<Schema, T> Clone for TypedCellHandle<Schema, T> {
fn clone(&self) -> Self {
*self
}
}
impl<Schema, T> Copy for TypedCellHandle<Schema, T> {}
#[cfg(feature = "thread-safe")]
impl<Schema> TypedThreadSafeContext<Schema> {
pub fn new() -> Self {
Self {
inner: ThreadSafeContext::new(),
_schema: PhantomData,
}
}
pub fn raw(&self) -> &ThreadSafeContext {
&self.inner
}
pub fn as_ref(&self) -> TypedThreadSafeContextRef<'_, Schema> {
TypedThreadSafeContextRef::new(&self.inner)
}
pub fn cell<T>(&self, value: T) -> TypedThreadSafeCellHandle<Schema, T>
where
T: PartialEq + Send + Sync + 'static,
{
TypedThreadSafeCellHandle::new(self.inner.source(value))
}
pub fn slot<T, F>(&self, compute: F) -> TypedThreadSafeSlotHandle<Schema, T>
where
T: Send + Sync + 'static,
F: for<'a> Fn(&TypedThreadSafeContextRef<'a, Schema>) -> T + Send + Sync + 'static,
{
let raw = self.inner.slot(move |ctx| {
let typed = TypedThreadSafeContextRef::new(ctx);
compute(&typed)
});
TypedThreadSafeSlotHandle::new(raw)
}
pub fn computed<T, F>(&self, compute: F) -> TypedThreadSafeSlotHandle<Schema, T>
where
T: PartialEq + Send + Sync + 'static,
F: for<'a> Fn(&TypedThreadSafeContextRef<'a, Schema>) -> T + Send + Sync + 'static,
{
let raw = self.inner.computed(move |ctx| {
let typed = TypedThreadSafeContextRef::new(ctx);
compute(&typed)
});
TypedThreadSafeSlotHandle::new(raw)
}
pub fn get<H: Read<Self> + ?Sized>(&self, handle: &H) -> <H as Read<Self>>::Output {
handle.read(self)
}
pub fn set<H: Write<Self> + ?Sized>(&self, handle: &H, value: <H as Write<Self>>::Value) {
handle.write(self, value)
}
#[deprecated(note = "use `TypedThreadSafeContext::get` (#lzcellkernel)")]
pub fn get_cell<T>(&self, handle: &TypedThreadSafeCellHandle<Schema, T>) -> T
where
T: Clone + Send + Sync + 'static,
{
self.get(handle)
}
#[deprecated(note = "use `TypedThreadSafeContext::set` (#lzcellkernel)")]
pub fn set_cell<T>(&self, handle: &TypedThreadSafeCellHandle<Schema, T>, value: T)
where
T: PartialEq + Send + Sync + 'static,
{
self.set(handle, value);
}
pub fn is_set<T>(&self, handle: &TypedThreadSafeSlotHandle<Schema, T>) -> bool
where
T: Send + Sync + 'static,
{
self.inner.is_set(&handle.raw)
}
}
#[cfg(feature = "thread-safe")]
impl<Schema, T: Clone + Send + Sync + 'static> Read<TypedThreadSafeContext<Schema>>
for TypedThreadSafeSlotHandle<Schema, T>
{
type Output = T;
fn read(&self, ctx: &TypedThreadSafeContext<Schema>) -> T {
ctx.inner.get(&self.raw)
}
}
#[cfg(feature = "thread-safe")]
impl<Schema, T: Clone + Send + Sync + 'static> Read<TypedThreadSafeContext<Schema>>
for TypedThreadSafeCellHandle<Schema, T>
{
type Output = T;
fn read(&self, ctx: &TypedThreadSafeContext<Schema>) -> T {
ctx.inner.get(&self.raw)
}
}
#[cfg(feature = "thread-safe")]
impl<Schema, T: PartialEq + Send + Sync + 'static> Write<TypedThreadSafeContext<Schema>>
for TypedThreadSafeCellHandle<Schema, T>
{
type Value = T;
fn write(&self, ctx: &TypedThreadSafeContext<Schema>, value: T) {
ctx.inner.set(&self.raw, value);
}
}
#[cfg(feature = "thread-safe")]
impl<Schema> Clone for TypedThreadSafeContext<Schema> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
_schema: PhantomData,
}
}
}
#[cfg(feature = "thread-safe")]
impl<Schema> Default for TypedThreadSafeContext<Schema> {
fn default() -> Self {
Self::new()
}
}
#[cfg(feature = "thread-safe")]
impl<'a, Schema> TypedThreadSafeContextRef<'a, Schema> {
fn new(inner: &'a ThreadSafeContext) -> Self {
Self {
inner,
_schema: PhantomData,
}
}
pub fn raw(&self) -> &'a ThreadSafeContext {
self.inner
}
pub fn get<H: Read<Self> + ?Sized>(&self, handle: &H) -> <H as Read<Self>>::Output {
handle.read(self)
}
#[deprecated(note = "use `TypedThreadSafeContextRef::get` (#lzcellkernel)")]
pub fn get_cell<T>(&self, handle: &TypedThreadSafeCellHandle<Schema, T>) -> T
where
T: Clone + Send + Sync + 'static,
{
self.get(handle)
}
}
#[cfg(feature = "thread-safe")]
impl<'a, Schema, T: Clone + Send + Sync + 'static> Read<TypedThreadSafeContextRef<'a, Schema>>
for TypedThreadSafeSlotHandle<Schema, T>
{
type Output = T;
fn read(&self, ctx: &TypedThreadSafeContextRef<'a, Schema>) -> T {
ctx.inner.get(&self.raw)
}
}
#[cfg(feature = "thread-safe")]
impl<'a, Schema, T: Clone + Send + Sync + 'static> Read<TypedThreadSafeContextRef<'a, Schema>>
for TypedThreadSafeCellHandle<Schema, T>
{
type Output = T;
fn read(&self, ctx: &TypedThreadSafeContextRef<'a, Schema>) -> T {
ctx.inner.get(&self.raw)
}
}
#[cfg(feature = "thread-safe")]
impl<Schema, T> TypedThreadSafeSlotHandle<Schema, T> {
fn new(raw: Computed<T>) -> Self {
Self {
raw,
_schema: PhantomData,
}
}
pub fn raw(&self) -> Computed<T> {
self.raw
}
pub fn get(&self, ctx: &TypedThreadSafeContext<Schema>) -> T
where
T: Clone + Send + Sync + 'static,
{
ctx.get(self)
}
pub fn get_ref(&self, ctx: &TypedThreadSafeContextRef<'_, Schema>) -> T
where
T: Clone + Send + Sync + 'static,
{
ctx.get(self)
}
pub fn clear(&self, ctx: &TypedThreadSafeContext<Schema>) {
ctx.inner.clear(&self.raw);
}
}
#[cfg(feature = "thread-safe")]
impl<Schema, T> Clone for TypedThreadSafeSlotHandle<Schema, T> {
fn clone(&self) -> Self {
*self
}
}
#[cfg(feature = "thread-safe")]
impl<Schema, T> Copy for TypedThreadSafeSlotHandle<Schema, T> {}
#[cfg(feature = "thread-safe")]
impl<Schema, T> TypedThreadSafeCellHandle<Schema, T> {
fn new(raw: Source<T>) -> Self {
Self {
raw,
_schema: PhantomData,
}
}
pub fn raw(&self) -> Source<T> {
self.raw
}
pub fn get(&self, ctx: &TypedThreadSafeContext<Schema>) -> T
where
T: Clone + Send + Sync + 'static,
{
ctx.raw().get(&self.raw)
}
pub fn get_ref(&self, ctx: &TypedThreadSafeContextRef<'_, Schema>) -> T
where
T: Clone + Send + Sync + 'static,
{
ctx.raw().get(&self.raw)
}
pub fn set(&self, ctx: &TypedThreadSafeContext<Schema>, value: T)
where
T: PartialEq + Send + Sync + 'static,
{
ctx.raw().set(&self.raw, value);
}
pub fn clear_dependents(&self, ctx: &TypedThreadSafeContext<Schema>) {
ctx.inner.clear_cell_dependents(&self.raw);
}
}
#[cfg(feature = "thread-safe")]
impl<Schema, T> Clone for TypedThreadSafeCellHandle<Schema, T> {
fn clone(&self) -> Self {
*self
}
}
#[cfg(feature = "thread-safe")]
impl<Schema, T> Copy for TypedThreadSafeCellHandle<Schema, T> {}
#[cfg(test)]
mod tests {
use super::*;
enum CycleSchema {}
#[test]
fn typed_context_binds_slot_and_cell_handles_to_schema() {
let ctx = TypedContext::<CycleSchema>::new();
let input = ctx.cell(2);
let doubled = ctx.slot(move |ctx| ctx.get(&input) * 2);
assert_eq!(ctx.get(&doubled), 4);
ctx.set(input, 3);
assert_eq!(doubled.get(&ctx), 6);
}
#[cfg(feature = "thread-safe")]
#[test]
fn typed_thread_safe_context_binds_slot_and_cell_handles_to_schema() {
let ctx = TypedThreadSafeContext::<CycleSchema>::new();
let input = ctx.cell(2);
let doubled = ctx.slot(move |ctx| ctx.get(&input) * 2);
assert_eq!(ctx.get(&doubled), 4);
ctx.set(&input, 3);
assert_eq!(doubled.get(&ctx), 6);
}
}