From 6856e97337ad191d12b590fe58d3d2308d03cf10 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Tue, 9 Nov 2021 00:48:29 -0800 Subject: [PATCH] Cleaning up some assetman code. --- src/file/asset.h | 1 - src/file/assetmanager.c | 305 ++++++++++++++++++++++++---------------- src/file/assetmanager.h | 217 +++++++++++++++++----------- 3 files changed, 315 insertions(+), 208 deletions(-) diff --git a/src/file/asset.h b/src/file/asset.h index 6b4f54b6..9fce4507 100644 --- a/src/file/asset.h +++ b/src/file/asset.h @@ -11,7 +11,6 @@ #include "../display/texture.h" #include "../display/font.h" #include "../script/scripter.h" -#include "xml.h" #if !defined(ASSET_PREFIX) #error Asset Prefix has not been defined. diff --git a/src/file/assetmanager.c b/src/file/assetmanager.c index 3d949a38..a1763706 100644 --- a/src/file/assetmanager.c +++ b/src/file/assetmanager.c @@ -39,10 +39,6 @@ void assetManagerInit(assetmanager_t *manager) { manager->holderCount = 0; } -void assetManagerStart(assetmanager_t *manager) { - threadStart(&manager->thread); -} - float assetManagerProgressGet(assetmanager_t *manager) { float done; uint8_t i; @@ -50,25 +46,43 @@ float assetManagerProgressGet(assetmanager_t *manager) { done = 0.0f; for(i = 0; i < manager->itemCount; i++) { - if(!assetManagerIsItemFinished(manager->items + i)) continue; + if(!assetManagerItemIsFinished(manager->items + i)) continue; done++; } return done / ((float) manager->itemCount); } -bool assetManagerIsItemFinished(assetmanageritem_t *item) { - // Sync done is always done - if(item->state == ASSET_MANAGER_STATE_SYNC_DONE) return true; - // Only check if ASYNC is done. - if(item->state != ASSET_MANAGER_STATE_ASYNC_DONE) return false; - // Does it need to still sync load? - if(ASSET_MANAGER_LOADERS[item->type].loadSync == NULL) return true; - return false; +assetmanagerowner_t assetManagerHolderCreate(assetmanager_t *man) { + uint8_t i; + + // Find first available number. + for(i = 0; i < 0xFF; i++) { + if(arrayFind( + sizeof(assetmanagerowner_t), man->holders, man->holderCount, &i + ) == -1) { + break; + } + } + + man->holders[man->holderCount++] = i; + return i;// No slots left. } +void assetManagerHolderRelease(assetmanager_t *man, assetmanagerowner_t hold) { + int32_t i = arrayFind( + sizeof(assetmanagerowner_t), man->holders, man->holderCount, &hold + ); + if(i == -1) return; + arraySplice(sizeof(uint8_t), man->holders, i, 1, man->holderCount); + man->holderCount--; +} // Thread Management +void assetManagerStart(assetmanager_t *manager) { + threadStart(&manager->thread); +} + int32_t _assetManagerThread(thread_t *thread) { // TODO: Can I allow multiple threads to run? uint8_t i; @@ -141,22 +155,99 @@ void assetManagerUpdate(assetmanager_t *manager) { manager->finished = assetManagerProgressGet(manager) >= 1.0f; } -assetmanageritem_t * assetManagerItemAdd(assetmanager_t *manager) { +assetmanageritem_t * assetManagerItemGet(assetmanager_t *man, char *key) { + uint8_t i; + assetmanageritem_t *item; + + for(i = 0; i < man->itemCount; i++) { + item = man->items + i; + if(strcmp(item->key, key) == 0) return item; + } + + return NULL; +} + +assetmanageritem_t * assetManagerItemAdd(assetmanager_t *manager, char *key) { + // Check if key already exists. assetmanageritem_t *item = manager->items + manager->itemCount++; item->state = ASSET_MANAGER_STATE_PENDING; + memcpy(item->key, key, strlen(key) + 1); + item->holderCount = 0x00; return item; } +uint8_t assetManagerItemGetOrAddHolder( + assetmanageritem_t *item, assetmanagerowner_t owner +) { + uint8_t i, firstEmpty; + firstEmpty = 0xFF; + + for(i = 0; i < item->holderCount; i++) { + if(item->holders[i] == owner) return i; + if(firstEmpty == 0xFF && item->holders[i] == 0xFF) { + firstEmpty = i; + } + } + + if(firstEmpty == 0xFF) firstEmpty = item->holderCount++; + item->holders[firstEmpty] = owner; + return firstEmpty; +} + +bool assetManagerItemIsFinished(assetmanageritem_t *item) { + // Sync done is always done + if(item->state == ASSET_MANAGER_STATE_SYNC_DONE) return true; + // Only check if ASYNC is done. + if(item->state != ASSET_MANAGER_STATE_ASYNC_DONE) return false; + // Does it need to still sync load? + if(ASSET_MANAGER_LOADERS[item->type].loadSync == NULL) return true; + return false; +} + +// Font +assetmanageritem_t * assetManagerLoadFont( + assetmanager_t *manager, assetmanagerowner_t owner, + font_t *font, char *fileName +) { + assetmanageritem_t *item; + item = assetManagerItemGet(manager, fileName); + if(item == NULL) { + item = assetManagerItemAdd(manager, fileName); + item->type = ASSET_MANAGER_TYPE_FONT; + item->data.font.fileName = fileName; + item->data.font.font = font; + } + assetManagerItemGetOrAddHolder(item, owner); + + return item; +} + +bool _assetManagerLoaderFontAsync(assetmanageritem_t *item) { + item->data.font.data = assetStringLoad(item->data.font.fileName); + return item->data.font.data != NULL; +} + +bool _assetManagerLoaderFontSync(assetmanageritem_t *item) { + fontInit(item->data.font.font, item->data.font.data); + free(item->data.font.data); + return true; +} + // Texture assetmanageritem_t * assetManagerLoadTexture( - assetmanager_t *manager, texture_t *texture, char *fileName + assetmanager_t *manager, assetmanagerowner_t owner, + texture_t *texture, char *fileName ) { - assetmanageritem_t *item = assetManagerItemAdd(manager); - - item->type = ASSET_MANAGER_TYPE_TEXTURE; - item->data.texture.fileName = fileName; - item->data.texture.texture = texture; + assetmanageritem_t *item; + item = assetManagerItemGet(manager, fileName); + if(item == NULL) { + item = assetManagerItemAdd(manager, fileName); + item->type = ASSET_MANAGER_TYPE_TEXTURE; + item->data.texture.fileName = fileName; + item->data.texture.texture = texture; + } + assetManagerItemGetOrAddHolder(item, owner); return item; } @@ -202,87 +293,28 @@ bool _assetManagerLoaderTextureSync(assetmanageritem_t *item) { return true; } - -// Font -assetmanageritem_t * assetManagerLoadFont( - assetmanager_t *manager, font_t *font, char *fileName -) { - assetmanageritem_t *item = assetManagerItemAdd(manager); - - item->type = ASSET_MANAGER_TYPE_FONT; - item->data.font.fileName = fileName; - item->data.font.font = font; - - return item; -} - -bool _assetManagerLoaderFontAsync(assetmanageritem_t *item) { - item->data.font.data = assetStringLoad(item->data.font.fileName); - return item->data.font.data != NULL; -} - -bool _assetManagerLoaderFontSync(assetmanageritem_t *item) { - fontInit(item->data.font.font, item->data.font.data); - free(item->data.font.data); - return true; -} - - -// Shader -assetmanageritem_t * assetManagerLoadShader( - assetmanager_t *manager, shader_t *shader, char *fileVert, char *fileFrag -) { - assetmanageritem_t *item = assetManagerItemAdd(manager); - - item->type = ASSET_MANAGER_TYPE_SHADER; - item->data.shader.shader = shader; - item->data.shader.fileVert = fileVert; - item->data.shader.fileFrag = fileFrag; - - return item; -} - -bool _assetManagerLoaderShaderAsync(assetmanageritem_t *item) { - item->data.shader.dataVert = assetStringLoad(item->data.shader.fileVert); - if(item->data.shader.dataVert == NULL) return false; - - item->data.shader.dataFrag = assetStringLoad(item->data.shader.fileFrag); - if(item->data.shader.dataFrag == NULL) { - free(item->data.shader.fileVert); - return false; - } - - return true; -} - -bool _assetManagerLoaderShaderSync(assetmanageritem_t *item) { - shaderInit( - item->data.shader.shader, - item->data.shader.dataVert, - item->data.shader.dataFrag - ); - free(item->data.shader.dataFrag); - free(item->data.shader.dataVert); - return true; -} - - // Scaled Texture assetmanageritem_t * assetManagerLoadScaledTexture( - assetmanager_t *manager, scaledtexture_t *st, char *path, char *file + assetmanager_t *manager, assetmanagerowner_t owner, + scaledtexture_t *st, char *path, char *file ) { - assetmanageritem_t *item = assetManagerItemAdd(manager); + assetmanageritem_t *item; + char buffer[ASSET_MANAGER_ITEM_NAME_MAX]; + sprintf(buffer, "%s/%s", path, file); + item = assetManagerItemGet(manager, buffer); + if(item == NULL) { + item = assetManagerItemAdd(manager, buffer); - item->type = ASSET_MANAGER_TYPE_SCALED_TEXTURE; - item->data.scaledTexture.scaledTexture = st; + item->type = ASSET_MANAGER_TYPE_SCALED_TEXTURE; + item->data.scaledTexture.scaledTexture = st; - // Unlike most other loaded things, here I actually use the MT itself for the - // storage of many variables. - st->scaleCount = 0; - st->baseWidth = 0; - st->baseHeight = 0; - st->path = path; - st->file = file; + st->scaleCount = 0; + st->baseWidth = 0; + st->baseHeight = 0; + st->path = path; + st->file = file; + } + assetManagerItemGetOrAddHolder(item, owner); return item; } @@ -328,18 +360,23 @@ bool _assetManagerLoaderScaledTextureAsync(assetmanageritem_t *item) { return true; } - // Texture Scale assetmanageritem_t * assetManagerLoadTextureScale( - assetmanager_t *manager, scaledtexture_t *st, texture_t *text, uint8_t scale + assetmanager_t *manager, assetmanagerowner_t owner, + scaledtexture_t *st, texture_t *text, uint8_t scale ) { - assetmanageritem_t *item = assetManagerItemAdd(manager); - - item->type = ASSET_MANAGER_TYPE_SCALE_TEXTURE; - item->data.scaleTexture.scale = scale; - item->data.scaleTexture.texture = text; - item->data.scaleTexture.scaledTexture = st; - + assetmanageritem_t *item; + char buffer[ASSET_MANAGER_ITEM_NAME_MAX]; + sprintf(buffer, "%s/%s_%u", st->path, st->file, scale); + item = assetManagerItemGet(manager, buffer); + if(item == NULL) { + item = assetManagerItemAdd(manager, buffer); + item->type = ASSET_MANAGER_TYPE_SCALE_TEXTURE; + item->data.scaleTexture.scale = scale; + item->data.scaleTexture.texture = text; + item->data.scaleTexture.scaledTexture = st; + } + assetManagerItemGetOrAddHolder(item, owner); return item; } @@ -386,24 +423,46 @@ bool _assetManagerLoaderTextureScaleSync(assetmanageritem_t *item) { return true; } - -assetmanagerowner_t assetManagerHolderCreate(assetmanager_t *man) { - uint8_t i; - - // Find first available number. - for(i = 0; i < 0xFF; i++) { - if(arrayFind(sizeof(uint8_t), man->holders, man->holderCount, &i) == -1) { - break; - } +// Shader +assetmanageritem_t * assetManagerLoadShader( + assetmanager_t *manager, assetmanagerowner_t owner, + shader_t *shader, char *fileVert, char *fileFrag +) { + assetmanageritem_t *item; + char buffer[ASSET_MANAGER_ITEM_NAME_MAX]; + sprintf(buffer, "%s/%s", fileVert, fileFrag); + item = assetManagerItemGet(manager, buffer); + if(item == NULL) { + item = assetManagerItemAdd(manager, buffer); + item->type = ASSET_MANAGER_TYPE_SHADER; + item->data.shader.shader = shader; + item->data.shader.fileVert = fileVert; + item->data.shader.fileFrag = fileFrag; } - - man->holders[man->holderCount++] = i; - return i;// No slots left. + assetManagerItemGetOrAddHolder(item, owner); + return item; } -void assetManagerHolderRelease(assetmanager_t *man, assetmanagerowner_t hold) { - uint8_t i = arrayFind(sizeof(uint8_t), man->holders, man->holderCount, &hold); - if(i == -1) return; - arraySplice(sizeof(uint8_t), man->holders, i, 1, man->holderCount); - man->holderCount--; -} \ No newline at end of file +bool _assetManagerLoaderShaderAsync(assetmanageritem_t *item) { + item->data.shader.dataVert = assetStringLoad(item->data.shader.fileVert); + if(item->data.shader.dataVert == NULL) return false; + + item->data.shader.dataFrag = assetStringLoad(item->data.shader.fileFrag); + if(item->data.shader.dataFrag == NULL) { + free(item->data.shader.fileVert); + return false; + } + + return true; +} + +bool _assetManagerLoaderShaderSync(assetmanageritem_t *item) { + shaderInit( + item->data.shader.shader, + item->data.shader.dataVert, + item->data.shader.dataFrag + ); + free(item->data.shader.dataFrag); + free(item->data.shader.dataVert); + return true; +} diff --git a/src/file/assetmanager.h b/src/file/assetmanager.h index 373793af..bd859fb9 100644 --- a/src/file/assetmanager.h +++ b/src/file/assetmanager.h @@ -6,18 +6,19 @@ */ #pragma once -#include "asset.h" -#include "../util/flags.h" -#include "../engine/thread.h" -#include "../display/shader.h" +#include "../libs.h" +#include "../display/font.h" #include "../display/texture.h" #include "../display/scaledtexture.h" -#include "../display/font.h" -#include "../script/scripter.h" +#include "../display/shader.h" +#include "../engine/thread.h" #include "../util/array.h" +#include "asset.h" #include "xml.h" #define ASSET_MANAGER_ITEMS_MAX 64 +#define ASSET_MANAGER_ITEM_NAME_MAX 32 + #define ASSET_MANAGER_HOLDERS_MAX 8 #define ASSET_MANAGER_STATE_PENDING 0x00 @@ -34,7 +35,13 @@ #define ASSET_MANAGER_TYPE_SCALED_TEXTURE 0x03 #define ASSET_MANAGER_TYPE_SCALE_TEXTURE 0x04 -// Types +// Loader Types +typedef struct { + font_t *font; + char *fileName; + char *data; +} assetmanagerfont_t; + typedef struct { texture_t *texture; char *fileName; @@ -42,20 +49,6 @@ typedef struct { pixel_t *data; } assetmanagertexture_t; -typedef struct { - shader_t *shader; - char *fileVert; - char *fileFrag; - char *dataVert; - char *dataFrag; -} assetmanagershader_t; - -typedef struct { - font_t *font; - char *fileName; - char *data; -} assetmanagerfont_t; - typedef struct { scaledtexture_t *scaledTexture; } assetmanagerscaledtexture_t; @@ -67,6 +60,13 @@ typedef struct { pixel_t *data; } assetmanagerscaletexture_t; +typedef struct { + shader_t *shader; + char *fileVert; + char *fileFrag; + char *dataVert; + char *dataFrag; +} assetmanagershader_t; // Item typedef uint8_t assetmanagerowner_t; @@ -82,11 +82,12 @@ typedef union { typedef struct { uint8_t type; uint8_t state; + char key[ASSET_MANAGER_ITEM_NAME_MAX]; assetmanagerassetdata_t data; assetmanagerowner_t holders[ASSET_MANAGER_HOLDERS_MAX]; + uint8_t holderCount; } assetmanageritem_t; - // Loader typedef bool assetmanagerloader_t(assetmanageritem_t *item); @@ -95,21 +96,19 @@ typedef struct { assetmanagerloader_t *loadSync; } assetmanagerloaderdefinition_t; - // Manager typedef struct { thread_t thread; + bool finished; assetmanageritem_t items[ASSET_MANAGER_ITEMS_MAX]; uint8_t itemCount; - bool finished; - assetmanagerowner_t holders[ASSET_MANAGER_HOLDERS_MAX]; uint8_t holderCount; } assetmanager_t; +// Constants extern assetmanagerloaderdefinition_t ASSET_MANAGER_LOADERS[]; - /** * Initialize the asset manager * @@ -117,30 +116,6 @@ extern assetmanagerloaderdefinition_t ASSET_MANAGER_LOADERS[]; */ void assetManagerInit(assetmanager_t *manager); -/** - * Begin asynchronously loading all of the assets - * - * @param manager Manager to begin async loading. - */ -void assetManagerStart(assetmanager_t *manager); - -/** - * Synchronously tick the asset manager. Some assets require some form of sync - * operations, such as buffering to the GPU, so make sure this is called at a - * good time for that task, such as right at the end of a frame. - * - * @param manager Manager to synchronously tick. - */ -void assetManagerUpdate(assetmanager_t *manager); - -/** - * Returns whether or not the given item is finished. - * - * @param item Item to check state of. - * @return True if finished, otherwise false. - */ -bool assetManagerIsItemFinished(assetmanageritem_t *item); - /** * Gets the progress of the asset manager as a representation of 0-1 as a % that * has loaded. @@ -150,82 +125,156 @@ bool assetManagerIsItemFinished(assetmanageritem_t *item); */ float assetManagerProgressGet(assetmanager_t *manager); +uint8_t assetManagerHolderCreate(assetmanager_t *man); +void assetManagerHolderRelease(assetmanager_t *man, uint8_t hold); + +//////////////////////////////////////////////////////////////////////////////// + +/** + * Begin asynchronously loading all of the assets + * + * @param manager Manager to begin async loading. + */ +void assetManagerStart(assetmanager_t *manager); + /** Private Thread that is executed asynchronously */ int32_t _assetManagerThread(thread_t *thread); +/** + * Synchronously tick the asset manager. Some assets require some form of sync + * operations, such as buffering to the GPU, so make sure this is called at a + * good time for that task, such as right at the end of a frame. + * + * @param manager Manager to synchronously tick. + */ +void assetManagerUpdate(assetmanager_t *manager); + +//////////////////////////////////////////////////////////////////////////////// + +/** + * Retreive an exisitng asset manager item by its key. + * + * @param man Manager to get from + * @param key Key to search for. + * @return The matching asset manager item, or NULL if not found. + */ +assetmanageritem_t * assetManagerItemGet(assetmanager_t *man, char *key); + /** * Private method, simply adds an item to the manager and resets the state. * * @param manager Manager to add to. + * @param key Key to use when adding. * @return The added and reset item. */ -assetmanageritem_t * assetManagerItemAdd(assetmanager_t *manager); +assetmanageritem_t * assetManagerItemAdd(assetmanager_t *manager, char *key); /** - * Queue a texture load onto the asset manager buffer. + * Add or get the index that a given holder has as a manager item. * - * @param manager Manager to queue on to. - * @param texture Texture to push the result in to. - * @param fileName Texture filename to load. - * @return A pointer to the asset manager item for tracking. + * @param i Asset Item to check. + * @param o Owner to get/add. + * @return The index within the item that the owner is at. */ -assetmanageritem_t * assetManagerLoadTexture( - assetmanager_t *manager, texture_t *texture, char *fileName +uint8_t assetManagerItemGetOrAddHolder( + assetmanageritem_t *i, assetmanagerowner_t o ); -bool _assetManagerLoaderTextureAsync(assetmanageritem_t *item); -bool _assetManagerLoaderTextureSync(assetmanageritem_t *item); +/** + * Checks if a given asset item is finished or not. + * + * @param item Item to check. + * @return True if finished, otherwise false. + */ +bool assetManagerItemIsFinished(assetmanageritem_t *item); + +//////////////////////////////////////////////////////////////////////////////// /** * Queue a font load onto the asset manager buffer. * * @param manager Manager to queue on to. + * @param owner Owner ID requesting to load this resource. * @param font Font to push the result in to. * @param fileName Filename of the asset to load. * @return A pointer to the asset manager item for tracking. */ assetmanageritem_t * assetManagerLoadFont( - assetmanager_t *manager, font_t *font, char *fileName + assetmanager_t *manager, assetmanagerowner_t owner, + font_t *font, char *fileName ); bool _assetManagerLoaderFontAsync(assetmanageritem_t *item); bool _assetManagerLoaderFontSync(assetmanageritem_t *item); +/** + * Queue a texture load onto the asset manager buffer. + * + * @param manager Manager to queue on to. + * @param owner Owner ID requesting to load this resource. + * @param texture Texture to push the result in to. + * @param fileName Texture filename to load. + * @return A pointer to the asset manager item for tracking. + */ +assetmanageritem_t * assetManagerLoadTexture( + assetmanager_t *manager, assetmanagerowner_t owner, + texture_t *texture, char *fileName +); + +bool _assetManagerLoaderTextureAsync(assetmanageritem_t *item); +bool _assetManagerLoaderTextureSync(assetmanageritem_t *item); + +/** + * Queue a scaled texture load asset to the asset manager buffer. This will not + * actually load the texture, just the scaled texture information. + * + * @param manager Manager to queue on to. + * @param owner Owner ID requesting to load this resource. + * @param mt Scaled Texture to load in to. + * @param path Path of the texture files + * @param file File name of the texture sets. + * @return A pointer to the asset manager item for tracking. + */ +assetmanageritem_t * assetManagerLoadScaledTexture( + assetmanager_t *manager, assetmanagerowner_t owner, + scaledtexture_t *st, char *path, char *file +); + +bool _assetManagerLoaderScaledTextureAsync(assetmanageritem_t *item); + +/** + * Load the given texture scale for a scaled texture. + * + * @param manager Manager to queue on to. + * @param owner Owner ID requesting to load this resource. + * @param st Scaled Texture to load in to. + * @param text Texture to load the scale in to. + * @param scale Scale to load. + * @return A pointer to the asset manager item for tracking. + */ +assetmanageritem_t * assetManagerLoadTextureScale( + assetmanager_t *manager, assetmanagerowner_t owner, + scaledtexture_t *st, texture_t *text, uint8_t scale +); + +bool _assetManagerLoaderTextureScaleAsync(assetmanageritem_t *item); +bool _assetManagerLoaderTextureScaleSync(assetmanageritem_t *item); + /** * Queues a shader load onto the asset manager buffer. * * @param manager Manager to queue on to. + * @param owner Owner ID requesting to load this resource. * @param shader Shader to push the result in to. * @param fileVert Vertex file in question to load. * @param fileFrag Fragment file in question to load. * @return A pointer to the asset manager item for tracking. */ assetmanageritem_t * assetManagerLoadShader( - assetmanager_t *manager, shader_t *shader, char *fileVert, char *fileFrag + assetmanager_t *manager, assetmanagerowner_t owner, + shader_t *shader, char *fileVert, char *fileFrag ); bool _assetManagerLoaderShaderAsync(assetmanageritem_t *item); bool _assetManagerLoaderShaderSync(assetmanageritem_t *item); - -assetmanageritem_t * assetManagerLoadScaledTexture( - assetmanager_t *manager, scaledtexture_t *mt, char *path, char *file -); - -bool _assetManagerLoaderScaledTextureAsync(assetmanageritem_t *item); - - - - -assetmanageritem_t * assetManagerLoadTextureScale( - assetmanager_t *manager, scaledtexture_t *st, texture_t *text, uint8_t scale -); - -bool _assetManagerLoaderTextureScaleAsync(assetmanageritem_t *item); -bool _assetManagerLoaderTextureScaleSync(assetmanageritem_t *item); - - - - -uint8_t assetManagerHolderCreate(assetmanager_t *man); -void assetManagerHolderRelease(assetmanager_t *man, uint8_t hold); \ No newline at end of file