Moved World::{RC, IM} to it's own crate.

This commit is contained in:
Filipe Rodrigues 2025-04-19 21:51:27 +01:00
parent db7041df89
commit a3d54fb1e7
Signed by: zenithsiz
SSH Key Fingerprint: SHA256:Mb5ppb3Sh7IarBO/sBTXLHbYEOz37hJAlslLQPPAPaU
21 changed files with 160 additions and 103 deletions

9
Cargo.lock generated
View File

@ -253,6 +253,7 @@ dependencies = [
"duplicate",
"dynatos-context",
"dynatos-util",
"dynatos-world",
"extend",
"futures",
"itertools",
@ -309,6 +310,14 @@ dependencies = [
"extend",
]
[[package]]
name = "dynatos-world"
version = "0.1.0"
dependencies = [
"derive_more",
"parking_lot",
]
[[package]]
name = "ecolor"
version = "0.31.1"

View File

@ -14,6 +14,7 @@ members = [
"dynatos-router",
"dynatos-title",
"dynatos-util",
"dynatos-world",
]
resolver = "2"
@ -33,6 +34,7 @@ dynatos-reactive = { path = "dynatos-reactive" }
dynatos-router = { path = "dynatos-router" }
dynatos-title = { path = "dynatos-title" }
dynatos-util = { path = "dynatos-util" }
dynatos-world = { path = "dynatos-world" }
# zutil
zutil-cloned = { git = "https://github.com/Zenithsiz/zutil", rev = "978fa5df733d59fc691812ce2fa6072bf901dc7f" }

View File

@ -7,6 +7,7 @@ edition = "2021"
dynatos-context = { workspace = true }
dynatos-util = { workspace = true }
dynatos-world = { workspace = true }
derive_more = { workspace = true, features = ["full"] }
duplicate = { workspace = true }

View File

@ -2,23 +2,16 @@
// Imports
use {
crate::{
trigger::TriggerWorld,
world::{IMut, IMutLike, IMutRef, IMutRefMut, IMutRefMutLike, Rc, RcLike},
SignalBorrow,
SignalWith,
Trigger,
World,
WorldDefault,
},
crate::{trigger::TriggerWorld, ReactiveWorld, SignalBorrow, SignalWith, Trigger},
core::{fmt, future::Future, ops::Deref},
dynatos_world::{IMut, IMutLike, IMutRef, IMutRefMut, IMutRefMutLike, Rc, RcLike, WorldDefault},
futures::stream::AbortHandle,
tokio::sync::Notify,
};
/// World for [`AsyncSignal`]
#[expect(private_bounds, reason = "We can't *not* leak some implementation details currently")]
pub trait AsyncSignalWorld<F: Loader> = World + TriggerWorld where IMut<Inner<F, Self>, Self>: Sized;
pub trait AsyncSignalWorld<F: Loader> = ReactiveWorld + TriggerWorld where IMut<Inner<F, Self>, Self>: Sized;
/// Inner
struct Inner<F: Loader, W: AsyncSignalWorld<F>> {

View File

@ -33,25 +33,17 @@
// Imports
use {
crate::{
trigger::TriggerWorld,
world::{IMut, IMutLike, IMutRef, UnsizeF},
Effect,
SignalBorrow,
SignalWith,
Trigger,
World,
WorldDefault,
},
crate::{trigger::TriggerWorld, world::UnsizeF, Effect, ReactiveWorld, SignalBorrow, SignalWith, Trigger},
core::{
fmt,
marker::{PhantomData, Unsize},
ops::{CoerceUnsized, Deref},
},
dynatos_world::{IMut, IMutLike, IMutRef, WorldDefault},
};
/// World for [`Derived`]
pub trait DerivedWorld<T, F: ?Sized> = World + TriggerWorld where IMut<Option<T>, Self>: Sized;
pub trait DerivedWorld<T, F: ?Sized> = ReactiveWorld + TriggerWorld where IMut<Option<T>, Self>: Sized;
/// Derived signal.
///

View File

@ -11,9 +11,8 @@
use core::panic::Location;
use {
crate::{
world::{self, Rc, RcLike, UnsizeF, Weak, WeakLike},
World,
WorldDefault,
world::{self, UnsizeF},
ReactiveWorld,
},
core::{
fmt,
@ -22,11 +21,13 @@ use {
ops::CoerceUnsized,
sync::atomic::{self, AtomicBool},
},
dynatos_world::{Rc, RcLike, Weak, WeakLike, WorldDefault},
};
/// World for [`Effect`]
#[expect(private_bounds, reason = "We can't *not* leak some implementation details currently")]
pub trait EffectWorld = World where Weak<Inner<world::F<Self>>, Self>: CoerceUnsized<Weak<Inner<world::F<Self>>, Self>>;
pub trait EffectWorld =
ReactiveWorld where Weak<Inner<world::F<Self>>, Self>: CoerceUnsized<Weak<Inner<world::F<Self>>, Self>>;
/// Effect inner
struct Inner<F: ?Sized> {

View File

@ -48,5 +48,5 @@ pub use self::{
},
trigger::{IntoSubscriber, Subscriber, Trigger, WeakTrigger},
with_default::{SignalWithDefault, WithDefault},
world::{World, WorldDefault, WorldGlobal, WorldThreadLocal},
world::ReactiveWorld,
};

View File

@ -2,25 +2,17 @@
// Imports
use {
crate::{
trigger::TriggerWorld,
world::{IMut, IMutLike, IMutRef, UnsizeF},
Effect,
SignalBorrow,
SignalWith,
Trigger,
World,
WorldDefault,
},
crate::{trigger::TriggerWorld, world::UnsizeF, Effect, ReactiveWorld, SignalBorrow, SignalWith, Trigger},
core::{
fmt,
marker::{PhantomData, Unsize},
ops::{CoerceUnsized, Deref},
},
dynatos_world::{IMut, IMutLike, IMutRef, WorldDefault},
};
/// World for [`Memo`]
pub trait MemoWorld<T, F: ?Sized> = World + TriggerWorld where IMut<Option<T>, Self>: Sized;
pub trait MemoWorld<T, F: ?Sized> = ReactiveWorld + TriggerWorld where IMut<Option<T>, Self>: Sized;
/// Memo signal.
///

View File

@ -23,23 +23,18 @@ pub use ops::{
// Imports
use {
crate::{
trigger::TriggerWorld,
world::{IMut, IMutLike, IMutRef, IMutRefMut, Rc, RcLike},
Trigger,
World,
WorldDefault,
},
crate::{trigger::TriggerWorld, ReactiveWorld, Trigger},
core::{
fmt,
marker::Unsize,
mem,
ops::{CoerceUnsized, Deref, DerefMut},
},
dynatos_world::{IMut, IMutLike, IMutRef, IMutRefMut, Rc, RcLike, WorldDefault},
};
/// World for [`Signal`]
pub trait SignalWorld = World + TriggerWorld;
pub trait SignalWorld = ReactiveWorld + TriggerWorld;
/// Inner
struct Inner<T: ?Sized, W: SignalWorld> {

View File

@ -7,17 +7,17 @@
use {
crate::{
effect::{self, EffectWorld},
world::{self, IMut, IMutLike, Rc, RcLike, Weak, WeakLike},
world,
Effect,
ReactiveWorld,
WeakEffect,
World,
WorldDefault,
},
core::{
fmt,
hash::{Hash, Hasher},
ops::CoerceUnsized,
},
dynatos_world::{IMut, IMutLike, Rc, RcLike, Weak, WeakLike, WorldDefault},
std::collections::{hash_map, HashMap},
};
#[cfg(debug_assertions)]
@ -28,7 +28,7 @@ use {
/// World for [`Trigger`]
#[expect(private_bounds, reason = "We can't *not* leak some implementation details currently")]
pub trait TriggerWorld = World + EffectWorld where IMut<HashMap<Subscriber<Self>, SubscriberInfo>, Self>: Sized;
pub trait TriggerWorld = ReactiveWorld + EffectWorld where IMut<HashMap<Subscriber<Self>, SubscriberInfo>, Self>: Sized;
/// Subscribers
#[derive(Debug)]

View File

@ -11,74 +11,35 @@
// Modules
pub mod effect_stack;
pub mod imut;
pub mod rc;
// Exports
pub use self::{
effect_stack::{EffectStack, EffectStackGlobal, EffectStackThreadLocal},
imut::{IMutFamily, IMutLike, IMutRefLike, IMutRefMutLike, ParkingLotRwLock, StdRefcell},
rc::{RcFamily, RcLike, StdArc, StdRc, WeakLike},
};
pub use self::effect_stack::{EffectStack, EffectStackGlobal, EffectStackThreadLocal};
// Imports
use {
crate::{effect::EffectWorld, WeakEffect},
core::marker::Unsize,
dynatos_world::{World, WorldGlobal, WorldThreadLocal},
};
/// World
pub trait World: Sized + Clone + 'static {
/// Reference-counted pointer family
type RC: RcFamily;
/// Inner mutability family
type IM: IMutFamily;
/// Reactive world
pub trait ReactiveWorld: World {
/// Effect stack
type EF: EffectStack<Self>;
}
/// Thread-local world
#[derive(Clone, Copy, Default)]
pub struct WorldThreadLocal;
impl World for WorldThreadLocal {
impl ReactiveWorld for WorldThreadLocal {
type EF = EffectStackThreadLocal;
type IM = StdRefcell;
type RC = StdRc;
}
/// Global world
#[derive(Clone, Copy, Default)]
pub struct WorldGlobal;
impl World for WorldGlobal {
impl ReactiveWorld for WorldGlobal {
type EF = EffectStackGlobal;
type IM = ParkingLotRwLock;
type RC = StdArc;
}
/// The `Rc` of the world `W`
pub type Rc<T: ?Sized, W: World> = <W::RC as RcFamily>::Rc<T>;
/// The `Weak` of the world `W`
pub type Weak<T: ?Sized, W: World> = <W::RC as RcFamily>::Weak<T>;
/// The `IMut` of the world `W`
pub type IMut<T: ?Sized, W: World> = <W::IM as IMutFamily>::IMut<T>;
/// The `IMutRef` of the world `W`
pub type IMutRef<'a, T: ?Sized + 'a, W: World> = <IMut<T, W> as IMutLike<T>>::Ref<'a>;
/// The `IMutRefMut` of the world `W`
pub type IMutRefMut<'a, T: ?Sized + 'a, W: World> = <IMut<T, W> as IMutLike<T>>::RefMut<'a>;
/// The effect stack function type of the world `W`
pub type F<W: World> = <W::EF as EffectStack<W>>::F;
pub type F<W: ReactiveWorld> = <W::EF as EffectStack<W>>::F;
/// `Unsize` into the effect stack function of the world `W`
pub trait UnsizeF<W: World> = Unsize<F<W>>;
pub trait UnsizeF<W: ReactiveWorld> = Unsize<F<W>>;
/// Pushes an effect onto the effect stack of the world `W`
pub fn push_effect<F, W>(effect: WeakEffect<F, W>)
@ -105,6 +66,3 @@ where
{
W::EF::top_effect()
}
/// Default world
pub type WorldDefault = WorldThreadLocal;

View File

@ -2,13 +2,13 @@
// Imports
use {
super::{IMut, IMutLike, World, WorldGlobal, WorldThreadLocal},
crate::{effect::EffectWorld, WeakEffect},
crate::{effect::EffectWorld, ReactiveWorld, WeakEffect},
core::marker::Unsize,
dynatos_world::{IMut, IMutLike, WorldGlobal, WorldThreadLocal},
};
/// Effect stack
pub trait EffectStack<W: World>: Sized {
pub trait EffectStack<W: ReactiveWorld>: Sized {
/// Effect function
type F: ?Sized + Fn() + Unsize<Self::F> + 'static;

12
dynatos-world/Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "dynatos-world"
version = "0.1.0"
edition = "2021"
[dependencies]
derive_more = { workspace = true }
parking_lot = { workspace = true }
[lints]
workspace = true

80
dynatos-world/src/lib.rs Normal file
View File

@ -0,0 +1,80 @@
//! `dynatos`'s world types.
// Features
#![feature(
unsize,
coerce_unsized,
unboxed_closures,
fn_traits,
test,
thread_local,
cfg_match,
trait_alias,
once_cell_try,
async_fn_traits,
local_waker,
cell_update
)]
// Lints
#![expect(
type_alias_bounds,
reason = "Although they're not enforced currently, they will be in the future and we want to be explicit already"
)]
// TODO: Get rid of all of the `*World` types strewn about. They only exist because we can't provide
// the necessary bounds, such as `T: Unsize<U> => Rc<T>: CoerceUnsized<Rc<U>>`.
// Modules
pub mod imut;
pub mod rc;
// Exports
pub use self::{
imut::{IMutFamily, IMutLike, IMutRefLike, IMutRefMutLike, ParkingLotRwLock, StdRefcell},
rc::{RcFamily, RcLike, StdArc, StdRc, WeakLike},
};
/// World
pub trait World: Sized + Clone + 'static {
/// Reference-counted pointer family
type RC: RcFamily;
/// Inner mutability family
type IM: IMutFamily;
}
/// Thread-local world
#[derive(Clone, Copy, Default)]
pub struct WorldThreadLocal;
impl World for WorldThreadLocal {
type IM = StdRefcell;
type RC = StdRc;
}
/// Global world
#[derive(Clone, Copy, Default)]
pub struct WorldGlobal;
impl World for WorldGlobal {
type IM = ParkingLotRwLock;
type RC = StdArc;
}
/// The `Rc` of the world `W`
pub type Rc<T: ?Sized, W: World> = <W::RC as RcFamily>::Rc<T>;
/// The `Weak` of the world `W`
pub type Weak<T: ?Sized, W: World> = <W::RC as RcFamily>::Weak<T>;
/// The `IMut` of the world `W`
pub type IMut<T: ?Sized, W: World> = <W::IM as IMutFamily>::IMut<T>;
/// The `IMutRef` of the world `W`
pub type IMutRef<'a, T: ?Sized + 'a, W: World> = <IMut<T, W> as IMutLike<T>>::Ref<'a>;
/// The `IMutRefMut` of the world `W`
pub type IMutRefMut<'a, T: ?Sized + 'a, W: World> = <IMut<T, W> as IMutLike<T>>::RefMut<'a>;
/// Default world
pub type WorldDefault = WorldThreadLocal;

View File

@ -726,6 +726,7 @@ dependencies = [
"dynatos-egui",
"dynatos-reactive",
"dynatos-util",
"dynatos-world",
"eframe",
"extend",
"tracing",
@ -884,6 +885,7 @@ dependencies = [
"duplicate",
"dynatos-context",
"dynatos-util",
"dynatos-world",
"extend",
"futures",
"itertools",
@ -904,6 +906,14 @@ dependencies = [
"extend",
]
[[package]]
name = "dynatos-world"
version = "0.1.0"
dependencies = [
"derive_more",
"parking_lot",
]
[[package]]
name = "ecolor"
version = "0.31.1"

View File

@ -10,6 +10,7 @@ dynatos-context = { path = "../dynatos-context" }
dynatos-egui = { path = "../dynatos-egui" }
dynatos-reactive = { path = "../dynatos-reactive" }
dynatos-util = { path = "../dynatos-util" }
dynatos-world = { path = "../dynatos-world" }
anyhow = "1.0.98"
duplicate = "2.0.0"

View File

@ -8,6 +8,7 @@ edition = "2021"
dynatos-egui = { workspace = true }
dynatos-reactive = { workspace = true }
dynatos-util = { workspace = true }
dynatos-world = { workspace = true }
anyhow = { workspace = true }
eframe = { workspace = true }

View File

@ -6,7 +6,8 @@
// Imports
use {
dynatos_egui::EguiEffect,
dynatos_reactive::{Signal, SignalGet, SignalSet, SignalUpdate, WorldGlobal},
dynatos_reactive::{Signal, SignalGet, SignalSet, SignalUpdate},
dynatos_world::WorldGlobal,
eframe::egui,
std::time::Duration,
zutil_cloned::cloned,

9
examples/Cargo.lock generated
View File

@ -226,6 +226,7 @@ dependencies = [
"duplicate",
"dynatos-context",
"dynatos-util",
"dynatos-world",
"extend",
"futures",
"itertools",
@ -265,6 +266,14 @@ dependencies = [
"extend",
]
[[package]]
name = "dynatos-world"
version = "0.1.0"
dependencies = [
"derive_more",
"parking_lot",
]
[[package]]
name = "either"
version = "1.10.0"