diff --git a/turtle-lib/src/circle_geometry.rs b/turtle-lib/src/circle_geometry.rs index 59718eb..0882710 100644 --- a/turtle-lib/src/circle_geometry.rs +++ b/turtle-lib/src/circle_geometry.rs @@ -10,11 +10,11 @@ pub enum CircleDirection { } /// Encapsulates all geometry for a circular arc -pub struct CircleGeometry { - pub center: Vec2, - pub radius: f32, - pub start_angle_from_center: f32, // radians - pub direction: CircleDirection, +pub(crate) struct CircleGeometry { + pub(crate) center: Vec2, + pub(crate) radius: f32, + pub(crate) start_angle_from_center: f32, // radians + pub(crate) direction: CircleDirection, } impl CircleGeometry { diff --git a/turtle-lib/src/commands_channel.rs b/turtle-lib/src/commands_channel.rs index 0b72d53..7fd1128 100644 --- a/turtle-lib/src/commands_channel.rs +++ b/turtle-lib/src/commands_channel.rs @@ -76,7 +76,7 @@ pub struct TurtleCommandSender { /// /// Paired with `TurtleCommandSender` via `turtle_command_channel()`. /// Automatically managed by `TurtleApp::process_commands()`. -pub struct TurtleCommandReceiver { +pub(crate) struct TurtleCommandReceiver { turtle_id: usize, rx: Receiver, } @@ -212,7 +212,7 @@ impl TurtleCommandReceiver { /// # } /// ``` #[must_use] -pub fn turtle_command_channel( +pub(crate) fn turtle_command_channel( turtle_id: usize, buffer_size: usize, ) -> (TurtleCommandSender, TurtleCommandReceiver) { diff --git a/turtle-lib/src/drawing.rs b/turtle-lib/src/drawing.rs index 5af9b3d..2841014 100644 --- a/turtle-lib/src/drawing.rs +++ b/turtle-lib/src/drawing.rs @@ -13,7 +13,7 @@ use macroquad::prelude::*; use tween::CubicInOut; /// Render the entire turtle world -pub fn render_world(world: &TurtleWorld) { +pub(crate) fn render_world(world: &TurtleWorld) { // Update camera zoom based on current screen size to prevent stretching let camera = Camera2D { zoom: vec2(1.0 / screen_width() * 2.0, 1.0 / screen_height() * 2.0), @@ -61,7 +61,7 @@ pub fn render_world(world: &TurtleWorld) { /// Render the turtle world with active tween visualization #[allow(clippy::too_many_lines)] -pub fn render_world_with_tweens(world: &TurtleWorld, zoom_level: f32) { +pub(crate) fn render_world_with_tweens(world: &TurtleWorld, zoom_level: f32) { // Update camera zoom based on current screen size to prevent stretching // Apply user zoom level by dividing by it (smaller zoom value = more zoomed in) let camera = Camera2D { @@ -386,7 +386,7 @@ fn draw_tween_arc( } /// Draw the turtle shape -pub fn draw_turtle(turtle_params: &TurtleParams) { +pub(crate) fn draw_turtle(turtle_params: &TurtleParams) { let rotated_vertices = turtle_params.shape.rotated_vertices(turtle_params.heading); if turtle_params.shape.filled { diff --git a/turtle-lib/src/execution.rs b/turtle-lib/src/execution.rs index 29de0cb..d2248b4 100644 --- a/turtle-lib/src/execution.rs +++ b/turtle-lib/src/execution.rs @@ -12,7 +12,7 @@ use crate::general::AnimationSpeed; /// Execute side effects for commands that don't involve movement /// Returns true if the command was handled (caller should skip movement processing) #[allow(clippy::too_many_lines)] -pub fn execute_command_side_effects(command: &TurtleCommand, state: &mut Turtle) -> bool { +pub(crate) fn execute_command_side_effects(command: &TurtleCommand, state: &mut Turtle) -> bool { match command { TurtleCommand::BeginFill => { if state.filling.is_some() { @@ -159,7 +159,7 @@ pub fn execute_command_side_effects(command: &TurtleCommand, state: &mut Turtle) /// Record fill vertices after movement commands have updated state #[tracing::instrument] -pub fn record_fill_vertices_after_movement( +pub(crate) fn record_fill_vertices_after_movement( command: &TurtleCommand, start_state: &TurtleParams, state: &mut Turtle, @@ -200,7 +200,7 @@ pub fn record_fill_vertices_after_movement( /// Execute a single turtle command, updating state and adding draw commands #[tracing::instrument] #[allow(clippy::too_many_lines)] -pub fn execute_command(command: &TurtleCommand, state: &mut Turtle) { +pub(crate) fn execute_command(command: &TurtleCommand, state: &mut Turtle) { // Try to execute as side-effect-only command first if execute_command_side_effects(command, state) { return; // Command fully handled @@ -346,7 +346,11 @@ pub fn execute_command(command: &TurtleCommand, state: &mut Turtle) { } /// Execute command on a specific turtle by ID -pub fn execute_command_with_id(command: &TurtleCommand, turtle_id: usize, world: &mut TurtleWorld) { +pub(crate) fn execute_command_with_id( + command: &TurtleCommand, + turtle_id: usize, + world: &mut TurtleWorld, +) { // Clone turtle state to avoid borrow checker issues if let Some(turtle) = world.get_turtle(turtle_id) { let mut state = turtle.clone(); @@ -359,7 +363,7 @@ pub fn execute_command_with_id(command: &TurtleCommand, turtle_id: usize, world: } /// Add drawing command for a completed tween -pub fn add_draw_for_completed_tween( +pub(crate) fn add_draw_for_completed_tween( command: &TurtleCommand, start_state: &TurtleParams, end_state: &mut TurtleParams, diff --git a/turtle-lib/src/export.rs b/turtle-lib/src/export.rs index d3a1b55..28dae84 100644 --- a/turtle-lib/src/export.rs +++ b/turtle-lib/src/export.rs @@ -17,7 +17,7 @@ pub enum DrawingFormat { // Weitere Formate wie Png, Pdf, ... } -pub trait DrawingExporter { +pub(crate) trait DrawingExporter { /// Export the drawing to the specified format and filename /// /// # Errors @@ -26,7 +26,7 @@ pub trait DrawingExporter { fn export(&self, world: &TurtleWorld, filename: &str) -> Result<(), ExportError>; } -pub fn parse_svg_export_arg() -> Option { +pub(crate) fn parse_svg_export_arg() -> Option { let args: Vec = std::env::args().collect(); let mut i = 1; while i < args.len() { diff --git a/turtle-lib/src/lib.rs b/turtle-lib/src/lib.rs index 8b4cc94..ba3db44 100644 --- a/turtle-lib/src/lib.rs +++ b/turtle-lib/src/lib.rs @@ -34,9 +34,9 @@ //! async fn main() { //! let mut plan = create_turtle_plan(); //! plan.forward(100.0).right(90.0).forward(100.0); -//! +//! //! let mut app = TurtleApp::new().with_commands(plan.build()); -//! +//! //! loop { //! clear_background(WHITE); //! app.update(); @@ -46,30 +46,28 @@ //! } //! ``` -pub mod builders; -pub mod circle_geometry; -pub mod commands; -pub mod commands_channel; -pub mod drawing; -pub mod execution; -pub mod general; -pub mod shapes; -pub mod state; -pub mod tessellation; -pub mod tweening; +pub(crate) mod builders; +pub(crate) mod circle_geometry; +pub(crate) mod commands; +pub(crate) mod commands_channel; +pub(crate) mod drawing; +pub(crate) mod execution; +pub(crate) mod general; +pub(crate) mod shapes; +pub(crate) mod state; +pub(crate) mod tessellation; +pub(crate) mod tweening; // Re-export commonly used types pub use builders::{CurvedMovement, DirectionalMovement, Turnable, TurtlePlan, WithCommands}; pub use commands::{CommandQueue, TurtleCommand}; -pub use commands_channel::{turtle_command_channel, TurtleCommandReceiver, TurtleCommandSender}; +pub use commands_channel::TurtleCommandSender; pub use general::{Angle, AnimationSpeed, Color, Coordinate, Length, Precision}; pub use shapes::{ShapeType, TurtleShape}; -pub use state::{DrawCommand, Turtle, TurtleWorld}; -pub use tweening::TweenController; pub mod export; #[cfg(feature = "svg")] -pub mod export_svg; +pub(crate) mod export_svg; // Re-export the turtle_main macro pub use turtle_lib_macros::turtle_main; @@ -79,6 +77,9 @@ pub use macroquad::prelude::{ vec2, BLACK, BLUE, DARKGRAY, GOLD, GREEN, ORANGE, PURPLE, RED, WHITE, YELLOW, }; +use crate::commands_channel::TurtleCommandReceiver; +use crate::state::TurtleWorld; +use crate::tweening::TweenController; use macroquad::prelude::*; use std::collections::HashMap; @@ -386,12 +387,12 @@ impl TurtleApp { /// Get reference to the world state #[must_use] - pub fn world(&self) -> &TurtleWorld { + pub(crate) fn world(&self) -> &TurtleWorld { &self.world } /// Get mutable reference to the world state - pub fn world_mut(&mut self) -> &mut TurtleWorld { + pub(crate) fn world_mut(&mut self) -> &mut TurtleWorld { &mut self.world } } diff --git a/turtle-lib/src/state.rs b/turtle-lib/src/state.rs index fdf036c..fcd1ab8 100644 --- a/turtle-lib/src/state.rs +++ b/turtle-lib/src/state.rs @@ -8,33 +8,33 @@ use macroquad::prelude::*; /// State during active fill operation #[derive(Clone, Debug)] -pub struct FillState { +pub(crate) struct FillState { /// Starting position of the fill - pub start_position: Coordinate, + pub(crate) start_position: Coordinate, /// All contours collected so far. Each contour is a separate closed path. /// The first contour is the outer boundary, subsequent contours are holes. - pub contours: Vec>, + pub(crate) contours: Vec>, /// Current contour being built (vertices for the active `pen_down` segment) - pub current_contour: Vec, + pub(crate) current_contour: Vec, /// Fill color (cached from when `begin_fill` was called) - pub fill_color: Color, + pub(crate) fill_color: Color, } /// Parameters that define a turtle's visual state #[derive(Clone, Debug)] -pub struct TurtleParams { - pub position: Vec2, - pub heading: f32, - pub pen_down: bool, - pub pen_width: f32, - pub color: Color, - pub fill_color: Option, - pub visible: bool, - pub shape: crate::shapes::TurtleShape, - pub speed: AnimationSpeed, +pub(crate) struct TurtleParams { + pub(crate) position: Vec2, + pub(crate) heading: f32, + pub(crate) pen_down: bool, + pub(crate) pen_width: f32, + pub(crate) color: Color, + pub(crate) fill_color: Option, + pub(crate) visible: bool, + pub(crate) shape: crate::shapes::TurtleShape, + pub(crate) speed: AnimationSpeed, } impl Default for TurtleParams { @@ -56,18 +56,18 @@ impl Default for TurtleParams { /// State of a single turtle #[derive(Clone, Debug)] -pub struct Turtle { - pub turtle_id: usize, - pub params: TurtleParams, +pub(crate) struct Turtle { + pub(crate) turtle_id: usize, + pub(crate) params: TurtleParams, // Fill tracking - pub filling: Option, + pub(crate) filling: Option, // Drawing commands created by this turtle - pub commands: Vec, + pub(crate) commands: Vec, // Animation controller for this turtle - pub tween_controller: TweenController, + pub(crate) tween_controller: TweenController, } impl Default for Turtle { @@ -259,9 +259,9 @@ impl Turtle { /// Cached mesh data that can be cloned and converted to Mesh when needed #[derive(Clone, Debug)] -pub struct MeshData { - pub vertices: Vec, - pub indices: Vec, +pub(crate) struct MeshData { + pub(crate) vertices: Vec, + pub(crate) indices: Vec, } impl MeshData { @@ -278,19 +278,19 @@ impl MeshData { /// Drawable elements in the world /// All drawing is done via Lyon-tessellated meshes for consistency and quality #[derive(Clone, Debug)] -pub struct TurtleSource { - pub command: crate::commands::TurtleCommand, - pub color: Color, - pub fill_color: Color, - pub pen_width: f32, - pub start_position: Vec2, - pub end_position: Vec2, - pub start_heading: f32, - pub contours: Option>>, +pub(crate) struct TurtleSource { + pub(crate) command: crate::commands::TurtleCommand, + pub(crate) color: Color, + pub(crate) fill_color: Color, + pub(crate) pen_width: f32, + pub(crate) start_position: Vec2, + pub(crate) end_position: Vec2, + pub(crate) start_heading: f32, + pub(crate) contours: Option>>, } #[derive(Clone, Debug)] -pub enum DrawCommand { +pub(crate) enum DrawCommand { /// Pre-tessellated mesh data (lines, arcs, circles, polygons - all use this) Mesh { data: MeshData, @@ -308,11 +308,11 @@ pub enum DrawCommand { } /// The complete turtle world containing all drawing state -pub struct TurtleWorld { +pub(crate) struct TurtleWorld { /// All turtles in the world (indexed by turtle ID) - pub turtles: Vec, - pub camera: Camera2D, - pub background_color: Color, + pub(crate) turtles: Vec, + pub(crate) camera: Camera2D, + pub(crate) background_color: Color, } impl TurtleWorld { diff --git a/turtle-lib/src/tessellation.rs b/turtle-lib/src/tessellation.rs index 214f402..3703a05 100644 --- a/turtle-lib/src/tessellation.rs +++ b/turtle-lib/src/tessellation.rs @@ -14,26 +14,30 @@ use macroquad::prelude::*; /// Convert macroquad Vec2 to Lyon Point #[must_use] -pub fn to_lyon_point(v: Vec2) -> Point { +pub(crate) fn to_lyon_point(v: Vec2) -> Point { point(v.x, v.y) } /// Convert Lyon Point to macroquad Vec2 #[allow(dead_code)] #[must_use] -pub fn to_macroquad_vec2(p: Point) -> Vec2 { +pub(crate) fn to_macroquad_vec2(p: Point) -> Vec2 { vec2(p.x, p.y) } /// Simple vertex type for Lyon tessellation #[derive(Copy, Clone, Debug)] -pub struct SimpleVertex { - pub position: [f32; 2], +pub(crate) struct SimpleVertex { + pub(crate) position: [f32; 2], } /// Build mesh data from Lyon tessellation #[must_use] -pub fn build_mesh_data(vertices: &[SimpleVertex], indices: &[u16], color: Color) -> MeshData { +pub(crate) fn build_mesh_data( + vertices: &[SimpleVertex], + indices: &[u16], + color: Color, +) -> MeshData { let verts: Vec = vertices .iter() .map(|v| Vertex { @@ -62,7 +66,7 @@ pub fn build_mesh_data(vertices: &[SimpleVertex], indices: &[u16], color: Color) /// # Errors /// /// Returns an error if no vertices are provided or if tessellation fails. -pub fn tessellate_polygon( +pub(crate) fn tessellate_polygon( vertices: &[Vec2], color: Color, ) -> Result> { @@ -107,7 +111,7 @@ pub fn tessellate_polygon( /// # Errors /// /// Returns an error if no contours are provided or if tessellation fails. -pub fn tessellate_multi_contour( +pub(crate) fn tessellate_multi_contour( contours: &[Vec], color: Color, ) -> Result> { @@ -203,7 +207,7 @@ pub fn tessellate_multi_contour( /// # Errors /// /// Returns an error if no vertices are provided or if tessellation fails. -pub fn tessellate_stroke( +pub(crate) fn tessellate_stroke( vertices: &[Vec2], color: Color, width: f32, @@ -249,7 +253,7 @@ pub fn tessellate_stroke( /// # Errors /// /// Returns an error if tessellation fails. -pub fn tessellate_circle( +pub(crate) fn tessellate_circle( center: Vec2, radius: f32, color: Color, @@ -295,7 +299,7 @@ pub fn tessellate_circle( /// /// Returns an error if tessellation fails. #[allow(clippy::too_many_arguments)] -pub fn tessellate_arc( +pub(crate) fn tessellate_arc( center: Vec2, radius: f32, start_angle_degrees: f32, diff --git a/turtle-lib/src/tweening.rs b/turtle-lib/src/tweening.rs index d183b87..79348e4 100644 --- a/turtle-lib/src/tweening.rs +++ b/turtle-lib/src/tweening.rs @@ -45,22 +45,22 @@ impl From for Vec2 { /// Controls tweening of turtle commands #[derive(Clone, Debug, Default)] -pub struct TweenController { +pub(crate) struct TweenController { queue: CommandQueue, current_tween: Option, speed: AnimationSpeed, } #[derive(Clone, Debug)] -pub struct CommandTween { - pub turtle_id: usize, - pub command: TurtleCommand, - pub start_time: f64, - pub duration: f64, - pub start_params: TurtleParams, - pub target_params: TurtleParams, - pub current_position: Vec2, - pub current_heading: f32, +pub(crate) struct CommandTween { + pub(crate) turtle_id: usize, + pub(crate) command: TurtleCommand, + pub(crate) start_time: f64, + pub(crate) duration: f64, + pub(crate) start_params: TurtleParams, + pub(crate) target_params: TurtleParams, + pub(crate) current_position: Vec2, + pub(crate) current_heading: f32, position_tweener: Tweener, heading_tweener: Tweener, pen_width_tweener: Tweener,