Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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