Skip to content

Simulator: one class per job, in the style of the library - #18

Merged
theAndreas merged 1 commit into
mainfrom
simulator-classes
Oct 30, 2026
Merged

theAndreas merged 1 commit into
mainfrom
simulator-classes

Conversation

@theAndreas

Copy link
Copy Markdown
Owner

The restructure meant for #16, which was merged before it was pushed there. Cherry-picked onto main unchanged, except that the simulator now includes MaxMatrixStandardTypes.h after #17's rename.

The simulator was two files that each did several jobs, with its state in file-scope variables and none of the conventions of src/. It is now one class per job, with the file header, banners, Doxygen blocks and macros of the library:

File Job
main.cpp setup(), loop(), and tick() for Mock::Tick
SimulatorOptions the command line
SimulatorPanel the model's LEDs for a wiring and mounting, and whether to draw again
SimulatorTerminal redrawn in place, or printed once after --for
SimulatorWeb the JSON for the page and its commands
SimulatorWebHost HTTP on loopback, the WebSocket clients
SimulatorWebSocket handshake, frames, SHA-1, base64, on strings only

Why this way. The classes start with Simulator because the simulator is linked with the sketch, the reason the library's start with MaxMatrix. No virtual interface for terminal and page: main.cpp picks one. Mock::Tick is a bare function pointer, so main.cpp keeps the objects at file scope. The host hands received messages back from task() instead of calling a function pointer, so the web view applies them to the panel it is handed, as MaxMatrixText is handed the panel.

New tests. SimulatorWebSocket has no socket in it, so test/SimulatorWebSocketTest.cpp checks it against the examples of FIPS 180-2, RFC 4648 and RFC 6455, plus what WebTest.sh cannot send: a key in other case, a 16 bit length, a frame split across reads, two frames in one read. Five faults put in by hand (mask index, base64 padding, a SHA-1 constant, the length check, the space after the header) were each caught.

Measured against the simulator on main. The JSON after hello, wiring GENERIC and upside-down 1 is byte for byte the same apart from the frame count. --for 2.5 prints the same panel plain, --upside-down and --wiring GENERIC. Exit codes for a wrong command line (2) and a taken port (1) are the same. 164 tests pass, 13 of them new. The library is untouched, so the examples' flash and RAM cannot change.

Not in here, each a bug of its own with its own test:

  • --port 70000 wraps to 4464, because atoi does no range check.
  • With --upside-down the terminal lists the intensities in chain order, while the page lists them by position from the left; only the page is right.

CLAUDE.md now says the conventions of src/ hold for simulator/ as well.

Simulator.cpp parsed the command line, drew in the terminal, compared
with --expect, built the JSON for the page and ran the loop; WebHost.cpp
held HTTP, the WebSocket protocol, SHA-1, base64 and the client slots in
file-scope state. Each now has a class of its own, with the file header,
banners, Doxygen blocks and macros of src/:

  main.cpp             setup(), loop(), tick() for Mock::Tick
  SimulatorOptions     the command line
  SimulatorPanel       the model's LEDs for a wiring and mounting, and
                       whether to draw again
  SimulatorTerminal    redrawn in place, or printed once after --for
  SimulatorWeb         the JSON for the page and its commands
  SimulatorWebHost     HTTP on loopback, the WebSocket clients
  SimulatorWebSocket   handshake, frames, SHA-1, base64 - on strings only

The classes start with Simulator because the simulator is linked with
the sketch, the same reason the library's start with MaxMatrix. The
WebSocket protocol has no socket in it, so test/SimulatorWebSocketTest
checks it against the examples of FIPS 180-2, RFC 4648 and RFC 6455,
and what WebTest.sh cannot send: a key in other case, a 16 bit length,
a frame split across reads, two frames in one read. Five faults put
into the protocol by hand were each caught. The host now hands the
messages back from task() rather than calling a function pointer, so
the web view can apply them to the panel it is given.

Nothing a user sees changes. Against the simulator before this commit:
the JSON after "hello", "wiring GENERIC" and "upside-down 1" is byte
for byte the same apart from the frame count; --for 2.5 prints the same
panel plain, --upside-down and --wiring GENERIC; the exit codes for a
wrong command line (2) and a taken port (1) are the same. 164 tests
pass, 13 of them new.

CLAUDE.md says the conventions of src/ hold for simulator/ as well.
@theAndreas
theAndreas merged commit 02da8de into main Oct 30, 2026
3 checks passed
@theAndreas
theAndreas deleted the simulator-classes branch October 30, 2026 08:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants