emb_ssdraw/lib.rs
1//! A simple screen saver for the display
2//!
3//! This is a simple screen saver that draws a random number of points on the display.
4//!
5//! # Usage
6//!
7//! Cargo.toml
8//! ```
9//! [dependencies]
10//! rand = { version = "0.8.5", features = ["small_rng"], default-features = false }
11//! ```
12//!
13//! src/main.rs
14//! ```
15//! use rand::rngs::SmallRng;
16//! use rand::SeedableRng;
17//!
18//! let mut rng = SmallRng::seed_from_u64(42);
19//! let mut screen_saver = ScreenSaver::<_, 32>::new(rng);
20//! let mut display = Display::new();
21//! loop {
22//! display.clear();
23//! screen_saver.tick_draw(&mut display);
24//! display.flush();
25//! }
26//!
27//! ```
28
29#![no_std]
30use embedded_graphics::{pixelcolor::BinaryColor, prelude::*, Drawable};
31use heapless::Vec;
32use rand::RngCore;
33
34/// A screen saver that draws a random number of points on the display
35pub struct ScreenSaver<R, const N: usize> {
36 points: Vec<Point, N>,
37 rng: R,
38}
39impl<R: RngCore, const N: usize> ScreenSaver<R, N> {
40 /// Create a new screen saver
41 pub fn new(rng: R) -> Self {
42 Self {
43 points: Vec::new(),
44 rng,
45 }
46 }
47 /// Tick the screen saver and draw it to the target
48 /// this is alias for calling [`tick`](ScreenSaver::tick) with target size and after [`draw`](ScreenSaver::draw) with the target
49 pub fn tick_draw<D>(&mut self, target: &mut D) -> Result<(), D::Error>
50 where
51 D: DrawTarget<Color = BinaryColor>,
52 {
53 let size = target.bounding_box().size;
54 self.tick(size.width, size.height);
55 self.draw(target)
56 }
57
58 /// Tick the screen saver and add a new point to the list
59 /// If the inner points buffer is full, the oldest point will be removed
60 /// panics if either w or h are greater than i32::max().
61 pub fn tick(&mut self, w: u32, h: u32) {
62 let x = (self.rng.next_u32() % w) as i32;
63 let y = (self.rng.next_u32() % h) as i32;
64 if let Err(overflowed) = self.points.push(Point::new(x, y)) {
65 self.points.remove(0);
66 let _ = self.points.push(overflowed);
67 }
68 }
69}
70
71impl<R: RngCore, const N: usize> Drawable for ScreenSaver<R, N> {
72 type Color = BinaryColor;
73 type Output = ();
74 fn draw<D>(&self, target: &mut D) -> Result<(), D::Error>
75 where
76 D: DrawTarget<Color = Self::Color>,
77 {
78 for p in self.points.iter() {
79 let _ = Pixel(*p, BinaryColor::On).draw(target);
80 }
81 Ok(())
82 }
83}