1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
use std::ops::Deref; use crate::deserialize_field_name; use crate::field::Field; use crate::parser::YamlElement; #[derive(Debug)] pub enum Chip<R: CodeRunner + Default> { None, Memory(MemoryChip), Yolol(YololChip<R>), } impl<R: CodeRunner + Default> Chip<R> { pub fn new(chip_type: String, yaml: &YamlElement) -> Self { match chip_type.as_str() { "!memory_chip" => Self::Memory(MemoryChip::default()), "!yolol_chip" => { let mut chip = YololChip { path: yaml["script"].as_str().map(|s| s.to_string()), ..YololChip::default() }; deserialize_field_name!(chip, chip_wait, yaml); Self::Yolol(chip) } _ => Self::None, } } pub fn load(&mut self) { if let Self::Yolol(chip) = self { if let Some(path) = chip.path.clone() { let mut runner = R::default(); if runner.parse(&path).is_some() { chip.runner = Some(runner); } else { println!("cannot find file {}", path); } } } } pub fn step(&mut self) { if let Self::Yolol(chip) = self { if chip.chip_wait.deref().into() { if let Some(runner) = &mut chip.runner { runner.step() } } } } pub fn update_globals(&mut self, globals: Vec<Field>) { if let Self::Yolol(chip) = self { if let Some(runner) = &mut chip.runner { runner.update_globals(globals) } } } pub fn get_global(&self) -> Vec<Field> { if let Self::Yolol(chip) = self { if let Some(runner) = &chip.runner { return runner.get_global(); } } vec![] } } #[derive(Debug, Default)] pub struct MemoryChip {} #[derive(Debug, Default)] pub struct YololChip<R: CodeRunner + Default> { chip_wait: Field, path: Option<String>, runner: Option<R>, } impl<'a, R: CodeRunner + Default> Default for Chip<R> { fn default() -> Self { Self::None } } pub trait CodeRunner: Default { fn parse(&mut self, path: &str) -> Option<()>; fn step(&mut self); fn update_globals(&mut self, globals: Vec<Field>); fn get_global(&self) -> Vec<Field>; } #[derive(Default, Debug)] pub struct NoneRunner; impl CodeRunner for NoneRunner { fn parse(&mut self, _: &str) -> Option<()> { None } fn step(&mut self) {} fn update_globals(&mut self, _: Vec<Field>) {} fn get_global(&self) -> Vec<Field> { vec![] } }