commit
This commit is contained in:
parent
bf48f12c8c
commit
66c86df2a4
8 changed files with 104 additions and 107 deletions
|
@ -51,8 +51,8 @@ pub enum HandlerCommand {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
pub struct InitialHandlerMessage<KeyConfig: Clone, KnobConfig: Clone> {
|
pub struct InitialHandlerMessage<KeyConfig: Clone, KnobConfig: Clone> {
|
||||||
pub key_configs: im::HashMap<KeyPath, (Box<str>, KeyConfig)>,
|
pub key_configs: im::HashMap<KeyPath, KeyConfig>,
|
||||||
pub knob_configs: im::HashMap<KnobPath, (Box<str>, KnobConfig)>,
|
pub knob_configs: im::HashMap<KnobPath, KnobConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
@ -64,8 +64,6 @@ pub enum HandlerInitializationResultMessage {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Error)]
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Error)]
|
||||||
pub enum HandlerInitializationError {
|
pub enum HandlerInitializationError {
|
||||||
#[error("The provided mode string is invalid: {message}")]
|
|
||||||
InvalidModeString { message: Box<str> },
|
|
||||||
#[error("The provided handler config is invalid: {message}")]
|
#[error("The provided handler config is invalid: {message}")]
|
||||||
InvalidConfig {
|
InvalidConfig {
|
||||||
supports_keys: bool,
|
supports_keys: bool,
|
||||||
|
|
|
@ -243,15 +243,6 @@ impl Display for ImageFilter {
|
||||||
is_first = false;
|
is_first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(color) = self.destructive.color {
|
|
||||||
if !is_first {
|
|
||||||
f.write_str("|")?
|
|
||||||
}
|
|
||||||
|
|
||||||
f.write_fmt(format_args!("color={}", color))?;
|
|
||||||
is_first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.destructive.grayscale {
|
if self.destructive.grayscale {
|
||||||
if !is_first {
|
if !is_first {
|
||||||
f.write_str("|")?
|
f.write_str("|")?
|
||||||
|
|
|
@ -1,33 +1,37 @@
|
||||||
[keys.1x2]
|
[keys.1x2]
|
||||||
icon = "@ph/skip-back"
|
icon = "@ph/skip-back"
|
||||||
|
|
||||||
handler = "playerctl previous"
|
handler = "playerctl"
|
||||||
config.mode = "previous"
|
config.mode = "previous"
|
||||||
config.style.inactive.icon = "@ph/skip-back[alpha=0.4]"
|
config.style.inactive.icon = "@ph/skip-back[alpha=0.4]"
|
||||||
|
|
||||||
[keys.2x2]
|
[keys.2x2]
|
||||||
icon = "@ph/play-pause[alpha=0.4]"
|
icon = "@ph/play-pause[alpha=0.4]"
|
||||||
|
|
||||||
handler = "playerctl play-pause"
|
handler = "playerctl"
|
||||||
|
config.mode = "play-pause"
|
||||||
config.style.paused.icon = "@ph/play"
|
config.style.paused.icon = "@ph/play"
|
||||||
config.style.playing.icon = "@ph/pause"
|
config.style.playing.icon = "@ph/pause"
|
||||||
|
|
||||||
[keys.3x2]
|
[keys.3x2]
|
||||||
icon = "@ph/skip-forward"
|
icon = "@ph/skip-forward"
|
||||||
|
|
||||||
handler = "playerctl next"
|
handler = "playerctl"
|
||||||
|
config.mode = "next"
|
||||||
config.style.inactive.icon = "@ph/skip-forward[alpha=0.4]"
|
config.style.inactive.icon = "@ph/skip-forward[alpha=0.4]"
|
||||||
|
|
||||||
[keys.1x3]
|
[keys.1x3]
|
||||||
icon = "@fad/shuffle[alpha=0.4]"
|
icon = "@fad/shuffle[alpha=0.4]"
|
||||||
|
|
||||||
handler = "playerctl shuffle"
|
handler = "playerctl"
|
||||||
|
config.mode = "shuffle"
|
||||||
config.style.on.icon = "@fad/shuffle[color=#58fc11]"
|
config.style.on.icon = "@fad/shuffle[color=#58fc11]"
|
||||||
|
|
||||||
[keys.2x3]
|
[keys.2x3]
|
||||||
icon = "@fad/repeat[alpha=0.4]"
|
icon = "@fad/repeat[alpha=0.4]"
|
||||||
|
|
||||||
handler = "playerctl loop"
|
handler = "playerctl"
|
||||||
|
config.mode = "loop"
|
||||||
config.style.single.icon = "@fad/repeat-one[color=#58fc11]"
|
config.style.single.icon = "@fad/repeat-one[color=#58fc11]"
|
||||||
config.style.all.icon = "@fad/repeat[color=#58fc11]"
|
config.style.all.icon = "@fad/repeat[color=#58fc11]"
|
||||||
|
|
||||||
|
@ -43,6 +47,7 @@ config.needy = true
|
||||||
icon = "@ph/computer-tower"
|
icon = "@ph/computer-tower"
|
||||||
label = "Gaming PC"
|
label = "Gaming PC"
|
||||||
|
|
||||||
handler = "home-assistant switch"
|
handler = "home-assistant"
|
||||||
|
config.mode = "switch"
|
||||||
config.name = "switch.mwin"
|
config.name = "switch.mwin"
|
||||||
config.style.on.icon = "@ph/computer-tower[color=#58fc11]"
|
config.style.on.icon = "@ph/computer-tower[color=#58fc11]"
|
|
@ -145,43 +145,6 @@ fn state_matches(target: &Target, state: &PaEntityState) -> bool {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Handler {
|
|
||||||
events_sender: broadcast::Sender<(KnobPath, KnobEvent)>,
|
|
||||||
#[allow(unused)]
|
|
||||||
runtime: tokio::runtime::Runtime,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Handler {
|
|
||||||
pub fn new(data: InitialHandlerMessage<(), KnobConfig>) -> Result<Self, HandlerInitializationError> {
|
|
||||||
let (events_sender, _) = broadcast::channel::<(KnobPath, KnobEvent)>(5);
|
|
||||||
let pa_volume_interface = Arc::new(PaVolumeInterface::spawn_thread("deckster handler".to_owned()));
|
|
||||||
|
|
||||||
let runtime = tokio::runtime::Builder::new_multi_thread().worker_threads(1).build().unwrap();
|
|
||||||
|
|
||||||
for (path, (mode, config)) in data.knob_configs {
|
|
||||||
if !mode.is_empty() {
|
|
||||||
return Err(HandlerInitializationError::InvalidModeString {
|
|
||||||
message: "No mode string allowed.".into(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let events_receiver = events_sender.subscribe();
|
|
||||||
let a = Arc::clone(&pa_volume_interface);
|
|
||||||
runtime.spawn(manage_knob(path, config, events_receiver, a));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Handler { events_sender, runtime })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DecksterHandler for Handler {
|
|
||||||
fn handle(&mut self, event: HandlerEvent) {
|
|
||||||
if let HandlerEvent::Knob { path, event } = event {
|
|
||||||
self.events_sender.send((path, event)).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn manage_knob(path: KnobPath, config: KnobConfig, mut events: broadcast::Receiver<(KnobPath, KnobEvent)>, pa_volume_interface: Arc<PaVolumeInterface>) {
|
async fn manage_knob(path: KnobPath, config: KnobConfig, mut events: broadcast::Receiver<(KnobPath, KnobEvent)>, pa_volume_interface: Arc<PaVolumeInterface>) {
|
||||||
let mut entity_state: Option<Arc<PaEntityState>> = None;
|
let mut entity_state: Option<Arc<PaEntityState>> = None;
|
||||||
|
|
||||||
|
@ -299,3 +262,33 @@ async fn manage_knob(path: KnobPath, config: KnobConfig, mut events: broadcast::
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Handler {
|
||||||
|
events_sender: broadcast::Sender<(KnobPath, KnobEvent)>,
|
||||||
|
#[allow(unused)]
|
||||||
|
runtime: tokio::runtime::Runtime,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Handler {
|
||||||
|
pub fn new(data: InitialHandlerMessage<(), KnobConfig>) -> Result<Self, HandlerInitializationError> {
|
||||||
|
let (events_sender, _) = broadcast::channel::<(KnobPath, KnobEvent)>(5);
|
||||||
|
let pa_volume_interface = Arc::new(PaVolumeInterface::spawn_thread("deckster handler".to_owned()));
|
||||||
|
|
||||||
|
let runtime = tokio::runtime::Builder::new_multi_thread().worker_threads(1).build().unwrap();
|
||||||
|
|
||||||
|
for (path, config) in data.knob_configs {
|
||||||
|
let events_receiver = events_sender.subscribe();
|
||||||
|
runtime.spawn(manage_knob(path, config, events_receiver, Arc::clone(&pa_volume_interface)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Handler { events_sender, runtime })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DecksterHandler for Handler {
|
||||||
|
fn handle(&mut self, event: HandlerEvent) {
|
||||||
|
if let HandlerEvent::Knob { path, event } = event {
|
||||||
|
self.events_sender.send((path, event)).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,24 +9,34 @@ use std::time::Duration;
|
||||||
|
|
||||||
use log::{error, warn};
|
use log::{error, warn};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
use tokio::sync::broadcast::error::RecvError;
|
use tokio::sync::broadcast::error::RecvError;
|
||||||
|
|
||||||
use deckster_mode::shared::handler_communication::{HandlerCommand, HandlerEvent, InitialHandlerMessage, KeyEvent};
|
use deckster_mode::shared::handler_communication::{HandlerCommand, HandlerEvent, HandlerInitializationError, InitialHandlerMessage, KeyEvent};
|
||||||
use deckster_mode::shared::path::KeyPath;
|
use deckster_mode::shared::path::KeyPath;
|
||||||
use deckster_mode::shared::state::KeyStyleByStateMap;
|
use deckster_mode::shared::state::KeyStyleByStateMap;
|
||||||
use deckster_mode::{send_command, DecksterHandler};
|
use deckster_mode::{send_command, DecksterHandler};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "mode", rename_all = "kebab-case")]
|
||||||
|
pub enum KeyConfig {
|
||||||
|
Play(ButtonConfig),
|
||||||
|
Pause(ButtonConfig),
|
||||||
|
PlayPause(ButtonConfig),
|
||||||
|
Previous(ButtonConfig),
|
||||||
|
Next(ButtonConfig),
|
||||||
|
Shuffle(ShuffleConfig),
|
||||||
|
Loop(LoopConfig),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct ButtonConfig {
|
pub struct ButtonConfig {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub style: KeyStyleByStateMap<ButtonState>,
|
pub style: KeyStyleByStateMap<ButtonState>,
|
||||||
pub command: ButtonCommand,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Deserialize)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
|
||||||
pub enum ButtonCommand {
|
pub enum ButtonCommand {
|
||||||
PlayPause,
|
PlayPause,
|
||||||
Play,
|
Play,
|
||||||
|
@ -35,7 +45,7 @@ pub enum ButtonCommand {
|
||||||
Next,
|
Next,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy, Deserialize)]
|
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub enum ButtonState {
|
pub enum ButtonState {
|
||||||
Inactive,
|
Inactive,
|
||||||
|
@ -43,13 +53,13 @@ pub enum ButtonState {
|
||||||
Paused,
|
Paused,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct ShuffleConfig {
|
pub struct ShuffleConfig {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub style: KeyStyleByStateMap<ShuffleState>,
|
pub style: KeyStyleByStateMap<ShuffleState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy, Deserialize)]
|
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub enum ShuffleState {
|
pub enum ShuffleState {
|
||||||
Inactive,
|
Inactive,
|
||||||
|
@ -57,13 +67,13 @@ pub enum ShuffleState {
|
||||||
On,
|
On,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct LoopConfig {
|
pub struct LoopConfig {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub style: KeyStyleByStateMap<LoopState>,
|
pub style: KeyStyleByStateMap<LoopState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy, Deserialize)]
|
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub enum LoopState {
|
pub enum LoopState {
|
||||||
Inactive,
|
Inactive,
|
||||||
|
@ -163,11 +173,11 @@ static STATE_WATCHER_LOOP: Lazy<PlayerctlStateWatcher<LoopState>> = Lazy::new(||
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
pub async fn handle_button(path: KeyPath, config: Arc<ButtonConfig>, mut events: broadcast::Receiver<KeyEvent>) {
|
pub async fn manage_button(path: KeyPath, config: ButtonConfig, mut events: broadcast::Receiver<(KeyPath, KeyEvent)>, command: ButtonCommand) {
|
||||||
let mut is_active = false;
|
let mut is_active = false;
|
||||||
let mut state = STATE_WATCHER_PLAYING.subscribe_to_state();
|
let mut state = STATE_WATCHER_PLAYING.subscribe_to_state();
|
||||||
|
|
||||||
let command = match config.command {
|
let command = match command {
|
||||||
ButtonCommand::PlayPause => "play-pause",
|
ButtonCommand::PlayPause => "play-pause",
|
||||||
ButtonCommand::Play => "play",
|
ButtonCommand::Play => "play",
|
||||||
ButtonCommand::Pause => "pause",
|
ButtonCommand::Pause => "pause",
|
||||||
|
@ -192,7 +202,11 @@ pub async fn handle_button(path: KeyPath, config: Arc<ButtonConfig>, mut events:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(event) = events.recv() => {
|
Ok((p, event)) = events.recv() => {
|
||||||
|
if p != path {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if event == KeyEvent::Press && is_active {
|
if event == KeyEvent::Press && is_active {
|
||||||
let status = std::process::Command::new("playerctl").arg(command).status().unwrap();
|
let status = std::process::Command::new("playerctl").arg(command).status().unwrap();
|
||||||
|
|
||||||
|
@ -205,7 +219,7 @@ pub async fn handle_button(path: KeyPath, config: Arc<ButtonConfig>, mut events:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_shuffle(path: KeyPath, config: Arc<ShuffleConfig>, mut events: broadcast::Receiver<KeyEvent>) {
|
pub async fn manage_shuffle(path: KeyPath, config: ShuffleConfig, mut events: broadcast::Receiver<(KeyPath, KeyEvent)>) {
|
||||||
let mut state = STATE_WATCHER_SHUFFLE.subscribe_to_state();
|
let mut state = STATE_WATCHER_SHUFFLE.subscribe_to_state();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -223,7 +237,11 @@ pub async fn handle_shuffle(path: KeyPath, config: Arc<ShuffleConfig>, mut event
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(event) = events.recv() => {
|
Ok((p, event)) = events.recv() => {
|
||||||
|
if p != path {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if event == KeyEvent::Press {
|
if event == KeyEvent::Press {
|
||||||
let current = *STATE_WATCHER_SHUFFLE.state.read().unwrap();
|
let current = *STATE_WATCHER_SHUFFLE.state.read().unwrap();
|
||||||
let new = match current {
|
let new = match current {
|
||||||
|
@ -242,7 +260,7 @@ pub async fn handle_shuffle(path: KeyPath, config: Arc<ShuffleConfig>, mut event
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_loop(path: KeyPath, config: Arc<LoopConfig>, mut events: broadcast::Receiver<KeyEvent>) {
|
pub async fn manage_loop(path: KeyPath, config: LoopConfig, mut events: broadcast::Receiver<(KeyPath, KeyEvent)>) {
|
||||||
let mut state = STATE_WATCHER_LOOP.subscribe_to_state();
|
let mut state = STATE_WATCHER_LOOP.subscribe_to_state();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -260,7 +278,11 @@ pub async fn handle_loop(path: KeyPath, config: Arc<LoopConfig>, mut events: bro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(event) = events.recv() => {
|
Ok((p, event)) = events.recv() => {
|
||||||
|
if p != path {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if event == KeyEvent::Press {
|
if event == KeyEvent::Press {
|
||||||
let current = *STATE_WATCHER_LOOP.state.read().unwrap();
|
let current = *STATE_WATCHER_LOOP.state.read().unwrap();
|
||||||
let new = match current {
|
let new = match current {
|
||||||
|
@ -287,22 +309,23 @@ pub struct Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handler {
|
impl Handler {
|
||||||
pub fn new(data: InitialHandlerMessage<()>) -> Result<Self, HandlerInitializationError> {
|
pub fn new(data: InitialHandlerMessage<KeyConfig, ()>) -> Result<Self, HandlerInitializationError> {
|
||||||
let (events_sender, _) = broadcast::channel::<(KnobPath, KnobEvent)>(5);
|
let (events_sender, _) = broadcast::channel::<(KeyPath, KeyEvent)>(5);
|
||||||
let pa_volume_interface = Arc::new(PaVolumeInterface::spawn_thread("deckster handler".to_owned()));
|
|
||||||
|
|
||||||
let runtime = tokio::runtime::Builder::new_multi_thread().worker_threads(1).build().unwrap();
|
let runtime = tokio::runtime::Builder::new_multi_thread().worker_threads(1).build().unwrap();
|
||||||
|
|
||||||
for (path, (mode, config)) in data.knob_configs {
|
for (path, config) in data.key_configs {
|
||||||
if !mode.is_empty() {
|
let events = events_sender.subscribe();
|
||||||
return Err(HandlerInitializationError::InvalidModeString {
|
|
||||||
message: "No mode string allowed.".into(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let events_receiver = events_sender.subscribe();
|
match config {
|
||||||
let a = Arc::clone(&pa_volume_interface);
|
KeyConfig::Loop(config) => runtime.spawn(manage_loop(path, config, events)),
|
||||||
runtime.spawn(manage_knob(path, config, events_receiver, a));
|
KeyConfig::Shuffle(config) => runtime.spawn(manage_shuffle(path, config, events)),
|
||||||
|
KeyConfig::Previous(config) => runtime.spawn(manage_button(path, config, events, ButtonCommand::Previous)),
|
||||||
|
KeyConfig::Next(config) => runtime.spawn(manage_button(path, config, events, ButtonCommand::Next)),
|
||||||
|
KeyConfig::Pause(config) => runtime.spawn(manage_button(path, config, events, ButtonCommand::Pause)),
|
||||||
|
KeyConfig::Play(config) => runtime.spawn(manage_button(path, config, events, ButtonCommand::Play)),
|
||||||
|
KeyConfig::PlayPause(config) => runtime.spawn(manage_button(path, config, events, ButtonCommand::PlayPause)),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Handler { events_sender, runtime })
|
Ok(Handler { events_sender, runtime })
|
||||||
|
@ -311,7 +334,7 @@ impl Handler {
|
||||||
|
|
||||||
impl DecksterHandler for Handler {
|
impl DecksterHandler for Handler {
|
||||||
fn handle(&mut self, event: HandlerEvent) {
|
fn handle(&mut self, event: HandlerEvent) {
|
||||||
if let HandlerEvent::Knob { path, event } = event {
|
if let HandlerEvent::Key { path, event } = event {
|
||||||
self.events_sender.send((path, event)).unwrap();
|
self.events_sender.send((path, event)).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
|
|
||||||
|
use crate::handler::Handler;
|
||||||
|
|
||||||
mod handler;
|
mod handler;
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
|
|
|
@ -17,7 +17,6 @@ use deckster_shared::path::{KeyPath, KnobPath};
|
||||||
|
|
||||||
pub struct KeyOrKnobConfig {
|
pub struct KeyOrKnobConfig {
|
||||||
pub handler_name: Box<str>,
|
pub handler_name: Box<str>,
|
||||||
pub mode_string: Box<str>,
|
|
||||||
pub handler_config: Arc<toml::Table>,
|
pub handler_config: Arc<toml::Table>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +61,7 @@ pub async fn start(
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(path, c)| {
|
.filter_map(|(path, c)| {
|
||||||
if *c.handler_name == handler_name {
|
if *c.handler_name == handler_name {
|
||||||
Some((path.clone(), (c.mode_string.clone(), Arc::clone(&c.handler_config))))
|
Some((path.clone(), Arc::clone(&c.handler_config)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -72,7 +71,7 @@ pub async fn start(
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(path, c)| {
|
.filter_map(|(path, c)| {
|
||||||
if *c.handler_name == handler_name {
|
if *c.handler_name == handler_name {
|
||||||
Some((path.clone(), (c.mode_string.clone(), Arc::clone(&c.handler_config))))
|
Some((path.clone(), Arc::clone(&c.handler_config)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,20 +54,13 @@ pub async fn start(config_directory: &Path, config: Config) -> Result<()> {
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|(page_id, p)| {
|
.flat_map(|(page_id, p)| {
|
||||||
p.keys.iter().map(|(position, k)| {
|
p.keys.iter().map(|(position, k)| {
|
||||||
let (handler_name, mode_string) = k
|
|
||||||
.handler
|
|
||||||
.split_once(' ')
|
|
||||||
.map(|(a, b)| (a.into(), b.into()))
|
|
||||||
.unwrap_or_else(|| (k.handler.as_str().into(), "".into()));
|
|
||||||
|
|
||||||
(
|
(
|
||||||
KeyPath {
|
KeyPath {
|
||||||
page_id: page_id.clone(),
|
page_id: page_id.clone(),
|
||||||
position: *position,
|
position: *position,
|
||||||
},
|
},
|
||||||
KeyOrKnobConfig {
|
KeyOrKnobConfig {
|
||||||
handler_name,
|
handler_name: k.handler.as_str().into(),
|
||||||
mode_string,
|
|
||||||
handler_config: Arc::clone(&k.config),
|
handler_config: Arc::clone(&k.config),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -84,20 +77,13 @@ pub async fn start(config_directory: &Path, config: Config) -> Result<()> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (handler_name, mode_string) = k
|
|
||||||
.handler
|
|
||||||
.split_once(' ')
|
|
||||||
.map(|(a, b)| (a.into(), b.into()))
|
|
||||||
.unwrap_or_else(|| (k.handler.as_str().into(), "".into()));
|
|
||||||
|
|
||||||
Some((
|
Some((
|
||||||
KnobPath {
|
KnobPath {
|
||||||
page_id: page_id.clone(),
|
page_id: page_id.clone(),
|
||||||
position,
|
position,
|
||||||
},
|
},
|
||||||
KeyOrKnobConfig {
|
KeyOrKnobConfig {
|
||||||
handler_name,
|
handler_name: k.handler.as_str().into(),
|
||||||
mode_string,
|
|
||||||
handler_config: Arc::clone(&k.config),
|
handler_config: Arc::clone(&k.config),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
|
@ -120,7 +106,7 @@ pub async fn start(config_directory: &Path, config: Config) -> Result<()> {
|
||||||
let device = available_device.connect().wrap_err("Connecting to the device failed.")?;
|
let device = available_device.connect().wrap_err("Connecting to the device failed.")?;
|
||||||
info!("Connected.");
|
info!("Connected.");
|
||||||
|
|
||||||
device.set_brightness(0.1);
|
device.set_brightness(0.5);
|
||||||
device.vibrate(VibrationPattern::RiseFall);
|
device.vibrate(VibrationPattern::RiseFall);
|
||||||
|
|
||||||
let io_worker_context = IoWorkerContext::create(config_directory, Arc::clone(&config), device, commands_sender.clone(), events_sender);
|
let io_worker_context = IoWorkerContext::create(config_directory, Arc::clone(&config), device, commands_sender.clone(), events_sender);
|
||||||
|
|
Loading…
Add table
Reference in a new issue