ftswarm/
swarm_object.rs

1use std::{future::Future, sync::Arc};
2
3use ftswarm_macros::Updateable;
4use ftswarm_proto::{command::{argument::Argument, rpc::{FtSwarmRPCCommand, RpcFunction}, FtSwarmCommand}, message_parser::rpc::RPCReturnParam};
5
6use crate::{lock, FtSwarm, Mutex};
7
8pub mod analog;
9pub mod digital;
10
11pub mod servo;
12pub mod actor;
13pub mod led;
14pub mod controller;
15
16
17pub type Io<T> = Arc<Mutex<Box<T>>>;
18
19pub trait Updateable {
20    fn handle_subscription(&mut self, message: &RPCReturnParam);
21}
22
23pub trait NewSwarmObject<Params> {
24    fn new(name: &str, swarm: FtSwarm, params: Params) -> Box<Self>;
25    fn init(&mut self) -> impl Future<Output=()> {
26        async move {}
27    }
28    fn name(&self) -> &str;
29    fn swarm(&self) -> &FtSwarm;
30}
31
32pub trait SwarmObject<Params>: NewSwarmObject<Params> + Updateable + Clone + Sync + Send {
33    fn create(swarm: &FtSwarm, name: &str, params: Params) -> impl Future<Output=Io<Self>>
34    where
35        Self: 'static,
36    {
37        let obj = Self::new(name, swarm.clone(), params);
38        let arc = Arc::new(Mutex::new(obj));
39        let for_closure = arc.clone();
40
41        async move {
42            swarm.push_cache(Box::new(move |subscription| {
43                let for_task = for_closure.clone();
44                tokio::spawn(async move {
45                    let mut obj = lock(&for_task).await;
46                    obj.handle_subscription(&subscription);
47                });
48            }), name).await;
49            {
50                let mut obj = lock(&arc).await;
51                obj.init().await;
52            }
53            arc
54        }
55    }
56
57    fn run_command(&self, func: RpcFunction, args: Vec<Argument>) -> impl Future<Output=Result<RPCReturnParam, String>> {
58        let command = FtSwarmRPCCommand {
59            target: self.name().to_string(),
60            function: func,
61            args,
62        };
63
64        self.swarm().transact(FtSwarmCommand::RPC(command))
65    }
66}
67
68#[derive(Clone)]
69pub struct Hysteresis(pub i32);
70
71
72#[derive(Clone)]
73pub enum NormallyOpen {
74    Open,
75    Closed,
76}
77
78impl Into<Argument> for NormallyOpen {
79    fn into(self) -> Argument {
80        match self {
81            NormallyOpen::Open => Argument::Int(0),
82            NormallyOpen::Closed => Argument::Int(1),
83        }
84    }
85}