Give every exported function a declaration, and check that it stays that way
Closes internal-consistency items 7 through 15. Nineteen non-static functions were in the ABI with no declaration anywhere, so no consumer could call them and any consumer could collide with them. The four gamepad_handle_* functions are the ones that mattered: controller.h declared akgl_controller_handle_button_down and three siblings that did not exist, so anything compiled against the header alone failed to link. The definitions carry the declared names now, which also closes Defects -> Known and still open item 10, and their documentation moved to the header. The rest are either declared under a "part of the internal API" block -- akgl_game_save_actors and akgl_game_load_versioncmp, which tests/game.c had to declare for itself, plus six tilemap loader helpers the untested-loader work wants to reach -- or static, which is what the four save iterators and load_objectnamemap should always have been. akgl_path_relative_from is deleted: declared nowhere, called from nowhere, never wrote its output, and leaked a pooled string on every call, so it closes Known and still open item 4 and item 40 by ceasing to exist. scripts/check_api_surface.sh keeps it closed. It reads the built library's dynamic symbol table and every public header with comments stripped, and fails on an exported akgl_* symbol that is declared nowhere. Stripping comments is the whole point -- four of these were mentioned in controller.h prose, which is how they went unnoticed. The pool-size ceilings are defined once, in heap.h, so the #ifndef override hook fires for the first time; actor.h, sprite.h and character.h were defining the same four unconditionally from headers heap.h includes above its own guard. tests/header_pool_override.c fails the compile if that regresses. Also here: (void) rather than () on the twelve no-argument entry points, AKERR_NOIGNORE only on declarations, static helpers with the akgl_ prefix dropped, and the six parameter-name mismatches. akgl_get_json_with_default had its two contexts swapped rather than merely misspelled -- the incoming one was `err` and its own was `e`, which is the name reserved for an incoming one. 24/24 pass, reindent --check clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,16 +24,6 @@
|
||||
|
||||
#include "testutil.h"
|
||||
|
||||
/*
|
||||
* akgl/controller.h declares these as akgl_controller_handle_*, but src has
|
||||
* always defined them as gamepad_handle_*. Declared here under the names that
|
||||
* actually link, so the tests can reach them without renaming shipped symbols.
|
||||
*/
|
||||
akerr_ErrorContext *gamepad_handle_button_down(void *appstate, SDL_Event *event);
|
||||
akerr_ErrorContext *gamepad_handle_button_up(void *appstate, SDL_Event *event);
|
||||
akerr_ErrorContext *gamepad_handle_added(void *appstate, SDL_Event *event);
|
||||
akerr_ErrorContext *gamepad_handle_removed(void *appstate, SDL_Event *event);
|
||||
|
||||
/** @brief Keyboard id the tests bind their control maps to. */
|
||||
#define TEST_KBID 11
|
||||
/** @brief Gamepad id the tests bind their control maps to. */
|
||||
@@ -424,7 +414,7 @@ akerr_ErrorContext *test_controller_gamepad_button_handlers(void)
|
||||
player->state = 0;
|
||||
player->movement_controls_face = false;
|
||||
make_button_event(&event, SDL_EVENT_GAMEPAD_BUTTON_DOWN, TEST_JSID, SDL_GAMEPAD_BUTTON_DPAD_DOWN);
|
||||
TEST_EXPECT_OK(e, gamepad_handle_button_down(&appstate_placeholder, &event),
|
||||
TEST_EXPECT_OK(e, akgl_controller_handle_button_down(&appstate_placeholder, &event),
|
||||
"dpad down press handler");
|
||||
TEST_ASSERT(e, AKGL_BITMASK_HAS(player->state, AKGL_ACTOR_STATE_MOVING_DOWN),
|
||||
"the dpad down handler did not set MOVING_DOWN (state %d)", player->state);
|
||||
@@ -432,7 +422,7 @@ akerr_ErrorContext *test_controller_gamepad_button_handlers(void)
|
||||
TEST_ASSERT(e, AKGL_BITMASK_HAS(player->state, AKGL_ACTOR_STATE_FACE_DOWN),
|
||||
"the dpad down handler did not set FACE_DOWN (state %d)", player->state);
|
||||
|
||||
TEST_EXPECT_OK(e, gamepad_handle_button_up(&appstate_placeholder, &event),
|
||||
TEST_EXPECT_OK(e, akgl_controller_handle_button_up(&appstate_placeholder, &event),
|
||||
"dpad down release handler");
|
||||
TEST_ASSERT(e, AKGL_BITMASK_HASNOT(player->state, AKGL_ACTOR_STATE_MOVING_DOWN),
|
||||
"the dpad down release handler did not clear MOVING_DOWN (state %d)", player->state);
|
||||
@@ -441,55 +431,55 @@ akerr_ErrorContext *test_controller_gamepad_button_handlers(void)
|
||||
|
||||
player->state = 0;
|
||||
make_button_event(&event, SDL_EVENT_GAMEPAD_BUTTON_DOWN, TEST_JSID, SDL_GAMEPAD_BUTTON_DPAD_UP);
|
||||
TEST_EXPECT_OK(e, gamepad_handle_button_down(&appstate_placeholder, &event), "dpad up press handler");
|
||||
TEST_EXPECT_OK(e, akgl_controller_handle_button_down(&appstate_placeholder, &event), "dpad up press handler");
|
||||
TEST_ASSERT(e, AKGL_BITMASK_HAS(player->state, AKGL_ACTOR_STATE_MOVING_UP),
|
||||
"the dpad up handler did not set MOVING_UP (state %d)", player->state);
|
||||
TEST_EXPECT_OK(e, gamepad_handle_button_up(&appstate_placeholder, &event), "dpad up release handler");
|
||||
TEST_EXPECT_OK(e, akgl_controller_handle_button_up(&appstate_placeholder, &event), "dpad up release handler");
|
||||
|
||||
player->state = 0;
|
||||
make_button_event(&event, SDL_EVENT_GAMEPAD_BUTTON_DOWN, TEST_JSID, SDL_GAMEPAD_BUTTON_DPAD_LEFT);
|
||||
TEST_EXPECT_OK(e, gamepad_handle_button_down(&appstate_placeholder, &event), "dpad left press handler");
|
||||
TEST_EXPECT_OK(e, akgl_controller_handle_button_down(&appstate_placeholder, &event), "dpad left press handler");
|
||||
TEST_ASSERT(e, AKGL_BITMASK_HAS(player->state, AKGL_ACTOR_STATE_MOVING_LEFT),
|
||||
"the dpad left handler did not set MOVING_LEFT (state %d)", player->state);
|
||||
TEST_EXPECT_OK(e, gamepad_handle_button_up(&appstate_placeholder, &event), "dpad left release handler");
|
||||
TEST_EXPECT_OK(e, akgl_controller_handle_button_up(&appstate_placeholder, &event), "dpad left release handler");
|
||||
|
||||
player->state = 0;
|
||||
make_button_event(&event, SDL_EVENT_GAMEPAD_BUTTON_DOWN, TEST_JSID, SDL_GAMEPAD_BUTTON_DPAD_RIGHT);
|
||||
TEST_EXPECT_OK(e, gamepad_handle_button_down(&appstate_placeholder, &event), "dpad right press handler");
|
||||
TEST_EXPECT_OK(e, akgl_controller_handle_button_down(&appstate_placeholder, &event), "dpad right press handler");
|
||||
TEST_ASSERT(e, AKGL_BITMASK_HAS(player->state, AKGL_ACTOR_STATE_MOVING_RIGHT),
|
||||
"the dpad right handler did not set MOVING_RIGHT (state %d)", player->state);
|
||||
TEST_EXPECT_OK(e, gamepad_handle_button_up(&appstate_placeholder, &event), "dpad right release handler");
|
||||
TEST_EXPECT_OK(e, akgl_controller_handle_button_up(&appstate_placeholder, &event), "dpad right release handler");
|
||||
|
||||
// With automatic facing on, the handler leaves facing to the actor's own
|
||||
// face function.
|
||||
player->state = 0;
|
||||
player->movement_controls_face = true;
|
||||
make_button_event(&event, SDL_EVENT_GAMEPAD_BUTTON_DOWN, TEST_JSID, SDL_GAMEPAD_BUTTON_DPAD_DOWN);
|
||||
TEST_EXPECT_OK(e, gamepad_handle_button_down(&appstate_placeholder, &event),
|
||||
TEST_EXPECT_OK(e, akgl_controller_handle_button_down(&appstate_placeholder, &event),
|
||||
"dpad down press with automatic facing on");
|
||||
TEST_ASSERT(e, AKGL_BITMASK_HASNOT(player->state, AKGL_ACTOR_STATE_FACE_DOWN),
|
||||
"the handler set facing even though the actor faces automatically (state %d)",
|
||||
player->state);
|
||||
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER, gamepad_handle_button_down(NULL, &event),
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER, akgl_controller_handle_button_down(NULL, &event),
|
||||
"dpad press handler with a NULL appstate");
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER,
|
||||
gamepad_handle_button_down(&appstate_placeholder, NULL),
|
||||
akgl_controller_handle_button_down(&appstate_placeholder, NULL),
|
||||
"dpad press handler with a NULL event");
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER, gamepad_handle_button_up(NULL, &event),
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER, akgl_controller_handle_button_up(NULL, &event),
|
||||
"dpad release handler with a NULL appstate");
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER,
|
||||
gamepad_handle_button_up(&appstate_placeholder, NULL),
|
||||
akgl_controller_handle_button_up(&appstate_placeholder, NULL),
|
||||
"dpad release handler with a NULL event");
|
||||
|
||||
// With no actor named "player" registered there is nothing to drive.
|
||||
CATCH(e, akgl_registry_init_actor());
|
||||
make_button_event(&event, SDL_EVENT_GAMEPAD_BUTTON_DOWN, TEST_JSID, SDL_GAMEPAD_BUTTON_DPAD_DOWN);
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER,
|
||||
gamepad_handle_button_down(&appstate_placeholder, &event),
|
||||
akgl_controller_handle_button_down(&appstate_placeholder, &event),
|
||||
"dpad press handler with no player actor registered");
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER,
|
||||
gamepad_handle_button_up(&appstate_placeholder, &event),
|
||||
akgl_controller_handle_button_up(&appstate_placeholder, &event),
|
||||
"dpad release handler with no player actor registered");
|
||||
} CLEANUP {
|
||||
} PROCESS(e) {
|
||||
@@ -506,22 +496,22 @@ akerr_ErrorContext *test_controller_device_events(void)
|
||||
// The dummy drivers present no gamepads, so the add and remove handlers
|
||||
// take their "unknown device" paths. Neither may crash.
|
||||
make_button_event(&event, SDL_EVENT_GAMEPAD_ADDED, 999, 0);
|
||||
TEST_EXPECT_OK(e, gamepad_handle_added(&appstate_placeholder, &event),
|
||||
TEST_EXPECT_OK(e, akgl_controller_handle_added(&appstate_placeholder, &event),
|
||||
"handling an add for a device that cannot be opened");
|
||||
|
||||
make_button_event(&event, SDL_EVENT_GAMEPAD_REMOVED, 999, 0);
|
||||
TEST_EXPECT_OK(e, gamepad_handle_removed(&appstate_placeholder, &event),
|
||||
TEST_EXPECT_OK(e, akgl_controller_handle_removed(&appstate_placeholder, &event),
|
||||
"handling a remove for a device that was never open");
|
||||
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER, gamepad_handle_added(NULL, &event),
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER, akgl_controller_handle_added(NULL, &event),
|
||||
"add handler with a NULL appstate");
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER,
|
||||
gamepad_handle_added(&appstate_placeholder, NULL),
|
||||
akgl_controller_handle_added(&appstate_placeholder, NULL),
|
||||
"add handler with a NULL event");
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER, gamepad_handle_removed(NULL, &event),
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER, akgl_controller_handle_removed(NULL, &event),
|
||||
"remove handler with a NULL appstate");
|
||||
TEST_EXPECT_STATUS(e, AKERR_NULLPOINTER,
|
||||
gamepad_handle_removed(&appstate_placeholder, NULL),
|
||||
akgl_controller_handle_removed(&appstate_placeholder, NULL),
|
||||
"remove handler with a NULL event");
|
||||
} CLEANUP {
|
||||
} PROCESS(e) {
|
||||
|
||||
Reference in New Issue
Block a user