Commit Graph
98 Commits
Author SHA1 Message Date
dietrich ea9a8839c4 Eliminate Per-Frame Allocation in Rendering Loop
We resolved **Issue 4.3 (Severe Per-Frame Allocation in Rendering
Loop)** by removing the intermediate `MeshData` structure and storing
`macroquad::prelude::Mesh` directly in
[`DrawCommand::Mesh`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/state.rs).

[`DrawCommand`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/state.rs)
- Dropped `Clone` and `Debug` derives from
  [`Turtle`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/state.rs#L58)
  and
  [`DrawCommand`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/state.rs#L351),
  accommodating Macroquad's `Mesh` which does not implement these
  traits.
- Changed
  [`DrawCommand::Mesh`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/state.rs#L353)
  to the tuple variant `DrawCommand::Mesh(macroquad::prelude::Mesh)`.
- Deleted `struct MeshData` and its `to_mesh` method.

[`tessellation.rs`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/tessellation.rs)
- Renamed `build_mesh_data` to
  [`build_mesh`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/tessellation.rs#L35)
  returning `macroquad::prelude::Mesh { vertices, indices, texture: None
  }` directly.
- Updated
  [`tessellate_polygon`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/tessellation.rs#L71),
  [`tessellate_multi_contour`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/tessellation.rs#L116),
  [`tessellate_stroke`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/tessellation.rs#L214),
  [`tessellate_circle`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/tessellation.rs#L259),
  and
  [`tessellate_arc`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/tessellation.rs#L308)
  to return `Result<Mesh, Box<dyn std::error::Error>>`.

[`drawing.rs`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/drawing.rs)
- In the main drawing loop
  ([`drawing.rs:36-38`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/drawing.rs#L36-L38)):
  ```rust
  DrawCommand::Mesh(mesh) => {
  draw_mesh(mesh);
  }
  ```
  Now borrows `&Mesh` directly from the command vector with **0 heap
  allocations and 0 vector clones per frame**.
- Updated fill preview ([line
  228](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/drawing.rs#L228)),
  tween arc/center indicators ([lines 309,
  329](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/drawing.rs#L309)),
  and turtle shape drawing ([line
  349](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/drawing.rs#L349))
  to pass `&mesh` directly to `draw_mesh(&mesh)` without vector cloning.

[`execution.rs`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/execution.rs)
- Updated
  [`commands.push(DrawCommand::Mesh(mesh))`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/execution.rs#L135)
  and
  [`tessellate_command`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/execution.rs#L337).
- Updated
  [`test_forward_left_forward`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/execution.rs#L487)
  to instantiate `mut state` directly without dummy cloning.

---

```bash
cargo test --lib
```
Output:
```
running 10 tests
test circle_geometry::tests::test_circle_left_geometry ... ok
test circle_geometry::tests::test_circle_right_geometry ... ok
test general::angle::tests::degrees_to_radians_roundtrip ... ok
test general::angle::tests::from_integer ... ok
test execution::tests::test_forward_left_forward ... ok
test general::angle::tests::negation ... ok
test tweening::tests::test_animated_mode_pops_to_current_tween ... ok
test tweening::tests::test_instant_mode_drains_queue ... ok
test
tweening::tests::test_instant_mode_respects_batch_limit_and_retains_pending
... ok
test tweening::tests::test_streaming_append_commands_does_not_accumulate
... ok

test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered
out; finished in 0.00s
```

All targets verified with `cargo check --all-targets` and `cargo clippy
--lib`.
2026-09-18 21:34:07 +02:00
dietrich 1d0e149d22 Fix Unbounded Memory Growth (Memory Leak) in TweenController
In
[`TweenController`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/tweening.rs),
commands are currently accumulated in `queue: CommandQueue` (which wraps
a `Vec<TurtleCommand>`). When commands execute in `update()`, an
internal `cursor: usize` increments, but executed commands are never
removed. In streaming and threaded applications (such as
[`examples/clock_threaded.rs`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/examples/clock_threaded.rs)),
new commands are appended continuously, causing `queue` to grow
unboundedly over time and exhaust memory.

We will replace `queue: CommandQueue` and `cursor: usize` with `queue:
std::collections::VecDeque<TurtleCommand>` inside `TweenController`.
Consumed commands will be removed immediately using `pop_front()`,
completely freeing memory as commands complete.

> [!NOTE]
> All design decisions were aligned during the `/grill-me` session:
  > - `TweenController` will internally store
  `std::collections::VecDeque<TurtleCommand>` and consume items via
  `pop_front()`.
  > - `self.cursor` is eliminated entirely.
  > - `CommandQueue` remains the public API container for passing
  batches of commands into `TweenController::new` and
  `TweenController::append_commands`.
  > - `TurtleCommand::Reset` retains its normal semantics (clearing
  drawings and parameters without clearing future queued commands), as
  continuous `pop_front()` already discards consumed commands.
  > - Standard `VecDeque` capacity behavior is maintained (no
  auto-shrinking) to prevent reallocation jitter in streaming scenarios.

[tweening.rs](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/tweening.rs)
- Import `std::collections::VecDeque`.
- Update `TweenController` struct definition:
  - Replace `queue: CommandQueue` and `cursor: usize` with `queue:
    VecDeque<TurtleCommand>`.
- In `TweenController::new`:
  - Initialize `queue` using `queue.into_iter().collect()`.
  - Remove `cursor` initialization.
- In `TweenController::append_commands`:
  - Extend `self.queue` directly from `new_queue: CommandQueue`.
- In `TweenController::update`:
  - **Instant mode**: Replace `while let Some(command) =
    self.queue.get(self.cursor).cloned()` with `while let Some(command)
    = self.queue.pop_front()`, removing `self.cursor += 1` and
    unnecessary command cloning.
  - **Animated mode**: Replace `if let Some(command) =
    self.queue.get(self.cursor).cloned()` with `if let Some(command) =
    self.queue.pop_front()`, removing `self.cursor += 1` and unnecessary
    command cloning.
- In `TweenController::is_complete`:
  - Update check to `self.current_tween.is_none() &&
    self.queue.is_empty()`.
- Add unit tests in `#[cfg(test)] mod tests`:
  - Verify queue drains to 0 length in Instant mode.
  - Verify queue drains in Animated mode with multiple frames.
  - Verify streaming `append_commands` calls continuously drain and do
    not accumulate.
  - Verify `is_complete()` transitions correctly.

---

[commands.rs](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/commands.rs)
- Update doc comments referencing `TweenController`'s cursor to reflect
  the queue consumption model.

- Run `cargo test -p turtle-lib --lib tweening` to execute the new unit
  tests.
- Run `cargo test -p turtle-lib` to ensure all existing tests in
  `turtle-lib` continue to pass.
- Run `cargo check --examples` to ensure all examples (including
  `clock_threaded.rs`) compile cleanly.

- Review memory behavior or run `examples/clock_threaded.rs` in debug to
  confirm streaming updates run smoothly.
2026-09-18 21:13:46 +02:00
dietrich 4752075d08 remove custom linker 2026-09-18 20:57:00 +02:00
dietrich 5e0e0e5be3 update the dependencies 2026-05-22 15:13:22 +02:00
dietrich 106dd79677 improve README 2026-05-21 22:51:19 +02:00
dietrich 89c778289c Merge pull request #5 from enaut/copilot/research-turtle-lib-architecture
Align turtle-lib API docs with actual speed/reset/coordinate/heading semantics
2026-05-21 22:17:42 +02:00
dietrich 59d6bc164e improve examples 2026-05-21 21:50:13 +02:00
dietrich ece26bfe04 create a svg log instead of caching the commands where they do not
belong...
2026-05-21 21:28:14 +02:00
dietrich 156301f272 remove dead code and translate german comments to english 2026-05-21 17:35:59 +02:00
dietrich 96b02f61be improve circle construction and rendering 2026-05-21 17:29:27 +02:00
dietrich 998cffdcbf make the drwing of the center of the circle a regular feature. 2026-05-21 15:05:23 +02:00
dietrich 6b558ca8a0 more consistent use of angle types 2026-05-21 15:02:57 +02:00
dietrich 3c076fdd03 improve command handling 2026-05-17 07:23:13 +02:00
dietrich 44046abe12 improve command handling 2026-05-16 16:03:09 +02:00
dietrich a7570911d8 reduce exposed internal functions and fields 2026-05-16 15:31:10 +02:00
dietrich cd589b2513 Merge pull request #4 from enaut/copilot/change-license-to-mit-or-apache2
Add dual MIT/Apache-2.0 license files
2026-01-16 19:43:28 +01:00
dietrich 8a4ed0bf32 avoid cfg svg in public macro 2026-01-02 14:47:21 +01:00
dietrich 402a8be205 additional feature flag to suppress a warning 2026-01-02 13:50:13 +01:00
dietrich 3820f20048 Merge pull request #2 from enaut/copilot/add-cmdline-parameters-svg-export
Add --export-svg CLI parameter to turtle_main macro
2026-01-02 12:09:03 +01:00
dietrich 6f29d97bb6 unify comandline parsing into function 2026-01-02 11:53:18 +01:00
dietrich cadc5a6798 fix cartesian axes example 2026-01-02 11:45:20 +01:00
dietrich 9831008b9f fix clippy lints 2025-10-24 17:35:23 +02:00
dietrich a3cad7d1bc update the README.md 2025-10-24 17:29:40 +02:00
dietrich 8128c212ae fix unused variable warning 2025-10-24 17:29:06 +02:00
dietrich 78ecc84493 use the builder syntax for yinyang 2025-10-24 16:35:27 +02:00
dietrich 73d0ef4881 make speed increas exponentially 2025-10-24 16:31:43 +02:00
dietrich ea5bb85e88 add a viewbox to the svg that has the whole drawing in frame 2025-10-24 16:31:25 +02:00
dietrich e6bc79ea7b now svg lines, circles and fills are exported 2025-10-23 16:15:02 +02:00
dietrich 6e6aa8b27e initial svg support 2025-10-23 09:40:08 +02:00
dietrich 88d188a794 small fixes for clippy compliance 2025-10-20 14:46:04 +02:00
dietrich 0e191c617c fix doc tests 2025-10-20 11:51:05 +02:00
dietrich 728549253d some more examples 2025-10-19 16:39:42 +02:00
dietrich 346a4fd720 adjust examples to y-axis-flip 2025-10-19 14:19:17 +02:00
dietrich 64bd8ee530 flip the direction of y now y increases upwards 2025-10-19 14:19:00 +02:00
dietrich 1d93c22a73 dashed_circle example 2025-10-19 09:24:31 +02:00
dietrich 9fda96e439 add a threaded clock example 2025-10-19 09:13:52 +02:00
dietrich 284fcdcb6d clock example improvements 2025-10-19 08:49:20 +02:00
dietrich b31ac29deb add clock and bezier example 2025-10-18 22:19:02 +02:00
dietrich 2199a7803f fix set heading 2025-10-18 22:18:36 +02:00
dietrich 28527e6113 improve hangman 2025-10-18 21:35:45 +02:00
dietrich 070b404bf4 add text capabilities 2025-10-18 19:50:55 +02:00
dietrich 14b93f657b improve hangman example 2025-10-18 08:28:36 +02:00
dietrich 16430f3958 add turtle.reset 2025-10-18 08:28:17 +02:00
dietrich 7e23dc9d9c add two threading examples 2025-10-17 19:17:22 +02:00
dietrich 6b81c76915 start with zero turtles 2025-10-17 19:16:43 +02:00
dietrich 3f21afadb2 add threading 2025-10-17 19:16:19 +02:00
dietrich fcca1a2db4 rename create_turtle{,_plan} 2025-10-17 18:38:44 +02:00
dietrich 3509060390 add multi turtle support 2025-10-17 08:59:29 +02:00
dietrich bbb9348497 initial multi-turtle support 2025-10-13 09:42:34 +02:00
dietrich 1366f5e77f remove redundant and unimportant information 2025-10-12 23:01:32 +02:00
dietrich 08a1802bd2 remove the bevy based turtle and rename turtle-lib-macroquad to turtle-lib 2025-10-12 20:31:05 +02:00
dietrich fe2beb01ed remove the bevy turtle 2025-10-12 19:39:09 +02:00
dietrich 630b4fdc44 add examples 2025-10-12 17:30:49 +02:00
dietrich f43a71739e Add docs 2025-10-12 17:30:38 +02:00
dietrich 6d7d3fc434 remove examples that are too much... 2025-10-12 16:23:13 +02:00
dietrich cef63ca32a add a macro for simpler first examples. 2025-10-12 16:13:25 +02:00
dietrich 453e8e39bd apply clippy pedantic 2025-10-12 15:30:48 +02:00
dietrich 033a1982fc unify draws and state updates from instant and animated drawing 2025-10-12 13:46:11 +02:00
dietrich c96d66247e add tracing logging 2025-10-12 13:22:21 +02:00
dietrich 62e87edd4d improve duration calculation for go_to and arc_drawing 2025-10-12 12:55:21 +02:00
dietrich 164be647b2 add deprecation readme 2025-10-12 12:40:40 +02:00
dietrich 00b9007f00 Implement tessellation for turtle graphics with fill support
- Added tessellation module to handle path tessellation using Lyon.
- Updated execution logic to record fill vertices and manage fill contours.
- Integrated tessellation into command execution for lines, arcs, and filled shapes.
- Enhanced TurtleState to track fill state and contours.
- Modified TweenController to handle fill commands and update drawing commands accordingly.
- Improved debug output for fill operations and tessellation processes.
2025-10-12 12:34:20 +02:00
dietrich c3f5136359 normalizing angles to prevent drift
also move the at least one frame check to the AnimationSpeed creation.
2025-10-10 09:26:18 +02:00
dietrich 5799d2aa07 improve speed to have one single point of truth. 2025-10-09 15:54:53 +02:00
dietrich cebad0459c unify Left and Right to turn and forward backward to move 2025-10-09 13:35:10 +02:00
dietrich 7da0dcf141 refactor for simpler circle command and removed duplicated code 2025-10-09 13:23:52 +02:00
dietrich 25753b47ce Initial macroquad version for compiletime reasons
```rust
// Movement
plan.forward(100);
plan.backward(50);

// Rotation
plan.left(90);    // degrees
plan.right(45);

// Circular arcs
plan.circle_left(50.0, 180.0, 36);   // radius, angle (degrees), segments
plan.circle_right(50.0, 180.0, 36);  // draws arc to the right

// Pen control
plan.pen_up();
plan.pen_down();

// Appearance
plan.set_color(RED);
plan.set_pen_width(5.0);
plan.hide();
plan.show();

// Turtle shape
plan.shape(ShapeType::Triangle);
plan.shape(ShapeType::Turtle);    // Default classic turtle shape
plan.shape(ShapeType::Circle);
plan.shape(ShapeType::Square);
plan.shape(ShapeType::Arrow);

// Custom shape
let custom = TurtleShape::new(
    vec![vec2(10.0, 0.0), vec2(-5.0, 5.0), vec2(-5.0, -5.0)],
    true  // filled
);
plan.set_shape(custom);

// Chaining
plan.forward(100).right(90).forward(50);
```
2025-10-09 09:12:16 +02:00
dietrich 9ab58e39e7 updating the examples 2025-10-01 17:12:45 +02:00
dietrich 8a56176ceb first port to modern bevy 2025-10-01 17:10:27 +02:00
dietrich da7b9493ec Merge remote-tracking branch 'sub/main' 2023-01-25 12:05:51 +01:00
dietrich eef4591815 deleting turtle_lib submodule 2023-01-25 12:05:32 +01:00
dietrich f1591bc9f1 Moved files 2023-01-25 12:03:07 +01:00
dietrich 15310f5184 moving files 2023-01-25 12:00:17 +01:00
dietrich d0e47b5b85 update the dependencies + new examples
`nikolaus` is AI generated an just wrong.

`interrupted_lines` does not work as expected
2023-01-25 12:00:09 +01:00
dietrich 85f32250b1 updated examples for simpler interface 2023-01-25 11:58:48 +01:00
dietrich 8686c81c00 update to updated movement commands 2023-01-25 11:58:48 +01:00
dietrich 5df6f74071 Adding a koch curve example 2023-01-25 11:58:48 +01:00
dietrich e997cbae38 Use the new builder instead and draw complexer forms 2023-01-25 11:58:48 +01:00
dietrich 5f47726943 Initial sample binary 2023-01-25 11:58:13 +01:00
dietrich 9af343b543 remove example submodule 2023-01-25 11:48:48 +01:00
dietrich 4746802f49 update to newer versions 2023-01-11 10:25:21 +01:00
dietrich 8c5c9b4ec6 Upgrade inspector-egui and add first pen_up
Unfortunately `pen_up` does not seem to work even though it compiles
2023-01-11 10:20:15 +01:00
dietrich c329e30ec8 simpler api, circles and examples 2022-12-21 11:08:35 +01:00
dietrich 75771e8556 Add circle drawing 2022-12-21 11:07:02 +01:00
dietrich ccdf5f209f updated movement commands 2022-12-19 09:44:25 +01:00
dietrich 043e44b7f2 make the movement commands accept anything into the unit 2022-12-19 09:43:38 +01:00
dietrich 8375fcfcae Adding a koch example and extend the turtle by:
* set_speed
  * extend_plan
2022-12-13 11:33:04 +01:00
dietrich 7bdc83c760 adding extend_plan and set_speed 2022-12-13 11:31:29 +01:00
dietrich f82f17416f update lib and example for the lib 2022-12-07 13:57:23 +01:00
dietrich f5aae7efe1 Add a builder for the turtle plans 2022-12-07 13:54:15 +01:00
dietrich 11b9539800 enable basic left and right rotation 2022-12-07 13:52:28 +01:00
dietrich 009f896e08 Add impl From<i16> for angle and length 2022-12-07 13:51:08 +01:00
dietrich e0926a00f7 Add Debug to a lot of structs 2022-12-07 13:50:21 +01:00
dietrich 08d4e67328 Add a license file 2022-12-06 14:23:08 +01:00
dietrich 99dcc47c89 Adding submodules 2022-12-06 14:16:59 +01:00
dietrich d043b7c7c3 Initial turtle project 2022-12-06 14:09:24 +01:00
dietrich fac9d218ad Initial turtle-lib commit
Working so far:
  * display a window
  * display a turtle
  * go forward
2022-12-06 14:04:44 +01:00
dietrich fc18a0dbb4 Initial commit 2022-12-06 13:54:37 +01:00