sim_lib_skill/
transport.rs1use std::sync::Arc;
2
3use sim_citizen_derive::non_citizen;
4use sim_kernel::{Cx, Expr, Object, ObjectCompat, Result, Symbol, Value};
5
6use crate::SkillCard;
7
8pub trait SkillEventSink {
10 fn emit(&mut self, cx: &mut Cx, event: Value) -> Result<()>;
12}
13
14pub trait SkillTransport: Send + Sync {
23 fn id(&self) -> &str;
25 fn kind(&self) -> &str;
27 fn discover(&self, cx: &mut Cx) -> Result<Vec<SkillCard>>;
29 fn call(
34 &self,
35 cx: &mut Cx,
36 card: &SkillCard,
37 args: Value,
38 events: Option<&mut dyn SkillEventSink>,
39 ) -> Result<Value>;
40 fn health(&self, cx: &mut Cx) -> Result<Value>;
42}
43
44#[derive(Clone)]
50#[non_citizen(
51 reason = "live skill transport handle; transport metadata is carried by skill/Card descriptor",
52 kind = "handle",
53 descriptor = "skill/Card"
54)]
55pub struct SkillTransportValue {
56 transport: Arc<dyn SkillTransport>,
57}
58
59impl SkillTransportValue {
60 pub fn new(transport: Arc<dyn SkillTransport>) -> Self {
62 Self { transport }
63 }
64
65 pub fn transport(&self) -> Arc<dyn SkillTransport> {
67 self.transport.clone()
68 }
69}
70
71impl Object for SkillTransportValue {
72 fn display(&self, _cx: &mut Cx) -> Result<String> {
73 Ok(format!(
74 "#<skill-transport {}:{}>",
75 self.transport.kind(),
76 self.transport.id()
77 ))
78 }
79
80 fn as_any(&self) -> &dyn std::any::Any {
81 self
82 }
83}
84
85impl ObjectCompat for SkillTransportValue {
86 fn as_expr(&self, cx: &mut Cx) -> Result<Expr> {
87 self.as_table(cx)?.object().as_expr(cx)
88 }
89
90 fn as_table(&self, cx: &mut Cx) -> Result<Value> {
91 cx.factory().table(vec![
92 (
93 Symbol::new("kind"),
94 cx.factory().symbol(Symbol::new("skill/transport"))?,
95 ),
96 (
97 Symbol::new("id"),
98 cx.factory().string(self.transport.id().to_owned())?,
99 ),
100 (
101 Symbol::new("transport-kind"),
102 cx.factory().string(self.transport.kind().to_owned())?,
103 ),
104 ])
105 }
106}
107
108pub fn skill_transport_value(cx: &mut Cx, transport: Arc<dyn SkillTransport>) -> Result<Value> {
110 cx.factory()
111 .opaque(Arc::new(SkillTransportValue::new(transport)))
112}