Fix: Propagate user exit signal to break animation loop
**CRITICAL BUG FIX**: When using -l (loop), the outer loop in main.rs was restarting the animation even after user pressed exit keys. Changes: - render() now returns Result<bool> instead of Result<()> - Returns true when user presses exit key (q/ESC/Ctrl+C) - Returns false when animation completes naturally - main.rs checks return value and breaks loop on user exit This fixes the infinite loop issue where pressing q/ESC/Ctrl+C had no effect when using the -l flag. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -43,7 +43,7 @@ impl AnimationEngine {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(&self, terminal: &mut TerminalManager) -> Result<()> {
|
pub async fn run(&self, terminal: &mut TerminalManager) -> Result<bool> {
|
||||||
let renderer = renderer::Renderer::new(
|
let renderer = renderer::Renderer::new(
|
||||||
&self.ascii_art,
|
&self.ascii_art,
|
||||||
self.duration_ms,
|
self.duration_ms,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ impl<'a> Renderer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn render(&self, terminal: &mut TerminalManager) -> Result<()> {
|
pub async fn render(&self, terminal: &mut TerminalManager) -> Result<bool> {
|
||||||
let mut timeline = Timeline::new(self.timeline.duration_ms(), self.timeline.fps());
|
let mut timeline = Timeline::new(self.timeline.duration_ms(), self.timeline.fps());
|
||||||
timeline.start();
|
timeline.start();
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ impl<'a> Renderer<'a> {
|
|||||||
loop {
|
loop {
|
||||||
// Check for exit FIRST
|
// Check for exit FIRST
|
||||||
if should_exit.load(Ordering::Relaxed) {
|
if should_exit.load(Ordering::Relaxed) {
|
||||||
break;
|
return Ok(true); // User requested exit
|
||||||
}
|
}
|
||||||
|
|
||||||
let frame_start = std::time::Instant::now();
|
let frame_start = std::time::Instant::now();
|
||||||
@@ -78,7 +78,7 @@ impl<'a> Renderer<'a> {
|
|||||||
|
|
||||||
// Check again before rendering
|
// Check again before rendering
|
||||||
if should_exit.load(Ordering::Relaxed) {
|
if should_exit.load(Ordering::Relaxed) {
|
||||||
break;
|
return Ok(true); // User requested exit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply effect
|
// Apply effect
|
||||||
@@ -93,7 +93,7 @@ impl<'a> Renderer<'a> {
|
|||||||
|
|
||||||
// Check before terminal operations
|
// Check before terminal operations
|
||||||
if should_exit.load(Ordering::Relaxed) {
|
if should_exit.load(Ordering::Relaxed) {
|
||||||
break;
|
return Ok(true); // User requested exit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render to terminal
|
// Render to terminal
|
||||||
@@ -129,12 +129,12 @@ impl<'a> Renderer<'a> {
|
|||||||
|
|
||||||
// Check if user wants to exit
|
// Check if user wants to exit
|
||||||
if should_exit.load(Ordering::Relaxed) {
|
if should_exit.load(Ordering::Relaxed) {
|
||||||
break;
|
return Ok(true); // User requested exit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if animation is complete before advancing
|
// Check if animation is complete before advancing
|
||||||
if timeline.is_complete() {
|
if timeline.is_complete() {
|
||||||
break;
|
return Ok(false); // Animation completed naturally
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance to next frame and wait
|
// Advance to next frame and wait
|
||||||
@@ -150,7 +150,7 @@ impl<'a> Renderer<'a> {
|
|||||||
|
|
||||||
while remaining > Duration::ZERO {
|
while remaining > Duration::ZERO {
|
||||||
if should_exit.load(Ordering::Relaxed) {
|
if should_exit.load(Ordering::Relaxed) {
|
||||||
break;
|
return Ok(true); // User requested exit during sleep
|
||||||
}
|
}
|
||||||
let sleep_time = remaining.min(chunk_duration);
|
let sleep_time = remaining.min(chunk_duration);
|
||||||
sleep(sleep_time).await;
|
sleep(sleep_time).await;
|
||||||
@@ -158,8 +158,6 @@ impl<'a> Renderer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_colors(&self, text: &str, progress: f64) -> String {
|
fn apply_colors(&self, text: &str, progress: f64) -> String {
|
||||||
|
|||||||
@@ -61,8 +61,14 @@ async fn run_piglet(args: PigletCli) -> Result<()> {
|
|||||||
|
|
||||||
// Run animation
|
// Run animation
|
||||||
loop {
|
loop {
|
||||||
animation_engine.run(&mut terminal).await?;
|
let user_exited = animation_engine.run(&mut terminal).await?;
|
||||||
|
|
||||||
|
// If user pressed exit key, stop looping
|
||||||
|
if user_exited {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not looping, stop after one animation
|
||||||
if !args.loop_animation {
|
if !args.loop_animation {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user