Skip to content

Commit

Permalink
Add simple DBus system
Browse files Browse the repository at this point in the history
  • Loading branch information
ananace committed Apr 14, 2024
1 parent e34ec1d commit b89190c
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ tokio = { version = "1.24.2", default-features = false, features = [
], optional = true }
log = { version = "0.4.14", default-features = false, optional = true }

# DBus
zbus = { version = "4.1.2", optional = true}

[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
# WebAssembly in the Web
js-sys = { version = "0.3.55", optional = true }
Expand Down Expand Up @@ -175,6 +178,7 @@ wasm-web = [
]
networking = ["std", "splits-io-api"]
auto-splitting = ["std", "livesplit-auto-splitting", "tokio", "log"]
dbus = ["tokio", "zbus"]

[lib]
bench = false
Expand Down
152 changes: 152 additions & 0 deletions src/dbus/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
//! The dbus module provides the functionality necessary to handle DBus
//! communication, specifically regarding reading and writing state to an
//! active timer.
use crate::{
timing::{SharedTimer, TimerPhase},
TimeSpan
};
use std::{
future::pending,
thread,
// thread::JoinHandle
};
use tokio::runtime;
use zbus::{
connection,
interface,
};

// This type exists mainly to make registering the DBus interface easier.
#[derive(Clone)]
struct DBusTimer(SharedTimer);

#[interface(name = "org.livesplit.LiveSplit")]
impl DBusTimer {
fn start(&self) {
self.0.write().unwrap().start();
}

fn split(&self) {
self.0.write().unwrap().split_or_start();
}

fn skip_split(&self) {
self.0.write().unwrap().skip_split();
}

fn undo_split(&self) {
self.0.write().unwrap().undo_split();
}

fn toggle_pause(&self) {
self.0.write().unwrap().toggle_pause_or_start();
}

fn reset(&self) {
self.0.write().unwrap().reset(true);
}

fn undo_all_pauses(&self) {
self.0.write().unwrap().undo_all_pauses();
}


#[zbus(property)]
fn comparison(&self) -> String {
self.0.write().unwrap().current_comparison().to_string()
}
#[zbus(property)]
fn set_comparison(&self, comparison: &str) {
let _ = self.0.write().unwrap().set_current_comparison(comparison);
}

fn previous_comparison(&self) {
self.0.write().unwrap().switch_to_previous_comparison();
}

fn next_comparison(&self) {
self.0.write().unwrap().switch_to_next_comparison();
}


fn toggle_timing_method(&self) {
self.0.write().unwrap().toggle_timing_method();
}

fn set_game_time(&self, time: f64) {
self.0.write().unwrap().set_game_time(TimeSpan::from_seconds(time));
}

fn pause_game_time(&self) {
self.0.write().unwrap().pause_game_time();
}

fn resume_game_time(&self) {
self.0.write().unwrap().resume_game_time();
}

fn set_variable(&self, name: &str, value: &str) {
self.0.write().unwrap().set_custom_variable(name, value);
}

#[zbus(property)]
fn running(&self) -> bool {
self.0.write().unwrap().current_phase() == TimerPhase::Running
}
#[zbus(property)]
fn set_running(&self, running: bool) {
if running {
match self.0.write().unwrap().current_phase() {
TimerPhase::Paused => self.0.write().unwrap().resume(),
TimerPhase::NotRunning => self.0.write().unwrap().start(),
_ => {}
};
} else {
self.0.write().unwrap().pause();
}
}
}

/// A system reference that will spin up a background thread to handle DBus
/// communication.
pub struct DBusSystem {
//dbus_worker: JoinHandle<zbus::Result<()>>,
}

impl DBusSystem {
/// Starts the DBus system, will take ownership of the name and handle
/// requests in the background.
pub fn new(timer: SharedTimer) -> Self {
let dbus_timer = DBusTimer(timer);
// let dbus_worker =
thread::Builder::new()
.name("DBus Worker".into())
.spawn(move || {
runtime::Builder::new_current_thread()
.enable_time()
.build()
.unwrap()
.block_on(run_dbus(dbus_timer))
})
.unwrap();

Self {
// dbus_worker,
}
}
}

async fn run_dbus(
timer: DBusTimer,
) -> zbus::Result<()> {
let _conn = connection::Builder::session()?
.name("org.livesplit.LiveSplit")?
.serve_at("/org/livesplit/LiveSplit", timer)?
.build()
.await?;

loop {
pending::<()>().await;
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ pub mod analysis;
pub mod auto_splitting;
pub mod comparison;
pub mod component;
#[cfg(feature = "dbus")]
pub mod dbus;
#[cfg(feature = "std")]
mod hotkey_config;
#[cfg(feature = "std")]
Expand Down

0 comments on commit b89190c

Please sign in to comment.