use crate::actor::*; use crate::error::Error; use preserves::value::Map; use std::any::Any; use std::sync::Arc; pub type DuringRetractionHandler = Box ActorResult>; pub struct During(Map>); pub type DuringResult = Result ActorResult>>, Error>; pub struct DuringEntity where E: 'static + Send + Sync, Fa: 'static + Send + Sync + FnMut(&mut E, &mut Activation, _Any) -> DuringResult, Fm: 'static + Send + Sync + FnMut(&mut E, &mut Activation, _Any) -> ActorResult, { state: E, assertion_handler: Option, message_handler: Option, during: During, } 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, _Any) -> ActorResult> where E: 'static + Send + Sync, { DuringEntity::new(state, None, None) } impl DuringEntity where E: 'static + Send + Sync, Fa: 'static + Send + Sync + FnMut(&mut E, &mut Activation, _Any) -> DuringResult, Fm: 'static + Send + Sync + FnMut(&mut E, &mut Activation, _Any) -> ActorResult, { pub fn new(state: E, assertion_handler: Option, message_handler: Option) -> Self { DuringEntity { state, assertion_handler, message_handler, during: During::new(), } } pub fn on_asserted(self, assertion_handler: Fa1) -> DuringEntity where Fa1: 'static + Send + Sync + FnMut(&mut E, &mut Activation, _Any) -> DuringResult, { DuringEntity { state: self.state, assertion_handler: Some(assertion_handler), message_handler: self.message_handler, during: self.during, } } pub fn on_message(self, message_handler: Fm1) -> DuringEntity where Fm1: 'static + Send + Sync + FnMut(&mut E, &mut Activation, _Any) -> ActorResult, { DuringEntity { state: self.state, assertion_handler: self.assertion_handler, message_handler: Some(message_handler), during: self.during, } } pub fn create(self, ac: &mut Actor) -> Arc { ac.create(self) } pub fn create_rec(self, ac: &mut Actor, f: F) -> Arc where F: FnOnce(&mut Actor, &mut E, &Arc) -> () { ac.create_rec(self, |ac, e, e_ref| f(ac, &mut e.state, e_ref)) } } impl Entity for DuringEntity where E: 'static + Send + Sync, Fa: 'static + Send + Sync + FnMut(&mut E, &mut Activation, _Any) -> DuringResult, Fm: 'static + Send + Sync + FnMut(&mut E, &mut Activation, _Any) -> ActorResult, { fn as_any(&mut self) -> &mut dyn Any { self } fn assert(&mut self, t: &mut Activation, a: _Any, 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: _Any) -> ActorResult { match &mut self.message_handler { Some(handler) => handler(&mut self.state, t, m), None => Ok(()), } } }