| ... | @@ -378,6 +378,9 @@ enum Replay { | ... | @@ -378,6 +378,9 @@ enum Replay { |
| 378 | Settle(Option<PathBuf>, std::sync::mpsc::Sender<()>), | 378 | Settle(Option<PathBuf>, std::sync::mpsc::Sender<()>), |
| 379 | /// A frame during a wait, as a visible window's display would ask for. | 379 | /// A frame during a wait, as a visible window's display would ask for. |
| 380 | Tick, | 380 | Tick, |
| | 381 | /// What the window sent itself when it found nothing on its way, at that instant: once it |
| | 382 | /// arrives, so has every event sent before. |
| | 383 | Mark(Instant), |
| 381 | Appearance(winit::window::Theme), | 384 | Appearance(winit::window::Theme), |
| 382 | /// Resizes the window's content, in points. | 385 | /// Resizes the window's content, in points. |
| 383 | Resize([f32; 2]), | 386 | Resize([f32; 2]), |
| ... | @@ -915,10 +918,13 @@ struct State { | ... | @@ -915,10 +918,13 @@ struct State { |
| 915 | zoom_typed: Option<String>, | 918 | zoom_typed: Option<String>, |
| 916 | /// Where a replay asked the next frame to be written. | 919 | /// Where a replay asked the next frame to be written. |
| 917 | snapshot: Option<PathBuf>, | 920 | snapshot: Option<PathBuf>, |
| 918 | /// A replay waiting for nothing to be on its way, and where it wants the accessibility | 921 | /// A replay waiting for nothing to be on its way, where it wants the accessibility tree |
| 919 | /// tree written then. | 922 | /// written then, and the mark sent since the window was last found busy. |
| 920 | /// Whether the last frame found the window quiet too, which the tree waits for. | 923 | replay_settle: Option<( |
| 921 | replay_settle: Option<(Option<PathBuf>, std::sync::mpsc::Sender<()>, bool)>, | 924 | Option<PathBuf>, |
| | 925 | std::sync::mpsc::Sender<()>, |
| | 926 | Option<Instant>, |
| | 927 | )>, |
| 922 | /// `SNOWBOUND_FRAMES`: a directory every frame drawn is also written to, named by | 928 | /// `SNOWBOUND_FRAMES`: a directory every frame drawn is also written to, named by |
| 923 | /// milliseconds since the window opened. | 929 | /// milliseconds since the window opened. |
| 924 | frames: Option<(PathBuf, Instant)>, | 930 | frames: Option<(PathBuf, Instant)>, |
| ... | @@ -5841,7 +5847,8 @@ fn spawn(work: impl FnOnce() + Send + 'static) { | ... | @@ -5841,7 +5847,8 @@ fn spawn(work: impl FnOnce() + Send + 'static) { |
| 5841 | RUNNING.fetch_add(1, Ordering::Relaxed); | 5847 | RUNNING.fetch_add(1, Ordering::Relaxed); |
| 5842 | let work = move || { | 5848 | let work = move || { |
| 5843 | work(); | 5849 | work(); |
| 5844 | RUNNING.fetch_sub(1, Ordering::Relaxed); | 5850 | // Whatever `work` sent is in the queue before the count shows it done. |
| | 5851 | RUNNING.fetch_sub(1, Ordering::Release); |
| 5845 | }; | 5852 | }; |
| 5846 | #[cfg(not(target_arch = "wasm32"))] | 5853 | #[cfg(not(target_arch = "wasm32"))] |
| 5847 | std::thread::spawn(work); | 5854 | std::thread::spawn(work); |
| ... | @@ -5919,6 +5926,10 @@ impl State { | ... | @@ -5919,6 +5926,10 @@ impl State { |
| 5919 | } | 5926 | } |
| 5920 | UserEvent::Redraw => self.window.request_redraw(), | 5927 | UserEvent::Redraw => self.window.request_redraw(), |
| 5921 | UserEvent::Replay(replay) => { | 5928 | UserEvent::Replay(replay) => { |
| | 5929 | let mark = match replay { |
| | 5930 | Replay::Mark(at) => Some(at), |
| | 5931 | _ => None, |
| | 5932 | }; |
| 5922 | match replay { | 5933 | match replay { |
| 5923 | Replay::Input(event) => self.input(event), | 5934 | Replay::Input(event) => self.input(event), |
| 5924 | Replay::Pinch(factor) => { | 5935 | Replay::Pinch(factor) => { |
| ... | @@ -5928,9 +5939,9 @@ impl State { | ... | @@ -5928,9 +5939,9 @@ impl State { |
| 5928 | } | 5939 | } |
| 5929 | Replay::Snapshot(path) => self.snapshot = Some(path), | 5940 | Replay::Snapshot(path) => self.snapshot = Some(path), |
| 5930 | Replay::Settle(path, settled) => { | 5941 | Replay::Settle(path, settled) => { |
| 5931 | self.replay_settle = Some((path, settled, false)); | 5942 | self.replay_settle = Some((path, settled, None)); |
| 5932 | } | 5943 | } |
| 5933 | Replay::Tick | Replay::Quit => {} | 5944 | Replay::Tick | Replay::Mark(_) | Replay::Quit => {} |
| 5934 | Replay::Appearance(appearance) => { | 5945 | Replay::Appearance(appearance) => { |
| 5935 | self.window.set_theme(Some(appearance)); | 5946 | self.window.set_theme(Some(appearance)); |
| 5936 | self.set_appearance(appearance); | 5947 | self.set_appearance(appearance); |
| ... | @@ -5945,21 +5956,29 @@ impl State { | ... | @@ -5945,21 +5956,29 @@ impl State { |
| 5945 | if let Err(error) = self.frame() { | 5956 | if let Err(error) = self.frame() { |
| 5946 | eprintln!("{error}"); | 5957 | eprintln!("{error}"); |
| 5947 | } | 5958 | } |
| 5948 | // Quiet on two frames apart, what a thread sent as it ended has been taken. | 5959 | // Quiet still when the mark sent on finding it quiet arrives, what a thread sent |
| | 5960 | // as it ended has been taken, however many frames wait in the queue before it. |
| 5949 | let quiet = self.settled() | 5961 | let quiet = self.settled() |
| 5950 | && self.opening.is_none() | 5962 | && self.opening.is_none() |
| 5951 | && RUNNING.load(Ordering::Relaxed) == 0 | 5963 | && RUNNING.load(Ordering::Acquire) == 0 |
| 5952 | && self.search.pending.load(Ordering::Relaxed) == 0; | 5964 | && self.search.pending.load(Ordering::Relaxed) == 0; |
| 5953 | if let Some((path, settled, was)) = self.replay_settle.take() { | 5965 | if let Some((path, settled, sent)) = self.replay_settle.take() { |
| 5954 | if !(quiet && was) { | 5966 | match (quiet, sent) { |
| 5955 | self.replay_settle = Some((path, settled, quiet)); | 5967 | (true, Some(sent)) if mark == Some(sent) => { |
| 5956 | } else { | 5968 | if let Some(path) = path |
| 5957 | if let Some(path) = path | 5969 | && let Err(error) = self.write_accessibility(&path) |
| 5958 | && let Err(error) = self.write_accessibility(&path) | 5970 | { |
| 5959 | { | 5971 | eprintln!("{error}"); |
| 5960 | eprintln!("{error}"); | 5972 | } |
| | 5973 | let _ = settled.send(()); |
| | 5974 | } |
| | 5975 | (true, None) => { |
| | 5976 | let now = Instant::now(); |
| | 5977 | let _ = self.proxy.send_event(UserEvent::Replay(Replay::Mark(now))); |
| | 5978 | self.replay_settle = Some((path, settled, Some(now))); |
| 5961 | } | 5979 | } |
| 5962 | let _ = settled.send(()); | 5980 | (true, sent) => self.replay_settle = Some((path, settled, sent)), |
| | 5981 | (false, _) => self.replay_settle = Some((path, settled, None)), |
| 5963 | } | 5982 | } |
| 5964 | } | 5983 | } |
| 5965 | } | 5984 | } |