diff --git a/turtle-lib-macros/src/lib.rs b/turtle-lib-macros/src/lib.rs index 98b2788..6ed75ff 100644 --- a/turtle-lib-macros/src/lib.rs +++ b/turtle-lib-macros/src/lib.rs @@ -128,54 +128,19 @@ pub fn turtle_main(args: TokenStream, input: TokenStream) -> TokenStream { quote! { #[macroquad::main(#window_title)] async fn main() { - // Parse command-line arguments for SVG export FIRST (before any graphics init) - let export_svg_path = turtle_lib::export::parse_svg_export_arg(); + // Build function reused for both export and normal rendering + let mut build_commands = |turtle: &mut turtle_lib::TurtlePlan| { + #fn_name(turtle); + }; - // Handle SVG export mode (execute instantly without rendering) - if let Some(filename) = export_svg_path { - #[cfg(feature = "svg")] - { - let mut turtle = turtle_lib::create_turtle_plan(); - #fn_name(&mut turtle); - - // Create app and execute instantly - let mut app = turtle_lib::TurtleApp::new() - .with_commands(turtle.build()); - - // Set instant speed to execute all commands immediately - // Use a high draw call limit (1000) to ensure all commands execute in one frame - app.set_all_turtles_speed(turtle_lib::AnimationSpeed::Instant(1000)); - - // Execute all commands instantly (no rendering needed) - while !app.all_animations_complete() { - app.update(); - } - - // Export to SVG - match app.export_drawing(&filename, turtle_lib::export::DrawingFormat::Svg) { - Ok(_) => { - println!("SVG exported successfully to: {}", filename); - std::process::exit(0); - } - Err(e) => { - eprintln!("Error exporting SVG: {:?}", e); - std::process::exit(1); - } - } - } - #[cfg(not(feature = "svg"))] - { - eprintln!("Error: SVG export feature is not enabled."); - eprintln!("Please rebuild with --features svg"); - std::process::exit(1); - } - } + // Handle optional SVG export internally in turtle-lib + turtle_lib::export::handle_svg_export(&mut build_commands); // Normal rendering mode (with window) let mut turtle = turtle_lib::create_turtle_plan(); // Call the user's function with the turtle - #fn_name(&mut turtle); + build_commands(&mut turtle); let mut app = turtle_lib::TurtleApp::new() .with_commands(turtle.build()); @@ -209,52 +174,18 @@ pub fn turtle_main(args: TokenStream, input: TokenStream) -> TokenStream { quote! { #[macroquad::main(#window_title)] async fn main() { - // Parse command-line arguments for SVG export FIRST (before any graphics init) - let export_svg_path = turtle_lib::export::parse_svg_export_arg(); + // Build function reused for both export and normal rendering + let mut build_commands = |turtle: &mut turtle_lib::TurtlePlan| { + let turtle = turtle; + #fn_block + }; - // Handle SVG export mode (execute instantly without rendering) - if let Some(filename) = export_svg_path { - #[cfg(feature = "svg")] - { - let mut turtle = turtle_lib::create_turtle_plan(); - #fn_block - - // Create app and execute instantly - let mut app = turtle_lib::TurtleApp::new() - .with_commands(turtle.build()); - - // Set instant speed to execute all commands immediately - // Use a high draw call limit (1000) to ensure all commands execute in one frame - app.set_all_turtles_speed(turtle_lib::AnimationSpeed::Instant(1000)); - - // Execute all commands instantly (no rendering needed) - while !app.all_animations_complete() { - app.update(); - } - - // Export to SVG - match app.export_drawing(&filename, turtle_lib::export::DrawingFormat::Svg) { - Ok(_) => { - println!("SVG exported successfully to: {}", filename); - std::process::exit(0); - } - Err(e) => { - eprintln!("Error exporting SVG: {:?}", e); - std::process::exit(1); - } - } - } - #[cfg(not(feature = "svg"))] - { - eprintln!("Error: SVG export feature is not enabled."); - eprintln!("Please rebuild with --features svg"); - std::process::exit(1); - } - } + // Handle optional SVG export internally in turtle-lib + turtle_lib::export::handle_svg_export(&mut build_commands); // Normal rendering mode (with window) let mut turtle = turtle_lib::create_turtle_plan(); - #fn_block + build_commands(&mut turtle); let mut app = turtle_lib::TurtleApp::new() .with_commands(turtle.build()); diff --git a/turtle-lib/src/export.rs b/turtle-lib/src/export.rs index 98086f1..d3a1b55 100644 --- a/turtle-lib/src/export.rs +++ b/turtle-lib/src/export.rs @@ -1,6 +1,7 @@ //! Export-Backend-Trait und zentrale Export-Typen use crate::state::TurtleWorld; +use crate::TurtlePlan; #[derive(Debug)] pub enum ExportError { @@ -36,3 +37,50 @@ pub fn parse_svg_export_arg() -> Option { } None } + +/// Handle the optional `--export-svg` CLI flag. +/// +/// The feature gating lives inside `turtle-lib`, so the `turtle_main` macro +/// no longer needs to reference cfg flags from the consuming crate. +pub fn handle_svg_export(build_commands: F) +where + F: FnMut(&mut TurtlePlan), +{ + // Avoid unused warnings when the feature is disabled + let _ = &build_commands; + + if let Some(filename) = parse_svg_export_arg() { + #[cfg(feature = "svg")] + { + let mut build_commands = build_commands; + let mut turtle = crate::create_turtle_plan(); + build_commands(&mut turtle); + + let mut app = crate::TurtleApp::new().with_commands(turtle.build()); + app.set_all_turtles_speed(crate::AnimationSpeed::Instant(1000)); + + while !app.all_animations_complete() { + app.update(); + } + + match app.export_drawing(&filename, crate::export::DrawingFormat::Svg) { + Ok(_) => { + println!("SVG exported successfully to: {}", filename); + std::process::exit(0); + } + Err(e) => { + eprintln!("Error exporting SVG: {:?}", e); + std::process::exit(1); + } + } + } + + #[cfg(not(feature = "svg"))] + { + let _ = &filename; + eprintln!("Error: SVG export feature is not enabled."); + eprintln!("Please rebuild with --features svg"); + std::process::exit(1); + } + } +}