use syndicate::actor::*; use syndicate::enclose; use syndicate::dataspace::Dataspace; use syndicate::language; use syndicate::schemas::dataspace::Observe; use syndicate::value::NestedValue; #[tokio::main] async fn main() -> ActorResult { syndicate::convenient_logging()?; Actor::top(None, |t| { let ds = Cap::new(&t.create(Dataspace::new(None))); let _ = t.prevent_inert_check(); t.spawn(Some(AnyValue::symbol("box")), enclose!((ds) move |t| { let current_value = t.named_field("current_value", 0u64); t.dataflow({ let mut state_assertion_handle = None; enclose!((ds, current_value) move |t| { let v = AnyValue::new(*t.get(¤t_value)); tracing::info!(?v, "asserting"); ds.update(t, &mut state_assertion_handle, &(), Some(&syndicate_macros::template!(""))); Ok(()) }) })?; let set_box_handler = syndicate::entity(()) .on_message(enclose!((current_value) move |(), t, captures: AnyValue| { let v = captures.value().to_sequence()?[0].value().to_u64()?; tracing::info!(?v, "from set-box"); t.set(¤t_value, v); Ok(()) })) .create_cap(t); ds.assert(t, language(), &Observe { pattern: syndicate_macros::pattern!{}, observer: set_box_handler, }); t.dataflow(enclose!((current_value) move |t| { if *t.get(¤t_value) == 1000000 { t.stop(); } Ok(()) }))?; Ok(()) })); t.spawn(Some(AnyValue::symbol("client")), enclose!((ds) move |t| { let box_state_handler = syndicate::entity(0u32) .on_asserted(enclose!((ds) move |count, t, captures: AnyValue| { *count = *count + 1; let value = captures.value().to_sequence()?[0].value().to_u64()?; tracing::info!(?value); let next = AnyValue::new(value + 1); tracing::info!(?next, "sending"); ds.message(t, &(), &syndicate_macros::template!("")); Ok(Some(Box::new(|count, t| { *count = *count - 1; if *count == 0 { tracing::info!("box state retracted"); t.stop(); } Ok(()) }))) })) .create_cap(t); ds.assert(t, language(), &Observe { pattern: syndicate_macros::pattern!{}, observer: box_state_handler, }); Ok(()) })); Ok(()) }).await??; Ok(()) }