Collapse bounds policies to reflect-only; drop abort and clamp
The executor kept every commanded point on-screen via a per-strategy
BoundsPolicy of abort / clamp / reflect. Measured against the real
strategies, the other two earned nothing: abort truncated a sweep at the
first edge (line on a narrow screen ran only 90 of 250 steps), and clamp
could park the cursor against an edge (a monotonic ramp stalled 162 steps
in a row) -- both counter to the program's whole purpose of keeping the
cursor moving. reflect bounces off the edge and keeps going, and is
already what line/diagonal need in loop mode. arc's declared clamp was
provably dead code (it clamps its own endpoint, so no sample ever leaves
the screen).
Collapse to reflect-only:
- strategies.ts: remove the BoundsPolicy type and the `bounds` field from
the interface and all six strategies. Keep the local clamp() helper --
it's arc's endpoint geometry, not an on-screen policy; docstring says so.
- executor.ts: resolveTarget loses its policy parameter and its null
return and just reflects both axes; delete clampInt; SweepOutcome drops
"aborted"; ExecuteOptions drops `bounds`; remove the Out of bounds log.
- keeper.ts: loopOpts is now { restore: false, loop: true } -- the
reflect override added with loop mode is redundant.
- tests: drop the abort-outcome, clamp, and bounds-override tests; simplify
fixed() to take no policy; add a regression test that a monotonic ramp
past an edge never yields two identical points in a row (the guarantee
that motivated removing clamp).
Behavior is unchanged for every pattern at normal cursor positions
(verified: line's normal sweep is byte-identical). The only differences
are at a screen edge, where motion now bounces instead of stopping. No
config keys, flags, or pattern names changed.
Docs updated to match, including in-code comments, the README strategies
table (Bounds column removed) and verbose description, the sequence
diagram (resolveTarget signature + getPosition/width ordering + a loop-mode
note), and a CHANGELOG Changed entry.
This commit is contained in:
@@ -38,12 +38,12 @@ sequenceDiagram
|
||||
end
|
||||
|
||||
Keeper->>Sim: simulateActivity(config, log, dev)
|
||||
Sim->>Dev: getPosition()
|
||||
Dev-->>Sim: start
|
||||
Sim->>Dev: width()
|
||||
Dev-->>Sim: width
|
||||
Sim->>Dev: height()
|
||||
Dev-->>Sim: height
|
||||
Sim->>Dev: getPosition()
|
||||
Dev-->>Sim: start
|
||||
Note over Sim: strategy = STRATEGIES[config.pattern]<br/>ctx = { start, width, height, rng }
|
||||
Sim->>Exec: executePath(strategy, ctx, dev, log, config)
|
||||
|
||||
@@ -51,7 +51,7 @@ sequenceDiagram
|
||||
Strat-->>Exec: iterable of Points
|
||||
|
||||
loop for each target point (clean run)
|
||||
Exec->>Exec: resolveTarget(bounds, target) → point
|
||||
Exec->>Exec: resolveTarget(target) → point (reflected on-screen)
|
||||
Exec->>Dev: setPosition(point)
|
||||
Exec->>Dev: sleep(stepDelay)
|
||||
Exec->>Dev: getPosition()
|
||||
@@ -86,3 +86,18 @@ sequenceDiagram
|
||||
follow-up `getPosition()` in `runKeeper` re-syncs `lastPos` to the origin as
|
||||
a no-op, and the next idle check sees no net movement (so the synthetic
|
||||
sweep is never mistaken for the user returning).
|
||||
- **On-screen confinement is uniform.** `resolveTarget` reflects any
|
||||
coordinate past a screen edge back inside the travel range — the sole,
|
||||
per-pattern-independent policy. A strategy emits ideal geometry and never
|
||||
bounds its own output.
|
||||
|
||||
## Loop mode (`--loop`)
|
||||
|
||||
This diagram is the single-sweep path (`config.loop === false`). Under
|
||||
`--loop`, `simulateActivity` instead repeats the step loop until the user
|
||||
interrupts: a pattern with an infinite `loopPath` (`line`, `diagonal`) runs
|
||||
that one never-ending path, while the others chain their finite `path` cycle
|
||||
after cycle, re-reading the cursor as the next `start` each time. The restore
|
||||
in the final step is skipped (`restore: false`), so successive cycles flow
|
||||
from where the last left off. Everything else — reflection, pacing, and the
|
||||
per-step interrupt check — is identical to the sweep traced above.
|
||||
|
||||
Reference in New Issue
Block a user