diff options
author | Melody Horn <melody@boringcactus.com> | 2021-03-07 22:27:59 -0700 |
---|---|---|
committer | Melody Horn <melody@boringcactus.com> | 2021-03-07 22:27:59 -0700 |
commit | 204ee3854d3d45338ed9f1659d44f23062bfac77 (patch) | |
tree | 8b58d90d7b9ad367f6be1f336cd6146f6417e87c | |
parent | b8bb816d72217c1afdb18858481db737e52a4e7f (diff) | |
download | hope-main.tar.gz hope-main.zip |
-rw-r--r-- | src/basic_actors.rs | 78 | ||||
-rw-r--r-- | src/main.rs | 85 | ||||
-rw-r--r-- | src/number.rs | 16 |
3 files changed, 160 insertions, 19 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, } diff --git a/src/main.rs b/src/main.rs index ef61de7..c457354 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,8 +12,6 @@ const WIDTH: usize = 1600; const HEIGHT: usize = 900; fn main() { - let mut buffer: Vec<u32> = vec![0; WIDTH * HEIGHT]; - let mut window = Window::new( "the Hope system", WIDTH, @@ -51,6 +49,34 @@ fn main() { ..Default::default() }; + let zero_constant = basic_actors::Constant { + r#type: u24.clone(), + value: actor::Value::Number(number::Number::from(0)), + }; + world.upsert_actor_type("Zero Constant".to_string(), Box::new(zero_constant)); + let zero_constant = system.add_child("Zero Constant".to_string()); + + let buffer_size_constant = basic_actors::Constant { + r#type: nonnegative_int.clone(), + value: actor::Value::Number(number::Number::from(WIDTH * HEIGHT)), + }; + world.upsert_actor_type("Buffer Size Constant".to_string(), Box::new(buffer_size_constant)); + let buffer_size_constant = system.add_child("Buffer Size Constant".to_string()); + + let repeat_u24 = basic_actors::RepeatValue { + r#type: u24.clone(), + }; + world.upsert_actor_type("Repeat u24".to_string(), Box::new(repeat_u24)); + let repeat_u24 = system.add_child("Repeat u24".to_string()); + system.add_cable( + actor::ProducerSlotID::ChildOutput(zero_constant, "Value".to_string()), + actor::ConsumerSlotID::ChildInput(repeat_u24, "Value".to_string()) + ); + system.add_cable( + actor::ProducerSlotID::ChildOutput(buffer_size_constant, "Value".to_string()), + actor::ConsumerSlotID::ChildInput(repeat_u24, "Count".to_string()) + ); + let deconstruct_record = basic_actors::DeconstructRecord { record_type: screen_position_type, }; @@ -61,39 +87,64 @@ fn main() { actor::ConsumerSlotID::ChildInput(deconstruct_record, "Record".to_string()) ); - world.upsert_actor_type("Add".to_string(), Box::new(basic_actors::Add)); + let width_constant = basic_actors::Constant { + r#type: nonnegative_int.clone(), + value: actor::Value::Number(number::Number::from(WIDTH)), + }; + world.upsert_actor_type("Width Constant".to_string(), Box::new(width_constant)); + let width_constant = system.add_child("Width Constant".to_string()); + + let multiply = basic_actors::Multiply; + world.upsert_actor_type("Multiply".to_string(), Box::new(multiply)); + let multiply = system.add_child("Multiply".to_string()); + system.add_cable( + actor::ProducerSlotID::ChildOutput(deconstruct_record, "Y".to_string()), + actor::ConsumerSlotID::ChildInput(multiply, "N1".to_string()) + ); + system.add_cable( + actor::ProducerSlotID::ChildOutput(width_constant, "Value".to_string()), + actor::ConsumerSlotID::ChildInput(multiply, "N2".to_string()) + ); + + let add = basic_actors::Add; + world.upsert_actor_type("Add".to_string(), Box::new(add)); let add = system.add_child("Add".to_string()); system.add_cable( actor::ProducerSlotID::ChildOutput(deconstruct_record, "X".to_string()), actor::ConsumerSlotID::ChildInput(add, "N1".to_string()) ); system.add_cable( - actor::ProducerSlotID::ChildOutput(deconstruct_record, "Y".to_string()), + actor::ProducerSlotID::ChildOutput(multiply, "Result".to_string()), actor::ConsumerSlotID::ChildInput(add, "N2".to_string()) ); - let buffer_size_constant = basic_actors::Constant { - r#type: nonnegative_int.clone(), - value: actor::Value::Number(number::Number::from(WIDTH * HEIGHT)), + let red_constant = basic_actors::Constant { + r#type: u24.clone(), + value: actor::Value::Number(number::Number::from(0xFF << 16)) }; - world.upsert_actor_type("Buffer Size Constant".to_string(), Box::new(buffer_size_constant)); - let buffer_size_constant = system.add_child("Buffer Size Constant".to_string()); + world.upsert_actor_type("Red Constant".to_string(), Box::new(red_constant)); + let red_constant = system.add_child("Red Constant".to_string()); - let repeat_u24 = basic_actors::RepeatValue { - r#type: u24, + let set_u24 = basic_actors::SetListItem { + r#type: u24.clone() }; - world.upsert_actor_type("Repeat u24".to_string(), Box::new(repeat_u24)); - let repeat_u24 = system.add_child("Repeat u24".to_string()); + world.upsert_actor_type("Set u24".to_string(), Box::new(set_u24)); + let set_u24 = system.add_child("Set u24".to_string()); + system.add_cable( + actor::ProducerSlotID::ChildOutput(repeat_u24, "List".to_string()), + actor::ConsumerSlotID::ChildInput(set_u24, "List".to_string()) + ); system.add_cable( actor::ProducerSlotID::ChildOutput(add, "Result".to_string()), - actor::ConsumerSlotID::ChildInput(repeat_u24, "Value".to_string()) + actor::ConsumerSlotID::ChildInput(set_u24, "Index".to_string()) ); system.add_cable( - actor::ProducerSlotID::ChildOutput(buffer_size_constant, "Value".to_string()), - actor::ConsumerSlotID::ChildInput(repeat_u24, "Count".to_string()) + actor::ProducerSlotID::ChildOutput(red_constant, "Value".to_string()), + actor::ConsumerSlotID::ChildInput(set_u24, "Value".to_string()) ); + system.add_cable( - actor::ProducerSlotID::ChildOutput(repeat_u24, "List".to_string()), + actor::ProducerSlotID::ChildOutput(set_u24, "List".to_string()), actor::ConsumerSlotID::Output("screen_buffer".to_string()) ); diff --git a/src/number.rs b/src/number.rs index 5ea7949..d40e50a 100644 --- a/src/number.rs +++ b/src/number.rs @@ -1,7 +1,7 @@ use std::cmp::max; use std::convert::TryFrom; use std::num::TryFromIntError; -use std::ops::Add; +use std::ops::{Add, Mul}; #[derive(Clone)] pub struct Number { @@ -59,3 +59,17 @@ impl Add for Number { } } } + +impl Mul for Number { + type Output = Number; + + fn mul(self, rhs: Self) -> Self::Output { + if self.integer_part.len() > 1 || rhs.integer_part.len() > 1 { + todo!() + } else { + Number { + integer_part: vec![self.integer_part[0] * rhs.integer_part[0]] + } + } + } +} |