central registry
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
/// Central module registry. Defines all modules with watch channels in one place.
|
||||||
|
///
|
||||||
|
/// Invoke with a callback macro name. The callback receives repeated entries of the form:
|
||||||
|
/// { $feature:literal, $field:ident, $state:ty, [$($name:literal),+], [$($sig_name:literal),+], $module:path, $signal:ident, [$($default_arg:literal),*], $config:ident }
|
||||||
|
///
|
||||||
|
/// Fields:
|
||||||
|
/// - feature: Cargo feature gate (e.g., "mod-network")
|
||||||
|
/// - field: AppReceivers field name (e.g., network)
|
||||||
|
/// - state: State type for the watch channel (e.g., NetworkState)
|
||||||
|
/// - names: CLI name aliases for dispatch (e.g., ["net", "network"])
|
||||||
|
/// - signaler_names: Waybar module names to signal when the channel fires
|
||||||
|
/// (usually [first dispatch name], but audio signals ["vol", "mic"])
|
||||||
|
/// - module: Module struct implementing WaybarModule (e.g., network::NetworkModule)
|
||||||
|
/// - signal: SignalsConfig field name (e.g., network)
|
||||||
|
/// - default_args: Default args for signaler evaluation
|
||||||
|
/// - config: Config section field name (e.g., network)
|
||||||
|
///
|
||||||
|
/// Modules without watch channels (power, game, pool/btrfs) are handled manually.
|
||||||
|
macro_rules! for_each_watched_module {
|
||||||
|
($m:ident) => {
|
||||||
|
$m! {
|
||||||
|
{ "mod-network", network, crate::state::NetworkState, ["net", "network"], ["net"], crate::modules::network::NetworkModule, network, [], network }
|
||||||
|
{ "mod-hardware", cpu, crate::state::CpuState, ["cpu"], ["cpu"], crate::modules::cpu::CpuModule, cpu, [], cpu }
|
||||||
|
{ "mod-hardware", memory, crate::state::MemoryState, ["mem", "memory"], ["mem"], crate::modules::memory::MemoryModule, memory, [], memory }
|
||||||
|
{ "mod-hardware", sys, crate::state::SysState, ["sys"], ["sys"], crate::modules::sys::SysModule, sys, [], sys }
|
||||||
|
{ "mod-hardware", gpu, crate::state::GpuState, ["gpu"], ["gpu"], crate::modules::gpu::GpuModule, gpu, [], gpu }
|
||||||
|
{ "mod-hardware", disks, Vec<crate::state::DiskInfo>, ["disk"], ["disk"], crate::modules::disk::DiskModule, disk, ["/"], disk }
|
||||||
|
{ "mod-bt", bluetooth, crate::state::BtState, ["bt", "bluetooth"], ["bt"], crate::modules::bt::BtModule, bt, ["show"], bt }
|
||||||
|
{ "mod-audio", audio, crate::state::AudioState, ["vol", "audio"], ["vol", "mic"], crate::modules::audio::AudioModule, audio, ["sink", "show"], audio }
|
||||||
|
{ "mod-dbus", mpris, crate::state::MprisState, ["mpris"], ["mpris"], crate::modules::mpris::MprisModule, mpris, [], mpris }
|
||||||
|
{ "mod-dbus", backlight, crate::state::BacklightState, ["backlight"], ["backlight"], crate::modules::backlight::BacklightModule, backlight, [], backlight }
|
||||||
|
{ "mod-dbus", keyboard, crate::state::KeyboardState, ["kbd", "keyboard"], ["kbd"], crate::modules::keyboard::KeyboardModule, keyboard, [], keyboard }
|
||||||
|
{ "mod-dbus", dnd, crate::state::DndState, ["dnd"], ["dnd"], crate::modules::dnd::DndModule, dnd, [], dnd }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#[macro_use]
|
||||||
|
mod macros;
|
||||||
mod config;
|
mod config;
|
||||||
mod daemon;
|
mod daemon;
|
||||||
mod error;
|
mod error;
|
||||||
|
|||||||
+58
-112
@@ -6,120 +6,66 @@ use crate::state::AppReceivers;
|
|||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use crate::modules::WaybarModule;
|
use crate::modules::WaybarModule;
|
||||||
|
|
||||||
pub async fn dispatch(
|
macro_rules! gen_dispatch {
|
||||||
module_name: &str,
|
($( { $feature:literal, $field:ident, $state:ty, [$($name:literal),+], [$($sig_name:literal),+], $module:path, $signal:ident, [$($default_arg:literal),*], $config:ident } )*) => {
|
||||||
#[allow(unused)] config: &Config,
|
pub async fn dispatch(
|
||||||
#[allow(unused)] state: &AppReceivers,
|
module_name: &str,
|
||||||
#[allow(unused)] args: &[&str],
|
#[allow(unused)] config: &Config,
|
||||||
) -> FluxoResult<WaybarOutput> {
|
#[allow(unused)] state: &AppReceivers,
|
||||||
if !config.is_module_enabled(module_name) {
|
#[allow(unused)] args: &[&str],
|
||||||
return Err(FluxoError::Disabled(module_name.to_string()));
|
) -> FluxoResult<WaybarOutput> {
|
||||||
}
|
if !config.is_module_enabled(module_name) {
|
||||||
|
return Err(FluxoError::Disabled(module_name.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
match module_name {
|
match module_name {
|
||||||
#[cfg(feature = "mod-network")]
|
$(
|
||||||
"net" | "network" => {
|
#[cfg(feature = $feature)]
|
||||||
crate::modules::network::NetworkModule
|
$($name)|+ => {
|
||||||
.run(config, state, args)
|
$module.run(config, state, args).await
|
||||||
.await
|
}
|
||||||
|
)*
|
||||||
|
|
||||||
|
// Dispatch-only modules (no watch channel)
|
||||||
|
#[cfg(feature = "mod-audio")]
|
||||||
|
"mic" => {
|
||||||
|
crate::modules::audio::AudioModule
|
||||||
|
.run(config, state, args)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
#[cfg(feature = "mod-hardware")]
|
||||||
|
"power" => {
|
||||||
|
crate::modules::power::PowerModule
|
||||||
|
.run(config, state, args)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
#[cfg(feature = "mod-hardware")]
|
||||||
|
"game" => {
|
||||||
|
crate::modules::game::GameModule
|
||||||
|
.run(config, state, args)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
#[cfg(feature = "mod-hardware")]
|
||||||
|
"pool" | "btrfs" => {
|
||||||
|
crate::modules::btrfs::BtrfsModule
|
||||||
|
.run(config, state, args)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
_ => Err(FluxoError::Ipc(format!("Unknown module: {}", module_name))),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "mod-hardware")]
|
|
||||||
"cpu" => {
|
/// Returns the default args used by the signaler when evaluating a module.
|
||||||
crate::modules::cpu::CpuModule
|
pub fn signaler_default_args(module_name: &str) -> &'static [&'static str] {
|
||||||
.run(config, state, args)
|
match module_name {
|
||||||
.await
|
$(
|
||||||
|
$($name)|+ => &[$($default_arg),*],
|
||||||
|
)*
|
||||||
|
"mic" => &["source", "show"],
|
||||||
|
_ => &[],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "mod-hardware")]
|
};
|
||||||
"mem" | "memory" => {
|
|
||||||
crate::modules::memory::MemoryModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
#[cfg(feature = "mod-hardware")]
|
|
||||||
"disk" => {
|
|
||||||
crate::modules::disk::DiskModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
#[cfg(feature = "mod-hardware")]
|
|
||||||
"pool" | "btrfs" => {
|
|
||||||
crate::modules::btrfs::BtrfsModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
#[cfg(feature = "mod-audio")]
|
|
||||||
"vol" | "audio" => {
|
|
||||||
crate::modules::audio::AudioModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
#[cfg(feature = "mod-audio")]
|
|
||||||
"mic" => {
|
|
||||||
crate::modules::audio::AudioModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
#[cfg(feature = "mod-hardware")]
|
|
||||||
"gpu" => {
|
|
||||||
crate::modules::gpu::GpuModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
#[cfg(feature = "mod-hardware")]
|
|
||||||
"sys" => {
|
|
||||||
crate::modules::sys::SysModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
#[cfg(feature = "mod-bt")]
|
|
||||||
"bt" | "bluetooth" => crate::modules::bt::BtModule.run(config, state, args).await,
|
|
||||||
#[cfg(feature = "mod-hardware")]
|
|
||||||
"power" => {
|
|
||||||
crate::modules::power::PowerModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
#[cfg(feature = "mod-hardware")]
|
|
||||||
"game" => {
|
|
||||||
crate::modules::game::GameModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
"backlight" => {
|
|
||||||
crate::modules::backlight::BacklightModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
"kbd" | "keyboard" => {
|
|
||||||
crate::modules::keyboard::KeyboardModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
"dnd" => {
|
|
||||||
crate::modules::dnd::DndModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
"mpris" => {
|
|
||||||
crate::modules::mpris::MprisModule
|
|
||||||
.run(config, state, args)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
_ => Err(FluxoError::Ipc(format!("Unknown module: {}", module_name))),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the default args used by the signaler when evaluating a module.
|
for_each_watched_module!(gen_dispatch);
|
||||||
pub fn signaler_default_args(module_name: &str) -> &'static [&'static str] {
|
|
||||||
match module_name {
|
|
||||||
"disk" => &["/"],
|
|
||||||
"vol" | "audio" => &["sink", "show"],
|
|
||||||
"mic" => &["source", "show"],
|
|
||||||
"bt" | "bluetooth" => &["show"],
|
|
||||||
_ => &[],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+65
-160
@@ -63,173 +63,78 @@ impl WaybarSignaler {
|
|||||||
debug!("Waybar process not found, skipping signal.");
|
debug!("Waybar process not found, skipping signal.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn run(mut self, config_lock: Arc<RwLock<Config>>, mut receivers: AppReceivers) {
|
macro_rules! gen_signaler_run {
|
||||||
let mut last_outputs: HashMap<&'static str, String> = HashMap::new();
|
($( { $feature:literal, $field:ident, $state:ty, [$($name:literal),+], [$($sig_name:literal),+], $module:path, $signal:ident, [$($default_arg:literal),*], $config:ident } )*) => {
|
||||||
|
impl WaybarSignaler {
|
||||||
|
pub async fn run(mut self, config_lock: Arc<RwLock<Config>>, mut receivers: AppReceivers) {
|
||||||
|
let mut last_outputs: HashMap<&'static str, String> = HashMap::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let signals = config_lock.read().await.signals.clone();
|
let signals = config_lock.read().await.signals.clone();
|
||||||
|
|
||||||
macro_rules! check_and_signal {
|
macro_rules! check_and_signal {
|
||||||
($module_name:expr, $signal_opt:expr) => {
|
($module_name:expr, $signal_opt:expr) => {
|
||||||
if let Some(sig) = $signal_opt {
|
if let Some(sig) = $signal_opt {
|
||||||
let config = config_lock.read().await;
|
let config = config_lock.read().await;
|
||||||
if let Some(out) = crate::daemon::evaluate_module_for_signaler(
|
if let Some(out) = crate::daemon::evaluate_module_for_signaler(
|
||||||
$module_name,
|
$module_name,
|
||||||
&receivers,
|
&receivers,
|
||||||
&config,
|
&config,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
if last_outputs.get($module_name) != Some(&out) {
|
if last_outputs.get($module_name) != Some(&out) {
|
||||||
last_outputs.insert($module_name, out);
|
last_outputs.insert($module_name, out);
|
||||||
self.send_signal(sig);
|
self.send_signal(sig);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate cfg-gated futures for each watched module
|
||||||
|
$(
|
||||||
|
#[cfg(not(feature = $feature))]
|
||||||
|
let $field = std::future::pending::<
|
||||||
|
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
||||||
|
>();
|
||||||
|
#[cfg(feature = $feature)]
|
||||||
|
let $field = receivers.$field.changed();
|
||||||
|
)*
|
||||||
|
|
||||||
|
// MPRIS scroll tick (special case — not a watched module)
|
||||||
|
#[cfg(not(feature = "mod-dbus"))]
|
||||||
|
let mpris_scroll_tick = std::future::pending::<
|
||||||
|
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
||||||
|
>();
|
||||||
|
#[cfg(feature = "mod-dbus")]
|
||||||
|
let mpris_scroll_tick = receivers.mpris_scroll_tick.changed();
|
||||||
|
|
||||||
|
tokio::select! {
|
||||||
|
$(
|
||||||
|
res = $field, if signals.$signal.is_some() => {
|
||||||
|
if res.is_ok() {
|
||||||
|
$(check_and_signal!($sig_name, signals.$signal);)+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
|
||||||
|
// MPRIS scroll tick (separate from mpris data changes)
|
||||||
|
res = mpris_scroll_tick, if signals.mpris.is_some() => {
|
||||||
|
if res.is_ok()
|
||||||
|
&& let Some(sig) = signals.mpris { self.send_signal(sig); }
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = sleep(Duration::from_secs(5)) => {
|
||||||
|
// loop and refresh config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// For disabled features, create futures that never resolve
|
|
||||||
#[cfg(not(feature = "mod-network"))]
|
|
||||||
let net_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-network")]
|
|
||||||
let net_changed = receivers.network.changed();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mod-hardware"))]
|
|
||||||
let cpu_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-hardware")]
|
|
||||||
let cpu_changed = receivers.cpu.changed();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mod-hardware"))]
|
|
||||||
let mem_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-hardware")]
|
|
||||||
let mem_changed = receivers.memory.changed();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mod-hardware"))]
|
|
||||||
let sys_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-hardware")]
|
|
||||||
let sys_changed = receivers.sys.changed();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mod-hardware"))]
|
|
||||||
let gpu_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-hardware")]
|
|
||||||
let gpu_changed = receivers.gpu.changed();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mod-hardware"))]
|
|
||||||
let disks_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-hardware")]
|
|
||||||
let disks_changed = receivers.disks.changed();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mod-bt"))]
|
|
||||||
let bt_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-bt")]
|
|
||||||
let bt_changed = receivers.bluetooth.changed();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mod-audio"))]
|
|
||||||
let audio_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-audio")]
|
|
||||||
let audio_changed = receivers.audio.changed();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mod-dbus"))]
|
|
||||||
let backlight_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
let backlight_changed = receivers.backlight.changed();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mod-dbus"))]
|
|
||||||
let keyboard_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
let keyboard_changed = receivers.keyboard.changed();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mod-dbus"))]
|
|
||||||
let dnd_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
let dnd_changed = receivers.dnd.changed();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mod-dbus"))]
|
|
||||||
let mpris_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
let mpris_changed = receivers.mpris.changed();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mod-dbus"))]
|
|
||||||
let mpris_scroll_tick_changed = std::future::pending::<
|
|
||||||
std::result::Result<(), tokio::sync::watch::error::RecvError>,
|
|
||||||
>();
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
let mpris_scroll_tick_changed = receivers.mpris_scroll_tick.changed();
|
|
||||||
|
|
||||||
tokio::select! {
|
|
||||||
res = net_changed, if signals.network.is_some() => {
|
|
||||||
if res.is_ok() { check_and_signal!("net", signals.network); }
|
|
||||||
}
|
|
||||||
res = cpu_changed, if signals.cpu.is_some() => {
|
|
||||||
if res.is_ok() { check_and_signal!("cpu", signals.cpu); }
|
|
||||||
}
|
|
||||||
res = mem_changed, if signals.memory.is_some() => {
|
|
||||||
if res.is_ok() { check_and_signal!("mem", signals.memory); }
|
|
||||||
}
|
|
||||||
res = sys_changed, if signals.sys.is_some() => {
|
|
||||||
if res.is_ok() { check_and_signal!("sys", signals.sys); }
|
|
||||||
}
|
|
||||||
res = gpu_changed, if signals.gpu.is_some() => {
|
|
||||||
if res.is_ok() { check_and_signal!("gpu", signals.gpu); }
|
|
||||||
}
|
|
||||||
res = disks_changed, if signals.disk.is_some() => {
|
|
||||||
if res.is_ok() { check_and_signal!("disk", signals.disk); }
|
|
||||||
}
|
|
||||||
res = bt_changed, if signals.bt.is_some() => {
|
|
||||||
if res.is_ok() { check_and_signal!("bt", signals.bt); }
|
|
||||||
}
|
|
||||||
res = audio_changed, if signals.audio.is_some() => {
|
|
||||||
if res.is_ok() {
|
|
||||||
check_and_signal!("vol", signals.audio);
|
|
||||||
check_and_signal!("mic", signals.audio);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res = backlight_changed, if signals.backlight.is_some() => {
|
|
||||||
if res.is_ok() { check_and_signal!("backlight", signals.backlight); }
|
|
||||||
}
|
|
||||||
res = keyboard_changed, if signals.keyboard.is_some() => {
|
|
||||||
if res.is_ok() { check_and_signal!("keyboard", signals.keyboard); }
|
|
||||||
}
|
|
||||||
res = dnd_changed, if signals.dnd.is_some() => {
|
|
||||||
if res.is_ok() { check_and_signal!("dnd", signals.dnd); }
|
|
||||||
}
|
|
||||||
res = mpris_changed, if signals.mpris.is_some() => {
|
|
||||||
if res.is_ok() { check_and_signal!("mpris", signals.mpris); }
|
|
||||||
}
|
|
||||||
res = mpris_scroll_tick_changed, if signals.mpris.is_some() => {
|
|
||||||
if res.is_ok()
|
|
||||||
&& let Some(sig) = signals.mpris { self.send_signal(sig); }
|
|
||||||
}
|
|
||||||
_ = sleep(Duration::from_secs(5)) => {
|
|
||||||
// loop and refresh config
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for_each_watched_module!(gen_signaler_run);
|
||||||
|
|||||||
+22
-37
@@ -4,44 +4,29 @@ use std::sync::Arc;
|
|||||||
use tokio::sync::{RwLock, mpsc, watch};
|
use tokio::sync::{RwLock, mpsc, watch};
|
||||||
use tokio::time::Instant;
|
use tokio::time::Instant;
|
||||||
|
|
||||||
#[derive(Clone)]
|
macro_rules! gen_app_receivers {
|
||||||
pub struct AppReceivers {
|
($( { $feature:literal, $field:ident, $state:ty, [$($name:literal),+], [$($sig_name:literal),+], $module:path, $signal:ident, [$($default_arg:literal),*], $config:ident } )*) => {
|
||||||
#[cfg(feature = "mod-network")]
|
#[derive(Clone)]
|
||||||
pub network: watch::Receiver<NetworkState>,
|
pub struct AppReceivers {
|
||||||
#[cfg(feature = "mod-hardware")]
|
$(
|
||||||
pub cpu: watch::Receiver<CpuState>,
|
#[cfg(feature = $feature)]
|
||||||
#[cfg(feature = "mod-hardware")]
|
pub $field: watch::Receiver<$state>,
|
||||||
pub memory: watch::Receiver<MemoryState>,
|
)*
|
||||||
#[cfg(feature = "mod-hardware")]
|
#[cfg(feature = "mod-bt")]
|
||||||
pub sys: watch::Receiver<SysState>,
|
pub bt_cycle: Arc<RwLock<usize>>,
|
||||||
#[cfg(feature = "mod-hardware")]
|
#[cfg(feature = "mod-dbus")]
|
||||||
pub gpu: watch::Receiver<GpuState>,
|
pub mpris_scroll: Arc<RwLock<MprisScrollState>>,
|
||||||
#[cfg(feature = "mod-hardware")]
|
#[cfg(feature = "mod-dbus")]
|
||||||
pub disks: watch::Receiver<Vec<DiskInfo>>,
|
pub mpris_scroll_tick: watch::Receiver<u64>,
|
||||||
#[cfg(feature = "mod-bt")]
|
pub health: Arc<RwLock<HashMap<String, ModuleHealth>>>,
|
||||||
pub bluetooth: watch::Receiver<BtState>,
|
#[cfg(feature = "mod-bt")]
|
||||||
#[cfg(feature = "mod-bt")]
|
pub bt_force_poll: mpsc::Sender<()>,
|
||||||
pub bt_cycle: Arc<RwLock<usize>>,
|
#[cfg(feature = "mod-audio")]
|
||||||
#[cfg(feature = "mod-audio")]
|
pub audio_cmd_tx: mpsc::Sender<crate::modules::audio::AudioCommand>,
|
||||||
pub audio: watch::Receiver<AudioState>,
|
}
|
||||||
#[cfg(feature = "mod-dbus")]
|
};
|
||||||
pub mpris: watch::Receiver<MprisState>,
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
pub backlight: watch::Receiver<BacklightState>,
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
pub keyboard: watch::Receiver<KeyboardState>,
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
pub dnd: watch::Receiver<DndState>,
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
pub mpris_scroll: Arc<RwLock<MprisScrollState>>,
|
|
||||||
#[cfg(feature = "mod-dbus")]
|
|
||||||
pub mpris_scroll_tick: watch::Receiver<u64>,
|
|
||||||
pub health: Arc<RwLock<HashMap<String, ModuleHealth>>>,
|
|
||||||
#[cfg(feature = "mod-bt")]
|
|
||||||
pub bt_force_poll: mpsc::Sender<()>,
|
|
||||||
#[cfg(feature = "mod-audio")]
|
|
||||||
pub audio_cmd_tx: mpsc::Sender<crate::modules::audio::AudioCommand>,
|
|
||||||
}
|
}
|
||||||
|
for_each_watched_module!(gen_app_receivers);
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct ModuleHealth {
|
pub struct ModuleHealth {
|
||||||
|
|||||||
Reference in New Issue
Block a user