Add frequent exit checks throughout render loop
The issue was that sleep() was blocking for 16-33ms without checking the exit flag. Now: - Check should_exit at 5 points in the render loop - Break sleep into 5ms chunks, checking between each chunk - This gives <5ms response time to exit commands Exit responds within 5ms: Press 'q', ESC, or Ctrl+C 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -65,17 +65,22 @@ impl<'a> Renderer<'a> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let frame_start = std::time::Instant::now();
|
// Check for exit FIRST
|
||||||
|
|
||||||
// Check if user requested exit
|
|
||||||
if should_exit.load(Ordering::Relaxed) {
|
if should_exit.load(Ordering::Relaxed) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let frame_start = std::time::Instant::now();
|
||||||
|
|
||||||
// Calculate progress with easing
|
// Calculate progress with easing
|
||||||
let linear_progress = timeline.progress();
|
let linear_progress = timeline.progress();
|
||||||
let eased_progress = self.easing.ease(linear_progress);
|
let eased_progress = self.easing.ease(linear_progress);
|
||||||
|
|
||||||
|
// Check again before rendering
|
||||||
|
if should_exit.load(Ordering::Relaxed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Apply effect
|
// Apply effect
|
||||||
let effect_result = self.effect.apply(self.ascii_art, eased_progress);
|
let effect_result = self.effect.apply(self.ascii_art, eased_progress);
|
||||||
|
|
||||||
@@ -86,6 +91,11 @@ impl<'a> Renderer<'a> {
|
|||||||
effect_result.text.clone()
|
effect_result.text.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Check before terminal operations
|
||||||
|
if should_exit.load(Ordering::Relaxed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Render to terminal
|
// Render to terminal
|
||||||
terminal.clear()?;
|
terminal.clear()?;
|
||||||
terminal.refresh_size()?;
|
terminal.refresh_size()?;
|
||||||
@@ -117,6 +127,11 @@ impl<'a> Renderer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if user wants to exit
|
||||||
|
if should_exit.load(Ordering::Relaxed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if animation is complete before advancing
|
// Check if animation is complete before advancing
|
||||||
if timeline.is_complete() {
|
if timeline.is_complete() {
|
||||||
break;
|
break;
|
||||||
@@ -128,7 +143,19 @@ impl<'a> Renderer<'a> {
|
|||||||
let elapsed = frame_start.elapsed();
|
let elapsed = frame_start.elapsed();
|
||||||
|
|
||||||
if elapsed < frame_duration {
|
if elapsed < frame_duration {
|
||||||
sleep(frame_duration - elapsed).await;
|
let sleep_duration = frame_duration - elapsed;
|
||||||
|
// Break sleep into small chunks to check should_exit frequently
|
||||||
|
let chunk_duration = Duration::from_millis(5);
|
||||||
|
let mut remaining = sleep_duration;
|
||||||
|
|
||||||
|
while remaining > Duration::ZERO {
|
||||||
|
if should_exit.load(Ordering::Relaxed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let sleep_time = remaining.min(chunk_duration);
|
||||||
|
sleep(sleep_time).await;
|
||||||
|
remaining = remaining.saturating_sub(sleep_time);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user