arch: push wire types out of ClientApp, extract event_service, cleanup dead code
- ClientApp stores domain types, RepaintCommand carries DisplayHint + Vec<(String,Value)> - adapters no longer convert Wire→Domain (eliminated duplication in esp32 + desktop) - event_service in application layer handles LayoutChanged/WebhookDataReceived/ThemeChanged - bootstrap event_handler reduced to 10-line dispatcher - polling_service reuses event_service::apply_and_broadcast (deduplicated broadcast pattern) - AppState.config_service() replaces 11 inline ConfigService::new() calls - delete unused poll_interval_secs parameter chain - delete unused StoragePort/ClientConfig (zero implementations)
This commit is contained in:
@@ -1,24 +1,24 @@
|
||||
use crate::conversions::wire_to_layout;
|
||||
use crate::conversions::{wire_to_display_hint, wire_to_layout, wire_to_widget_state};
|
||||
use client_domain::{BoundingBox, Color, LayoutEngine, RenderTree, ThemeConfig};
|
||||
use protocol::{
|
||||
ServerMessage, WidgetDescriptor, WireColor, WireDisplayHint, WireLayoutNode, WireWidgetState,
|
||||
};
|
||||
use domain::{DisplayHint, Value, WidgetError, WidgetState};
|
||||
use protocol::{ServerMessage, WidgetDescriptor, WireColor, WireLayoutNode};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct ClientApp {
|
||||
screen: BoundingBox,
|
||||
render_tree: Option<RenderTree>,
|
||||
widget_states: HashMap<u16, (WireDisplayHint, WireWidgetState)>,
|
||||
widget_states: HashMap<u16, (DisplayHint, WidgetState)>,
|
||||
theme: ThemeConfig,
|
||||
theme_changed: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RepaintCommand {
|
||||
pub widget_id: u16,
|
||||
pub bounds: BoundingBox,
|
||||
pub display_hint: WireDisplayHint,
|
||||
pub state: WireWidgetState,
|
||||
pub display_hint: DisplayHint,
|
||||
pub data: Vec<(String, Value)>,
|
||||
pub error: Option<WidgetError>,
|
||||
}
|
||||
|
||||
impl ClientApp {
|
||||
@@ -77,9 +77,10 @@ impl ClientApp {
|
||||
let new_tree = LayoutEngine::compute(&layout, self.screen);
|
||||
|
||||
self.widget_states.clear();
|
||||
for w in &widgets {
|
||||
self.widget_states
|
||||
.insert(w.id, (w.display_hint.clone(), w.state.clone()));
|
||||
for w in widgets {
|
||||
let hint = wire_to_display_hint(w.display_hint);
|
||||
let state = wire_to_widget_state(w.state);
|
||||
self.widget_states.insert(w.id, (hint, state));
|
||||
}
|
||||
|
||||
let repaints = self.build_repaints_for_all(&new_tree);
|
||||
@@ -96,21 +97,19 @@ impl ClientApp {
|
||||
let mut repaints = Vec::new();
|
||||
|
||||
for w in widgets {
|
||||
let hint = wire_to_display_hint(w.display_hint);
|
||||
let state = wire_to_widget_state(w.state);
|
||||
|
||||
let changed = self
|
||||
.widget_states
|
||||
.get(&w.id)
|
||||
.is_none_or(|(_, prev_state)| *prev_state != w.state);
|
||||
.is_none_or(|(_, prev)| *prev != state);
|
||||
|
||||
if changed {
|
||||
if let Some(bounds) = tree.get_widget_bounds(w.id) {
|
||||
repaints.push(RepaintCommand {
|
||||
widget_id: w.id,
|
||||
bounds: *bounds,
|
||||
display_hint: w.display_hint.clone(),
|
||||
state: w.state.clone(),
|
||||
});
|
||||
repaints.push(Self::make_repaint(w.id, *bounds, &hint, &state));
|
||||
}
|
||||
self.widget_states.insert(w.id, (w.display_hint, w.state));
|
||||
self.widget_states.insert(w.id, (hint, state));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,18 +121,32 @@ impl ClientApp {
|
||||
|
||||
for (id, (hint, state)) in &self.widget_states {
|
||||
if let Some(bounds) = tree.get_widget_bounds(*id) {
|
||||
repaints.push(RepaintCommand {
|
||||
widget_id: *id,
|
||||
bounds: *bounds,
|
||||
display_hint: hint.clone(),
|
||||
state: state.clone(),
|
||||
});
|
||||
repaints.push(Self::make_repaint(*id, *bounds, hint, state));
|
||||
}
|
||||
}
|
||||
|
||||
repaints.sort_by_key(|r| r.widget_id);
|
||||
repaints
|
||||
}
|
||||
|
||||
fn make_repaint(
|
||||
id: u16,
|
||||
bounds: BoundingBox,
|
||||
hint: &DisplayHint,
|
||||
state: &WidgetState,
|
||||
) -> RepaintCommand {
|
||||
RepaintCommand {
|
||||
widget_id: id,
|
||||
bounds,
|
||||
display_hint: hint.clone(),
|
||||
data: state
|
||||
.data
|
||||
.iter()
|
||||
.map(|(k, v)| (k.clone(), v.clone()))
|
||||
.collect(),
|
||||
error: state.error.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn wire_color(c: WireColor) -> Color {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use client_application::{ClientApp, RepaintCommand};
|
||||
use client_application::ClientApp;
|
||||
use client_domain::BoundingBox;
|
||||
use protocol::{
|
||||
ServerMessage, WidgetDescriptor, WireAlignItems, WireContainerNode, WireDirection,
|
||||
@@ -84,8 +84,8 @@ fn data_update_only_repaints_changed_widgets() {
|
||||
assert_eq!(repaints.len(), 1);
|
||||
assert_eq!(repaints[0].widget_id, 1);
|
||||
assert_eq!(
|
||||
repaints[0].state.data[0].value,
|
||||
WireValue::String("6.1°C".into())
|
||||
repaints[0].data[0],
|
||||
("temperature".into(), domain::Value::String("6.1°C".into()))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user