Compare commits
23 Commits
wip-1
...
da2a8f5bfc
Author | SHA1 | Date | |
---|---|---|---|
da2a8f5bfc | |||
d09c82c3fc | |||
c9496e3dc3 | |||
bbdb3d7404 | |||
a237bb7dc8 | |||
3a850105a8 | |||
7d44c11c78 | |||
457ae73c50 | |||
8bb46b6f78 | |||
4b256bc0d9 | |||
2af9918239 | |||
bfdf7c3230 | |||
b6e34111ff | |||
|
e57ceeb149 | ||
|
e0491fafe8 | ||
|
bf4ef46699 | ||
|
42fc0b0c62 | ||
|
3c3952a8a9 | ||
|
2f8b94ae61 | ||
|
d7f312ffe4 | ||
|
9a749c40a1 | ||
|
272bc49eaa | ||
|
b468eb8533 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
/.vscode
|
||||
/.embuild
|
||||
/target
|
||||
/Cargo.lock
|
26
.vscode/launch.json
vendored
26
.vscode/launch.json
vendored
@@ -1,26 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "probe-rs-debug",
|
||||
"request": "launch",
|
||||
"name": "probe-rs Test",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"connectUnderReset": true,
|
||||
"chip": "ESP32S3",
|
||||
"flashingConfig": {
|
||||
"flashingEnabled": true,
|
||||
"haltAfterReset": true
|
||||
},
|
||||
"coreConfigs": [
|
||||
{
|
||||
"coreIndex": 0,
|
||||
"programBinary": "./target/xtensa-esp32s3-espidf/debug/${workspaceFolderBasename}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -11,13 +11,11 @@ name = "renderbug"
|
||||
harness = false # do not use the built in cargo test harness -> resolve rust-analyzer errors
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
lto = true
|
||||
opt-level = "s"
|
||||
|
||||
[profile.dev]
|
||||
debug = true # Symbols are nice and they don't increase the size on Flash
|
||||
opt-level = "z"
|
||||
lto = true
|
||||
|
||||
[features]
|
||||
default = ["std", "esp-idf-svc/native", "rmt", "smart-leds"]
|
||||
@@ -50,7 +48,6 @@ embedded-graphics = { version = "0.8.1", optional = true, features = ["fixed_poi
|
||||
ansi_term = "0.12.1"
|
||||
num = "0.4.3"
|
||||
chrono = "0.4.38"
|
||||
fugit = "0.3.7"
|
||||
|
||||
[build-dependencies]
|
||||
embuild = "0.32.0"
|
||||
|
1
espflash.toml
Normal file
1
espflash.toml
Normal file
@@ -0,0 +1 @@
|
||||
partition_table = "partitions.csv"
|
5
partitions.csv
Normal file
5
partitions.csv
Normal file
@@ -0,0 +1,5 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, , 0x6000,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
factory, app, factory, , 3M,
|
|
13
src/TODO.md
13
src/TODO.md
@@ -1,15 +1,18 @@
|
||||
[x] cfg macros
|
||||
[ ] warnings
|
||||
[x] rgb crate
|
||||
[ ] Layer blending
|
||||
[ ] Refactor idle pattern into test pattern
|
||||
[ ] Wifi
|
||||
[x] Layer blending
|
||||
[x] Refactor idle pattern into test pattern
|
||||
[x] Wifi
|
||||
[ ] JSON surface map loading
|
||||
[ ] Weather
|
||||
[ ] Circadian Rhythm
|
||||
[ ] NTP
|
||||
[x] Circadian Rhythm
|
||||
[x] NTP
|
||||
[ ] Config to only start a subset of tasks on startup
|
||||
[ ] Serial CLI
|
||||
[ ] Surface blending API
|
||||
[ ] Layer blending equations
|
||||
[ ] Surface rotation
|
||||
[ ] esp8266 port
|
||||
[ ] event system
|
||||
[ ] threaded schedulers
|
18
src/main.rs
18
src/main.rs
@@ -21,29 +21,31 @@ use crate::geometry::Rectangle;
|
||||
fn main() {
|
||||
let mut board: DefaultBoard = Board::take();
|
||||
|
||||
log::info!("Board: {}", core::any::type_name_of_val(&board));
|
||||
log::info!("🐛 Booting Renderbug!");
|
||||
|
||||
log::info!("Creating tasks");
|
||||
log::info!("📡 Board {}", core::any::type_name_of_val(&board));
|
||||
|
||||
log::info!("⚙️ Creating tasks");
|
||||
let mut system = board.system_tasks();
|
||||
log::info!("System scheduler: {}", core::any::type_name_of_val(&system));
|
||||
log::info!("⏰ System scheduler: {}", core::any::type_name_of_val(&system));
|
||||
|
||||
log::info!("Creating output");
|
||||
log::info!("💡 Creating output");
|
||||
let output = board.output();
|
||||
log::info!("Output: {}", core::any::type_name_of_val(&output));
|
||||
|
||||
log::info!("Preparing surfaces");
|
||||
log::info!("🎨 Preparing surfaces");
|
||||
let mut surfaces = board.surfaces();
|
||||
log::info!("Surface implementation: {}", core::any::type_name_of_val(&output));
|
||||
|
||||
log::info!("Creating animations");
|
||||
log::info!("🌌 Creating animations");
|
||||
let mut animations = FixedSizeScheduler::new([
|
||||
Box::new(animations::IdleTask::new(&mut surfaces)),
|
||||
//Box::new(animations::TestPattern::new(surfaces.new_surface(&Rectangle::everything()).unwrap())),
|
||||
Box::new(animations::TestPattern::new(surfaces.new_surface(&Rectangle::everything()).unwrap())),
|
||||
]);
|
||||
|
||||
let mut renderer = FixedSizeScheduler::new([Box::new(Renderer::new(output, surfaces))]);
|
||||
|
||||
log::info!("Starting event bus");
|
||||
log::info!("🚌 Starting event bus");
|
||||
let mut bus = EventBus::new();
|
||||
|
||||
log::info!("Ready to rock and roll");
|
||||
|
@@ -20,7 +20,7 @@ pub trait Select<'a> {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LinearCoordView {
|
||||
rect: Rectangle<Virtual>,
|
||||
max_x: u8,
|
||||
idx: usize,
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ pub type LinearCoords = Coordinates<LinearSpace>;
|
||||
impl<'a> CoordinateView<'a> for LinearCoordView {
|
||||
type Space = LinearSpace;
|
||||
fn next(&mut self) -> Option<(VirtualCoordinates, LinearCoords)> {
|
||||
if self.idx as u8 == self.rect.bottom_right.x {
|
||||
if self.idx as u8 == self.max_x {
|
||||
None
|
||||
} else {
|
||||
let virt = VirtualCoordinates::new(self.idx as u8, 0); // FIXME: scale8
|
||||
@@ -62,7 +62,7 @@ impl<'a> Select<'a> for LinearPixelMapping {
|
||||
type View = LinearCoordView;
|
||||
fn select(&'a self, rect: &Rectangle<Virtual>) -> Self::View {
|
||||
LinearCoordView {
|
||||
rect: rect.clone(),
|
||||
max_x: rect.bottom_right.x,
|
||||
idx: 0,
|
||||
}
|
||||
}
|
||||
@@ -107,6 +107,24 @@ impl<const STRIDE_NUM: usize> StrideMapping<STRIDE_NUM> {
|
||||
])
|
||||
}
|
||||
|
||||
pub fn new_cyberplague() -> Self {
|
||||
Self::from_json(&[
|
||||
(0, 6, 6, false),
|
||||
(1, 6, 6, true),
|
||||
(2, 6, 6, false),
|
||||
(3, 4, 9, true),
|
||||
(4, 4, 14, false),
|
||||
(5, 0, 17, true),
|
||||
(6, 2, 12, false),
|
||||
(7, 0, 18, true),
|
||||
(8, 4, 14, false),
|
||||
(9, 5, 9, true),
|
||||
(10, 4, 7, false),
|
||||
(11, 5, 6, true),
|
||||
(12, 5, 6, false)
|
||||
])
|
||||
}
|
||||
|
||||
pub fn new_jar() -> Self {
|
||||
Self::from_json(&[
|
||||
(0, 0, 17, false),
|
||||
@@ -151,6 +169,12 @@ impl<const STRIDE_NUM: usize> StrideMapping<STRIDE_NUM> {
|
||||
])
|
||||
}
|
||||
|
||||
pub fn new_albus() -> Self {
|
||||
Self::from_json(&[
|
||||
(0, 0, 50 * 3, false)
|
||||
])
|
||||
}
|
||||
|
||||
pub fn from_json(stride_json: &[(u8, u8, u8, bool)]) -> Self {
|
||||
let mut strides = [Stride::default(); STRIDE_NUM];
|
||||
let stride_count = stride_json.len();
|
||||
@@ -191,8 +215,6 @@ impl<const STRIDE_NUM: usize> StrideMapping<STRIDE_NUM> {
|
||||
let s = size.take().unwrap();
|
||||
log::info!("size={:?}", s);
|
||||
|
||||
log::info!("strides={:?}", strides);
|
||||
|
||||
Self {
|
||||
strides,
|
||||
pixel_count: physical_idx,
|
||||
|
@@ -10,8 +10,10 @@ use chrono::Timelike;
|
||||
use chrono::Utc;
|
||||
|
||||
use esp_idf_svc::eventloop::{EspSubscription, EspSystemEventLoop, System};
|
||||
use esp_idf_svc::hal::gpio::Pins;
|
||||
use esp_idf_svc::hal::modem::Modem;
|
||||
use esp_idf_svc::hal::prelude::Peripherals;
|
||||
use esp_idf_svc::hal::rmt::RMT;
|
||||
use esp_idf_svc::hal::task::thread::ThreadSpawnConfiguration;
|
||||
use esp_idf_svc::mqtt::client::EspMqttClient;
|
||||
use esp_idf_svc::mqtt::client::EspMqttConnection;
|
||||
@@ -37,66 +39,12 @@ use crate::task::FixedSizeScheduler;
|
||||
use crate::task::Task;
|
||||
use crate::time::Periodically;
|
||||
|
||||
pub mod i2s {
|
||||
use esp_idf_svc::hal::i2s::*;
|
||||
use rgb::ComponentBytes;
|
||||
use rgb::Rgb;
|
||||
|
||||
use crate::mappings::*;
|
||||
use crate::buffers::Pixbuf;
|
||||
use crate::render::Output;
|
||||
use crate::render::Sample;
|
||||
|
||||
pub struct I2SOutput<'d> {
|
||||
driver: I2sDriver<'d, I2sTx>,
|
||||
pixbuf: [Rgb<u8>; 310],
|
||||
pixmap: StrideMapping,
|
||||
}
|
||||
|
||||
impl<'d> I2SOutput<'d> {
|
||||
fn new(driver: I2sDriver<'d, I2sTx>) -> Self {
|
||||
I2SOutput {
|
||||
driver,
|
||||
pixbuf: Pixbuf::new(),
|
||||
pixmap: StrideMapping::new_jar()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d> Output for I2SOutput<'d> {
|
||||
fn on_event(&mut self, event: &crate::events::Event) {
|
||||
|
||||
}
|
||||
|
||||
fn blank(&mut self) {
|
||||
self.pixbuf.blank();
|
||||
}
|
||||
|
||||
fn commit(&mut self) {
|
||||
let bytes = self.pixbuf.as_bytes();
|
||||
let mut written = self.driver.preload_data(bytes).unwrap();
|
||||
self.driver.tx_enable().unwrap();
|
||||
while written < bytes.len() {
|
||||
let next = &bytes[written..];
|
||||
written += self.driver.write(next, 0).unwrap();
|
||||
}
|
||||
self.driver.tx_disable().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d> Sample for I2SOutput<'d> {
|
||||
type Pixel = Rgb<u8>;
|
||||
fn sample(&mut self, rect: &crate::geometry::Rectangle<crate::geometry::Virtual>) -> impl crate::render::PixelView<Pixel = Self::Pixel> {
|
||||
StrideSampler::new(&mut self.pixbuf, self.pixmap.select(rect))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Esp32Board {
|
||||
sys_loop: EspSystemEventLoop,
|
||||
modem: Option<Modem>,
|
||||
pins: Option<Pins>,
|
||||
rmt: Option<RMT>,
|
||||
surfaces: BufferedSurfacePool,
|
||||
output: Option<<Self as Board>::Output>
|
||||
}
|
||||
|
||||
impl Board for Esp32Board {
|
||||
@@ -104,6 +52,14 @@ impl Board for Esp32Board {
|
||||
type Surfaces = BufferedSurfacePool;
|
||||
type Scheduler = FixedSizeScheduler<4>;
|
||||
|
||||
fn chip_id() -> u64 {
|
||||
let mut chip_id: [u8; 8] = [0; 8];
|
||||
unsafe {
|
||||
esp_efuse_mac_get_default(&mut chip_id as *mut u8);
|
||||
}
|
||||
return u64::from_be_bytes(chip_id);
|
||||
}
|
||||
|
||||
fn take() -> Self {
|
||||
// It is necessary to call this function once. Otherwise some patches to the runtime
|
||||
// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
|
||||
@@ -115,18 +71,25 @@ impl Board for Esp32Board {
|
||||
let peripherals = Peripherals::take().unwrap();
|
||||
let sys_loop = EspSystemEventLoop::take().unwrap();
|
||||
|
||||
let mut chip_id: [u8; 8] = [0; 8];
|
||||
unsafe {
|
||||
esp_efuse_mac_get_default(&mut chip_id as *mut u8);
|
||||
Esp32Board {
|
||||
modem: Some(peripherals.modem),
|
||||
sys_loop: sys_loop.clone(),
|
||||
surfaces: BufferedSurfacePool::new(),
|
||||
pins: Some(peripherals.pins),
|
||||
rmt: Some(peripherals.rmt)
|
||||
}
|
||||
}
|
||||
|
||||
log::info!("Setting up output for chip ID {:x?}", chip_id);
|
||||
fn output(&mut self) -> Self::Output {
|
||||
|
||||
log::info!("Setting up output for chip ID {:x?}", Self::chip_id());
|
||||
|
||||
const POWER_VOLTS : u32 = 5;
|
||||
const POWER_MA : u32 = 500;
|
||||
const MAX_POWER_MW : u32 = POWER_VOLTS * POWER_MA;
|
||||
let pins = peripherals.pins;
|
||||
|
||||
let pins = self.pins.take().unwrap();
|
||||
let rmt = self.rmt.take().unwrap();
|
||||
ThreadSpawnConfiguration {
|
||||
pin_to_core: Some(esp_idf_svc::hal::cpu::Core::Core1),
|
||||
..Default::default()
|
||||
@@ -135,12 +98,12 @@ impl Board for Esp32Board {
|
||||
// But the implementation spawns a thread based on the core the driver was created in,
|
||||
// so we create the driver in another thread briefly.
|
||||
// Fun stuff.
|
||||
let output = match chip_id { // panel test board
|
||||
let output = match Self::chip_id().to_be_bytes() { // panel test board
|
||||
[72, 202, 67, 89, 145, 204, 0, 0] => {
|
||||
StrideOutput::new(
|
||||
Pixbuf::new(),
|
||||
StrideMapping::new_panel(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(peripherals.rmt.channel0, pins.gpio5).unwrap() }).join().unwrap(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(rmt.channel0, pins.gpio5).unwrap() }).join().unwrap(),
|
||||
MAX_POWER_MW
|
||||
)
|
||||
},
|
||||
@@ -148,15 +111,15 @@ impl Board for Esp32Board {
|
||||
StrideOutput::new(
|
||||
Pixbuf::new(),
|
||||
StrideMapping::new_jar(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(peripherals.rmt.channel0, pins.gpio14).unwrap() }).join().unwrap(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(rmt.channel0, pins.gpio14).unwrap() }).join().unwrap(),
|
||||
MAX_POWER_MW
|
||||
)
|
||||
},
|
||||
[0x4a, 0xca, 0x43, 0x59, 0x85, 0x58, 0x0, 0x0] => { // Albus the tree
|
||||
StrideOutput::new(
|
||||
Pixbuf::new(),
|
||||
StrideMapping::new_jar(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(peripherals.rmt.channel0, pins.gpio5).unwrap() }).join().unwrap(),
|
||||
StrideMapping::new_albus(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(rmt.channel0, pins.gpio5).unwrap() }).join().unwrap(),
|
||||
MAX_POWER_MW
|
||||
)
|
||||
},
|
||||
@@ -164,7 +127,7 @@ impl Board for Esp32Board {
|
||||
StrideOutput::new(
|
||||
Pixbuf::new(),
|
||||
StrideMapping::new_fairylights(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(peripherals.rmt.channel0, pins.gpio5).unwrap() }).join().unwrap(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(rmt.channel0, pins.gpio5).unwrap() }).join().unwrap(),
|
||||
MAX_POWER_MW
|
||||
)
|
||||
},
|
||||
@@ -172,15 +135,23 @@ impl Board for Esp32Board {
|
||||
StrideOutput::new(
|
||||
Pixbuf::new(),
|
||||
StrideMapping::new_fairylights(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(peripherals.rmt.channel0, pins.gpio5).unwrap() }).join().unwrap(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(rmt.channel0, pins.gpio5).unwrap() }).join().unwrap(),
|
||||
MAX_POWER_MW
|
||||
)
|
||||
}
|
||||
},
|
||||
[0xfc, 0xf5, 0xc4, 0x05, 0xb8, 0x30, 0x0, 0x0] => { // cyberplague
|
||||
StrideOutput::new(
|
||||
Pixbuf::new(),
|
||||
StrideMapping::new_cyberplague(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(rmt.channel0, pins.gpio13).unwrap() }).join().unwrap(),
|
||||
MAX_POWER_MW
|
||||
)
|
||||
},
|
||||
_ => {
|
||||
StrideOutput::new(
|
||||
Pixbuf::new(),
|
||||
StrideMapping::new(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(peripherals.rmt.channel0, pins.gpio5).unwrap() }).join().unwrap(),
|
||||
std::thread::spawn(move || { FastWs2812Esp32Rmt::new(rmt.channel0, pins.gpio5).unwrap() }).join().unwrap(),
|
||||
MAX_POWER_MW
|
||||
)
|
||||
}
|
||||
@@ -189,16 +160,7 @@ impl Board for Esp32Board {
|
||||
..Default::default()
|
||||
}.set().unwrap();
|
||||
|
||||
Esp32Board {
|
||||
modem: Some(peripherals.modem),
|
||||
sys_loop: sys_loop.clone(),
|
||||
surfaces: BufferedSurfacePool::new(),
|
||||
output: Some(output)
|
||||
}
|
||||
}
|
||||
|
||||
fn output(&mut self) -> Self::Output {
|
||||
self.output.take().unwrap()
|
||||
output
|
||||
}
|
||||
|
||||
fn surfaces(&mut self) -> Self::Surfaces {
|
||||
@@ -265,9 +227,9 @@ impl CircadianRhythm {
|
||||
adjusted_end.hour += 24;
|
||||
}
|
||||
|
||||
let start_time = start.hour * 60;
|
||||
let end_time = end.hour * 60;
|
||||
let now_time = hour * 60 + minute;
|
||||
let start_time = (start.hour as u16).wrapping_mul(60);
|
||||
let end_time = (end.hour as u16).wrapping_mul(60);
|
||||
let now_time = (hour as u16).wrapping_mul(60).wrapping_add(minute as u16);
|
||||
|
||||
let duration = end_time - start_time;
|
||||
let cur_duration = now_time - start_time;
|
||||
@@ -499,6 +461,8 @@ impl Task for WifiTask {
|
||||
|
||||
fn stop(&mut self) {
|
||||
log::info!("Stopping wifi");
|
||||
self.wifi_sub.take().unwrap();
|
||||
self.ip_sub.take().unwrap();
|
||||
self.disconnect();
|
||||
}
|
||||
}
|
||||
|
@@ -1,44 +0,0 @@
|
||||
use rgb::Rgb;
|
||||
use super::smart_leds_lib::rmt::FastWs2812Esp32Rmt;
|
||||
use super::smart_leds_lib::StrideOutput;
|
||||
|
||||
use crate::task::{FixedSizeScheduler, Task};
|
||||
use crate::buffers::StaticSurfacePool;
|
||||
|
||||
use super::Board;
|
||||
|
||||
pub struct Esp32Board<'a> {
|
||||
output: Option<<Self as Board>::Output>,
|
||||
surfaces: Option<StaticSurfacePool>,
|
||||
tasks: Option<[&'a mut dyn Task; 1]>
|
||||
}
|
||||
|
||||
impl<'a> Board for Esp32Board<'a> {
|
||||
type Output = StrideOutput<[Rgb<u8>; 310], FastWs2812Esp32Rmt<'a>>;
|
||||
type Surfaces = StaticSurfacePool;
|
||||
type Scheduler = FixedSizeScheduler<0>;
|
||||
fn take() -> Self {
|
||||
let peripherals = esp_hal::init(esp_hal::Config::default());
|
||||
//esp_alloc::heap_allocator!(72 * 1024);
|
||||
|
||||
const POWER_VOLTS : u32 = 5;
|
||||
const POWER_MA : u32 = 500;
|
||||
const MAX_POWER_MW : u32 = POWER_VOLTS * POWER_MA;
|
||||
let pins = peripherals.pins;
|
||||
|
||||
|
||||
Esp32Board { output: None, surfaces: None, tasks: None }
|
||||
}
|
||||
|
||||
fn output(&mut self) -> Self::Output {
|
||||
self.output.take().unwrap()
|
||||
}
|
||||
|
||||
fn surfaces(&mut self) -> Self::Surfaces {
|
||||
self.surfaces.take().unwrap()
|
||||
}
|
||||
|
||||
fn system_tasks(&mut self) -> Self::Scheduler {
|
||||
FixedSizeScheduler::new([])
|
||||
}
|
||||
}
|
@@ -20,4 +20,5 @@ pub trait Board {
|
||||
fn output(&mut self) -> Self::Output;
|
||||
fn surfaces(&mut self) -> Self::Surfaces;
|
||||
fn system_tasks(&mut self) -> Self::Scheduler;
|
||||
fn chip_id() -> u64;
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
use smart_leds_trait::SmartLedsWrite;
|
||||
|
||||
use crate::buffers::Pixbuf;
|
||||
use crate::events::Variant;
|
||||
use crate::render::{HardwarePixel, Output, PixelView, Sample};
|
||||
use crate::power::brightness_for_mw;
|
||||
use crate::geometry::*;
|
||||
@@ -57,7 +56,7 @@ impl<P: Pixbuf<Pixel=T::Color>, T: FastWrite> Output for StrideOutput<P, T> {
|
||||
|
||||
fn on_event(&mut self, event: &crate::events::Event) {
|
||||
match event {
|
||||
crate::events::Event::PropertyChange("output.brightness", new_brightness) => self.brightness = new_brightness.clone().into(),
|
||||
crate::events::Event::PropertyChange("output.brightness", Variant::Byte(new_brightness)) => self.brightness = *new_brightness,
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
16
src/task.rs
16
src/task.rs
@@ -42,18 +42,18 @@ impl ScheduledTask {
|
||||
}
|
||||
|
||||
fn start(&mut self) {
|
||||
self.state = match self.state {
|
||||
ScheduledState::Stopped => ScheduledState::Start,
|
||||
ScheduledState::Stop => ScheduledState::Running,
|
||||
_ => self.state
|
||||
match self.state {
|
||||
ScheduledState::Stopped => self.state = ScheduledState::Start,
|
||||
ScheduledState::Stop => self.state = ScheduledState::Running,
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
fn stop(&mut self) {
|
||||
self.state = match self.state {
|
||||
ScheduledState::Running => ScheduledState::Stop,
|
||||
ScheduledState::Start => ScheduledState::Stopped,
|
||||
_ => self.state
|
||||
match self.state {
|
||||
ScheduledState::Running => self.state = ScheduledState::Stop,
|
||||
ScheduledState::Start => self.state = ScheduledState::Stopped,
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
use core::time::Duration;
|
||||
use std::time::Instant;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug)]
|
||||
pub struct Periodically {
|
||||
last_run: Instant,
|
||||
duration: Duration
|
||||
|
Reference in New Issue
Block a user