Commit Graph
4 Commits
Author SHA1 Message Date
adminandClaude Opus 5.5 2ff3a78607 Put the shapes of a vector drawing on layers and in groups (#190)
game-maker / gate (push) Successful in 2m41s
game-maker / suite (push) Failing after 7h24m17s
A vector drawing was one flat list of shapes. With many shapes the
list got hard to read, and several shapes could not be kept or moved
together. Now the shapes stand on layers, as in pixel art, and can be
put into groups that nest.

- A drawing has layers, each with a name and an eye. A hidden layer
  is neither in the tab nor in the picture a sprite wears, and its
  shapes cannot be pressed. One layer is the one worked on: the pen
  and Add shape draw onto it, and SHAPES lists what is on it.
- The inspector has a list LAYERS over the shapes. Its plus adds a
  layer, the cross on a row removes it with all on it, the last one
  stays. A double-click renames, a drag sorts.
- Group (Ctrl+G) puts the selected shapes into a group, Ungroup
  (Ctrl+Shift+G) takes it away. A group stands over its rows in the
  list, the rows one step in, and a row is dragged into a group or
  out of it.
- In the tab a press on a shape takes its outermost group, and a drag
  moves the group as one undo step.
- The model has layers with a tree of shapes and groups instead of a
  flat shapes array. The rules are pure functions in
  core/model/vectorTree.ts. A drawing saved before opens with all its
  shapes on one layer.
- SortableList takes rows with a depth and drops into a tree. The
  flat lists of tilemap and pixel art run as before.

Decided here:

- A group has no transformation of its own and cannot be hidden or
  locked. Rotating and scaling is the follow-up #291.
- A group is never empty: the one that loses its last shape goes
  with it.
- Several selected shapes are dragged together, grouped or not, and
  a click on a shape of the selection keeps the selection. This is
  what #217 asked for.
- Shift+click selects like Ctrl+click. With Select, Shift pans only
  beside the shapes, as in the scene view. The middle button pans
  anywhere, and with the pen and Paint Shift pans as before.
- A row of the list picks one shape of a group alone.
- Shapes change their layer through a row Layer in the inspector,
  which is there from two layers on. Rows are not dragged between
  layers.
- A group cannot span two layers, the button is off then.
- The pen does not draw onto a hidden layer, the hint says so.
- Groups are always shown unfolded.
- The four order buttons work inside the own group or layer.

Tests:
- Gate: 204 files, 3067 tests (3008 + 59), exit 0
- e2e 47,48: 108 checks. e2e 39,40,47,48 before the Shift change:
  209 checks. No full run, the sum of 1645 (1639 + 6) is reckoned
  and CI measures it.
- 59 unit tests: 36 in tests/core/vector-tree.test.ts, 23 in
  tests/editor/vector-layers.test.ts
- Six e2e checks with a real mouse in block 47j
- 47 unit counter-probes for layers and groups and three for the
  Shift click all fail tests, run on stein2
- Three browser counter-probes fail their checks
- Two screenshots looked at (group in the list, hidden layer)
- Only unit tested: the row Layer, sorting and removing layers,
  copying a group, the Shift pan beside the shapes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:13:43 +02:00
adminandClaude Opus 5.5 d6171fd386 Preview pixel art and curve fields once per frame too (#274)
game-maker / gate (push) Successful in 2m37s
game-maker / suite (push) Successful in 13m24s
The previous commit left two findings open: in the pixel art tab the
palette colour and the opacity of a layer still told the editor about
every input, and so did the place fields of the curve tab. They now
follow the same rule as the inspector rows.

- PixelArtSide writes colour and opacity into the model on every
  input and requests the preview through a FramePreview. Both commits
  cancel a waiting preview first.
- CurveCanvas.movePicked does the same for the t and v fields of the
  picked point. Showing another curve cancels a waiting preview.
- Also fixed: when the colour picker ended on the colour it started
  from, the model was put back but nobody was told, so the previewed
  colour stayed on screen. commitColor now says so, as the opacity
  already did.

The gain was not measured for either tab, only the behaviour is
tested.

Tests:
- Gate: 198 files, 2911 tests (2907 + 4), exit 0
- e2e 47,48,53: 117 checks passed
- Four new unit tests in tests/editor/frame-preview.test.ts: colour,
  opacity, curve fields and the return to the starting colour
- Seven counter-probes fail, one test each. They ran on stein2, not
  in the container.
- No new e2e check, the sum stays at 1616. Neither the full suite nor
  the smokes ran for this state, and there was no counter-probe in
  the browser.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 12:02:12 +02:00
adminandClaude Opus 5.5 c4a9280140 Preview inspector edits once per frame, not per input (#274)
Scrubbing a number in the inspector and dragging a colour stop of a
gradient told the editor about every input. Pixi repeats each pointer
move shortly after, so both gestures paid for two previews per move.
The issue asked to measure first and to build only from 10 % per
move. The measurement showed about 50 %.

- previewingHandlers still writes the model on every input but
  requests the preview through a FramePreview of its own. The commit
  cancels a waiting preview first.
- The preview handler of the GradientBar in shapeSection.ts does the
  same.
- Wider than the issue describes: the row handlers also serve typing,
  the arrow keys and the colour picker. All of them preview once per
  frame now.

Measured on stein2, fixture project with 120 extra objects, 120 moves
8 ms apart, three runs each:
- Scrub: 236 project events before, 51 to 61 after. 45 to 50 ms per
  move before, 22 to 27 after.
- Colour stop: 238 project events before, 50 to 51 after. 44 to 49 ms
  per move before, 22 after.
- One preview still costs 13 to 17 ms. That price per frame is what
  remains.

Finding, not fixed here: in the pixel art tab the palette colour and
the opacity of a layer still preview on every input
(PixelArtSide.ts), and so do the head fields of the curve tab.
Neither was measured.

Tests:
- Gate: 198 files, 2907 tests (2903 + 4), exit 0
- e2e, full run: 1616 checks passed (1615 + 1), exit 0
- Smokes: 24 / 19 / 21, exit 0
- Four new unit tests in tests/editor/frame-preview.test.ts, two for
  a row and two for a colour stop
- One new e2e check in module 02: a held scrub gave 10 project events
  in 12 frames, and the value is there before the release
- Four unit counter-probes fail, 1 to 2 tests each. They ran on
  stein2, not in the container.
- The browser counter-probe fails the new check with 50 events in 16
  frames

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 11:25:37 +02:00
adminandClaude Opus 5.5 30fb3a2316 Dragging previews once per frame instead of on every move (#213)
game-maker / gate (push) Successful in 2m52s
game-maker / suite (push) Successful in 8m43s
Scene view, texture tab and graph called state.preview() on every
pointer move. Each call rebuilds panels, the editor run and generated
images, so a drag in a busy project cost up to 34 ms per move. The
model is still written on every move. Only the preview now waits for
the next frame.

- New FramePreview in src/editor/framePreview.ts. request() goes into
  the move handler, cancel() into the release. The rule lives in one
  place instead of six copies.
- Scene view: object drag, polygon corners and tilemap strokes use it.
- Texture tab: frames, slice edges and collision corners use it.
- Graph: nodes, groups and comments use it through GraphDrags. That
  covers the state machine, shader and particle tabs as well.
- Vector art is unchanged. Its frame already writes the model since
  #129.

Findings:
- The texture tab paid twice per move (232 project events for 120
  moves). Pixi sends a second pointer event 4 to 8 ms after each real
  move as a hover update. It now lands in the same frame for free.
- Inspector scrubbing and gradient stop dragging still preview on
  every input. Both lie outside the three canvases of the issue.

Measured with a throwaway probe, 120 moves at 8 ms, 120 extra objects:
scene 26.2 -> 18.5 ms/move, texture 34.2 -> 17.9, graph 28.8 -> 17.0.
Project events dropped from 120/232/119 to 48/48/41.

Tests:
- ./check.sh: 147 files, 2204 tests, exit 0 (before 146 / 2199).
- 5 new unit tests in tests/editor/frame-preview.test.ts, including
  the real GraphDrags. Counter-checks (direct preview in the graph,
  no cancel on release, one key per name) each fail the expected test.
- e2e 1-16,29,31,36,37,39-43: 708 checks passed.
- e2e 1-16,26,28: 634 checks passed.
- No new e2e check, the check sum stays at 1314.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 11:08:11 +02:00