Skip to content

Commit

Permalink
Expose more of the Server Protocol (#827)
Browse files Browse the repository at this point in the history
This exposes more of the Server Protocol publicly, so it can also be
used as a client.
  • Loading branch information
CryZe authored Jul 15, 2024
1 parent 8d5b0f6 commit 3c3762b
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 87 deletions.
19 changes: 11 additions & 8 deletions capi/src/command_sink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//! processing a command, changes to the timer are reported as events. Various
//! error conditions can occur if the command couldn't be processed.
use std::{future::Future, ops::Deref, pin::Pin, sync::Arc};
use std::{borrow::Cow, future::Future, ops::Deref, pin::Pin, sync::Arc};

use livesplit_core::{
event::{self, Result},
Expand Down Expand Up @@ -50,15 +50,15 @@ pub(crate) trait CommandSinkAndQuery: Send + Sync + 'static {
fn dyn_undo_all_pauses(&self) -> Fut;
fn dyn_switch_to_previous_comparison(&self) -> Fut;
fn dyn_switch_to_next_comparison(&self) -> Fut;
fn dyn_set_current_comparison(&self, comparison: &str) -> Fut;
fn dyn_set_current_comparison(&self, comparison: Cow<'_, str>) -> Fut;
fn dyn_toggle_timing_method(&self) -> Fut;
fn dyn_set_current_timing_method(&self, method: TimingMethod) -> Fut;
fn dyn_initialize_game_time(&self) -> Fut;
fn dyn_set_game_time(&self, time: TimeSpan) -> Fut;
fn dyn_pause_game_time(&self) -> Fut;
fn dyn_resume_game_time(&self) -> Fut;
fn dyn_set_loading_times(&self, time: TimeSpan) -> Fut;
fn dyn_set_custom_variable(&self, name: &str, value: &str) -> Fut;
fn dyn_set_custom_variable(&self, name: Cow<'_, str>, value: Cow<'_, str>) -> Fut;
}

type Fut = Pin<Box<dyn Future<Output = Result> + 'static>>;
Expand Down Expand Up @@ -107,7 +107,7 @@ where
fn dyn_switch_to_next_comparison(&self) -> Fut {
Box::pin(self.switch_to_next_comparison())
}
fn dyn_set_current_comparison(&self, comparison: &str) -> Fut {
fn dyn_set_current_comparison(&self, comparison: Cow<'_, str>) -> Fut {
Box::pin(self.set_current_comparison(comparison))
}
fn dyn_toggle_timing_method(&self) -> Fut {
Expand All @@ -131,7 +131,7 @@ where
fn dyn_set_loading_times(&self, time: TimeSpan) -> Fut {
Box::pin(self.set_loading_times(time))
}
fn dyn_set_custom_variable(&self, name: &str, value: &str) -> Fut {
fn dyn_set_custom_variable(&self, name: Cow<'_, str>, value: Cow<'_, str>) -> Fut {
Box::pin(self.set_custom_variable(name, value))
}
}
Expand Down Expand Up @@ -185,7 +185,10 @@ impl event::CommandSink for CommandSink {
self.0.dyn_switch_to_next_comparison()
}

fn set_current_comparison(&self, comparison: &str) -> impl Future<Output = Result> + 'static {
fn set_current_comparison(
&self,
comparison: Cow<'_, str>,
) -> impl Future<Output = Result> + 'static {
self.0.dyn_set_current_comparison(comparison)
}

Expand Down Expand Up @@ -222,8 +225,8 @@ impl event::CommandSink for CommandSink {

fn set_custom_variable(
&self,
name: &str,
value: &str,
name: Cow<'_, str>,
value: Cow<'_, str>,
) -> impl Future<Output = Result> + 'static {
self.0.dyn_set_custom_variable(name, value)
}
Expand Down
17 changes: 10 additions & 7 deletions capi/src/web_command_sink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! timer commands. All of them are optional except for `getTimer`.
use core::ptr;
use std::{cell::Cell, convert::TryFrom, future::Future, sync::Arc};
use std::{borrow::Cow, cell::Cell, convert::TryFrom, future::Future, sync::Arc};

use livesplit_core::{
event::{CommandSink, Error, Event, Result, TimerQuery},
Expand Down Expand Up @@ -221,12 +221,15 @@ impl CommandSink for WebCommandSink {
)
}

fn set_current_comparison(&self, comparison: &str) -> impl Future<Output = Result> + 'static {
fn set_current_comparison(
&self,
comparison: Cow<'_, str>,
) -> impl Future<Output = Result> + 'static {
debug_assert!(!self.locked.get());
handle_action_value(
self.set_current_comparison
.as_ref()
.and_then(|f| f.call1(&self.obj, &JsValue::from_str(comparison)).ok()),
.and_then(|f| f.call1(&self.obj, &JsValue::from_str(&comparison)).ok()),
)
}

Expand Down Expand Up @@ -301,15 +304,15 @@ impl CommandSink for WebCommandSink {

fn set_custom_variable(
&self,
name: &str,
value: &str,
name: Cow<'_, str>,
value: Cow<'_, str>,
) -> impl Future<Output = Result> + 'static {
debug_assert!(!self.locked.get());
handle_action_value(self.set_custom_variable.as_ref().and_then(|f| {
f.call2(
&self.obj,
&JsValue::from_str(name),
&JsValue::from_str(value),
&JsValue::from_str(&name),
&JsValue::from_str(&value),
)
.ok()
}))
Expand Down
2 changes: 1 addition & 1 deletion src/auto_splitting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ impl<E: event::CommandSink + TimerQuery + Send> AutoSplitTimer for Timer<E> {
}

fn set_variable(&mut self, name: &str, value: &str) {
drop(self.0.set_custom_variable(name, value));
drop(self.0.set_custom_variable(name.into(), value.into()));
}

fn log(&mut self, message: fmt::Arguments<'_>) {
Expand Down
2 changes: 1 addition & 1 deletion src/component/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! the chosen comparison throughout the whole attempt. Every point of the graph
//! represents a split. Its x-coordinate is proportional to the split time and
//! its y-coordinate is proportional to the split delta. The entire diagram is
//! refered to as the chart and it contains the graph. The x-axis is the
//! referred to as the chart and it contains the graph. The x-axis is the
//! horizontal line that separates positive deltas from negative ones.
// The words "padding" and "content" are from the CSS box model. "Padding" is an
Expand Down
44 changes: 27 additions & 17 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use core::{future::Future, ops::Deref};

use alloc::sync::Arc;
use alloc::{borrow::Cow, sync::Arc};

use crate::{TimeSpan, Timer, TimingMethod};

Expand Down Expand Up @@ -59,13 +59,14 @@ pub enum Event {
LoadingTimesSet = 16,
/// A custom variable has been set.
CustomVariableSet = 17,
/// An unknown event occurred.
#[serde(other)]
Unknown,
}

impl TryFrom<u32> for Event {
type Error = ();

fn try_from(value: u32) -> Result<Self, Self::Error> {
Ok(match value {
impl From<u32> for Event {
fn from(value: u32) -> Self {
match value {
0 => Event::Started,
1 => Event::Splitted,
2 => Event::Finished,
Expand All @@ -84,8 +85,8 @@ impl TryFrom<u32> for Event {
15 => Event::GameTimeResumed,
16 => Event::LoadingTimesSet,
17 => Event::CustomVariableSet,
_ => return Err(()),
})
_ => Event::Unknown,
}
}
}

Expand Down Expand Up @@ -238,7 +239,10 @@ pub trait CommandSink {
fn switch_to_next_comparison(&self) -> impl Future<Output = Result> + 'static;
/// Tries to set the current comparison to the comparison specified. If the
/// comparison doesn't exist an error is returned.
fn set_current_comparison(&self, comparison: &str) -> impl Future<Output = Result> + 'static;
fn set_current_comparison(
&self,
comparison: Cow<'_, str>,
) -> impl Future<Output = Result> + 'static;
/// Toggles between the `Real Time` and `Game Time` timing methods.
fn toggle_timing_method(&self) -> impl Future<Output = Result> + 'static;
/// Sets the current timing method to the timing method provided.
Expand Down Expand Up @@ -269,8 +273,8 @@ pub trait CommandSink {
/// be stored in the splits file.
fn set_custom_variable(
&self,
name: &str,
value: &str,
name: Cow<'_, str>,
value: Cow<'_, str>,
) -> impl Future<Output = Result> + 'static;
}

Expand Down Expand Up @@ -347,7 +351,10 @@ impl CommandSink for crate::SharedTimer {
async { Ok(Event::ComparisonChanged) }
}

fn set_current_comparison(&self, comparison: &str) -> impl Future<Output = Result> + 'static {
fn set_current_comparison(
&self,
comparison: Cow<'_, str>,
) -> impl Future<Output = Result> + 'static {
let result = self.write().unwrap().set_current_comparison(comparison);
async move { result }
}
Expand Down Expand Up @@ -392,8 +399,8 @@ impl CommandSink for crate::SharedTimer {

fn set_custom_variable(
&self,
name: &str,
value: &str,
name: Cow<'_, str>,
value: Cow<'_, str>,
) -> impl Future<Output = Result> + 'static {
self.write().unwrap().set_custom_variable(name, value);
async { Ok(Event::CustomVariableSet) }
Expand Down Expand Up @@ -457,7 +464,10 @@ impl<T: CommandSink + ?Sized> CommandSink for Arc<T> {
CommandSink::switch_to_next_comparison(&**self)
}

fn set_current_comparison(&self, comparison: &str) -> impl Future<Output = Result> + 'static {
fn set_current_comparison(
&self,
comparison: Cow<'_, str>,
) -> impl Future<Output = Result> + 'static {
CommandSink::set_current_comparison(&**self, comparison)
}

Expand Down Expand Up @@ -494,8 +504,8 @@ impl<T: CommandSink + ?Sized> CommandSink for Arc<T> {

fn set_custom_variable(
&self,
name: &str,
value: &str,
name: Cow<'_, str>,
value: Cow<'_, str>,
) -> impl Future<Output = Result> + 'static {
CommandSink::set_custom_variable(&**self, name, value)
}
Expand Down
Loading

0 comments on commit 3c3762b

Please sign in to comment.