diff options
| -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]] +            } +        } +    } +}  |