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

@@ -152,11 +152,29 @@ akerr_ErrorContext *akgl_controller_handle_event(void *appstate, SDL_Event *even
}
/**
* @brief Gamepad handle button down.
* @param appstate Application state supplied by SDL.
* @param event SDL input event to process.
* @brief Set the movement and facing bits on the "player" actor for a D-pad or arrow press.
*
* A whole-application shortcut rather than a control-map binding: it looks the
* actor up by the literal name `"player"` in #AKGL_REGISTRY_ACTOR instead of
* being told which actor to act on, so it only ever drives one. The
* akgl_Actor_cmhf_* handlers are the general form.
*
* Facing follows movement unless the actor sets `movement_controls_face`, which
* is how an actor that aims independently of the direction it walks opts out.
*
* Declared nowhere -- `controller.h` advertises this as
* `akgl_controller_handle_button_down`, which does not exist. TODO.md, "Known
* and still open" item 10.
*
* @param appstate Passed through from SDL. Required as a non-`NULL` token only;
* never read.
* @param event The button or key event. Required. Both the gamepad and
* keyboard unions are read on every call, so the arm that does
* not correspond to the event type is read as garbage -- which
* works only because no real button and keycode pair collides.
* @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 @p appstate or @p event is `NULL`, or if there is
* no actor registered under the name "player".
*/
akerr_ErrorContext *gamepad_handle_button_down(void *appstate, SDL_Event *event)
{
@@ -210,11 +228,20 @@ akerr_ErrorContext *gamepad_handle_button_down(void *appstate, SDL_Event *event)
}
/**
* @brief Gamepad handle button up.
* @param appstate Application state supplied by SDL.
* @param event SDL input event to process.
* @brief Clear the movement bit on the "player" actor for a D-pad or arrow release, and reset its animation.
*
* The counterpart to gamepad_handle_button_down. It clears only the movement
* bit, leaving the facing bits alone so the actor keeps looking the way it was
* walking, and rewinds `curSpriteFrameId` to 0 so the next step starts from the
* first frame of the walk cycle rather than wherever it stopped.
*
* Declared nowhere; see gamepad_handle_button_down.
*
* @param appstate Passed through from SDL. Required as a non-`NULL` token only.
* @param event The button or key release event. Required.
* @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 @p appstate or @p event is `NULL`, or if there is
* no actor registered under the name "player".
*/
akerr_ErrorContext *gamepad_handle_button_up(void *appstate, SDL_Event *event)
{
@@ -256,11 +283,28 @@ akerr_ErrorContext *gamepad_handle_button_up(void *appstate, SDL_Event *event)
}
/**
* @brief Gamepad handle added.
* @param appstate Application state supplied by SDL.
* @param event SDL input event to process.
* @brief Open a gamepad that has just been plugged in, and log its mapping.
*
* SDL delivers no button events from an unopened gamepad, so a device that
* appears mid-session has to be opened here the way akgl_controller_open_gamepads
* opens the ones present at startup. A gamepad SDL has already opened is logged
* and left alone.
*
* The mapping is logged because a controller with no entry in the database
* produces no button events at all, and that is otherwise indistinguishable
* from a broken binding.
*
* Declared nowhere; see gamepad_handle_button_down.
*
* @param appstate Passed through from SDL. Required as a non-`NULL` token only.
* @param event The SDL_EVENT_GAMEPAD_ADDED event. Required. The joystick id
* is read out of the `gbutton` arm rather than `gdevice`, which
* works because the two share their `which` field.
* @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 @p appstate or @p event is `NULL`.
*
* @note A failed `SDL_OpenGamepad` is logged rather than reported: this returns
* success and the device stays silent.
*/
akerr_ErrorContext *gamepad_handle_added(void *appstate, SDL_Event *event)
{
@@ -293,11 +337,19 @@ akerr_ErrorContext *gamepad_handle_added(void *appstate, SDL_Event *event)
}
/**
* @brief Gamepad handle removed.
* @param appstate Application state supplied by SDL.
* @param event SDL input event to process.
* @brief Close a gamepad that has been unplugged.
*
* An unplugged device SDL still has open is a leaked handle, so this closes it.
* A removal for a device that was never opened is logged and otherwise ignored.
* Any control map still holding that `jsid` simply stops matching -- the map is
* not torn down.
*
* Declared nowhere; see gamepad_handle_button_down.
*
* @param appstate Passed through from SDL. Required as a non-`NULL` token only.
* @param event The SDL_EVENT_GAMEPAD_REMOVED event. Required.
* @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 @p appstate or @p event is `NULL`.
*/
akerr_ErrorContext *gamepad_handle_removed(void *appstate, SDL_Event *event)
{