Commit Graph
109 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 bc925ffe26 svg text size and orientation 2026-07-20 13:39:42 +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
copilot-swe-agent[bot]andenaut 77ca219621 Refine SetHeading conversion wording
Agent-Logs-Url: https://github.com/enaut/turtlers/sessions/5fb2f5ed-163f-4c2d-8180-1e96150e7e46

Co-authored-by: enaut <290005+enaut@users.noreply.github.com>
2026-05-21 20:09:15 +00:00
copilot-swe-agent[bot]andenaut 2ac52ecc92 Fix turtle-lib API docs and invariant wording
Agent-Logs-Url: https://github.com/enaut/turtlers/sessions/5fb2f5ed-163f-4c2d-8180-1e96150e7e46

Co-authored-by: enaut <290005+enaut@users.noreply.github.com>
2026-05-21 20:08:40 +00: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
copilot-swe-agent[bot]andenaut 4ce176f44d Add LICENSE-MIT and LICENSE-APACHE files for dual licensing
Co-authored-by: enaut <290005+enaut@users.noreply.github.com>
2026-01-16 18:34:55 +00:00
copilot-swe-agent[bot] ef6e8e4c76 Initial plan 2026-01-16 18:31:28 +00: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
copilot-swe-agent[bot]andenaut 9568bc10d9 Add comment explaining intentional code duplication in proc macro
Co-authored-by: enaut <290005+enaut@users.noreply.github.com>
2026-01-01 20:44:27 +00:00
copilot-swe-agent[bot]andenaut cbe249b9b7 Update README with CLI SVG export documentation and examples
Co-authored-by: enaut <290005+enaut@users.noreply.github.com>
2026-01-01 20:42:53 +00:00
copilot-swe-agent[bot]andenaut f5140361d5 Add documentation comment explaining magic number in instant speed
Co-authored-by: enaut <290005+enaut@users.noreply.github.com>
2026-01-01 20:41:52 +00:00
copilot-swe-agent[bot]andenaut c806570156 Implement CLI --export-svg parameter for instant SVG export
Co-authored-by: enaut <290005+enaut@users.noreply.github.com>
2026-01-01 20:40:06 +00:00
copilot-swe-agent[bot]andenaut d85a9c7d26 Add --export-svg CLI parameter support to turtle_main macro
Co-authored-by: enaut <290005+enaut@users.noreply.github.com>
2026-01-01 20:31:58 +00:00
copilot-swe-agent[bot] 2b64be29a8 Initial plan 2026-01-01 20:27:41 +00: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