Files
barbar/crates/core/src/app.rs
T
2026-09-13 14:37:59 +01:00

56 lines
2.0 KiB
Rust

use std::collections::{BTreeMap, BTreeSet};
use iced::window;
use common::{BarModule, Inbox, Modules, Service};
use toml::Table;
/// Application state: module registry, routing, popup bookkeeping.
pub(crate) struct Bar {
/// Module whose popup is open; None = closed.
pub(crate) active_popup: Option<String>,
/// Module registry keyed by stable module id.
pub(crate) modules: BTreeMap<&'static str, Box<dyn BarModule>>,
/// Left, Middle, Right ; Module Order
pub(crate) order: (Vec<Modules>, Vec<Modules>, Vec<Modules>),
/// Surface id of the open popup.
pub(crate) popup_id: Option<window::Id>,
/// Fan-out routing table: module id -> services it wants.
pub(crate) routes: BTreeMap<&'static str, Vec<Service>>,
/// One inbound mailbox per running service, keyed by route key. Modules
/// send here (`Target::Service`) to talk to a running service.
pub(crate) inputs: BTreeMap<&'static str, Inbox>,
}
impl Bar {
pub(crate) fn new(
modules_config_table: &Table,
modules_order: (Vec<Modules>, Vec<Modules>, Vec<Modules>),
) -> Self {
// Registry owns construction: adding a module never edits this file.
let modules: BTreeMap<&'static str, Box<dyn BarModule>> =
modules::all(modules_config_table.clone())
.into_iter()
.map(|m| (m.id(), m))
.collect();
let routes: BTreeMap<&'static str, Vec<Service>> = modules
.iter()
.map(|(id, module)| (*id, module.services()))
.collect();
// One inbox per distinct service any module wants.
let wanted: BTreeSet<&'static str> = routes.values().flatten().map(|s| s.0).collect();
let inputs = wanted
.into_iter()
.map(|key| (key, Inbox::new(key)))
.collect();
Self {
active_popup: None,
modules,
order: modules_order,
popup_id: None,
routes,
inputs,
}
}
}