Skip to content

Commit

Permalink
Impl no-std support
Browse files Browse the repository at this point in the history
  • Loading branch information
matthunz committed Dec 13, 2023
1 parent 8f2fb8e commit 5af395c
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 45 deletions.
10 changes: 6 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ repository = "https://github.com/concoct-rs/concoct"

[features]
std = []
rt = []
futures = ["std"]
rt = ["std"]
futures = ["std", "dep:futures"]
full = ["rt", "futures"]

[dependencies]
futures = "0.3.29"
slotmap = "1.0.7"
futures = { version = "0.3.29", optional = true }
hashbrown = { version = "0.14.3", default-features = false }
rustc-hash = { version = "1.1.0", default-features = false }
slotmap = { version = "1.0.7", default-features = false }

[dev-dependencies]
tokio = { version = "1.35.0", features = ["full"] }
Expand Down
37 changes: 20 additions & 17 deletions src/context.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::marker::PhantomData;
use slotmap::DefaultKey;
use std::marker::PhantomData;

pub struct Context<T: ?Sized> {
key: DefaultKey,
Expand Down Expand Up @@ -55,9 +55,9 @@ impl<T> Context<T> {
.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()),
(self.key, core::any::TypeId::of::<M>()),
vec![alloc::rc::Rc::new(core::cell::RefCell::new(
move |msg: &dyn core::any::Any| f(msg.downcast_ref().unwrap()),
))],
);
}
Expand All @@ -74,17 +74,20 @@ impl<T> Context<T> {
});
}

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
}
cfg_futures!(
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
Expand Down Expand Up @@ -116,8 +119,8 @@ impl<T> Context<T> {
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>| {
f: alloc::rc::Rc::new(core::cell::RefCell::new(
move |any_task: &mut dyn crate::rt::AnyTask, msg: Box<dyn core::any::Any>| {
let task = any_task.as_any_mut().downcast_mut::<T>().unwrap();
task.handle(Context::new(key), *msg.downcast().unwrap());
},
Expand Down
23 changes: 13 additions & 10 deletions src/handle.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::{rt::AnyTask, Context, Object, Runtime, Signal, SignalHandle, Slot};
use futures::channel::mpsc;
use slotmap::DefaultKey;
use std::{
use core::{
cell::{self, RefCell},
marker::PhantomData,
mem,
ops::Deref,
rc::Rc,

};
use alloc::rc::Rc;

pub(crate) struct Dropper {
pub(crate) key: DefaultKey,
Expand Down Expand Up @@ -67,13 +67,16 @@ impl<T> Handle<T> {
Context::<T>::new(self.dropper.key).bind(&Context::from_handle(other))
}

pub fn channel<M>(&self) -> mpsc::UnboundedReceiver<M>
where
T: Signal<M>,
M: Clone + 'static,
{
Context::<T>::new(self.dropper.key).channel()
}
cfg_futures!(
pub fn channel<M>(&self) -> futures::channel::mpsc::UnboundedReceiver<M>
where
T: Signal<M>,
M: Clone + 'static,
{
Context::<T>::new(self.dropper.key).channel()
}
);


pub fn borrow(&self) -> Ref<T> {
let rc = Runtime::current().inner.borrow_mut().tasks[self.dropper.key].clone();
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg))]

extern crate alloc;

macro_rules! cfg_rt {
($($i:item)*) => {
$(
Expand Down
26 changes: 15 additions & 11 deletions src/rt.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use crate::{Context, Handle, Object};
use futures::{channel::mpsc, Future, StreamExt};
use slotmap::{DefaultKey, SlotMap};
use std::{
use alloc::rc::Rc;
use core::{
any::{Any, TypeId},
cell::RefCell,
collections::HashMap,
rc::Rc, pin::Pin,
pin::Pin, hash::BuildHasherDefault,
future::Future
};
use hashbrown::HashMap;
use rustc_hash::FxHasher;
use slotmap::{DefaultKey, SlotMap};

pub enum RuntimeMessage {
Signal {
Expand All @@ -21,7 +23,8 @@ pub enum RuntimeMessage {

pub(crate) struct Inner {
pub(crate) tasks: SlotMap<DefaultKey, Rc<RefCell<dyn AnyTask>>>,
pub(crate) listeners: HashMap<(DefaultKey, TypeId), Vec<Rc<RefCell<dyn FnMut(&dyn Any)>>>>,
pub(crate) listeners:
HashMap<(DefaultKey, TypeId), Vec<Rc<RefCell<dyn FnMut(&dyn Any)>>>, BuildHasherDefault<FxHasher>>,
pub(crate) channel: Box<dyn Channel>,
}

Expand All @@ -37,7 +40,7 @@ pub struct Runtime {
cfg_futures!(
impl Default for Runtime {
fn default() -> Self {
let (tx, rx) = mpsc::unbounded();
let (tx, rx) = futures::channel::mpsc::unbounded();
Self::new(Box::new(Mpsc {
tx,rx
}))
Expand All @@ -50,7 +53,7 @@ impl Runtime {
Self {
inner: Rc::new(RefCell::new(Inner {
tasks: SlotMap::new(),
listeners: HashMap::new(),
listeners: HashMap::with_hasher(BuildHasherDefault::default()),
channel,
})),
}
Expand Down Expand Up @@ -175,15 +178,15 @@ impl Drop for RuntimeGuard {
pub trait Channel {
fn send(&mut self, msg: RuntimeMessage);

fn next(&mut self) -> Pin<Box<dyn Future<Output = Option<RuntimeMessage>>+ '_>>;
fn next(&mut self) -> Pin<Box<dyn Future<Output = Option<RuntimeMessage>> + '_>>;

fn try_next(&mut self) -> Option<RuntimeMessage>;
}

cfg_futures!(
pub struct Mpsc {
pub tx: mpsc::UnboundedSender<RuntimeMessage>,
pub rx: mpsc::UnboundedReceiver<RuntimeMessage>,
pub tx: futures::channel::mpsc::UnboundedSender<RuntimeMessage>,
pub rx: futures::channel::mpsc::UnboundedReceiver<RuntimeMessage>,
}

impl Channel for Mpsc {
Expand All @@ -192,6 +195,7 @@ cfg_futures!(
}

fn next(&mut self) -> Pin<Box<dyn Future<Output = Option<RuntimeMessage>> + '_>> {
use futures::StreamExt;
Box::pin(async move {
self.rx.next().await
})
Expand Down
5 changes: 3 additions & 2 deletions src/signal_handle.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::{Handle, Object, Runtime, Slot};
use alloc::rc::Rc;
use slotmap::DefaultKey;
use std::{
use core::{
any::{Any, TypeId},
cell::RefCell,
marker::PhantomData,
rc::Rc,

};

pub struct SignalHandle<M> {
Expand Down
3 changes: 2 additions & 1 deletion src/slot_handle.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{rt::AnyTask, Runtime};
use alloc::rc::Rc;
use slotmap::DefaultKey;
use std::{any::Any, cell::RefCell, marker::PhantomData, rc::Rc};
use core::{any::Any, cell::RefCell, marker::PhantomData};

pub struct SlotHandle<M> {
pub(crate) key: DefaultKey,
Expand Down

0 comments on commit 5af395c

Please sign in to comment.