diff --git a/discord-rpc/src/config.rs b/discord-rpc/src/config.rs index dd7c7d2..224b47e 100644 --- a/discord-rpc/src/config.rs +++ b/discord-rpc/src/config.rs @@ -1,24 +1,7 @@ -use preferences::{AppInfo, Preferences}; -use ruspiro_singleton::Singleton; - -use crate::melee::SlippiMenuScene; - -pub const APP_INFO: AppInfo = AppInfo { - name: "conf", - author: "Slippi Discord Integration", -}; -const PREFS_KEY: &str = "app_config"; - -pub static CONFIG: Singleton = Singleton::lazy(&|| { - match AppConfig::load(&APP_INFO, PREFS_KEY) { - Ok(cfg) => cfg, - Err(_) => AppConfig::default() - } -}); - structstruck::strike! { - #[strikethrough[derive(Serialize, Deserialize, PartialEq, Debug)]] - pub struct AppConfig { + /// Core configuration object for this library. + #[strikethrough[derive(Debug, serde::Serialize, serde::Deserialize, PartialEq)]] + pub struct Config { pub global: struct { pub show_in_game_character: bool, pub show_in_game_time: bool @@ -68,12 +51,12 @@ structstruck::strike! { } } -impl Default for AppConfig { +impl Default for Config { fn default() -> Self { - AppConfig { + Config { global: Global { show_in_game_character: true, - show_in_game_time: true + show_in_game_time: true, }, slippi: Slippi { enabled: true, @@ -83,39 +66,34 @@ impl Default for AppConfig { enabled: true, show_rank: true, show_view_ranked_profile_button: true, - show_score: true + show_score: true, }, unranked: Unranked { enabled: true }, direct: Direct { enabled: true }, - teams: Teams { enabled: true } + teams: Teams { enabled: true }, }, uncle_punch: UnclePunch { enabled: true }, vs_mode: VsMode { enabled: true }, training_mode: TrainingMode { enabled: true }, stadium: Stadium { enabled: true, - hrc: Hrc { - enabled: true - }, + hrc: Hrc { enabled: true }, btt: Btt { enabled: true, - show_stage_name: true + show_stage_name: true, }, - mmm: Mmm { - enabled: true - } - } + mmm: Mmm { enabled: true }, + }, } } } -pub fn write_config(val: &AppConfig) { - let _ = val.save(&APP_INFO, PREFS_KEY); -} - // Utility implementations +// Commented out for the moment +/* +use crate::melee::SlippiMenuScene; impl SlippiMenuScene { - pub fn is_enabled(&self, c: &AppConfig) -> bool { + pub fn is_enabled(&self, c: &Config) -> bool { match *self { SlippiMenuScene::Ranked => c.slippi.ranked.enabled, SlippiMenuScene::Unranked => c.slippi.unranked.enabled, @@ -123,4 +101,4 @@ impl SlippiMenuScene { SlippiMenuScene::Teams => c.slippi.teams.enabled } } -} \ No newline at end of file +}*/ diff --git a/discord-rpc/src/lib.rs b/discord-rpc/src/lib.rs index 1b5acde..b410e14 100644 --- a/discord-rpc/src/lib.rs +++ b/discord-rpc/src/lib.rs @@ -8,6 +8,9 @@ use std::thread; use dolphin_integrations::Log; +mod config; +pub use config::Config; + mod error; pub use error::DiscordRPCError; @@ -16,6 +19,7 @@ pub(crate) type Result = std::result::Result; /// Message payloads that the inner thread listens for. #[derive(Debug)] pub enum Message { + ConfigUpdate(Config), Dropping, } @@ -30,8 +34,8 @@ pub struct DiscordHandler { impl DiscordHandler { /// Kicks off the background thread, which monitors game state and emits /// updates to Discord accordingly. - pub fn new(ram_offset: u8) -> Result { - tracing::info!(target: Log::DiscordRPC, "Initializing DiscordRPC"); + pub fn new(ram_offset: u8, config: Config) -> Result { + tracing::info!(target: Log::DiscordRPC, "Initializing DiscordHandler"); // Create a sender and receiver channel pair to communicate between threads. let (tx, rx) = channel::(); @@ -40,13 +44,13 @@ impl DiscordHandler { // the loop breaks - either due to shutdown or intentional drop - the underlying // OS thread will clean itself up. thread::Builder::new() - .name("SlippiDiscordRPC".to_string()) + .name("SlippiDiscordHandler".to_string()) .spawn(move || { - if let Err(e) = Self::start(rx, ram_offset) { + if let Err(e) = Self::start(rx, ram_offset, config) { tracing::error!( target: Log::DiscordRPC, error = ?e, - "SlippiDiscordRPC thread encountered an error: {e}" + "SlippiDiscordHandler thread encountered an error: {e}" ); } }) @@ -56,22 +60,35 @@ impl DiscordHandler { } /// Must be called on a background thread. Runs the core event loop. - fn start(rx: Receiver, ram_offset: u8) -> Result<()> { + fn start(rx: Receiver, ram_offset: u8, config: Config) -> Result<()> { Ok(()) } + + /// Passes a new configuration into the background handler. + pub fn update_config(&mut self, config: Config) { + if let Err(e) = self.tx.send(Message::ConfigUpdate(config)) { + // @TODO: Maybe add an OSD log message here? + + tracing::error!( + target: Log::DiscordRPC, + error = ?e, + "Failed to update DiscordHandler config" + ); + } + } } impl Drop for DiscordHandler { /// Notifies the background thread that we're dropping. The thread should /// listen for the message and break its runloop accordingly. fn drop(&mut self) { - tracing::info!(target: Log::DiscordRPC, "Dropping DiscordRPC"); + tracing::info!(target: Log::DiscordRPC, "Dropping DiscordHandler"); if let Err(e) = self.tx.send(Message::Dropping) { tracing::warn!( target: Log::DiscordRPC, error = ?e, - "Failed to notify child thread that DiscordRPC is dropping" + "Failed to notify child thread that DiscordHandler is dropping" ); } } diff --git a/exi/src/lib.rs b/exi/src/lib.rs index ac54b1e..39d192f 100644 --- a/exi/src/lib.rs +++ b/exi/src/lib.rs @@ -10,7 +10,7 @@ use std::time::Duration; use ureq::AgentBuilder; use dolphin_integrations::Log; -use slippi_discord_rpc::DiscordHandler; +use slippi_discord_rpc::{Config as DiscordHandlerConfig, DiscordHandler}; use slippi_game_reporter::GameReporter; use slippi_jukebox::Jukebox; use slippi_user::UserManager; @@ -32,8 +32,8 @@ pub enum JukeboxConfiguration { /// Configuration instructions that the FFI layer uses to call over here. #[derive(Debug)] pub enum DiscordHandlerConfiguration { - Start { ram_offset: u8 }, - + Start { ram_offset: u8, config: DiscordHandlerConfig }, + UpdateConfig { config: DiscordHandlerConfig }, Stop, } @@ -134,13 +134,18 @@ impl SlippiEXIDevice { return; } - if self.discord_handler.is_some() { + if let Some(discord_handler) = &mut self.discord_handler { + if let DiscordHandlerConfiguration::UpdateConfig { config } = config { + discord_handler.update_config(config); + return; + } + tracing::warn!(target: Log::SlippiOnline, "Discord handler is already running."); return; } - if let DiscordHandlerConfiguration::Start { ram_offset } = config { - match DiscordHandler::new(ram_offset) { + if let DiscordHandlerConfiguration::Start { ram_offset, config } = config { + match DiscordHandler::new(ram_offset, config) { Ok(handler) => { self.discord_handler = Some(handler); },