195 lines
5.6 KiB
C
195 lines
5.6 KiB
C
#include <stdlib.h>
|
|
#include <akerror.h>
|
|
|
|
#include <sdl3game/game.h>
|
|
#include <sdl3game/sprite.h>
|
|
#include <sdl3game/heap.h>
|
|
#include <sdl3game/registry.h>
|
|
#include <sdl3game/staticstring.h>
|
|
#include <sdl3game/iterator.h>
|
|
#include <sdl3game/error.h>
|
|
|
|
akgl_Actor HEAP_ACTOR[AKGL_MAX_HEAP_ACTOR];
|
|
akgl_Sprite HEAP_SPRITE[AKGL_MAX_HEAP_SPRITE];
|
|
akgl_SpriteSheet HEAP_SPRITESHEET[AKGL_MAX_HEAP_SPRITESHEET];
|
|
akgl_Character HEAP_CHARACTER[AKGL_MAX_HEAP_CHARACTER];
|
|
akgl_String HEAP_STRING[AKGL_MAX_HEAP_STRING];
|
|
|
|
akerr_ErrorContext *akgl_heap_init()
|
|
{
|
|
PREPARE_ERROR(errctx);
|
|
int i = 0;
|
|
akerr_name_for_status(AKGL_ERR_SDL, "SDL Error");
|
|
for ( i = 0; i < AKGL_MAX_HEAP_ACTOR; i++) {
|
|
memset(&HEAP_ACTOR[i], 0x00, sizeof(akgl_Actor));
|
|
}
|
|
for ( i = 0; i < AKGL_MAX_HEAP_SPRITE; i++) {
|
|
memset(&HEAP_SPRITE[i], 0x00, sizeof(akgl_Sprite));
|
|
}
|
|
for ( i = 0; i < AKGL_MAX_HEAP_SPRITESHEET; i++) {
|
|
memset(&HEAP_SPRITESHEET[i], 0x00, sizeof(akgl_SpriteSheet));
|
|
}
|
|
for ( i = 0; i < AKGL_MAX_HEAP_CHARACTER; i++) {
|
|
memset(&HEAP_CHARACTER[i], 0x00, sizeof(akgl_Character));
|
|
}
|
|
for ( i = 0; i < AKGL_MAX_HEAP_STRING; i++) {
|
|
memset(&HEAP_STRING[i], 0x00, sizeof(akgl_String));
|
|
}
|
|
SUCCEED_RETURN(errctx);
|
|
}
|
|
|
|
akerr_ErrorContext *akgl_heap_next_actor(akgl_Actor **dest)
|
|
{
|
|
PREPARE_ERROR(errctx);
|
|
for (int i = 0; i < AKGL_MAX_HEAP_ACTOR; i++ ) {
|
|
if ( HEAP_ACTOR[i].refcount != 0 ) {
|
|
continue;
|
|
}
|
|
*dest = &HEAP_ACTOR[i];
|
|
SUCCEED_RETURN(errctx);
|
|
}
|
|
FAIL_RETURN(errctx, AKERR_HEAP, "Unable to find unused actor on the heap");
|
|
}
|
|
|
|
akerr_ErrorContext *akgl_heap_next_sprite(akgl_Sprite **dest)
|
|
{
|
|
PREPARE_ERROR(errctx);
|
|
for (int i = 0; i < AKGL_MAX_HEAP_SPRITE; i++ ) {
|
|
if ( HEAP_SPRITE[i].refcount != 0 ) {
|
|
continue;
|
|
}
|
|
*dest = &HEAP_SPRITE[i];
|
|
SUCCEED_RETURN(errctx);
|
|
}
|
|
FAIL_RETURN(errctx, AKERR_HEAP, "Unable to find unused sprite on the heap");
|
|
}
|
|
|
|
akerr_ErrorContext *akgl_heap_next_spritesheet(akgl_SpriteSheet **dest)
|
|
{
|
|
PREPARE_ERROR(errctx);
|
|
for (int i = 0; i < AKGL_MAX_HEAP_SPRITESHEET; i++ ) {
|
|
if ( HEAP_SPRITESHEET[i].refcount != 0 ) {
|
|
continue;
|
|
}
|
|
*dest = &HEAP_SPRITESHEET[i];
|
|
SUCCEED_RETURN(errctx);
|
|
}
|
|
FAIL_RETURN(errctx, AKERR_HEAP, "Unable to find unused spritesheet on the heap");
|
|
}
|
|
|
|
akerr_ErrorContext *akgl_heap_next_character(akgl_Character **dest)
|
|
{
|
|
PREPARE_ERROR(errctx);
|
|
for (int i = 0; i < AKGL_MAX_HEAP_CHARACTER; i++ ) {
|
|
if ( HEAP_CHARACTER[i].refcount != 0 ) {
|
|
continue;
|
|
}
|
|
*dest = &HEAP_CHARACTER[i];
|
|
SUCCEED_RETURN(errctx);
|
|
}
|
|
FAIL_RETURN(errctx, AKERR_HEAP, "Unable to find unused character on the heap");
|
|
}
|
|
|
|
akerr_ErrorContext *akgl_heap_next_string(akgl_String **dest)
|
|
{
|
|
PREPARE_ERROR(errctx);
|
|
for (int i = 0; i < AKGL_MAX_HEAP_STRING; i++ ) {
|
|
if ( HEAP_STRING[i].refcount != 0 ) {
|
|
continue;
|
|
}
|
|
*dest = &HEAP_STRING[i];
|
|
SUCCEED_RETURN(errctx);
|
|
}
|
|
FAIL_RETURN(errctx, AKERR_HEAP, "Unable to find unused string on the heap");
|
|
}
|
|
|
|
akerr_ErrorContext *akgl_heap_release_actor(akgl_Actor *ptr)
|
|
{
|
|
int i = 0;
|
|
PREPARE_ERROR(errctx);
|
|
FAIL_ZERO_RETURN(errctx, ptr, AKERR_NULLPOINTER, "NULL actor reference");
|
|
if ( ptr->refcount > 0 ) {
|
|
ptr->refcount -= 1;
|
|
}
|
|
if ( ptr->refcount == 0 ) {
|
|
for ( i = 0; i < AKGL_ACTOR_MAX_CHILDREN; i++ ) {
|
|
if ( ptr->children[i] != NULL ) {
|
|
CATCH_AND_RETURN(errctx, akgl_heap_release_actor(ptr->children[i]));
|
|
}
|
|
}
|
|
if ( ptr->basechar != NULL ) {
|
|
CATCH_AND_RETURN(errctx, akgl_heap_release_character(ptr->basechar));
|
|
}
|
|
memset(ptr, 0x00, sizeof(akgl_Actor));
|
|
SDL_ClearProperty(AKGL_REGISTRY_ACTOR, (char *)&ptr->name);
|
|
}
|
|
SUCCEED_RETURN(errctx);
|
|
}
|
|
|
|
akerr_ErrorContext *akgl_heap_release_character(akgl_Character *basechar)
|
|
{
|
|
PREPARE_ERROR(errctx);
|
|
akgl_Iterator opflags;
|
|
FAIL_ZERO_RETURN(errctx, basechar, AKERR_NULLPOINTER, "NULL character reference");
|
|
AKGL_BITMASK_CLEAR(opflags.flags);
|
|
AKGL_BITMASK_ADD(opflags.flags, AKGL_ITERATOR_OP_RELEASE);
|
|
|
|
if ( basechar->refcount > 0 ) {
|
|
basechar->refcount -= 1;
|
|
}
|
|
if ( basechar->refcount == 0 ) {
|
|
SDL_EnumerateProperties(basechar->state_sprites, &akgl_character_state_sprites_iterate, (void *)&opflags);
|
|
SDL_ClearProperty(AKGL_REGISTRY_CHARACTER, (char *)&basechar->name);
|
|
}
|
|
SUCCEED_RETURN(errctx);
|
|
}
|
|
|
|
akerr_ErrorContext *akgl_heap_release_sprite(akgl_Sprite *ptr)
|
|
{
|
|
PREPARE_ERROR(errctx);
|
|
FAIL_ZERO_RETURN(errctx, ptr, AKERR_NULLPOINTER, "Received NULL sprite reference");
|
|
if ( ptr->refcount > 0 ) {
|
|
ptr->refcount -= 1;
|
|
}
|
|
if ( ptr->refcount == 0 ) {
|
|
ATTEMPT {
|
|
CATCH(errctx, akgl_heap_release_spritesheet(ptr->sheet));
|
|
} CLEANUP {
|
|
SDL_ClearProperty(AKGL_REGISTRY_SPRITE, (char *)&ptr->name);
|
|
} PROCESS(errctx) {
|
|
} FINISH(errctx, true);
|
|
}
|
|
SUCCEED_RETURN(errctx);
|
|
}
|
|
|
|
akerr_ErrorContext *akgl_heap_release_spritesheet(akgl_SpriteSheet *ptr)
|
|
{
|
|
PREPARE_ERROR(errctx);
|
|
FAIL_ZERO_RETURN(errctx, ptr, AKERR_NULLPOINTER, "Received NULL spritesheet reference");
|
|
if ( ptr->refcount > 0 ) {
|
|
ptr->refcount -= 1;
|
|
}
|
|
if ( ptr->refcount == 0 ) {
|
|
// TODO : If we go threaded, make sure this is only happening on the main thread
|
|
SDL_ClearProperty(AKGL_AKGL_REGISTRY_SPRITESHEET, (char *)&ptr->name);
|
|
if ( ptr-> texture != NULL )
|
|
SDL_DestroyTexture(ptr->texture);
|
|
ptr->texture = NULL;
|
|
}
|
|
SUCCEED_RETURN(errctx);
|
|
}
|
|
|
|
akerr_ErrorContext *akgl_heap_release_string(akgl_String *ptr)
|
|
{
|
|
PREPARE_ERROR(errctx);
|
|
FAIL_ZERO_RETURN(errctx, ptr, AKERR_NULLPOINTER, "Received NULL string reference");
|
|
if ( ptr->refcount > 0 ) {
|
|
ptr->refcount -= 1;
|
|
}
|
|
if ( ptr->refcount == 0 ) {
|
|
memset(&ptr->data, 0x00, AKGL_MAX_STRING_LENGTH);
|
|
}
|
|
SUCCEED_RETURN(errctx);
|
|
}
|
|
|