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}