2020-12-07 14:39:35 +01:00
|
|
|
use std::fmt;
|
|
|
|
|
2021-01-26 15:33:50 +01:00
|
|
|
use std::sync::Mutex;
|
2020-12-07 14:39:35 +01:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
use futures::channel::mpsc;
|
2021-01-26 15:33:50 +01:00
|
|
|
use futures_signals::signal::Mutable;
|
2020-12-07 14:39:35 +01:00
|
|
|
|
|
|
|
use crate::machine::Machine;
|
2021-01-26 15:33:50 +01:00
|
|
|
use crate::actor::ActorSignal;
|
2020-12-07 14:39:35 +01:00
|
|
|
|
|
|
|
use crate::error::Result;
|
|
|
|
|
2020-12-07 15:58:25 +01:00
|
|
|
pub type MachineMap = HashMap<String, Machine>;
|
2020-12-15 13:12:22 +01:00
|
|
|
pub type ActorMap = HashMap<String, Mutex<mpsc::Sender<Option<ActorSignal>>>>;
|
2020-12-07 15:58:25 +01:00
|
|
|
pub type InitMap = HashMap<String, Mutable<Option<Machine>>>;
|
2020-12-07 14:39:35 +01:00
|
|
|
|
2020-12-07 15:58:25 +01:00
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
2020-12-07 14:39:35 +01:00
|
|
|
pub enum Error {
|
2021-09-21 07:48:19 +02:00
|
|
|
NoSuchInitiator(String),
|
|
|
|
NoSuchMachine(String),
|
|
|
|
NoSuchActor(String),
|
2020-12-07 14:39:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Error {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self {
|
2021-09-21 07:48:19 +02:00
|
|
|
Error::NoSuchInitiator(n) => write!(f, "No initiator \"{}\" found.", n),
|
|
|
|
Error::NoSuchActor(n) => write!(f, "No actor \"{}\" found.", n),
|
|
|
|
Error::NoSuchMachine(n) => write!(f, "No machine \"{}\" found.", n),
|
2020-12-07 14:39:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Main signal network
|
|
|
|
///
|
|
|
|
/// Network as per FRP, not the one with packages and frames
|
2020-12-14 11:02:46 +01:00
|
|
|
// TODO De/Serialize established connection on startup/shutdown.
|
2020-12-07 14:39:35 +01:00
|
|
|
pub struct Network {
|
2020-12-07 15:58:25 +01:00
|
|
|
inits: InitMap,
|
|
|
|
|
|
|
|
// Store connections
|
|
|
|
//miconn: Vec<(String, String)>,
|
|
|
|
|
2020-12-16 11:32:31 +01:00
|
|
|
pub machines: MachineMap,
|
2020-12-07 15:58:25 +01:00
|
|
|
|
|
|
|
// Store connections
|
|
|
|
//maconn: Vec<(String, String)>,
|
|
|
|
|
2020-12-07 14:39:35 +01:00
|
|
|
actors: ActorMap,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Network {
|
|
|
|
pub fn new(machines: MachineMap, actors: ActorMap, inits: InitMap) -> Self {
|
|
|
|
Self { machines, actors, inits }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn connect_init(&self, init_key: &String, machine_key: &String) -> Result<()> {
|
|
|
|
let init = self.inits.get(init_key)
|
2021-09-21 07:48:19 +02:00
|
|
|
.ok_or_else(|| Error::NoSuchInitiator(init_key.clone()))?;
|
2020-12-07 14:39:35 +01:00
|
|
|
let machine = self.machines.get(machine_key)
|
2021-09-21 07:48:19 +02:00
|
|
|
.ok_or_else(|| Error::NoSuchMachine(machine_key.clone()))?;
|
2020-12-07 14:39:35 +01:00
|
|
|
|
2020-12-07 15:58:25 +01:00
|
|
|
init.set(Some(machine.clone()));
|
|
|
|
Ok(())
|
2020-12-07 14:39:35 +01:00
|
|
|
}
|
|
|
|
|
2020-12-15 13:12:22 +01:00
|
|
|
pub fn connect_actor(&mut self, machine_key: &String, actor_key: &String)
|
|
|
|
-> Result<()>
|
|
|
|
{
|
2020-12-07 14:39:35 +01:00
|
|
|
let machine = self.machines.get(machine_key)
|
2021-09-21 07:48:19 +02:00
|
|
|
.ok_or_else(|| Error::NoSuchMachine(machine_key.clone()))?;
|
2020-12-15 13:12:22 +01:00
|
|
|
let actor = self.actors.get(actor_key)
|
2021-09-21 07:48:19 +02:00
|
|
|
.ok_or_else(|| Error::NoSuchActor(actor_key.clone()))?;
|
2020-12-07 14:39:35 +01:00
|
|
|
|
2020-12-15 13:12:22 +01:00
|
|
|
// FIXME Yeah this should not unwrap. Really, really shoudln't.
|
|
|
|
let mut guard = actor.try_lock().unwrap();
|
|
|
|
|
2021-09-21 07:48:19 +02:00
|
|
|
guard.try_send(Some(Box::new(machine.signal())))
|
|
|
|
.map_err(|_| Error::NoSuchActor(actor_key.clone()).into())
|
2020-12-07 14:39:35 +01:00
|
|
|
}
|
|
|
|
}
|