#![deny(missing_docs)]
use ghost_actor::*;
ghost_chan! {
pub chan TickEvent<GhostError> {
fn tick(message: String) -> ();
}
}
pub type TickEventReceiver = futures::channel::mpsc::Receiver<TickEvent>;
ghost_chan! {
pub chan TickActor<GhostError> {
fn start_tick(prefix: String, interval_ms: u64) -> ();
}
}
pub async fn spawn_tick() -> (GhostSender<TickActor>, TickEventReceiver) {
let builder = actor_builder::GhostActorBuilder::new();
let (event_sender, event_receiver) = futures::channel::mpsc::channel(10);
let sender = builder
.channel_factory()
.create_channel::<TickActor>()
.await
.unwrap();
tokio::task::spawn(builder.spawn(TickImpl { event_sender }));
(sender, event_receiver)
}
struct TickImpl {
event_sender: futures::channel::mpsc::Sender<TickEvent>,
}
impl GhostControlHandler for TickImpl {}
impl GhostHandler<TickActor> for TickImpl {}
impl TickActorHandler for TickImpl {
fn handle_start_tick(
&mut self,
prefix: String,
interval_ms: u64,
) -> TickActorHandlerResult<()> {
let event_sender = self.event_sender.clone();
tokio::task::spawn(async move {
loop {
if let Err(_) = event_sender
.tick(format!("{} - {} ms tick", prefix, interval_ms))
.await
{
break;
}
tokio::time::delay_for(std::time::Duration::from_millis(
interval_ms,
))
.await;
}
});
Ok(must_future::MustBoxFuture::new(async move { Ok(()) }))
}
}
#[tokio::main]
async fn main() {
let (tick_sender, tick_receiver) = spawn_tick().await;
tick_sender
.start_tick("Apple".to_string(), 1)
.await
.unwrap();
tick_sender
.start_tick("Banana".to_string(), 9)
.await
.unwrap();
struct ParentImpl;
impl GhostControlHandler for ParentImpl {}
impl GhostHandler<TickEvent> for ParentImpl {}
impl TickEventHandler for ParentImpl {
fn handle_tick(
&mut self,
message: String,
) -> TickEventHandlerResult<()> {
println!("got tick: {}", message);
Ok(must_future::MustBoxFuture::new(async move { Ok(()) }))
}
}
let builder = actor_builder::GhostActorBuilder::new();
builder
.channel_factory()
.attach_receiver(tick_receiver)
.await
.unwrap();
tokio::task::spawn(builder.spawn(ParentImpl));
tokio::time::delay_for(std::time::Duration::from_millis(20)).await;
}