diff --git a/beacon/src/client.rs b/beacon/src/client.rs index bfd945d2..85f44eb8 100644 --- a/beacon/src/client.rs +++ b/beacon/src/client.rs @@ -99,9 +99,10 @@ enum Action { Forward(mpsc::Sender), } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub enum Command { RewindTo { message: usize }, + GoLive, } #[tokio::main] diff --git a/beacon/src/lib.rs b/beacon/src/lib.rs index 8d1c31f5..e7fe9d75 100644 --- a/beacon/src/lib.rs +++ b/beacon/src/lib.rs @@ -36,6 +36,14 @@ impl Connection { let _ = commands.send(client::Command::RewindTo { message }).await; } } + + pub fn go_live<'a>(&self) -> impl Future + 'a { + let commands = self.commands.clone(); + + async move { + let _ = commands.send(client::Command::GoLive).await; + } + } } #[derive(Debug, Clone)] @@ -128,14 +136,19 @@ pub fn run() -> impl Stream { let mut last_message_number = None; while let Some(command) = command_receiver.recv().await { - let client::Command::RewindTo { message } = command; + match command { + client::Command::RewindTo { message } => { + if Some(message) == last_message_number { + continue; + } - if Some(message) == last_message_number { - continue; + last_message_number = Some(message); + } + client::Command::GoLive => { + last_message_number = None; + } } - last_message_number = Some(message); - let _ = send(&mut writer, command).await.inspect_err(|error| { log::error!("Error when sending command: {error}") diff --git a/debug/src/lib.rs b/debug/src/lib.rs index 8f5a0096..5329c1a7 100644 --- a/debug/src/lib.rs +++ b/debug/src/lib.rs @@ -21,6 +21,15 @@ pub enum Primitive { #[derive(Debug, Clone, Copy)] pub enum Command { RewindTo { message: usize }, + GoLive, +} + +pub fn enable() { + internal::enable(); +} + +pub fn disable() { + internal::disable(); } pub fn init(name: &str) { @@ -91,10 +100,6 @@ pub fn time_with(name: impl Into, f: impl FnOnce() -> T) -> T { result } -pub fn skip_next_timing() { - internal::skip_next_timing(); -} - pub fn commands() -> Subscription { internal::commands() } @@ -139,7 +144,7 @@ mod internal { if let Some(palette) = LAST_PALETTE.read().expect("Read last palette").as_ref() { - BEACON.log(client::Event::ThemeChanged(*palette)); + log(client::Event::ThemeChanged(*palette)); } Ok(()) @@ -154,18 +159,18 @@ mod internal { if LAST_PALETTE.read().expect("Read last palette").as_ref() != Some(&palette) { - BEACON.log(client::Event::ThemeChanged(palette)); + log(client::Event::ThemeChanged(palette)); *LAST_PALETTE.write().expect("Write last palette") = Some(palette); } } pub fn tasks_spawned(amount: usize) { - BEACON.log(client::Event::CommandsSpawned(amount)); + log(client::Event::CommandsSpawned(amount)); } pub fn subscriptions_tracked(amount: usize) { - BEACON.log(client::Event::SubscriptionsTracked(amount)); + log(client::Event::SubscriptionsTracked(amount)); } pub fn boot() -> Span { @@ -193,7 +198,7 @@ mod internal { message }; - BEACON.log(client::Event::MessageLogged { number, message }); + log(client::Event::MessageLogged { number, message }); span } @@ -230,8 +235,12 @@ mod internal { span(span::Stage::Custom(name.into())) } - pub fn skip_next_timing() { - SKIP_NEXT_SPAN.store(true, atomic::Ordering::Relaxed); + pub fn enable() { + ENABLED.store(true, atomic::Ordering::Relaxed); + } + + pub fn disable() { + ENABLED.store(false, atomic::Ordering::Relaxed); } pub fn commands() -> Subscription { @@ -243,6 +252,7 @@ mod internal { client::Command::RewindTo { message } => { Command::RewindTo { message } } + client::Command::GoLive => Command::GoLive, }; Some((command, receiver)) @@ -253,7 +263,7 @@ mod internal { } fn span(span: span::Stage) -> Span { - BEACON.log(client::Event::SpanStarted(span.clone())); + log(client::Event::SpanStarted(span.clone())); Span { span, @@ -271,6 +281,12 @@ mod internal { } } + fn log(event: client::Event) { + if ENABLED.load(atomic::Ordering::Relaxed) { + BEACON.log(event); + } + } + #[derive(Debug)] pub struct Span { span: span::Stage, @@ -279,14 +295,7 @@ mod internal { impl Span { pub fn finish(self) { - if SKIP_NEXT_SPAN.fetch_and(false, atomic::Ordering::Relaxed) { - return; - } - - BEACON.log(client::Event::SpanFinished( - self.span, - self.start.elapsed(), - )); + log(client::Event::SpanFinished(self.span, self.start.elapsed())); } } @@ -297,7 +306,7 @@ mod internal { static NAME: RwLock = RwLock::new(String::new()); static LAST_UPDATE: AtomicUsize = AtomicUsize::new(0); static LAST_PALETTE: RwLock> = RwLock::new(None); - static SKIP_NEXT_SPAN: AtomicBool = AtomicBool::new(false); + static ENABLED: AtomicBool = AtomicBool::new(true); } #[cfg(any(not(feature = "enable"), target_arch = "wasm32"))] @@ -309,6 +318,9 @@ mod internal { use std::io; + pub fn enable() {} + pub fn disable() {} + pub fn init(_name: &str) {} pub fn toggle_comet() -> Result<(), io::Error> { @@ -361,8 +373,6 @@ mod internal { Span } - pub fn skip_next_timing() {} - pub fn commands() -> Subscription { Subscription::none() } diff --git a/devtools/Cargo.toml b/devtools/Cargo.toml index 3034f9c3..44fa9fb4 100644 --- a/devtools/Cargo.toml +++ b/devtools/Cargo.toml @@ -17,6 +17,6 @@ workspace = true time-travel = ["iced_program/time-travel"] [dependencies] +iced_debug.workspace = true iced_program.workspace = true iced_widget.workspace = true -iced_debug.workspace = true diff --git a/devtools/src/lib.rs b/devtools/src/lib.rs index 7bcf100a..6c3004d8 100644 --- a/devtools/src/lib.rs +++ b/devtools/src/lib.rs @@ -116,7 +116,7 @@ where mode: Mode, show_notification: bool, rewind: Option, - log: Vec, + messages: Vec, } #[derive(Debug, Clone)] @@ -150,7 +150,7 @@ where mode: Mode::None, show_notification: true, rewind: None, - log: Vec::new(), + messages: Vec::new(), }, executor::spawn_blocking(|mut sender| { thread::sleep(seconds(2)); @@ -254,13 +254,13 @@ where } }, Event::Program(message) => { - if self.rewind.is_some() { - return Task::none(); - } - #[cfg(feature = "time-travel")] { - self.log.push(message.clone()); + self.messages.push(message.clone()); + } + + if self.rewind.is_some() { + debug::enable(); } let span = debug::update(&message); @@ -268,6 +268,10 @@ where debug::tasks_spawned(task.units()); span.finish(); + if self.rewind.is_some() { + debug::disable(); + } + task.map(Event::Program) } Event::Command(command) => { @@ -277,24 +281,33 @@ where { let (mut state, _) = program.boot(); - if message < self.log.len() { + if message < self.messages.len() { // TODO: Run concurrently (?) - for message in &self.log[0..message] { + for message in &self.messages[0..message] { let _ = program .update(&mut state, message.clone()); } } self.rewind = Some(state); + debug::disable(); } #[cfg(not(feature = "time-travel"))] let _ = message; } + debug::Command::GoLive => { + #[cfg(feature = "time-travel")] + { + self.rewind = None; + debug::enable(); + } + } } Task::none() } + Event::Discard => Task::none(), } } @@ -305,7 +318,16 @@ where ) -> Element<'_, Event

, P::Theme, P::Renderer> { let state = self.rewind.as_ref().unwrap_or(&self.state); - let view = program.view(state, window).map(Event::Program); + let view = { + let view = program.view(state, window); + + if self.rewind.is_some() { + view.map(|_| Event::Discard) + } else { + view.map(Event::Program) + } + }; + let theme = program.theme(state, window); let derive_theme = move || { @@ -455,6 +477,7 @@ where Message(Message), Program(P::Message), Command(debug::Command), + Discard, } impl

fmt::Debug for Event

@@ -466,6 +489,7 @@ where Self::Message(message) => message.fmt(f), Self::Program(message) => message.fmt(f), Self::Command(command) => command.fmt(f), + Self::Discard => f.write_str("Discard"), } } } @@ -477,9 +501,10 @@ where { fn clone(&self) -> Self { match self { - Event::Message(message) => Event::Message(message.clone()), - Event::Program(message) => Event::Program(message.clone()), - Event::Command(command) => Event::Command(*command), + Self::Message(message) => Self::Message(message.clone()), + Self::Program(message) => Self::Program(message.clone()), + Self::Command(command) => Self::Command(*command), + Self::Discard => Self::Discard, } } } diff --git a/src/lib.rs b/src/lib.rs index c1c9fa38..e9ca3a04 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -535,7 +535,7 @@ pub use alignment::Vertical::{Bottom, Top}; pub mod debug { //! Debug your applications. - pub use iced_debug::{Span, skip_next_timing, time, time_with}; + pub use iced_debug::{Span, time, time_with}; } pub mod task {