Files
libakgl/examples/CMakeLists.txt

17 lines
759 B
CMake
Raw Normal View History

Add the UI demo: title menu, raw-CLAY options screen, HUD and dialog examples/uidemo is the program the UI chapter quotes. Three screens, three ways of building an interface: the title screen is one akgl_UiMenu plus a heading label; the options screen is written in raw CLAY() declarations -- hover highlighting inside the declaration, clicks paired with the application's own press edge -- because the widgets are a convenience, not a boundary; and the play screen is two HUD labels and the one-call dialog over a checkerboard standing in for a game world. No tilemap, no actors, no physics: everything left on screen is the subject. Its route_event() is the documented call-order contract in the flesh -- UI first, consumed events stop there, then the current screen's keys -- and the screen routing is the focus model, stated rather than invented. The headless smoke run (example_uidemo, --frames 240 --demo) tours every path through the real event chain: a mouse click on the centred menu (the consumed path, landing on the middle row by symmetry), keyboard into and out of the options screen, the dialog opened and dismissed, and Quit confirmed from the menu. The run prints its score and settings so a pass can be read, not just counted. docs_game_figures gains a uidemo frame -- the play screen with the dialog up -- for the chapter to come. Co-Authored-By: Claude Code (Claude Fable 5, claude-fable-5) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
2026-08-02 11:24:58 -04:00
# The tutorial games and demos.
Compile, link and run every example in the documentation libakgl exports 157 functions and the only user-facing documentation was a FAQ in README.md whose examples did not compile: two unbalanced `PASS()` calls, a `sprite->frameids = [0, 1, 2, 3];` that is not C in any dialect, a stray `9` inside a bitmask expression, an `int screenwidth = NULL`, and -- in the first snippet a reader ever saw -- the exact `strncpy` call AGENTS.md forbids. That is not a reader routing around typos. It is what happens to samples that nothing executes. This is akbasic's documentation harness with the interpreter taken out and the ability to link and run put in. The contract is a set of fence info strings, so an example is ordinary markdown that still highlights on the forge: ```c compiled with -fsyntax-only -Wall -Werror ```c wrap=NAME the same, wrapped in tests/docs_preludes/NAME.pre/.post ```c run=NAME linked against akgl and run headless ```c excerpt=PATH must still appear verbatim in PATH ```c screenshot=NAME also the source of docs/images/NAME.png ```json kind=KIND loaded through the real akgl_*_load_json ```output the exact stdout of the runnable block above it `run=` is why this links at all: -fsyntax-only proves a call typechecks, not that the startup order works or that an ATTEMPT block gives back what it took. `json kind=` exists because the asset formats are documented in prose and read by four loaders with nothing tying the two together -- util/assets/littleguy.json is already invalid against the loader it ships with. A fence with no info string is a hard error, and so is an unknown one. The failure mode this exists to prevent is passing because it quietly ran nothing, so an unannotated block is a missing decision rather than a default. Exit status is the number of failed examples; 2 for a usage error, which is a different thing and has to be distinguishable. Proven to fail on all ten of its failure modes -- untagged fence, non-compiling snippet, stale excerpt, orphan output block, unknown info string, run= output mismatch, invalid JSON, missing figure, a -Werror warning, and a dangling preload= -- because a check that has never failed has not been tested. `-Werror` here although AKGL_WERROR stays off for the library: that option is off so a new compiler's diagnostic cannot break a consumer's build, and a doc snippet is not a consumer. A sample that warns is a sample that teaches the warning. Registered as `docs_examples` and `docs_screenshots`. No docs-path filter in CI, deliberately: documentation goes stale because the code moved, not because somebody edited a chapter. Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 20:58:11 -04:00
#
# Each one is a complete, running program that the matching chapter quotes with
# `c excerpt=examples/...` blocks rather than restating -- so a tutorial cannot
# drift from a program that builds, because the excerpt check fails the moment
# the source moves.
#
# Every subdirectory is guarded on its own. The games are written by separate
# passes and land at different times, and a configure that fails because one of
# them is not there yet would block the other. There is nothing clever about the
# guard; it exists so an incomplete tree still builds.
Add the UI demo: title menu, raw-CLAY options screen, HUD and dialog examples/uidemo is the program the UI chapter quotes. Three screens, three ways of building an interface: the title screen is one akgl_UiMenu plus a heading label; the options screen is written in raw CLAY() declarations -- hover highlighting inside the declaration, clicks paired with the application's own press edge -- because the widgets are a convenience, not a boundary; and the play screen is two HUD labels and the one-call dialog over a checkerboard standing in for a game world. No tilemap, no actors, no physics: everything left on screen is the subject. Its route_event() is the documented call-order contract in the flesh -- UI first, consumed events stop there, then the current screen's keys -- and the screen routing is the focus model, stated rather than invented. The headless smoke run (example_uidemo, --frames 240 --demo) tours every path through the real event chain: a mouse click on the centred menu (the consumed path, landing on the middle row by symmetry), keyboard into and out of the options screen, the dialog opened and dismissed, and Quit confirmed from the menu. The run prints its score and settings so a pass can be read, not just counted. docs_game_figures gains a uidemo frame -- the play screen with the dialog up -- for the chapter to come. Co-Authored-By: Claude Code (Claude Fable 5, claude-fable-5) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
2026-08-02 11:24:58 -04:00
foreach(_example sidescroller jrpg uidemo)
Compile, link and run every example in the documentation libakgl exports 157 functions and the only user-facing documentation was a FAQ in README.md whose examples did not compile: two unbalanced `PASS()` calls, a `sprite->frameids = [0, 1, 2, 3];` that is not C in any dialect, a stray `9` inside a bitmask expression, an `int screenwidth = NULL`, and -- in the first snippet a reader ever saw -- the exact `strncpy` call AGENTS.md forbids. That is not a reader routing around typos. It is what happens to samples that nothing executes. This is akbasic's documentation harness with the interpreter taken out and the ability to link and run put in. The contract is a set of fence info strings, so an example is ordinary markdown that still highlights on the forge: ```c compiled with -fsyntax-only -Wall -Werror ```c wrap=NAME the same, wrapped in tests/docs_preludes/NAME.pre/.post ```c run=NAME linked against akgl and run headless ```c excerpt=PATH must still appear verbatim in PATH ```c screenshot=NAME also the source of docs/images/NAME.png ```json kind=KIND loaded through the real akgl_*_load_json ```output the exact stdout of the runnable block above it `run=` is why this links at all: -fsyntax-only proves a call typechecks, not that the startup order works or that an ATTEMPT block gives back what it took. `json kind=` exists because the asset formats are documented in prose and read by four loaders with nothing tying the two together -- util/assets/littleguy.json is already invalid against the loader it ships with. A fence with no info string is a hard error, and so is an unknown one. The failure mode this exists to prevent is passing because it quietly ran nothing, so an unannotated block is a missing decision rather than a default. Exit status is the number of failed examples; 2 for a usage error, which is a different thing and has to be distinguishable. Proven to fail on all ten of its failure modes -- untagged fence, non-compiling snippet, stale excerpt, orphan output block, unknown info string, run= output mismatch, invalid JSON, missing figure, a -Werror warning, and a dangling preload= -- because a check that has never failed has not been tested. `-Werror` here although AKGL_WERROR stays off for the library: that option is off so a new compiler's diagnostic cannot break a consumer's build, and a doc snippet is not a consumer. A sample that warns is a sample that teaches the warning. Registered as `docs_examples` and `docs_screenshots`. No docs-path filter in CI, deliberately: documentation goes stale because the code moved, not because somebody edited a chapter. Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 20:58:11 -04:00
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_example}/CMakeLists.txt")
add_subdirectory(${_example})
endif()
endforeach()