From 1a40f2e6614ff88f9b392b495c03c1f14a5effe0 Mon Sep 17 00:00:00 2001 From: Alex Mikhalev Date: Thu, 17 Jan 2019 14:08:47 -0800 Subject: [PATCH] Make CommandGroup a GenericCommand --- src/command.rs | 69 ++++++++++++++++++++++++++------------------------ src/robot.rs | 4 +-- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/command.rs b/src/command.rs index a478763..53075d1 100644 --- a/src/command.rs +++ b/src/command.rs @@ -164,22 +164,25 @@ macro_rules! command_impl { pub type CommandRef = Rc>; -pub struct CommandGroup { - commands: Vec, - command_data: CommandData, +pub struct CommandGroupConfig { + pub commands: Vec, +} + +impl CommandGroupConfig { + pub fn new(commands: Vec) -> Self { + Self { commands } + } +} + +pub struct CommandGroupState { current_idx: Option, has_initialized: bool, has_cancelled: bool, } -impl CommandGroup { - pub fn new(data: CommandData, commands: TCommands) -> Self - where - TCommands: IntoIterator, - { - CommandGroup { - commands: commands.into_iter().collect(), - command_data: data, +impl Default for CommandGroupState { + fn default() -> Self { + CommandGroupState { current_idx: None, has_initialized: false, has_cancelled: false, @@ -187,51 +190,49 @@ impl CommandGroup { } } -impl WithCommandData for CommandGroup { - fn command_data(&self) -> &CommandData { - &self.command_data - } -} +pub type CommandGroup = GenericCommand; impl Command for CommandGroup { fn init(&mut self) { - if self.current_idx.is_some() { + if self.state.current_idx.is_some() { error!("CommandGroup init called twice"); } - self.current_idx = Some(0); - self.has_initialized = false; - self.has_cancelled = false; + self.state.current_idx = Some(0); + self.state.has_initialized = false; + self.state.has_cancelled = false; debug!("CommandGroup {} init", self.command_data().name()); } fn step(&mut self) -> CommandResult { use self::CommandResult::*; - if self.has_cancelled { + let state = &mut self.state; + let commands = &self.config.commands; + if state.has_cancelled { debug!("CommandGroup step called after cancelled"); return CommandResult::Cancel; } - let mut current_idx = if let Some(c) = self.current_idx { + let mut current_idx = if let Some(c) = state.current_idx { c } else { error!("CommandGroup step called before init"); - self.has_cancelled = true; + state.has_cancelled = true; return CommandResult::Cancel; }; let mut result: CommandResult; loop { - if current_idx >= self.commands.len() { + if current_idx >= commands.len() { debug!("CommandGroup out of commands"); return CommandResult::Done; } - let mut command = self.commands[current_idx].borrow_mut(); - if !self.has_initialized { + let mut command = commands[current_idx].borrow_mut(); + if !state.has_initialized { debug!( "CommandGroup init {0} ({1})", current_idx, command.command_data().name() ); command.init(); - self.has_initialized = true; + state.has_initialized = true; } result = command.step(); if result != Continue { @@ -246,29 +247,31 @@ impl Command for CommandGroup { match result { Done => { current_idx += 1; - self.has_initialized = false; + state.has_initialized = false; } Cancel => { - self.has_cancelled = true; + state.has_cancelled = true; break; } _ => break, } } - self.current_idx = Some(current_idx); + state.current_idx = Some(current_idx); CommandResult::Continue } fn finish(&mut self, result: CommandResult) { + let state = &mut self.state; + let commands = &mut self.config.commands; if result == CommandResult::Cancel { - if let Some(command) = self + if let Some(command) = state .current_idx - .and_then(|current_idx| self.commands.get(current_idx)) + .and_then(|current_idx| commands.get(current_idx)) { command.borrow_mut().finish(result); } } - self.current_idx = None; + state.current_idx = None; } } diff --git a/src/robot.rs b/src/robot.rs index 6704a95..1316a4e 100644 --- a/src/robot.rs +++ b/src/robot.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use std::thread; use std::time::Duration; -use command::{CommandData, CommandGroup, CommandRef, CommandScheduler}; +use command::{CommandData, CommandGroup, CommandGroupConfig, CommandRef, CommandScheduler}; use drive::{Drive, DriveRef}; mod cmds { @@ -77,7 +77,7 @@ impl Robot { let log_command = cmds::LogCmd::new_ref(CommandData::new(2, "LogCommand"), ()); let command_group = CommandGroup::new( CommandData::new(1, "Group"), - vec![command, log_command], + CommandGroupConfig::new(vec![command, log_command]), ); let command_ref: CommandRef = Rc::new(RefCell::new(command_group));