use crate::actor::*; use crate::error::Error; use preserves::value::Map; use std::sync::Arc; use std::marker::PhantomData; pub struct During(Map>); pub type DuringRetractionHandler = Box ActorResult>; pub type DuringResult = Result>, Error>; pub struct DuringEntity where M: 'static + Send, E: 'static + Send, Fa: 'static + Send + FnMut(&mut E, &mut Activation, M) -> DuringResult, Fm: 'static + Send + FnMut(&mut E, &mut Activation, M) -> ActorResult, { state: E, assertion_handler: Option, message_handler: Option, during: During, phantom: PhantomData, } impl During { pub fn new() -> Self { During(Map::new()) } pub fn await_retraction ActorResult>( &mut self, h: Handle, f: F, ) -> ActorResult { self.0.insert(h, Box::new(f)); Ok(()) } pub fn retract(&mut self, h: Handle) -> DuringRetractionHandler { self.0.remove(&h).unwrap_or_else(|| Box::new(|_, _| Ok(()))) } } pub fn entity( state: E ) -> DuringEntity DuringResult, fn (&mut E, &mut Activation, M) -> ActorResult> where E: 'static + Send, { DuringEntity::new(state, None, None) } impl DuringEntity where M: 'static + Send, E: 'static + Send, Fa: 'static + Send + FnMut(&mut E, &mut Activation, M) -> DuringResult, Fm: 'static + Send + FnMut(&mut E, &mut Activation, M) -> ActorResult, { pub fn new(state: E, assertion_handler: Option, message_handler: Option) -> Self { DuringEntity { state, assertion_handler, message_handler, during: During::new(), phantom: PhantomData, } } pub fn on_asserted(self, assertion_handler: Fa1) -> DuringEntity where Fa1: 'static + Send + FnMut(&mut E, &mut Activation, M) -> DuringResult, { DuringEntity { state: self.state, assertion_handler: Some(assertion_handler), message_handler: self.message_handler, during: self.during, phantom: PhantomData, } } pub fn on_asserted_facet( self, mut assertion_handler: Fa1, ) -> DuringEntity DuringResult>, Fm> where Fa1: 'static + Send + FnMut(&mut E, &mut Activation, M) -> ActorResult { self.on_asserted(Box::new(move |state, t, a| { let facet_id = t.facet(|t| assertion_handler(state, t, a))?; Ok(Some(Box::new(move |_state, t| { t.stop_facet(facet_id, None); Ok(()) }))) })) } pub fn on_message(self, message_handler: Fm1) -> DuringEntity where Fm1: 'static + Send + FnMut(&mut E, &mut Activation, M) -> ActorResult, { DuringEntity { state: self.state, assertion_handler: self.assertion_handler, message_handler: Some(message_handler), during: self.during, phantom: PhantomData, } } pub fn create(self, t: &mut Activation) -> Arc> { t.create(self) } } impl DuringEntity where E: 'static + Send, Fa: 'static + Send + FnMut(&mut E, &mut Activation, AnyValue) -> DuringResult, Fm: 'static + Send + FnMut(&mut E, &mut Activation, AnyValue) -> ActorResult, { pub fn create_cap(self, t: &mut Activation) -> Arc { Cap::new(&self.create(t)) } } impl Entity for DuringEntity where M: Send, E: 'static + Send, Fa: 'static + Send + FnMut(&mut E, &mut Activation, M) -> DuringResult, Fm: 'static + Send + FnMut(&mut E, &mut Activation, M) -> ActorResult, { fn assert(&mut self, t: &mut Activation, a: M, h: Handle) -> ActorResult { match &mut self.assertion_handler { Some(handler) => match handler(&mut self.state, t, a)? { Some(f) => self.during.await_retraction(h, f), None => Ok(()) } None => Ok(()), } } fn retract(&mut self, t: &mut Activation, h: Handle) -> ActorResult { self.during.retract(h)(&mut self.state, t) } fn message(&mut self, t: &mut Activation, m: M) -> ActorResult { match &mut self.message_handler { Some(handler) => handler(&mut self.state, t, m), None => Ok(()), } } }