From 36d5ff553a1d65d70da5251b8865d62294c929f6 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Sun, 7 Mar 2021 09:12:47 -0700 Subject: tear it all up and implement super basic actors --- src/actor.rs | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 2 deletions(-) (limited to 'src/actor.rs') diff --git a/src/actor.rs b/src/actor.rs index 3b03fa6..e83c003 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -1,4 +1,14 @@ +use std::collections::HashMap; +use std::sync::mpsc::{Receiver, Sender}; +use std::thread; + +use uuid::Uuid; + use crate::number::Number; +use crate::world::World; + +#[derive(Clone, Hash, Copy, Eq, PartialEq)] +pub struct ActorId(Uuid); #[derive(Clone)] pub enum Type { @@ -17,6 +27,14 @@ pub enum Type { }, } +#[derive(Clone)] +pub enum Value { + String(String), + Record(Vec<(String, Value)>), + Number(Number), + List(Vec), +} + #[derive(Clone)] pub struct Slot { pub name: String, @@ -24,6 +42,77 @@ pub struct Slot { } pub trait Actorful { - fn inputs() -> Vec; - fn outputs() -> Vec; + fn inputs(&self) -> Vec; + fn outputs(&self) -> Vec; + fn launch(&self, input_channels: HashMap>, output_channels: HashMap>, world: &mut World); + fn boxed_clone(&self) -> Box; +} + +#[derive(Clone)] +pub enum ProducerSlotID { + Input(String), + ChildOutput(ActorId, String), +} + +#[derive(Clone)] +pub enum ConsumerSlotID { + Output(String), + ChildInput(ActorId, String), +} + +#[derive(Clone, Default)] +pub struct ProgrammableActor { + pub inputs: Vec, + pub outputs: Vec, + pub children: HashMap, + pub cables: Vec<(ProducerSlotID, ConsumerSlotID)>, +} + +impl ProgrammableActor { + pub fn add_child(&mut self, actor_type: String) -> ActorId { + let id = ActorId(Uuid::new_v4()); + self.children.insert(id, actor_type); + id + } + + pub fn add_cable(&mut self, in_slot: ProducerSlotID, out_slot: ConsumerSlotID) { + self.cables.push((in_slot, out_slot)); + } +} + +impl Actorful for ProgrammableActor { + fn inputs(&self) -> Vec { + self.inputs.clone() + } + + fn outputs(&self) -> Vec { + self.outputs.clone() + } + + fn launch(&self, mut input_channels: HashMap>, mut output_channels: HashMap>, world: &mut World) { + let mut child_channels = HashMap::new(); + for (&child_id, child_type) in &self.children { + let (_, child_inputs, child_outputs) = world.spawn_actor(child_type); + child_channels.insert(child_id, (child_inputs, child_outputs)); + } + for (source, dest) in &self.cables { + let source = match source { + ProducerSlotID::Input(name) => input_channels.remove(name).unwrap(), + ProducerSlotID::ChildOutput(id, name) => child_channels[id].1.remove(name).unwrap() + }; + let dest = match dest { + ConsumerSlotID::Output(name) => output_channels.remove(name).unwrap(), + ConsumerSlotID::ChildInput(id, name) => child_channels[id].0.remove(name).unwrap() + }; + thread::spawn(move || { + for val in source.iter() { + dest.send(val).unwrap() + } + }); + } + } + + fn boxed_clone(&self) -> Box { + Box::new(self.clone()) + } } -- cgit v1.2.3