mirror of
https://codeberg.org/Fl1tzi/microdeck.git
synced 2024-05-19 19:20:20 +00:00
bringing trash out & formatting
This commit is contained in:
parent
8c32cd611a
commit
9f1fd35835
29
src/main.rs
29
src/main.rs
|
@ -2,16 +2,16 @@ use hidapi::HidApi;
|
|||
use log::{debug, error, info, trace, warn};
|
||||
use serde::Deserialize;
|
||||
use simple_logger;
|
||||
use tokio::sync::mpsc::error::TrySendError;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::io::ErrorKind;
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use std::{env, path::PathBuf};
|
||||
use std::fs;
|
||||
use tokio::process::Command;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::mpsc::error::TrySendError;
|
||||
use tokio::sync::Mutex;
|
||||
mod modules;
|
||||
use elgato_streamdeck as streamdeck;
|
||||
|
@ -42,7 +42,7 @@ pub struct Config {
|
|||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct GlobalConfig {
|
||||
default_font: Option<String>
|
||||
default_font: Option<String>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -219,14 +219,16 @@ pub async fn device_key_listener(
|
|||
ButtonStateUpdate::ButtonDown(i) => {
|
||||
let options = skip_if_none!(keys.get(&i));
|
||||
let actions = &options.1 .0;
|
||||
if send_key_event(options, actions, HostEvent::ButtonPressed).await == false {
|
||||
if send_key_event(options, actions, HostEvent::ButtonPressed).await
|
||||
== false
|
||||
{
|
||||
debug!("Removed key {} from listeners (receiver dropped)", &i);
|
||||
keys.remove(&i);
|
||||
}
|
||||
}
|
||||
ButtonStateUpdate::ButtonUp(i) => {
|
||||
let options = skip_if_none!(keys.get(&i));
|
||||
let actions = &options.1.1;
|
||||
let actions = &options.1 .1;
|
||||
/* let sender = &options.0;
|
||||
let on_release = &options.1 .1;
|
||||
if let Some(actions) = on_release {
|
||||
|
@ -237,7 +239,9 @@ pub async fn device_key_listener(
|
|||
debug!("Removed key {} from listeners (does not respond)", &i);
|
||||
}
|
||||
}*/
|
||||
if send_key_event(options, actions, HostEvent::ButtonReleased).await == false {
|
||||
if send_key_event(options, actions, HostEvent::ButtonReleased).await
|
||||
== false
|
||||
{
|
||||
debug!("Removed key {} from listeners (receiver dropped)", &i);
|
||||
keys.remove(&i);
|
||||
}
|
||||
|
@ -254,7 +258,14 @@ pub async fn device_key_listener(
|
|||
|
||||
/// manually sends the script event or try to send it to the module.
|
||||
/// Returns false if the receiver is dead and can therefore be removed.
|
||||
pub async fn send_key_event(options: &(mpsc::Sender<HostEvent>, (Option<Vec<String>>, Option<Vec<String>>)), actions: &Option<Vec<String>>, event: HostEvent) -> bool {
|
||||
pub async fn send_key_event(
|
||||
options: &(
|
||||
mpsc::Sender<HostEvent>,
|
||||
(Option<Vec<String>>, Option<Vec<String>>),
|
||||
),
|
||||
actions: &Option<Vec<String>>,
|
||||
event: HostEvent,
|
||||
) -> bool {
|
||||
let sender = &options.0;
|
||||
if let Some(actions) = actions {
|
||||
execute_button_action(actions).await;
|
||||
|
@ -262,9 +273,7 @@ pub async fn send_key_event(options: &(mpsc::Sender<HostEvent>, (Option<Vec<Stri
|
|||
if let Err(e) = sender.try_send(event) {
|
||||
match e {
|
||||
TrySendError::Full(_) => trace!("Buffer full: {:?}", e),
|
||||
TrySendError::Closed(_) => {
|
||||
return false
|
||||
}
|
||||
TrySendError::Closed(_) => return false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
151
src/modules.rs
151
src/modules.rs
|
@ -1,32 +1,21 @@
|
|||
mod blank;
|
||||
mod counter;
|
||||
|
||||
use std::{
|
||||
collections::HashMap, error::Error, future::Future, hash::Hash, pin::Pin, sync::Arc,
|
||||
thread::JoinHandle,
|
||||
};
|
||||
|
||||
use crate::{Button, DeviceConfig};
|
||||
use async_trait::async_trait;
|
||||
pub use elgato_streamdeck as streamdeck;
|
||||
use futures_util::TryFutureExt;
|
||||
use image::DynamicImage;
|
||||
use log::{debug, error, info, trace, warn};
|
||||
pub use streamdeck::info::ImageFormat;
|
||||
use streamdeck::AsyncStreamDeck;
|
||||
pub use streamdeck::StreamDeckError;
|
||||
use streamdeck::info::Kind;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::{
|
||||
sync::Mutex,
|
||||
time::{sleep, Duration},
|
||||
};
|
||||
use std::{error::Error, sync::Arc};
|
||||
|
||||
use self::blank::Blank;
|
||||
use self::counter::Counter;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
type ModuleFunction = Box<dyn Fn(DeviceAccess, ChannelReceiver, Button) -> Result<(), ReturnError>>;
|
||||
use crate::Button;
|
||||
use async_trait::async_trait;
|
||||
pub use elgato_streamdeck as streamdeck;
|
||||
use image::DynamicImage;
|
||||
use log::{error, info, trace};
|
||||
pub use streamdeck::info::ImageFormat;
|
||||
use streamdeck::info::Kind;
|
||||
use streamdeck::AsyncStreamDeck;
|
||||
pub use streamdeck::StreamDeckError;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
/// Events that are coming from the host
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
@ -60,117 +49,7 @@ pub async fn start_module(
|
|||
Ok(_) => info!("MODULE {} closed", button.index),
|
||||
Err(e) => error!("MODULE {}: {:?}", button.index, e),
|
||||
}
|
||||
/*
|
||||
match Counter::run(device_access, button_receiver, button.clone()).await {
|
||||
Ok(_) => info!("MODULE {} closed", button.index),
|
||||
Err(e) => error!("MODULE {}: {:?}", button.index, e)
|
||||
}*/
|
||||
}
|
||||
/* #[derive(Clone)]
|
||||
pub struct Bridge;
|
||||
|
||||
impl Bridge {
|
||||
|
||||
/*pub async fn start(&mut self) {
|
||||
/*tokio::join!(self.listener(), ColorModule::run(channel, button))
|
||||
.1
|
||||
.unwrap();*/
|
||||
/*tokio::select! {
|
||||
v = ColorModule::run(self.button_receiver, button) => {
|
||||
match v {
|
||||
Ok(_) => info!("MODULE {} closed", self.button.index),
|
||||
Err(e) => error!("MODULE {}: {:?}", self.button.index, e)
|
||||
}
|
||||
},
|
||||
_ = self.listener() => {}
|
||||
}*/
|
||||
|
||||
/*tokio::spawn(ColorModule::run(channel, button));
|
||||
loop {
|
||||
self.listener().await;
|
||||
sleep(Duration::from_millis(10)).await;
|
||||
}*/
|
||||
}*/
|
||||
|
||||
/* pub async fn listener(&mut self) {
|
||||
loop {
|
||||
if let Ok(event) = self.host_receiver.try_recv() {
|
||||
trace!("MODULE {}: {:?}", self.button.index, event);
|
||||
match event {
|
||||
ModuleEvent::Subscribe(e) => self.events.push(e),
|
||||
ModuleEvent::Image(i) => {
|
||||
println!("UPLOADED IMAGE")
|
||||
}
|
||||
}
|
||||
}
|
||||
sleep(Duration::from_millis(20)).await;
|
||||
}
|
||||
}*/
|
||||
|
||||
pub async fn start_module<F, Fut>(&self, config: Button, module: F)
|
||||
where
|
||||
// Has to be the same as [Module::run]
|
||||
F: FnOnce(Receiver<HostEvent>, Button) -> Fut,
|
||||
Fut: Future<Output = Result<(), Box<dyn Error>>>,
|
||||
{
|
||||
//let channel = ModuleChannel::new(self.sender.clone(), self.receiver.clone()).await;
|
||||
//module(channel, config).await;
|
||||
}
|
||||
}*/
|
||||
|
||||
/*
|
||||
/// A wrapper around the channel to provide easier communication for the module. It is designed to
|
||||
/// be not blocking.
|
||||
pub struct ModuleChannel {
|
||||
pub sender: Sender<ModuleEvent>,
|
||||
pub receiver: Receiver<HostEvent>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ModuleChannelError {
|
||||
/// The host disconnected
|
||||
HostDisconnected,
|
||||
/// The message buffer is full. Either the host or the module is not consuming
|
||||
/// messages.
|
||||
BufferFull,
|
||||
/// The message buffer does not include any events for the module
|
||||
Empty,
|
||||
}*/
|
||||
|
||||
/* impl ModuleChannel {
|
||||
pub async fn new(
|
||||
sender: Sender<ModuleEvent>,
|
||||
receiver: Receiver<HostEvent>,
|
||||
) -> ModuleChannel {
|
||||
ModuleChannel { sender, receiver }
|
||||
}
|
||||
|
||||
/// Send a message without blocking - [crossbeam_channel::Sender::try_send]
|
||||
pub async fn send(&self, message: ModuleEvent) -> Result<(), ModuleChannelError> {
|
||||
self.sender
|
||||
.try_send(message)
|
||||
.map_err(|e| match e {
|
||||
crossbeam_channel::TrySendError::Full(_) => ModuleChannelError::BufferFull,
|
||||
crossbeam_channel::TrySendError::Disconnected(_) => {
|
||||
ModuleChannelError::HostDisconnected
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Receive messages without blocking - [crossbeam_channel::Receiver::try_recv]
|
||||
pub async fn receive(&self) -> Result<HostEvent, ModuleChannelError> {
|
||||
self.receiver.try_recv().map_err(|e| {
|
||||
match e {
|
||||
crossbeam_channel::TryRecvError::Empty => ModuleChannelError::Empty,
|
||||
crossbeam_channel::TryRecvError::Disconnected => {
|
||||
ModuleChannelError::HostDisconnected
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn update_image(&self, img: DynamicImage) {}
|
||||
}*/
|
||||
|
||||
/// Wrapper to provide easier access to the Deck
|
||||
pub struct DeviceAccess {
|
||||
|
@ -182,7 +61,11 @@ pub struct DeviceAccess {
|
|||
impl DeviceAccess {
|
||||
pub async fn new(streamdeck: Arc<AsyncStreamDeck>, index: u8) -> DeviceAccess {
|
||||
let kind = streamdeck.kind();
|
||||
DeviceAccess { streamdeck, kind, index }
|
||||
DeviceAccess {
|
||||
streamdeck,
|
||||
kind,
|
||||
index,
|
||||
}
|
||||
}
|
||||
|
||||
/// write a raw image to the Deck
|
||||
|
|
|
@ -6,7 +6,7 @@ use super::{ChannelReceiver, DeviceAccess, HostEvent, ReturnError};
|
|||
use async_trait::async_trait;
|
||||
use image::{Rgb, RgbImage};
|
||||
use imageproc::drawing::draw_text_mut;
|
||||
use rusttype::{Scale, Font};
|
||||
use rusttype::{Font, Scale};
|
||||
|
||||
/// A module which displays a counter
|
||||
pub struct Counter;
|
||||
|
@ -24,7 +24,7 @@ impl Module for Counter {
|
|||
let (h, w) = streamdeck.resolution();
|
||||
|
||||
let mut stream = button_receiver.lock().await;
|
||||
|
||||
|
||||
let mut counter: u32 = 0;
|
||||
loop {
|
||||
if let Some(event) = stream.recv().await {
|
||||
|
@ -32,13 +32,23 @@ impl Module for Counter {
|
|||
HostEvent::ButtonPressed => {
|
||||
counter += 1;
|
||||
let mut image = RgbImage::new(h as u32, w as u32);
|
||||
draw_text_mut(&mut image, Rgb([255, 255, 255]), 10, 10, Scale::uniform(20.0), &font, format!("{}", counter).as_str());
|
||||
streamdeck.write_img(image::DynamicImage::ImageRgb8(image)).await.unwrap();
|
||||
},
|
||||
draw_text_mut(
|
||||
&mut image,
|
||||
Rgb([255, 255, 255]),
|
||||
10,
|
||||
10,
|
||||
Scale::uniform(20.0),
|
||||
&font,
|
||||
format!("{}", counter).as_str(),
|
||||
);
|
||||
streamdeck
|
||||
.write_img(image::DynamicImage::ImageRgb8(image))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue