167 lines
4.4 KiB
Rust
167 lines
4.4 KiB
Rust
use crate::{
|
|
dbus::{button::Button, button_path, deck_path},
|
|
store::Store,
|
|
};
|
|
use std::collections::BTreeSet;
|
|
use streamdeck_common::Input;
|
|
use zbus::{Connection, SignalContext};
|
|
|
|
pub(super) struct Deck {
|
|
connection: Connection,
|
|
serial_number: String,
|
|
name: String,
|
|
product_name: String,
|
|
port_name: String,
|
|
store: Store,
|
|
buttons: BTreeSet<String>,
|
|
}
|
|
|
|
impl Deck {
|
|
#[tracing::instrument(skip(connection))]
|
|
pub(crate) async fn hydrate(
|
|
connection: Connection,
|
|
serial_number: String,
|
|
product_name: String,
|
|
port_name: String,
|
|
store: Store,
|
|
) -> anyhow::Result<()> {
|
|
let commands = store.get_commands(&serial_number).await?;
|
|
let name = store.deck_name(&serial_number).await?;
|
|
|
|
let path = deck_path(&serial_number);
|
|
|
|
let deck = Deck {
|
|
connection: connection.clone(),
|
|
serial_number,
|
|
name: name.unwrap_or_else(|| String::from("Streamdeck")),
|
|
product_name,
|
|
port_name,
|
|
store,
|
|
buttons: BTreeSet::new(),
|
|
};
|
|
|
|
let _ = connection.object_server().at(path.clone(), deck).await?;
|
|
|
|
let iface_ref = connection
|
|
.object_server()
|
|
.interface::<_, Deck>(path)
|
|
.await?;
|
|
let mut iface = iface_ref.get_mut().await;
|
|
|
|
for (input, command) in commands {
|
|
let command = serde_json::to_string(&command)?;
|
|
iface.create_button(input, command).await?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[zbus::dbus_interface(name = "dog.asonix.git.asonix.StreamdeckDaemon.Deck")]
|
|
impl Deck {
|
|
#[dbus_interface(property)]
|
|
async fn name(&self) -> &str {
|
|
tracing::debug!("name");
|
|
&self.name
|
|
}
|
|
|
|
#[dbus_interface(property)]
|
|
async fn set_name(&mut self, name: String) {
|
|
tracing::debug!("set name");
|
|
if self
|
|
.store
|
|
.set_deck_name(&self.serial_number, &name)
|
|
.await
|
|
.is_ok()
|
|
{
|
|
self.name = name;
|
|
}
|
|
}
|
|
|
|
#[dbus_interface(property)]
|
|
async fn product_name(&self) -> &str {
|
|
tracing::debug!("product_name");
|
|
&self.product_name
|
|
}
|
|
|
|
#[dbus_interface(property)]
|
|
async fn port_name(&self) -> &str {
|
|
tracing::debug!("port_name");
|
|
&self.port_name
|
|
}
|
|
|
|
async fn get_buttons(&self) -> Vec<String> {
|
|
tracing::debug!("get buttons");
|
|
self.buttons.iter().cloned().collect()
|
|
}
|
|
|
|
async fn create_button(&mut self, input: Input, command: String) -> zbus::fdo::Result<String> {
|
|
tracing::debug!("create button");
|
|
let path = button_path(&self.serial_number, &input);
|
|
|
|
self.buttons.insert(path.clone());
|
|
|
|
Button::hydrate(
|
|
self.connection.clone(),
|
|
self.serial_number.clone(),
|
|
input.clone(),
|
|
self.store.clone(),
|
|
)
|
|
.await
|
|
.map_err(crate::dbus::fail)?;
|
|
|
|
let iface = self
|
|
.connection
|
|
.object_server()
|
|
.interface::<_, Button>(path.clone())
|
|
.await?;
|
|
|
|
let mut iface_ref = iface.get_mut().await;
|
|
iface_ref.set_command(command).await;
|
|
|
|
let ctx = iface.signal_context();
|
|
|
|
Self::button_added(ctx, input).await?;
|
|
|
|
Ok(path)
|
|
}
|
|
|
|
async fn remove_button(&mut self, input: Input) -> zbus::fdo::Result<()> {
|
|
tracing::debug!("remove button");
|
|
let path = button_path(&self.serial_number, &input);
|
|
|
|
self.buttons.remove(&path);
|
|
|
|
let _ = self
|
|
.connection
|
|
.object_server()
|
|
.remove::<Button, _>(path.clone())
|
|
.await?;
|
|
|
|
self.store
|
|
.unset(&self.serial_number, input.clone())
|
|
.await
|
|
.map_err(crate::dbus::fail)?;
|
|
|
|
let iface = self
|
|
.connection
|
|
.object_server()
|
|
.interface::<_, Self>(path)
|
|
.await?;
|
|
let ctx = iface.signal_context();
|
|
|
|
Self::button_removed(ctx, input).await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[dbus_interface(signal)]
|
|
pub(super) async fn button_pushed(ctx: &SignalContext<'_>, input: Input) -> zbus::Result<()>;
|
|
|
|
#[dbus_interface(signal)]
|
|
async fn button_added(ctx: &SignalContext<'_>, input: Input) -> zbus::Result<()>;
|
|
|
|
#[dbus_interface(signal)]
|
|
async fn button_removed(ctx: &SignalContext<'_>, input: Input) -> zbus::Result<()>;
|
|
}
|