use retracer::{database::Database, interface::component_editor::CommandTypeEditor, History}; /// Generate commands from their type name struct CommandFactory(); impl CommandFactory { fn new() -> Box<CommandFactory> { Box::new(CommandFactory()) } } impl command_factory::CommandFactory for CommandFactory { fn new_command(&self, command_name: CTName) -> Box<dyn Command<D>> { match command_name { "AddCounter" => AddCounter::new(), "RemoveCounter" => RemoveCounter::new(), _ => panic!("Command type does not exist."), } } } /// Add a new Counter struct AddCounter(); impl AddCounter { pub fn new() -> Self { AddCounter() } pub fn register<D: Database + Default>(history: HistoryInterface<D>) -> Result<(), ()> { CommandTypeEditor::new("AddCounter").register_to(history) } pub fn pre_run() {} pub fn setup() {} } impl Command for AddCounter { fn command_type(&self) -> CTName { "AddCounter" } fn set_arguments(&mut self, data: Arguments) {} fn arguments(&self) -> Arguments {} fn run(&self, history: HistoryInterface<D>) -> ExecutionResult<D> { let board = history.get_element_here("MainBoard"); let element_name = change.new_element("Counter"); let counter = Counter { name: element_name, value: 0, }; change.history().element(element_name).new_version(); // new_version_named("X") } } /// Remove a Counter of the Board struct RemoveCounter(Arguments); impl RemoveCounter { pub fn new() -> Self { RemoveCounter(Arguments::new()) } pub fn register<D: Database + Default>(history: HistoryInterface<D>) { CommandTypeEditor::new("RemoveCounter") .arguments(HashMap::from([("self", "Board"), ("idx", "Integer")])) .register_to(history); } } impl Command for RemoveCounter { fn command_type(&self) -> CTName { "RemoveCounter" } fn set_arguments(&mut self, data: Arguments) { self.0 = data; } fn arguments(&self) -> Arguments { self.0 } fn run(&self, change: Change<D>) -> ExecutionResult<D> { let (board, idx): (Board, usize) = change.load_data(); let (board_cmp, idx_cmp): (ElementVersionComponent, InputVersionComponent) = change.load_components(); board_cmp .change(change) .children_mut(change) .remove(board.counters[idx]); } } /// Register command types pub fn register_command_types() { history .register_new_command_type(vec![ AddCounter::type_description(), RemoveCounter::type_description(), IncrementCounter::type_description(), ]) .unwrap() }