use rmicrobit::display::Render; use rmicrobit::graphics::image::GreyscaleImage; use rmicrobit::graphics::scrolling::{Animate, ScrollingImages}; use rmicrobit::graphics::scrolling_text; pub trait Animator { type Image: Render; fn next(&mut self); fn get_image(&self) -> Self::Image; } pub trait RefAnimator { type Image: Render; fn next(&mut self); fn get_image_ref(&self) -> &Self::Image; } struct Ticker { slowdown: usize, subtick: usize, } impl Ticker { fn reset(&mut self, slowdown: usize) { self.slowdown = slowdown; self.subtick = 0; } fn tick(&mut self) -> bool { self.subtick += 1; if self.subtick == self.slowdown { self.subtick = 0; true } else { false } } } impl Default for Ticker { fn default() -> Ticker { Ticker {slowdown: 1, subtick: 0} } } /////////// pub struct FunctionalAnimation { pub length: usize, pub render: fn (usize) -> GreyscaleImage, } impl FunctionalAnimation { const BLANK: FunctionalAnimation = FunctionalAnimation { length: 1, render: { fn blank(_index: usize) -> GreyscaleImage {GreyscaleImage::blank()}; blank }, }; } pub struct FunctionalAnimator { frame_index: usize, animation: &'static FunctionalAnimation, } impl FunctionalAnimator { pub fn reset(&mut self, animation: &'static FunctionalAnimation) { self.frame_index = 0; self.animation = animation; } } impl Default for FunctionalAnimator { fn default() -> FunctionalAnimator { FunctionalAnimator { frame_index: 0, animation: &FunctionalAnimation::BLANK, } } } impl Animator for FunctionalAnimator { type Image = GreyscaleImage; fn next(&mut self) { self.frame_index += 1; if self.frame_index == self.animation.length { self.frame_index = 0; } } fn get_image(&self) -> Self::Image { (self.animation.render)(self.frame_index) } } /////////// #[derive(Default)] pub struct ScrollingImageAnimator { ticker: Ticker, scroller: ScrollingImages<&'static GreyscaleImage>, } impl ScrollingImageAnimator { pub fn reset(&mut self, images: &'static [&'static GreyscaleImage], slowdown: usize) { self.ticker.reset(slowdown); self.scroller.set_images(images); } } impl RefAnimator for ScrollingImageAnimator { type Image = ScrollingImages<&'static GreyscaleImage>; fn next(&mut self) { if self.ticker.tick() { self.scroller.tick(); } } fn get_image_ref(&self) -> &Self::Image { &self.scroller } } /////////// #[derive(Default)] pub struct ScrollingStaticTextAnimator { ticker: Ticker, scroller: scrolling_text::ScrollingStaticText, } impl ScrollingStaticTextAnimator { pub fn reset(&mut self, message: &'static [u8], slowdown: usize) { self.ticker.reset(slowdown); self.scroller.set_message(message); } } impl RefAnimator for ScrollingStaticTextAnimator { type Image = scrolling_text::ScrollingStaticText; fn next(&mut self) { if self.ticker.tick() { self.scroller.tick(); } } fn get_image_ref(&self) -> &Self::Image { &self.scroller } } /////////// #[derive(Default)] pub struct ScrollingBufferedTextAnimator { ticker: Ticker, scroller: scrolling_text::ScrollingBufferedText, } impl ScrollingBufferedTextAnimator { pub fn reset(&mut self, message: &[u8], slowdown: usize) { self.ticker.reset(slowdown); self.scroller.set_message(message); } } impl RefAnimator for ScrollingBufferedTextAnimator { type Image = scrolling_text::ScrollingBufferedText; fn next(&mut self) { if self.ticker.tick() { self.scroller.tick(); } } fn get_image_ref(&self) -> &Self::Image { &self.scroller } }