aboutsummaryrefslogtreecommitdiff
path: root/src/basic_actors.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic_actors.rs')
-rw-r--r--src/basic_actors.rs63
1 files changed, 38 insertions, 25 deletions
diff --git a/src/basic_actors.rs b/src/basic_actors.rs
index 6f514d6..da391cf 100644
--- a/src/basic_actors.rs
+++ b/src/basic_actors.rs
@@ -1,5 +1,5 @@
use std::collections::HashMap;
-use std::sync::mpsc::{Sender, Receiver};
+use std::sync::mpsc::{SyncSender, Receiver};
use crate::actor::{Value, Type, Actorful, Slot};
use crate::number::Number;
@@ -20,10 +20,14 @@ impl Actorful for Constant {
vec![Slot { name: "Value".to_string(), r#type: self.r#type.clone() }]
}
- fn launch(&self, _input_channels: HashMap<String, Receiver<Value>>, output_channels: HashMap<String, Sender<Value>>, _world: &mut World) {
- loop {
- output_channels["Value"].send(self.value.clone()).unwrap()
- }
+ fn launch(&self, _input_channels: HashMap<String, Receiver<Value>>,
+ output_channels: HashMap<String, SyncSender<Value>>, _world: &mut World) -> Box<dyn FnOnce() + Send> {
+ let value = self.value.clone();
+ Box::new(move || {
+ loop {
+ output_channels["Value"].send(value.clone()).unwrap()
+ }
+ })
}
fn boxed_clone(&self) -> Box<dyn Actorful + Send> {
@@ -46,14 +50,17 @@ impl Actorful for Add {
vec![Slot { name: "Result".to_string(), r#type: Type::AnyNumber }]
}
- fn launch(&self, mut input_channels: HashMap<String, Receiver<Value>>, output_channels: HashMap<String, Sender<Value>>, _world: &mut World) {
+ 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();
- for (n1, n2) in n1.iter().zip(n2.iter()) {
- if let (Value::Number(n1), Value::Number(n2)) = (n1, n2) {
- output_channels["Result"].send(Value::Number(n1 + n2)).unwrap();
+ Box::new(move || {
+ for (n1, n2) in n1.iter().zip(n2.iter()) {
+ if let (Value::Number(n1), Value::Number(n2)) = (n1, n2) {
+ output_channels["Result"].send(Value::Number(n1 + n2)).unwrap();
+ }
}
- }
+ })
}
fn boxed_clone(&self) -> Box<dyn Actorful + Send> {
@@ -82,18 +89,21 @@ impl Actorful for RepeatValue {
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, Sender<Value>>, _world: &mut World) {
+ fn launch(&self, mut input_channels: HashMap<String, Receiver<Value>>,
+ output_channels: HashMap<String, SyncSender<Value>>, _world: &mut World) -> Box<dyn FnOnce() + Send> {
let value = input_channels.remove("Value").unwrap();
let count = input_channels.remove("Count").unwrap();
- for (value, count) in value.iter().zip(count.iter()) {
- if let Value::Number(count) = count {
- // TODO figure out what a smart thing to do would be here instead
- // this API design is deliberately suboptimal because i'd like to not do it
- let count: usize = format!("{}", count).parse().unwrap();
- let vec = vec![value; count];
- output_channels["List"].send(Value::List(vec)).unwrap();
+ Box::new(move || {
+ for (value, count) in value.iter().zip(count.iter()) {
+ if let Value::Number(count) = count {
+ // TODO figure out what a smart thing to do would be here instead
+ // this API design is deliberately suboptimal because i'd like to not do it
+ let count: usize = format!("{}", count).parse().unwrap();
+ let vec = vec![value; count];
+ output_channels["List"].send(Value::List(vec)).unwrap();
+ }
}
- }
+ })
}
fn boxed_clone(&self) -> Box<dyn Actorful + Send> {
@@ -119,15 +129,18 @@ impl Actorful for DeconstructRecord {
}
}
- fn launch(&self, mut input_channels: HashMap<String, Receiver<Value>>, output_channels: HashMap<String, Sender<Value>>, _world: &mut World) {
+ fn launch(&self, mut input_channels: HashMap<String, Receiver<Value>>,
+ output_channels: HashMap<String, SyncSender<Value>>, _world: &mut World) -> Box<dyn FnOnce() + Send> {
let record = input_channels.remove("Record").unwrap();
- for record in record.iter() {
- if let Value::Record(fields) = record {
- for (label, value) in fields {
- output_channels[&label].send(value).unwrap();
+ Box::new(move || {
+ for record in record.iter() {
+ if let Value::Record(fields) = record {
+ for (label, value) in fields {
+ output_channels[&label].send(value).unwrap();
+ }
}
}
- }
+ })
}
fn boxed_clone(&self) -> Box<dyn Actorful + Send> {