emulator: get RPC working w/ Cargo features

This commit is contained in:
2025-06-17 23:48:28 +01:00
parent 3a40719e54
commit 687dea99ca
8 changed files with 318 additions and 54 deletions
+74 -26
View File
@@ -1,42 +1,50 @@
use std::thread;
#[cfg(feature = "discord-rpc")]
use std::sync::Arc;
use std::{
path::Path,
sync::mpsc::{Receiver, Sender},
thread,
};
#[cfg(feature = "discord-rpc")]
use dsa_rs::emulator::misc::rpc::{RpcClient, get_rpc_client_or_none};
use dsa_rs::emulator::{
system::{emulator::run_emulator, memory::MainStore, processor::Processor},
config::Config,
system::{
emulator::run_emulator,
memory::MainStore,
model::{Command, State},
processor::Processor,
},
ui::{
control_unit::ControlPanel, editor::Editor, interface::EmulatorUI,
memory_inspector::MemoryInspector, stack_inspector::StackInspector,
},
};
fn main() -> Result<(), eframe::Error> {
// Initialize Channels
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize channels and read in configuration.
let (cmd_sender, cmd_receiver) = std::sync::mpsc::channel();
let (state_sender, state_receiver) = std::sync::mpsc::channel();
let (state_sender, state_reciever) = std::sync::mpsc::channel();
let config = Config::load(Path::new(".dsa.emulator.toml"))?;
let mainstore = MainStore::new();
let processor = Processor::new(Box::new(mainstore), vec![]);
// Setup RPC if enabled.
#[cfg(feature = "discord-rpc")]
let (rpc_sender, rpc_reciever) = std::sync::mpsc::channel();
thread::spawn(move || {
run_emulator(&cmd_receiver, &state_sender, processor);
});
#[cfg(feature = "discord-rpc")]
let rpc_client =
get_rpc_client_or_none(&config, rpc_sender, rpc_reciever)?.map(Arc::new);
// Create UI
let mut ui = EmulatorUI::new(cmd_sender.clone(), state_receiver);
#[cfg(feature = "discord-rpc")]
setup_emulator(cmd_receiver, state_sender, rpc_client);
#[cfg(not(feature = "discord-rpc"))]
setup_emulator(cmd_receiver, state_sender);
// Create UI modules
let control_unit = ControlPanel::new(cmd_sender.clone());
ui.add_component(Box::new(control_unit));
let ui = setup_ui(cmd_sender, state_reciever);
let mem_inspector = MemoryInspector::new(cmd_sender.clone());
ui.add_component(Box::new(mem_inspector));
let stack_inspector = StackInspector::new();
ui.add_component(Box::new(stack_inspector));
let editor = Editor::new(cmd_sender.clone());
ui.add_component(Box::new(editor));
// Run UI
// Run UI.
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_inner_size([800.0, 600.0]),
..Default::default()
@@ -49,5 +57,45 @@ fn main() -> Result<(), eframe::Error> {
cc.egui_ctx.set_visuals(egui::Visuals::default());
Ok(Box::new(ui))
}),
)
)?;
Ok(())
}
fn setup_emulator(
cmd_receiver: Receiver<Command>,
state_sender: Sender<State>,
#[cfg(feature = "discord-rpc")] rpc_client: Option<Arc<RpcClient>>,
) {
let main_store = MainStore::new();
let processor = Processor::new(Box::new(main_store), vec![]);
thread::spawn(move || {
#[cfg(feature = "discord-rpc")]
run_emulator(&cmd_receiver, &state_sender, processor, rpc_client.as_ref());
#[cfg(not(feature = "discord-rpc"))]
run_emulator(&cmd_receiver, &state_sender, processor);
});
}
/// Creates the [`EmulatorUI`].
fn setup_ui(cmd_sender: Sender<Command>, state_reciever: Receiver<State>) -> EmulatorUI {
let mut ui = EmulatorUI::new(cmd_sender.clone(), state_reciever);
// Create UI modules.
let control_unit = ControlPanel::new(cmd_sender.clone());
ui.add_component(Box::new(control_unit));
let mem_inspector = MemoryInspector::new(cmd_sender.clone());
ui.add_component(Box::new(mem_inspector));
let stack_inspector = StackInspector::new();
ui.add_component(Box::new(stack_inspector));
let editor = Editor::new(cmd_sender.clone());
ui.add_component(Box::new(editor));
ui
}