Skip to content

Commit

Permalink
Impl rt crate feature
Browse files Browse the repository at this point in the history
  • Loading branch information
matthunz committed Dec 13, 2023
1 parent 585dfa6 commit 884cca8
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 118 deletions.
11 changes: 10 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,20 @@ description = "Cross-platform UI framework"
repository = "https://github.com/concoct-rs/concoct"

[features]
full = []
rt = []
full = ["rt"]

[dependencies]
futures = "0.3.29"
slotmap = "1.0.7"

[dev-dependencies]
tokio = { version = "1.35.0", features = ["full"] }

[package.metadata.docs.rs]
features = ["full"]
rustdoc-args = ["--cfg", "docsrs"]

[[example]]
name = "counter"
required-features = ["full"]
203 changes: 101 additions & 102 deletions src/context.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
use crate::{rt::AnyTask, Handle, Object, Runtime, Signal, SignalHandle, Slot, SlotHandle};
use futures::channel::mpsc;
use slotmap::DefaultKey;
use std::{
any::{Any, TypeId},
cell::RefCell,
marker::PhantomData,
rc::Rc,
};
use std::marker::PhantomData;

pub struct Context<T: ?Sized> {
key: DefaultKey,
Expand All @@ -23,110 +16,116 @@ impl<T> Clone for Context<T> {
}

impl<T> Context<T> {
pub(crate) fn new(key: DefaultKey) -> Self {
Self {
key,
_marker: PhantomData,
cfg_rt!(
pub(crate) fn new(key: DefaultKey) -> Self {
Self {
key,
_marker: PhantomData,
}
}
}

pub(crate) fn from_handle(handle: &Handle<T>) -> Self {
Self::new(handle.dropper.key)
}
pub(crate) fn from_handle(handle: &crate::Handle<T>) -> Self {
Self::new(handle.dropper.key)
}

pub fn send<M>(&self, msg: M)
where
T: Slot<M> + 'static,
M: 'static,
{
let key = self.key;
Runtime::current()
.tx
.unbounded_send(crate::rt::RuntimeMessage::Handle {
key,
f: Box::new(move |any_task| {
let task = any_task.as_any_mut().downcast_mut::<T>().unwrap();
task.handle(Context::new(key), msg);
}),
})
.unwrap();
}
pub fn send<M>(&self, msg: M)
where
T: crate::Slot<M> + 'static,
M: 'static,
{
let key = self.key;
crate::Runtime::current()
.tx
.unbounded_send(crate::rt::RuntimeMessage::Handle {
key,
f: Box::new(move |any_task| {
let task = any_task.as_any_mut().downcast_mut::<T>().unwrap();
task.handle(Context::new(key), msg);
}),
})
.unwrap();
}

pub fn listen<M>(&self, mut f: impl FnMut(&M) + 'static)
where
T: Signal<M>,
M: 'static,
{
Runtime::current().inner.borrow_mut().listeners.insert(
(self.key, TypeId::of::<M>()),
vec![Rc::new(RefCell::new(move |msg: &dyn Any| {
f(msg.downcast_ref().unwrap())
}))],
);
}
pub fn listen<M>(&self, mut f: impl FnMut(&M) + 'static)
where
T: crate::Signal<M>,
M: 'static,
{
crate::Runtime::current()
.inner
.borrow_mut()
.listeners
.insert(
(self.key, std::any::TypeId::of::<M>()),
vec![std::rc::Rc::new(std::cell::RefCell::new(
move |msg: &dyn std::any::Any| f(msg.downcast_ref().unwrap()),
))],
);
}

pub fn bind<M>(&self, other: &Context<impl Object + Slot<M> + 'static>)
where
T: Signal<M>,
M: Clone + 'static,
{
let other = other.clone();
pub fn bind<M>(&self, other: &Context<impl crate::Object + crate::Slot<M> + 'static>)
where
T: crate::Signal<M>,
M: Clone + 'static,
{
let other = other.clone();

self.listen(move |msg: &M| {
other.send(msg.clone());
});
}
self.listen(move |msg: &M| {
other.send(msg.clone());
});
}

pub fn channel<M>(&self) -> mpsc::UnboundedReceiver<M>
where
T: Signal<M>,
M: Clone + 'static,
{
let (tx, rx) = mpsc::unbounded();
self.listen(move |msg: &M| {
tx.unbounded_send(msg.clone()).unwrap();
});
rx
}
pub fn channel<M>(&self) -> futures::channel::mpsc::UnboundedReceiver<M>
where
T: crate::Signal<M>,
M: Clone + 'static,
{
let (tx, rx) = futures::channel::mpsc::unbounded();
self.listen(move |msg: &M| {
tx.unbounded_send(msg.clone()).unwrap();
});
rx
}

pub fn emit<M>(&self, msg: M)
where
T: Signal<M> + 'static,
M: 'static,
{
let key = self.key;
Runtime::current()
.tx
.unbounded_send(crate::rt::RuntimeMessage::Signal {
key,
msg: Box::new(msg),
})
.unwrap();
}
pub fn emit<M>(&self, msg: M)
where
T: crate::Signal<M> + 'static,
M: 'static,
{
let key = self.key;
crate::Runtime::current()
.tx
.unbounded_send(crate::rt::RuntimeMessage::Signal {
key,
msg: Box::new(msg),
})
.unwrap();
}

pub fn signal<M>(&self) -> SignalHandle<M> {
let key = self.key;
SignalHandle {
key: key,
_marker: PhantomData,
pub fn signal<M>(&self) -> crate::SignalHandle<M> {
let key = self.key;
crate::SignalHandle {
key: key,
_marker: PhantomData,
}
}
}

pub fn slot<M>(&self) -> SlotHandle<M>
where
T: Slot<M> + 'static,
M: 'static,
{
let key = self.key;
SlotHandle {
key,
f: Rc::new(RefCell::new(
move |any_task: &mut dyn AnyTask, msg: Box<dyn Any>| {
let task = any_task.as_any_mut().downcast_mut::<T>().unwrap();
task.handle(Context::new(key), *msg.downcast().unwrap());
},
)),
_marker: PhantomData,
pub fn slot<M>(&self) -> crate::SlotHandle<M>
where
T: crate::Slot<M> + 'static,
M: 'static,
{
let key = self.key;
crate::SlotHandle {
key,
f: std::rc::Rc::new(std::cell::RefCell::new(
move |any_task: &mut dyn crate::rt::AnyTask, msg: Box<dyn std::any::Any>| {
let task = any_task.as_any_mut().downcast_mut::<T>().unwrap();
task.handle(Context::new(key), *msg.downcast().unwrap());
},
)),
_marker: PhantomData,
}
}
}
);
}
30 changes: 22 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
mod handle;
pub use self::handle::Handle;
#![cfg_attr(docsrs, feature(doc_cfg))]

macro_rules! cfg_rt {
($($i:item)*) => {
$(
#[cfg(feature = "rt")]
#[cfg_attr(docsrs, doc(cfg(feature = "rt")))]
$i
)*
};
}

mod context;
pub use self::context::Context;

mod object;
pub use self::object::Object;

mod rt;
pub use self::rt::{Runtime, RuntimeGuard};
cfg_rt!(
mod handle;
pub use self::handle::Handle;

mod rt;
pub use self::rt::{Runtime, RuntimeGuard};

mod slot_handle;
pub use slot_handle::SlotHandle;
mod slot_handle;
pub use slot_handle::SlotHandle;

mod signal_handle;
pub use signal_handle::SignalHandle;
mod signal_handle;
pub use signal_handle::SignalHandle;
);

pub trait Signal<M>: Object {}

Expand Down
16 changes: 9 additions & 7 deletions src/object.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use crate::{Context, Handle, Runtime};
use crate::Context;

pub trait Object {
#[allow(unused_variables)]
fn start(&mut self, cx: Context<Self>) {}

fn spawn(self) -> Handle<Self>
where
Self: Sized + 'static,
{
Runtime::current().spawn(self)
}
cfg_rt!(
fn spawn(self) -> crate::Handle<Self>
where
Self: Sized + 'static,
{
crate::Runtime::current().spawn(self)
}
);
}

0 comments on commit 884cca8

Please sign in to comment.