commit
This commit is contained in:
parent
2fce4312eb
commit
2059555174
5 changed files with 142 additions and 1 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -624,6 +624,19 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "execute"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"color-eyre",
|
||||
"deckster_mode",
|
||||
"env_logger",
|
||||
"log",
|
||||
"serde",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
version = "0.6.11"
|
||||
|
|
|
@ -58,4 +58,11 @@ config.mode = "toggle"
|
|||
config.entity_id = "light.moritz_zimmer_stehlampe"
|
||||
config.style.on.icon = "@ph/computer-tower[color=#58fc11]"
|
||||
config.style.disconnected.icon = "@ph/computer-tower[alpha=0.2]"
|
||||
config.disconnected_state = "disconnected"
|
||||
config.disconnected_state = "disconnected"
|
||||
|
||||
[keys.4x1]
|
||||
label = "9"
|
||||
|
||||
handler = "execute"
|
||||
config.program = "wtype"
|
||||
config.args = ["9"]
|
13
handlers/execute/Cargo.toml
Normal file
13
handlers/execute/Cargo.toml
Normal file
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "execute"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
deckster_mode = { path = "../../crates/deckster_mode" }
|
||||
clap = { version = "4.4.18", features = ["derive"] }
|
||||
color-eyre = "0.6.2"
|
||||
serde = { version = "1.0.196", features = ["derive"] }
|
||||
env_logger = "0.11.1"
|
||||
log = "0.4.20"
|
||||
tokio = { version = "1.35.1", features = ["macros", "parking_lot", "rt", "process", "sync"] }
|
82
handlers/execute/src/handler.rs
Normal file
82
handlers/execute/src/handler.rs
Normal file
|
@ -0,0 +1,82 @@
|
|||
use deckster_mode::shared::handler_communication::{HandlerEvent, HandlerInitializationError, InitialHandlerMessage, KeyEvent};
|
||||
use deckster_mode::shared::path::KeyPath;
|
||||
use deckster_mode::DecksterHandler;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
use std::thread;
|
||||
use tokio::process::Command;
|
||||
use tokio::sync::broadcast;
|
||||
use tokio::task::LocalSet;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct KeyConfig {
|
||||
program: Box<str>,
|
||||
#[serde(default)]
|
||||
args: Box<[String]>,
|
||||
}
|
||||
|
||||
pub struct Handler {
|
||||
events_sender: broadcast::Sender<(KeyPath, KeyEvent)>,
|
||||
}
|
||||
|
||||
impl Handler {
|
||||
pub fn new(data: InitialHandlerMessage<(), KeyConfig, ()>) -> Result<Self, HandlerInitializationError> {
|
||||
let (events_sender, _) = broadcast::channel::<(KeyPath, KeyEvent)>(5);
|
||||
|
||||
thread::spawn({
|
||||
let events_sender = events_sender.clone();
|
||||
|
||||
move || {
|
||||
let runtime = tokio::runtime::Builder::new_current_thread().enable_io().build().unwrap();
|
||||
let task_set = LocalSet::new();
|
||||
|
||||
for (path, config) in data.key_configs {
|
||||
task_set.spawn_local(manage_key(events_sender.subscribe(), path, config));
|
||||
}
|
||||
|
||||
runtime.block_on(task_set)
|
||||
}
|
||||
});
|
||||
|
||||
Ok(Handler { events_sender })
|
||||
}
|
||||
}
|
||||
|
||||
impl DecksterHandler for Handler {
|
||||
fn handle(&mut self, event: HandlerEvent) {
|
||||
if let HandlerEvent::Key { path, event } = event {
|
||||
self.events_sender.send((path, event)).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn manage_key(mut events: broadcast::Receiver<(KeyPath, KeyEvent)>, path: KeyPath, config: KeyConfig) {
|
||||
let mut command = Command::new(config.program.as_ref());
|
||||
let command = command.args(config.args.clone().iter());
|
||||
|
||||
while let Ok((p, event)) = events.recv().await {
|
||||
if p != path {
|
||||
continue;
|
||||
}
|
||||
|
||||
if event == KeyEvent::Press {
|
||||
tokio::spawn({
|
||||
let future = command.status();
|
||||
let path = path.clone();
|
||||
|
||||
async move {
|
||||
let result = future.await;
|
||||
|
||||
match result {
|
||||
Ok(status) => {
|
||||
if !status.success() {
|
||||
log::error!("Process failed with status (key at {}): {}", &path, status)
|
||||
}
|
||||
}
|
||||
Err(error) => log::error!("Failed to spawn process (key at {}): {}", &path, error),
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
26
handlers/execute/src/main.rs
Normal file
26
handlers/execute/src/main.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use clap::Parser;
|
||||
use color_eyre::Result;
|
||||
|
||||
use crate::handler::Handler;
|
||||
|
||||
mod handler;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(name = "execute")]
|
||||
enum CliCommand {
|
||||
#[command(name = "deckster-run", hide = true)]
|
||||
Run,
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
env_logger::init();
|
||||
let command = CliCommand::parse();
|
||||
|
||||
match command {
|
||||
CliCommand::Run => {
|
||||
deckster_mode::run(Handler::new)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Add table
Reference in a new issue