2025-08-03 10:07:35 -04:00
|
|
|
#define UNHANDLED_ERROR_TERMINATION_BEHAVIOR \
|
|
|
|
|
handle_unhandled_error(errctx);
|
|
|
|
|
|
2026-01-05 08:58:06 -05:00
|
|
|
#include <akerror.h>
|
2025-08-03 10:07:35 -04:00
|
|
|
|
|
|
|
|
#define UNHANDLED_ERROR_EXIT 0
|
|
|
|
|
#define UNHANDLED_ERROR_SET 1
|
|
|
|
|
|
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
2025-08-03 10:41:09 -04:00
|
|
|
#include <sdl3game/iterator.h>
|
|
|
|
|
#include <sdl3game/registry.h>
|
|
|
|
|
#include <sdl3game/actor.h>
|
|
|
|
|
#include <sdl3game/heap.h>
|
|
|
|
|
|
2025-08-03 10:07:35 -04:00
|
|
|
int UNHANDLED_ERROR_BEHAVIOR;
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_ErrorContext *unhandled_error_context;
|
2025-08-03 10:07:35 -04:00
|
|
|
|
2026-05-03 23:57:55 -04:00
|
|
|
void handle_unhandled_error_noexit(akerr_ErrorContext *errctx)
|
2025-08-03 10:07:35 -04:00
|
|
|
{
|
|
|
|
|
if ( errctx == NULL ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if ( UNHANDLED_ERROR_BEHAVIOR == UNHANDLED_ERROR_EXIT ) {
|
|
|
|
|
exit(errctx->status);
|
|
|
|
|
}
|
|
|
|
|
if ( UNHANDLED_ERROR_BEHAVIOR == UNHANDLED_ERROR_SET ) {
|
|
|
|
|
unhandled_error_context = errctx;
|
|
|
|
|
errctx->refcount += 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-06 23:18:42 -04:00
|
|
|
int akgl_actor_updated;
|
|
|
|
|
akerr_ErrorContext *akgl_actor_update_noop(akgl_Actor *obj)
|
2025-08-03 10:07:35 -04:00
|
|
|
{
|
|
|
|
|
PREPARE_ERROR(errctx);
|
2026-05-06 23:18:42 -04:00
|
|
|
akgl_actor_updated = 1;
|
2025-08-03 10:07:35 -04:00
|
|
|
SUCCEED_RETURN(errctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Currently the renderer assumes there is a global variable named `renderer`
|
2026-05-06 23:18:42 -04:00
|
|
|
int akgl_actor_rendered;
|
|
|
|
|
akerr_ErrorContext *akgl_actor_render_noop(akgl_Actor *obj, SDL_Renderer *r)
|
2025-08-03 10:07:35 -04:00
|
|
|
{
|
|
|
|
|
PREPARE_ERROR(errctx);
|
2026-05-06 23:18:42 -04:00
|
|
|
akgl_actor_rendered = 1;
|
2025-08-03 10:07:35 -04:00
|
|
|
SUCCEED_RETURN(errctx);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_ErrorContext *test_registry_actor_iterator_nullpointers(void)
|
2025-08-03 10:07:35 -04:00
|
|
|
{
|
|
|
|
|
PREPARE_ERROR(errctx);
|
|
|
|
|
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_ErrorUnhandledErrorHandler defaulthandler = akerr_handler_unhandled_error;
|
2025-08-03 10:07:35 -04:00
|
|
|
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_handler_unhandled_error = handle_unhandled_error_noexit;
|
2025-08-03 10:07:35 -04:00
|
|
|
ATTEMPT {
|
|
|
|
|
UNHANDLED_ERROR_BEHAVIOR = UNHANDLED_ERROR_SET;
|
2026-05-06 23:18:42 -04:00
|
|
|
DETECT(unhandled_error_context, akgl_registry_iterate_actor(NULL, AKGL_REGISTRY_ACTOR, ""));
|
2025-08-03 10:07:35 -04:00
|
|
|
} CLEANUP {
|
|
|
|
|
UNHANDLED_ERROR_BEHAVIOR = UNHANDLED_ERROR_EXIT;
|
|
|
|
|
} PROCESS(unhandled_error_context) {
|
2026-05-03 23:57:55 -04:00
|
|
|
} HANDLE(unhandled_error_context, AKERR_NULLPOINTER) {
|
2025-08-03 10:07:35 -04:00
|
|
|
printf("Handled\n");
|
|
|
|
|
} FINISH(unhandled_error_context, true);
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_handler_unhandled_error = defaulthandler;
|
2025-08-03 10:07:35 -04:00
|
|
|
SUCCEED_RETURN(errctx);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_ErrorContext *test_registry_actor_iterator_missingactor(void)
|
2025-08-03 10:07:35 -04:00
|
|
|
{
|
|
|
|
|
PREPARE_ERROR(errctx);
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_ErrorUnhandledErrorHandler defaulthandler = akerr_handler_unhandled_error;
|
2025-08-03 10:07:35 -04:00
|
|
|
|
2026-05-06 23:18:42 -04:00
|
|
|
akgl_Iterator iter = {
|
2025-08-03 10:07:35 -04:00
|
|
|
.layerid = 0,
|
|
|
|
|
.flags = 0
|
|
|
|
|
};
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_handler_unhandled_error = handle_unhandled_error_noexit;
|
2025-08-03 10:07:35 -04:00
|
|
|
ATTEMPT {
|
|
|
|
|
UNHANDLED_ERROR_BEHAVIOR = UNHANDLED_ERROR_SET;
|
|
|
|
|
DETECT(
|
|
|
|
|
unhandled_error_context,
|
2026-05-06 23:18:42 -04:00
|
|
|
akgl_registry_iterate_actor(
|
2025-08-03 10:07:35 -04:00
|
|
|
&iter,
|
2026-05-06 23:18:42 -04:00
|
|
|
AKGL_REGISTRY_ACTOR,
|
2025-08-03 10:07:35 -04:00
|
|
|
"Actor who doesn't exist")
|
|
|
|
|
);
|
|
|
|
|
} CLEANUP {
|
|
|
|
|
UNHANDLED_ERROR_BEHAVIOR = UNHANDLED_ERROR_EXIT;
|
|
|
|
|
} PROCESS(unhandled_error_context) {
|
2026-05-03 23:57:55 -04:00
|
|
|
} HANDLE(unhandled_error_context, AKERR_KEY) {
|
2025-08-03 10:07:35 -04:00
|
|
|
printf("Handled\n");
|
|
|
|
|
} FINISH(unhandled_error_context, true);
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_handler_unhandled_error = defaulthandler;
|
2025-08-03 10:07:35 -04:00
|
|
|
SUCCEED_RETURN(errctx);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_ErrorContext *test_registry_actor_iterator_updaterender(void)
|
2025-08-03 10:07:35 -04:00
|
|
|
{
|
2026-05-06 23:18:42 -04:00
|
|
|
akgl_Actor *testactor;
|
|
|
|
|
akgl_Iterator iter = {
|
2025-08-03 10:07:35 -04:00
|
|
|
.layerid = 0,
|
2026-05-06 23:18:42 -04:00
|
|
|
.flags = AKGL_ITERATOR_OP_UPDATE | AKGL_ITERATOR_OP_RENDER
|
2025-08-03 10:07:35 -04:00
|
|
|
};
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_ErrorUnhandledErrorHandler defaulthandler = akerr_handler_unhandled_error;
|
2025-08-03 10:07:35 -04:00
|
|
|
|
|
|
|
|
PREPARE_ERROR(errctx);
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_handler_unhandled_error = handle_unhandled_error_noexit;
|
2025-08-03 10:07:35 -04:00
|
|
|
ATTEMPT {
|
|
|
|
|
UNHANDLED_ERROR_BEHAVIOR = UNHANDLED_ERROR_SET;
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(unhandled_error_context, akgl_heap_next_actor(&testactor));
|
|
|
|
|
CATCH(unhandled_error_context, akgl_actor_initialize(testactor, "test"));
|
2025-08-03 10:07:35 -04:00
|
|
|
|
|
|
|
|
testactor->layer = 0;
|
2026-05-06 23:18:42 -04:00
|
|
|
testactor->updatefunc = &akgl_actor_update_noop;
|
|
|
|
|
testactor->renderfunc = &akgl_actor_render_noop;
|
2025-08-03 10:07:35 -04:00
|
|
|
|
|
|
|
|
DETECT(
|
|
|
|
|
unhandled_error_context,
|
2026-05-06 23:18:42 -04:00
|
|
|
akgl_registry_iterate_actor(
|
2025-08-03 10:07:35 -04:00
|
|
|
&iter,
|
2026-05-06 23:18:42 -04:00
|
|
|
AKGL_REGISTRY_ACTOR,
|
2025-08-03 10:07:35 -04:00
|
|
|
"test")
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
FAIL_ZERO_BREAK(
|
|
|
|
|
unhandled_error_context,
|
2026-05-06 23:18:42 -04:00
|
|
|
akgl_actor_updated,
|
2026-05-03 23:57:55 -04:00
|
|
|
AKERR_BEHAVIOR,
|
2025-08-03 10:07:35 -04:00
|
|
|
"actor->updatefunc not called by the iterator"
|
|
|
|
|
);
|
|
|
|
|
FAIL_ZERO_BREAK(
|
|
|
|
|
unhandled_error_context,
|
2026-05-06 23:18:42 -04:00
|
|
|
akgl_actor_rendered,
|
2026-05-03 23:57:55 -04:00
|
|
|
AKERR_BEHAVIOR,
|
2025-08-03 10:07:35 -04:00
|
|
|
"actor->renderfunc not called by the iterator"
|
|
|
|
|
);
|
|
|
|
|
} CLEANUP {
|
|
|
|
|
UNHANDLED_ERROR_BEHAVIOR = UNHANDLED_ERROR_EXIT;
|
2026-05-06 23:18:42 -04:00
|
|
|
IGNORE(akgl_heap_release_actor(testactor));
|
2025-08-03 10:07:35 -04:00
|
|
|
} PROCESS(unhandled_error_context) {
|
|
|
|
|
} FINISH(unhandled_error_context, true);
|
|
|
|
|
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_handler_unhandled_error = defaulthandler;
|
2025-08-03 10:07:35 -04:00
|
|
|
|
|
|
|
|
SUCCEED_RETURN(errctx);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-06 23:18:42 -04:00
|
|
|
akerr_ErrorContext *test_akgl_actor_set_character(void)
|
2025-08-03 10:07:35 -04:00
|
|
|
{
|
2026-05-06 23:18:42 -04:00
|
|
|
akgl_Actor *testactor = NULL;
|
|
|
|
|
akgl_Character *testchar = NULL;
|
2025-08-03 10:07:35 -04:00
|
|
|
|
|
|
|
|
PREPARE_ERROR(errctx);
|
|
|
|
|
|
|
|
|
|
ATTEMPT {
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_actor_set_character(NULL, "test"));
|
2025-08-03 10:07:35 -04:00
|
|
|
} CLEANUP {
|
|
|
|
|
} PROCESS(errctx) {
|
2026-05-03 23:57:55 -04:00
|
|
|
} HANDLE(errctx, AKERR_NULLPOINTER) {
|
2025-08-03 10:07:35 -04:00
|
|
|
printf("Handled\n");
|
|
|
|
|
} FINISH(errctx, true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ATTEMPT {
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_heap_next_actor(&testactor));
|
2025-08-03 10:07:35 -04:00
|
|
|
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_actor_initialize(testactor, "test"));
|
2025-08-03 10:07:35 -04:00
|
|
|
testactor->layer = 0;
|
2026-05-06 23:18:42 -04:00
|
|
|
testactor->updatefunc = &akgl_actor_update_noop;
|
|
|
|
|
testactor->renderfunc = &akgl_actor_render_noop;
|
2025-08-03 10:07:35 -04:00
|
|
|
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_actor_set_character(testactor, "test"));
|
2025-08-03 10:07:35 -04:00
|
|
|
} CLEANUP {
|
2026-05-06 23:18:42 -04:00
|
|
|
IGNORE(akgl_heap_release_actor(testactor));
|
2025-08-03 10:07:35 -04:00
|
|
|
} PROCESS(errctx) {
|
2026-05-03 23:57:55 -04:00
|
|
|
} HANDLE(errctx, AKERR_NULLPOINTER) {
|
2025-08-03 10:07:35 -04:00
|
|
|
printf("Handled\n");
|
|
|
|
|
} FINISH(errctx, true);
|
|
|
|
|
|
|
|
|
|
ATTEMPT {
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_heap_next_actor(&testactor));
|
|
|
|
|
CATCH(errctx, akgl_heap_next_character(&testchar));
|
2025-08-03 10:07:35 -04:00
|
|
|
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_actor_initialize(testactor, "test"));
|
2025-08-03 10:07:35 -04:00
|
|
|
testactor->layer = 0;
|
2026-05-06 23:18:42 -04:00
|
|
|
testactor->updatefunc = &akgl_actor_update_noop;
|
|
|
|
|
testactor->renderfunc = &akgl_actor_render_noop;
|
2025-08-03 10:07:35 -04:00
|
|
|
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_character_initialize(testchar, "test"));
|
2025-08-03 10:07:35 -04:00
|
|
|
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_actor_set_character(testactor, "test"));
|
2025-08-03 10:07:35 -04:00
|
|
|
} CLEANUP {
|
2026-05-06 23:18:42 -04:00
|
|
|
IGNORE(akgl_heap_release_actor(testactor));
|
|
|
|
|
IGNORE(akgl_heap_release_character(testchar));
|
2025-08-03 10:07:35 -04:00
|
|
|
} PROCESS(errctx) {
|
|
|
|
|
} FINISH(errctx, true);
|
|
|
|
|
|
|
|
|
|
SUCCEED_RETURN(errctx);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-03 23:57:55 -04:00
|
|
|
akerr_ErrorContext *test_actor_manage_children(void)
|
2025-08-03 10:07:35 -04:00
|
|
|
{
|
2026-05-06 23:18:42 -04:00
|
|
|
akgl_Actor *parent = NULL;
|
|
|
|
|
akgl_Actor *child = NULL;
|
|
|
|
|
akgl_String *tmpstring = NULL;
|
2025-08-03 10:07:35 -04:00
|
|
|
int i = 0;
|
|
|
|
|
int j = 0;
|
|
|
|
|
PREPARE_ERROR(errctx);
|
|
|
|
|
|
|
|
|
|
ATTEMPT {
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_heap_init());
|
|
|
|
|
CATCH(errctx, akgl_heap_next_string(&tmpstring));
|
|
|
|
|
CATCH(errctx, akgl_heap_next_actor(&parent));
|
|
|
|
|
CATCH(errctx, akgl_actor_initialize(parent, "parent"));
|
|
|
|
|
for ( i = 0 ; i < AKGL_ACTOR_MAX_CHILDREN; i++ ) {
|
2025-08-03 10:07:35 -04:00
|
|
|
sprintf((char *)&tmpstring->data, "child %d", i);
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_heap_next_actor(&child));
|
|
|
|
|
CATCH(errctx, akgl_actor_initialize(child, (char *)&tmpstring->data));
|
2025-08-03 10:07:35 -04:00
|
|
|
CATCH(errctx, parent->addchild(parent, child));
|
|
|
|
|
// Release our claim on the actor so the parent can own the child and kill it
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_heap_release_actor(child));
|
2025-08-03 10:07:35 -04:00
|
|
|
}
|
|
|
|
|
} CLEANUP {
|
2026-05-06 23:18:42 -04:00
|
|
|
IGNORE(akgl_heap_release_string(tmpstring));
|
2025-08-03 10:07:35 -04:00
|
|
|
} PROCESS(errctx) {
|
|
|
|
|
} FINISH(errctx, true);
|
|
|
|
|
|
|
|
|
|
ATTEMPT {
|
|
|
|
|
// Doesn't matter which child we use for this test
|
|
|
|
|
child = parent->children[1];
|
|
|
|
|
CATCH(errctx, parent->addchild(parent, child));
|
|
|
|
|
} CLEANUP {
|
|
|
|
|
if ( errctx == NULL ) {
|
2026-05-03 23:57:55 -04:00
|
|
|
FAIL(errctx, AKERR_BEHAVIOR, "addchild does not throw AKERR_RELATIONSHIP when child already has a parent");
|
2025-08-03 10:07:35 -04:00
|
|
|
}
|
|
|
|
|
} PROCESS(errctx) {
|
2026-05-03 23:57:55 -04:00
|
|
|
} HANDLE(errctx, AKERR_RELATIONSHIP) {
|
2025-08-03 10:07:35 -04:00
|
|
|
// Expected behavior
|
2026-05-03 23:57:55 -04:00
|
|
|
SDL_Log("addchild throws AKERR_RELATIONSHIP when child already has a parent");
|
2025-08-03 10:07:35 -04:00
|
|
|
} FINISH(errctx, true);
|
|
|
|
|
|
|
|
|
|
ATTEMPT {
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_heap_next_actor(&child));
|
2025-08-03 10:07:35 -04:00
|
|
|
CATCH(errctx, parent->addchild(parent, child));
|
|
|
|
|
} CLEANUP {
|
|
|
|
|
if ( errctx == NULL ) {
|
2026-05-03 23:57:55 -04:00
|
|
|
FAIL(errctx, AKERR_BEHAVIOR, "addchild does not throw AKERR_OUTOFBOUNDS when all children already set");
|
2025-08-03 10:07:35 -04:00
|
|
|
}
|
|
|
|
|
} PROCESS(errctx) {
|
2026-05-03 23:57:55 -04:00
|
|
|
} HANDLE(errctx, AKERR_OUTOFBOUNDS) {
|
2025-08-03 10:07:35 -04:00
|
|
|
// Expected behavior
|
2026-05-03 23:57:55 -04:00
|
|
|
SDL_Log("addchild throws AKERR_OUTOFBOUNDS when all children already set");
|
2025-08-03 10:07:35 -04:00
|
|
|
} FINISH(errctx, true);
|
|
|
|
|
|
|
|
|
|
ATTEMPT {
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_heap_release_actor(parent));
|
2025-08-03 10:07:35 -04:00
|
|
|
// All actor objects on the heap should be empty now
|
2026-05-06 23:18:42 -04:00
|
|
|
for ( i = 0; i < AKGL_MAX_HEAP_ACTOR; i++) {
|
2026-05-03 23:57:55 -04:00
|
|
|
FAIL_NONZERO_BREAK(errctx, HEAP_ACTOR[i].refcount, AKERR_VALUE, "Actor not properly cleared");
|
|
|
|
|
FAIL_NONZERO_BREAK(errctx, HEAP_ACTOR[i].parent, AKERR_VALUE, "Actor not properly cleared");
|
2026-05-06 23:18:42 -04:00
|
|
|
for ( j = 0 ; j < AKGL_ACTOR_MAX_CHILDREN; j++) {
|
2025-08-03 10:07:35 -04:00
|
|
|
if ( HEAP_ACTOR[i].children[j] != NULL ) {
|
2026-05-03 23:57:55 -04:00
|
|
|
FAIL(errctx, AKERR_VALUE, "Actor not properly cleared");
|
2025-08-03 10:07:35 -04:00
|
|
|
goto _test_actor_addchild_heaprelease_cleanup;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-05-06 23:18:42 -04:00
|
|
|
for ( j = 0; j < AKGL_ACTOR_MAX_CHILDREN; j++) {
|
2025-08-03 10:07:35 -04:00
|
|
|
sprintf((char *)&tmpstring->data, "child %d", i);
|
|
|
|
|
FAIL_NONZERO_BREAK(
|
|
|
|
|
errctx,
|
2026-05-06 23:18:42 -04:00
|
|
|
SDL_GetPointerProperty(AKGL_REGISTRY_ACTOR, (char *)&tmpstring->data, NULL),
|
2026-05-03 23:57:55 -04:00
|
|
|
AKERR_KEY,
|
2025-08-03 10:07:35 -04:00
|
|
|
"Child %s was not removed from the registry",
|
|
|
|
|
(char *)&tmpstring->data);
|
|
|
|
|
}
|
|
|
|
|
_test_actor_addchild_heaprelease_cleanup:
|
|
|
|
|
} CLEANUP {
|
|
|
|
|
} PROCESS(errctx) {
|
|
|
|
|
} FINISH(errctx, true);
|
|
|
|
|
|
|
|
|
|
ATTEMPT {
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_heap_next_actor(&parent));
|
|
|
|
|
CATCH(errctx, akgl_actor_initialize(parent, "parent"));
|
|
|
|
|
CATCH(errctx, akgl_heap_next_actor(&child));
|
|
|
|
|
CATCH(errctx, akgl_actor_initialize(child, "child"));
|
2025-08-03 10:07:35 -04:00
|
|
|
// Don't release our claim on the child. The child should not be reclaimed.
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_heap_release_actor(parent));
|
2026-05-03 23:57:55 -04:00
|
|
|
FAIL_NONZERO_BREAK(errctx, child->parent, AKERR_VALUE, "Child still references released parent");
|
|
|
|
|
FAIL_ZERO_BREAK(errctx, child->refcount, AKERR_VALUE, "Child prematurely released");
|
|
|
|
|
FAIL_NONZERO_BREAK(errctx, strcmp(child->name, "child"), AKERR_VALUE, "Child had identity erased");
|
2025-08-03 10:07:35 -04:00
|
|
|
FAIL_ZERO_BREAK(
|
|
|
|
|
errctx,
|
2026-05-06 23:18:42 -04:00
|
|
|
(child == SDL_GetPointerProperty(AKGL_REGISTRY_ACTOR, child->name, NULL)),
|
2026-05-03 23:57:55 -04:00
|
|
|
AKERR_KEY,
|
2025-08-03 10:07:35 -04:00
|
|
|
"Child prematurely removed from the registry");
|
|
|
|
|
// Now we can release the child
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_heap_release_actor(child));
|
2025-08-03 10:07:35 -04:00
|
|
|
} CLEANUP {
|
|
|
|
|
} PROCESS(errctx) {
|
|
|
|
|
} FINISH(errctx, true);
|
|
|
|
|
|
|
|
|
|
SUCCEED_RETURN(errctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(void)
|
|
|
|
|
{
|
2026-05-06 23:18:42 -04:00
|
|
|
akgl_actor_updated = 0;
|
|
|
|
|
akgl_actor_rendered = 0;
|
2025-08-03 10:07:35 -04:00
|
|
|
UNHANDLED_ERROR_BEHAVIOR = UNHANDLED_ERROR_EXIT;
|
|
|
|
|
PREPARE_ERROR(errctx);
|
|
|
|
|
ATTEMPT {
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, akgl_registry_init_actor());
|
|
|
|
|
CATCH(errctx, akgl_registry_init_sprite());
|
|
|
|
|
CATCH(errctx, akgl_registry_init_spritesheet());
|
|
|
|
|
CATCH(errctx, akgl_registry_init_character());
|
2025-08-03 10:07:35 -04:00
|
|
|
|
|
|
|
|
CATCH(errctx, test_registry_actor_iterator_nullpointers());
|
|
|
|
|
CATCH(errctx, test_registry_actor_iterator_missingactor());
|
|
|
|
|
CATCH(errctx, test_registry_actor_iterator_updaterender());
|
2026-05-06 23:18:42 -04:00
|
|
|
CATCH(errctx, test_akgl_actor_set_character());
|
2025-08-03 10:07:35 -04:00
|
|
|
CATCH(errctx, test_actor_manage_children());
|
|
|
|
|
} CLEANUP {
|
|
|
|
|
} PROCESS(errctx) {
|
|
|
|
|
} FINISH_NORETURN(errctx);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|