Files
libakgl/tests/docs_preludes/docs_prelude.h
Andrew Kesterson b7ff54b09f Vendor clay and bring the UI subsystem up: arena, lifecycle, status band
clay v0.14 (deps/clay, zlib licence) supplies the layout engine for the new
akgl_ui subsystem. Sources-listed rather than add_subdirectory()'d, on the
semver/libccd precedent: clay's CMakeLists declares no library target, builds
its examples by default, and requires CMake 3.27 against this project's 3.10.
src/ui_clay.c is the one CLAY_IMPLEMENTATION translation unit, compiled -w on
the vendored-code terms but with clay's symbols deliberately exported --
consumers' CLAY() macros resolve against libakgl.so, and akgl/ui.h warns them
never to link a second clay.

The subsystem is runtime-optional the way collision is: always compiled in,
inert until akgl_ui_init(), which bounds clay to the overridable AKGL_UI_*
ceilings, checks Clay_MinMemorySize() against a static BSS arena (no malloc),
and refuses with both numbers in the message when it does not fit. Measured:
812544 bytes at the default 1024 elements / 4096 measured words, against a
1 MiB arena. clay's void-callback layout errors are logged as they happen and
the first is stashed for the error protocol to raise later.

AKGL_ERR_UI joins the status band before AKGL_ERR_LIMIT, named in
akgl_error_init. New `ui` test suite covers validation, the init/shutdown
lifecycle, and arena exhaustion via the akgl_ui_arena_limit test hook (same
contract as akgl_ccd_arena_set_limit). clay.h is installed beside semver.h,
its licence beside libccd's, and the headers suite proves akgl/ui.h
self-contained -- clay.h compiles clean under -Wall.

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 10:53:11 -04:00

66 lines
2.0 KiB
C

/**
* @file docs_prelude.h
* @brief The include set every `c wrap=`, `c run=` and `c screenshot=` block gets.
*
* The four preludes in this directory all begin with this file, so the list of
* headers a wrapped example can rely on lives in exactly one place. It is not
* reachable from a `c` block with no `wrap=`: an unwrapped block is a whole
* translation unit and has to show its own `#include` lines, which is usually
* what a chapter wants a reader to see.
*
* Every public header, deliberately. The `headers` suite already proves each one
* is self-contained, so there is no ordering to get right, and an example that
* calls one subsystem while illustrating another does not have to grow an
* include line that is noise in the chapter.
*
* `docs_frame()` is declared here rather than in tools/docs_screenshot.c so the
* host and the akglframe prelude cannot drift apart on the signature.
*/
#ifndef _AKGL_DOCS_PRELUDE_H_
#define _AKGL_DOCS_PRELUDE_H_
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
#include <akerror.h>
#include <akstdlib.h>
#include <akgl/actor.h>
#include <akgl/assets.h>
#include <akgl/audio.h>
#include <akgl/character.h>
#include <akgl/controller.h>
#include <akgl/draw.h>
#include <akgl/error.h>
#include <akgl/game.h>
#include <akgl/heap.h>
#include <akgl/iterator.h>
#include <akgl/json_helpers.h>
#include <akgl/physics.h>
#include <akgl/registry.h>
#include <akgl/renderer.h>
#include <akgl/sprite.h>
#include <akgl/staticstring.h>
#include <akgl/text.h>
#include <akgl/tilemap.h>
#include <akgl/types.h>
#include <akgl/ui.h>
#include <akgl/util.h>
/**
* @brief One frame of drawing, supplied by a `c screenshot=NAME` block.
*
* tools/docs_screenshot.c brings libakgl up against an offscreen target, calls
* this, and writes what it drew to `docs/images/NAME.png`. The body is the
* chapter's own listing, wrapped by tests/docs_preludes/akglframe.pre.
*/
akerr_ErrorContext AKERR_NOIGNORE *docs_frame(void);
#endif // _AKGL_DOCS_PRELUDE_H_