Document what the functions actually do instead of that they can fail

The Doxygen comments were generated from the declarations, so 217 @throws
lines across 21 headers read "When the corresponding validation or operation
fails" and told a caller nothing beyond the status name. The @param lines were
the same shape: every output was "Output destination populated by the
function", every instance "Object to initialize, inspect, or modify".

Rewritten against the implementations, following the pattern libakstdlib
already uses:

- @throws names the condition. akgl_sprite_load_json separated AKERR_KEY
  (absent) from AKERR_TYPE (present, wrong type) from AKERR_OUTOFBOUNDS
  (filename too long, or array indexed past its end), and gained AKGL_ERR_SDL
  and AKGL_ERR_HEAP, which it raises and never declared.
- Parameters say whether they are required, what a NULL means, and what is
  written on a failure path. Where an argument is not checked, the doc says so:
  akgl_heap_next_actor's dest is a crash on NULL, not an error, and
  akgl_render_2d_frame_start dereferences self before testing it.
- The conventions move up to the file blocks so the per-function docs stay
  short. json_helpers.h states once that absence is an error here and that
  json_t * results are borrowed; heap.h explains the pool model and the
  acquire asymmetry; physics.h carries the thrust/environmental/velocity table.
- Struct fields, enum values, macros and exported globals are documented,
  including the dead ones - sprite_w/sprite_h, movetimer, p_scale and
  timer_gravity are read by nothing, and say so.

Also fixes ten comments in error.h and audio.h that opened with /** rather
than /**<, so Doxygen attached them to the following entity and rendered the
text as part of the macro's value. Verified against the generated HTML.

Comments only - no declaration changed. Doxygen builds clean under
WARN_AS_ERROR, scripts/reindent.sh --check passes, 19/19 suites pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-31 11:02:20 -04:00
parent 582008a411
commit f0858b0d38
28 changed files with 3090 additions and 1012 deletions

View File

@@ -91,12 +91,28 @@ void akgl_character_state_sprites_iterate(void *userdata, SDL_PropertiesID regis
}
/**
* @brief Character load json state int from strings.
* @param states JSON array of actor-state names.
* @param dest Output destination populated by the function.
* @brief OR a JSON array of actor-state names together into one bitmask.
*
* This is what lets a character JSON say `["FACE_LEFT", "MOVING_LEFT"]` rather
* than a number: each name is looked up in #AKGL_REGISTRY_ACTOR_STATE_STRINGS
* and OR-ed in. A name that is not a known state is an error rather than being
* skipped -- a typo in a state name would otherwise bind a sprite to the wrong
* combination and show up as art that never appears.
*
* @param states JSON array of state-name strings. Required. An empty array is
* legal and leaves @p dest as it was.
* @param dest Receives the OR of every named bit. Required in practice, and
* **not** checked -- the guard that should test it tests @p states
* a second time instead, so a `NULL` here is a crash. It is OR-ed
* into rather than assigned, so the caller must zero it first.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_KEY When the corresponding validation or operation fails.
* @throws AKERR_NULLPOINTER When the corresponding validation or operation fails.
* @throws AKERR_NULLPOINTER If @p states is `NULL`.
* @throws AKERR_KEY If a name is not in the actor-state registry. The message
* quotes it. Note that bits 11 and 12 are unreachable by name; see
* akgl_registry_init_actor_state_strings.
* @throws AKERR_TYPE If an array element is not a string.
* @throws AKERR_OUTOFBOUNDS If the array is indexed past its end.
* @throws AKGL_ERR_HEAP If the string pool is exhausted.
*/
static akerr_ErrorContext *akgl_character_load_json_state_int_from_strings(json_t *states, int *dest)
{
@@ -123,11 +139,27 @@ static akerr_ErrorContext *akgl_character_load_json_state_int_from_strings(json_
}
/**
* @brief Character load json inner.
* @param json JSON object to parse.
* @param obj Object to initialize, inspect, or modify.
* @brief Name a character and build its state-to-sprite map from a JSON document.
*
* The half of akgl_character_load_json that deals with identity and sprites; the
* caller handles the numeric fields afterwards. Reads `name`, initializes the
* character with it, then walks `sprite_mappings` binding each named sprite to
* the bitmask its `state` array adds up to.
*
* Every sprite named must already be in #AKGL_REGISTRY_SPRITE.
*
* @param json The parsed character document. Required in practice; not checked,
* and passed straight to accessors that report it.
* @param obj The pooled character to fill in. Required, unchecked -- it is
* handed to akgl_character_initialize, which does check it.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_NULLPOINTER When the corresponding validation or operation fails.
* @throws AKERR_NULLPOINTER If a mapping names a sprite that is not registered.
* The message names the character, the state, and the sprite.
* @throws AKERR_KEY If `name`, `sprite_mappings`, or a mapping's `sprite` or
* `state` is absent, or if a state name is unknown.
* @throws AKERR_TYPE If one of those keys has the wrong JSON type.
* @throws AKERR_OUTOFBOUNDS If an array is indexed past its end.
* @throws AKGL_ERR_HEAP If the string pool is exhausted.
*/
static akerr_ErrorContext *akgl_character_load_json_inner(json_t *json, akgl_Character *obj)
{