events: rewrite the eventing system to reduce mutex usage to just the measurement bus

This commit is contained in:
2025-12-24 09:11:16 +01:00
parent 36f232f43c
commit 046406291a
11 changed files with 185 additions and 284 deletions

View File

@@ -1,13 +1,12 @@
use alloc::sync::Arc;
use display_interface::DisplayError;
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex, pubsub::DynSubscriber};
use embassy_time::{Duration, Instant, Timer};
use embedded_graphics::{pixelcolor::BinaryColor, prelude::DrawTarget};
use figments::{mappings::embedded_graphics::Matrix2DSpace, prelude::{Coordinates, Rectangle}, render::{RenderSource, Shader}, surface::{BufferedSurfacePool, NullSurface, NullBufferPool, Surface, SurfaceBuilder, Surfaces}};
use figments_render::output::{Brightness, OutputAsync};
use embassy_time::{Duration, Timer};
use embedded_graphics::pixelcolor::BinaryColor;
use figments::{mappings::embedded_graphics::Matrix2DSpace, prelude::{Coordinates, Rectangle}, render::Shader, surface::{BufferedSurfacePool, NullBufferPool, Surface, SurfaceBuilder, Surfaces}};
use figments_render::output::Brightness;
use log::*;
use crate::{animation::Animation, backoff::Backoff, events::{Notification, Prediction, SensorSource, SensorState, Telemetry}, graphics::{display::DisplayControls, oled_ui::{OledUniforms, Screen}}};
use crate::{animation::Animation, events::{Personality, Prediction}, graphics::{display::DisplayControls, oled_ui::{OledUniforms, Screen}}};
#[cfg(feature="oled")]
pub type OledUiSurfacePool = BufferedSurfacePool<OledUniforms, Matrix2DSpace, BinaryColor>;
@@ -22,7 +21,7 @@ pub type LockedUniforms = Arc<Mutex<CriticalSectionRawMutex, OledUniforms>>;
pub struct OledUI<S: Surface + core::fmt::Debug> {
overlay: S,
controls: DisplayControls,
uniforms: Arc<Mutex<CriticalSectionRawMutex, OledUniforms>>
uniforms: LockedUniforms
}
struct OverlayShader {}
@@ -57,35 +56,32 @@ impl<S: core::fmt::Debug + Surface<CoordinateSpace = Matrix2DSpace, Pixel = Bina
FADE_OUT.apply(&mut self.overlay).await;
}
pub async fn on_event(&mut self, event: Telemetry) {
pub async fn on_event(&mut self, event: Prediction) {
match event {
// Waking and sleeping
Telemetry::Notification(Notification::Sleep) => {
warn!("Putting OLED display to sleep");
self.screen_transition(Screen::Sleeping).await;
Timer::after_secs(1).await;
self.screen_transition(Screen::Blank).await;
self.controls.set_on(false);
//ui_state.sleep = true
Prediction::SetPersonality(personality) => {
match personality {
Personality::Waking => {
warn!("Waking up OLED display");
self.controls.set_on(true);
self.screen_transition(Screen::Waking).await;
Timer::after_secs(1).await;
self.screen_transition(Screen::Home).await;
},
Personality::Sleeping => {
warn!("Putting OLED display to sleep");
self.screen_transition(Screen::Sleeping).await;
Timer::after_secs(1).await;
self.screen_transition(Screen::Blank).await;
self.controls.set_on(false);
},
_ => ()
}
self.with_uniforms(|state| { state.ui.personality = personality }).await;
},
Telemetry::Notification(Notification::WakeUp) => {
warn!("Waking up OLED display");
self.controls.set_on(true);
self.screen_transition(Screen::Waking).await;
Timer::after_secs(1).await;
self.screen_transition(Screen::Home).await;
//ui_state.sleep = false
},
// State updates
Telemetry::Prediction(Prediction::Velocity(v)) => self.with_uniforms(|state| {state.ui.velocity = v;}).await,
Telemetry::Prediction(Prediction::Location(loc)) => self.with_uniforms(|state| {state.ui.location = loc}).await,
Telemetry::Prediction(Prediction::Motion(motion)) => self.with_uniforms(|state| {state.ui.motion = motion}).await,
Telemetry::Notification(Notification::SceneChange(scene)) => self.with_uniforms(|state| {state.ui.scene = scene}).await,
Telemetry::Notification(Notification::SetBrakelight(b)) => self.with_uniforms(|state| {state.ui.brakelight = b}).await,
Telemetry::Notification(Notification::SetHeadlight(b)) => self.with_uniforms(|state| {state.ui.headlight = b}).await,
Telemetry::Notification(Notification::SensorStatus(src, sensor_state)) => self.with_uniforms(|state| {state.ui.sensor_states[src] = sensor_state}).await,
_ => ()
Prediction::Velocity(v) => self.with_uniforms(|state| {state.ui.velocity = v;}).await,
Prediction::Location(loc) => self.with_uniforms(|state| {state.ui.location = loc}).await,
Prediction::Motion{ prev: _, next: motion } => self.with_uniforms(|state| {state.ui.motion = motion}).await,
Prediction::SensorStatus(src, sensor_state, ) => self.with_uniforms(|state| {state.ui.sensor_states[src] = sensor_state}).await,
}
}
@@ -97,7 +93,7 @@ impl<S: core::fmt::Debug + Surface<CoordinateSpace = Matrix2DSpace, Pixel = Bina
}
#[embassy_executor::task]
pub async fn oled_ui(mut events: DynSubscriber<'static, Telemetry>, mut ui: OledUI<OledSurface>) {
pub async fn oled_ui(mut events: DynSubscriber<'static, Prediction>, mut ui: OledUI<OledSurface>) {
ui.screen_transition(Screen::Bootsplash).await;
Timer::after_secs(3).await;