@@ 1,3 1,5 @@
+use core::cmp::max;
+use esp_println::println;
use fugit::MicrosDurationU64;
use libm::{ceilf, powf};
use smart_leds::RGB8;
@@ 7,6 9,7 @@ use crate::map::Map;
pub struct SnakeAnimation<const LEDS_COUNT: usize> {
step: usize,
+ finished: bool,
order: [usize; LEDS_COUNT],
previous_factor: f32,
color: RGB8,
@@ 17,12 20,21 @@ impl<const LEDS_COUNT: usize> SnakeAnimation<LEDS_COUNT> {
pub fn new(order: [usize; LEDS_COUNT], previous_factor: f32, color: RGB8, step_duration: MicrosDurationU64) -> Self {
Self {
step: 0,
+ finished: false,
order,
previous_factor,
color,
step_duration
}
}
+
+ fn is_first_step(&self) -> bool {
+ self.step == 1
+ }
+
+ fn is_last_step(&self) -> bool {
+ self.finished
+ }
}
impl<const LEDS_COUNT: usize> Animation for SnakeAnimation<LEDS_COUNT> {
@@ 35,7 47,8 @@ impl<const LEDS_COUNT: usize> Animation for SnakeAnimation<LEDS_COUNT> {
}
fn next(&mut self) -> Result<AnimationStep, AnimationError> {
- if self.step == LEDS_COUNT - 1 {
+ if self.step == LEDS_COUNT + 100 {
+ self.finished = true;
return Err(AnimationError::LastStep);
}
@@ 44,7 57,11 @@ impl<const LEDS_COUNT: usize> Animation for SnakeAnimation<LEDS_COUNT> {
}
fn apply(&mut self, map: &mut Map) -> Result<(), AnimationError> {
- for (i, led_index) in self.order.iter().take(self.step).enumerate() {
+ if self.is_first_step() {
+ map.clear();
+ }
+
+ for (i, led_index) in self.order.iter().take(self.step.max(LEDS_COUNT)).enumerate() {
let mult_factor = self.step - i - 1;
let coeff = powf(self.previous_factor, mult_factor as f32);
let rgb = self.color;
@@ 57,6 74,10 @@ impl<const LEDS_COUNT: usize> Animation for SnakeAnimation<LEDS_COUNT> {
map.set(*led_index, color).ok().unwrap();
}
+ if self.is_last_step() {
+ map.clear();
+ }
+
Ok(())
}
}=
\ No newline at end of file
@@ 0,0 1,58 @@
+use esp_println::println;
+use fugit::ExtU64;
+use smart_leds::RGB8;
+use crate::animations::snake_animation::SnakeAnimation;
+use crate::commands::command_data::CommandData;
+use crate::commands::command_handler::{CommandHandleError, SpecificCommandHandler};
+use crate::commands::command_handler::CommandHandleError::WrongArguments;
+use crate::constants;
+
+#[derive(Default)]
+pub struct SnakeCommand;
+
+impl SpecificCommandHandler for SnakeCommand {
+ fn handle(&self, command: CommandData) -> Result<(), CommandHandleError> {
+ let (cmd, animation) = command.deconstruct_animation();
+
+ if cmd.parsed_arguments().len() < 6 {
+ println!("Less than 6 args.");
+ return Err(WrongArguments);
+ }
+
+ let coeff = cmd.parsed_arguments()[1].try_to_integer();
+
+ let r = cmd.parsed_arguments()[2].try_to_integer();
+ let g = cmd.parsed_arguments()[3].try_to_integer();
+ let b = cmd.parsed_arguments()[4].try_to_integer();
+ let duration = cmd.parsed_arguments()[5].try_to_integer();
+
+ if r.is_none() || g.is_none() || b.is_none() || coeff.is_none() || duration.is_none() {
+ println!("Cold not parse r, g, b, coeff or duration.");
+ return Err(WrongArguments);
+ }
+
+ let coeff = coeff.unwrap();
+ let r = r.unwrap();
+ let g = g.unwrap();
+ let b = b.unwrap();
+ let duration = duration.unwrap();
+
+ if r > 255 || g > 255 || b > 255 || coeff > 255 {
+ return Err(WrongArguments);
+ }
+ let coeff = coeff as f32 / 255.0;
+
+ animation
+ .set_animation(SnakeAnimation::<{ constants::LEDS_COUNT }>::new(
+ [24, 19, 16, 10, 15, 9, 6, 8, 3, 0, 4, 1, 2, 5, 11, 7, 12, 18, 21, 29, 27, 34, 38, 31, 17, 25, 45, 30, 36, 35, 42, 44, 56, 48, 61, 57, 65, 68, 59, 49, 55, 63, 71, 69, 62, 47, 53, 46, 51, 64, 52, 67, 70, 66, 60, 58, 54, 50, 37, 40, 41, 23, 22, 14, 13, 20, 28, 33, 39, 43, 32, 26],
+ coeff,
+ RGB8 { r: r as u8, g: g as u8, b: b as u8 },
+ (duration as u64 * 1000u64).micros())
+ );
+ Ok(())
+ }
+
+ fn help(&self) -> &'static str {
+ "<coeff> <R> <G> <B> <duration> - Let snake run with the given base color and coefficient of light off"
+ }
+}<
\ No newline at end of file