diff options
Diffstat (limited to 'src/basic_actors.rs')
-rw-r--r-- | src/basic_actors.rs | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/src/basic_actors.rs b/src/basic_actors.rs index 6418694..9bff7d9 100644 --- a/src/basic_actors.rs +++ b/src/basic_actors.rs @@ -70,8 +70,41 @@ impl Actorful for Add { } #[derive(Clone)] +pub struct Multiply; + +impl Actorful for Multiply { + fn inputs(&self) -> Vec<Slot> { + vec![ + Slot { name: "N1".to_string(), r#type: Type::AnyNumber }, + Slot { name: "N2".to_string(), r#type: Type::AnyNumber }, + ] + } + + fn outputs(&self) -> Vec<Slot> { + vec![Slot { name: "Result".to_string(), r#type: Type::AnyNumber }] + } + + fn launch(&self, mut input_channels: HashMap<String, Receiver<Value>>, + output_channels: HashMap<String, SyncSender<Value>>, _world: &mut World) -> Box<dyn FnOnce() + Send> { + let n1 = input_channels.remove("N1").unwrap(); + let n2 = input_channels.remove("N2").unwrap(); + Box::new(move || { + for (n1, n2) in n1.iter().zip(n2.iter()) { + if let (Value::Number(n1), Value::Number(n2)) = (n1, n2) { + let _ = output_channels["Result"].try_send(Value::Number(n1 * n2)); + } + } + }) + } + + fn boxed_clone(&self) -> Box<dyn Actorful + Send> { + Box::new(self.clone()) + } +} + +#[derive(Clone)] pub struct RepeatValue { - pub(crate) r#type: Type, + pub r#type: Type, } impl Actorful for RepeatValue { @@ -111,6 +144,49 @@ impl Actorful for RepeatValue { } #[derive(Clone)] +pub struct SetListItem { + pub r#type: Type, +} + +impl Actorful for SetListItem { + fn inputs(&self) -> Vec<Slot> { + let nonnegative_integer = Type::NumberInRange { + min: Some(Number::from(0)), + max: None, + }; + vec![ + Slot { name: "List".to_string(), r#type: Type::List { contents: Box::new(self.r#type.clone()) } }, + Slot { name: "Index".to_string(), r#type: nonnegative_integer }, + Slot { name: "Value".to_string(), r#type: self.r#type.clone() }, + ] + } + + fn outputs(&self) -> Vec<Slot> { + vec![Slot { name: "List".to_string(), r#type: Type::List { contents: Box::new(self.r#type.clone()) } }] + } + + fn launch(&self, mut input_channels: HashMap<String, Receiver<Value>>, + output_channels: HashMap<String, SyncSender<Value>>, _world: &mut World) -> Box<dyn FnOnce() + Send> { + let list = input_channels.remove("List").unwrap(); + let index = input_channels.remove("Index").unwrap(); + let value = input_channels.remove("Value").unwrap(); + Box::new(move || { + for ((list, index), value) in list.iter().zip(index.iter()).zip(value.iter()) { + if let (Value::List(mut list), Value::Number(index)) = (list, index) { + let index: usize = index.try_into().unwrap(); + list[index] = value; + let _ = output_channels["List"].try_send(Value::List(list)); + } + } + }) + } + + fn boxed_clone(&self) -> Box<dyn Actorful + Send> { + Box::new(self.clone()) + } +} + +#[derive(Clone)] pub struct DeconstructRecord { pub record_type: Type, } |