diff --git a/workspace/.vscode/launch.json b/workspace/.vscode/launch.json index 3828624..d42726e 100644 --- a/workspace/.vscode/launch.json +++ b/workspace/.vscode/launch.json @@ -20,7 +20,7 @@ } }, "args": [], - "cwd": "${workspaceFolder}/workspace" + "cwd": "${workspaceFolder}" }, { "type": "lldb", @@ -39,7 +39,7 @@ } }, "args": [], - "cwd": "${workspaceFolder}/workspace" + "cwd": "${workspaceFolder}" } ] } \ No newline at end of file diff --git a/workspace/Cargo.lock b/workspace/Cargo.lock index 5d34f31..0fea607 100644 --- a/workspace/Cargo.lock +++ b/workspace/Cargo.lock @@ -344,6 +344,15 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bindgen" version = "0.70.1" @@ -1327,6 +1336,9 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ + "futures-core", + "futures-sink", + "nanorand", "spin", ] @@ -2685,6 +2697,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + [[package]] name = "ndk" version = "0.7.0" @@ -5976,6 +5997,8 @@ version = "0.1.0" dependencies = [ "anyhow", "async-nats", + "bincode", + "flume", "image 0.25.2", "indexmap", "known-folders", diff --git a/workspace/Cargo.toml b/workspace/Cargo.toml index f22f1ad..4065ab4 100644 --- a/workspace/Cargo.toml +++ b/workspace/Cargo.toml @@ -27,6 +27,8 @@ notan = { version = "0.12.1", features = [ tao = "0.30.3" rocket = "0.5.1" async-nats = "0.37.0" +flume = "0.11.0" +bincode = "1.3.3" [build-dependencies] winresource = "0.1.17" diff --git a/workspace/src/bin/log_history.rs b/workspace/src/bin/log_history.rs index 3d3c1cd..6aabbb7 100644 --- a/workspace/src/bin/log_history.rs +++ b/workspace/src/bin/log_history.rs @@ -29,6 +29,7 @@ struct LogFile { #[derive(AppState, Serialize, Deserialize)] struct State { log_history: IndexSet, + #[serde(skip)] log_viewer_path: PathBuf, #[serde(skip)] open_files: HashMap, @@ -186,9 +187,11 @@ fn init(_gfx: &mut Graphics) -> State { } } - state.unwrap_or_else(|| State { + let mut state = state.unwrap_or_else(|| State { log_history: IndexSet::new(), - log_viewer_path, + log_viewer_path: PathBuf::new(), open_files: HashMap::new(), - }) + }); + state.log_viewer_path = log_viewer_path; + state } diff --git a/workspace/src/main.rs b/workspace/src/main.rs index d1b1569..833d4c2 100644 --- a/workspace/src/main.rs +++ b/workspace/src/main.rs @@ -9,6 +9,8 @@ use std::str::FromStr; use std::{path::PathBuf, time::Duration}; use indexmap::IndexSet; +use rocket::futures::StreamExt; +use serde::{Deserialize, Serialize}; use tao::{ event::{Event, WindowEvent}, event_loop::{ControlFlow, EventLoop}, @@ -20,6 +22,28 @@ use tray_icon::{ MouseButton, TrayIcon, TrayIconBuilder, TrayIconEvent, TrayIconEventReceiver, }; +#[derive(Serialize, Deserialize, Debug)] +enum WorkspaceClientMessage { + AddLogEntry(LogFile), + GetLogHistory, +} + +#[derive(Serialize, Deserialize, Debug)] +enum WorkspaceServerMessage { + LogHistory(IndexSet), +} + +#[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Debug)] +struct LogFile { + name: String, + path: PathBuf, +} + +#[derive(Serialize, Deserialize, Debug)] +struct State { + log_history: IndexSet, +} + fn main() -> anyhow::Result<()> { let log_history_exe = std::env::current_exe() .ok() @@ -27,14 +51,22 @@ fn main() -> anyhow::Result<()> { .map(|exe| exe.join("log_history.exe")) .unwrap_or_else(|| PathBuf::from("log_history.exe")); - let nats_server_exe = std::env::current_exe() + let mut nats_server_exe = std::env::current_exe() .ok() .and_then(|exe| exe.parent().map(|p| p.to_path_buf())) .map(|exe| exe.join("nats-server.exe")) .unwrap_or_else(|| PathBuf::from("nats-server.exe")); + if !nats_server_exe.exists() { + nats_server_exe = PathBuf::from("nats-server.exe"); + } + + if !log_history_exe.exists() { + panic!("Could not find exe: {:#?}", log_history_exe); + } + let mut nats_server = Command::new(nats_server_exe) - .args(["--addr", "127.0.0.0", "--port", "42999"]) + .args(["--addr=127.0.0.1", "--port=42666"]) .spawn() .unwrap(); @@ -43,10 +75,6 @@ fn main() -> anyhow::Result<()> { .build() .unwrap(); - if !log_history_exe.exists() { - panic!("Could not find exe: {:#?}", log_history_exe); - } - let event_loop = EventLoop::new(); let mut window = Some( @@ -60,8 +88,45 @@ fn main() -> anyhow::Result<()> { let log_history_i = MenuItem::new("Logs", true, None); let quit_i = MenuItem::new("Quit", true, None); - let nats = rt.block_on(async_nats::connect("nats://localhost:4222"))?; - // let mut log_history = IndexSet::new(); + let (client_tx, client_rx) = flume::bounded(1024); + + rt.spawn(async move { + let nats = async_nats::connect("nats://localhost:42666").await.unwrap(); + let mut sub = nats.subscribe("workspace.>").await.unwrap(); + while let Some(msg) = sub.next().await { + client_tx.send_async(msg).await.unwrap(); + } + }); + + let (server_tx, server_rx) = flume::bounded::<(&str, Vec)>(1024); + rt.spawn(async move { + let nats = async_nats::connect("nats://localhost:42666").await.unwrap(); + while let Ok((subject, msg)) = server_rx.recv_async().await { + nats.publish(subject, msg.into()).await.unwrap(); + } + }); + + let data = known_folders::get_known_folder_path(known_folders::KnownFolder::LocalAppData) + .unwrap() + .join("workspace") + .join("log_history") + .join("data.rsn"); + + let mut state = None; + if data.exists() { + match std::fs::read_to_string(data) { + Ok(data) => { + state = Some(rsn::from_str(&data).unwrap()); + } + Err(_err) => { + // warn!("Couldn't read data file: {}", err); + } + } + } + + let mut state = state.unwrap_or_else(|| State { + log_history: IndexSet::new(), + }); let mut tray_icon = None; let mut log_history_process: Option = None; event_loop.run(move |event, _, control_flow| { @@ -98,6 +163,30 @@ fn main() -> anyhow::Result<()> { } } + if let Ok(msg) = client_rx.try_recv() { + match bincode::deserialize::(&msg.payload) { + Ok(msg) => match msg { + WorkspaceClientMessage::AddLogEntry(log_file) => { + state.log_history.shift_insert(0, log_file); + server_tx + .send(( + "workspace.log_history", + bincode::serialize(&state.log_history).unwrap(), + )) + .unwrap(); + } + WorkspaceClientMessage::GetLogHistory => server_tx + .send(( + "workspace.log_history", + bincode::serialize(&state.log_history).unwrap(), + )) + .unwrap(), + }, + Err(e) => eprintln!("{}", e), + } + // msg.payload + } + match event { Event::WindowEvent { event: WindowEvent::CloseRequested,