Technically refactored.

This commit is contained in:
2021-11-14 22:42:10 -08:00
parent 54d01b5ed6
commit 9b4acae63c
74 changed files with 1161 additions and 744 deletions

View File

@ -25,13 +25,8 @@ assetmanagerloaderdefinition_t ASSET_MANAGER_LOADERS[] = {
},
{
&_assetManagerLoaderScaledTextureAsync,
NULL,
NULL
},
{
&_assetManagerLoaderTextureScaleAsync,
&_assetManagerLoaderTextureScaleSync,
&_assetManagerLoaderTextureScaleDispose
&_assetManagerLoaderScaledTextureSync,
&_assetManagerLoaderScaledTextureDispose
}
};
@ -48,15 +43,42 @@ void assetManagerInit(assetmanager_t *manager) {
float assetManagerProgressGet(assetmanager_t *manager) {
float done;
uint8_t i;
assetmanageritem_t *item;
done = 0.0f;
for(i = 0; i < manager->itemCount; i++) {
if(!assetManagerItemIsFinished(manager->items + i)) continue;
done++;
item = manager->items + i;
done += assetManagerItemIsFinished(
item, ASSET_MANAGER_LOADERS + item->type
) ? 1 : 0;
}
return done / ((float)manager->itemCount);
}
return done / ((float) manager->itemCount);
float assetManagerProgressGetForHolder(
assetmanager_t *manager, assetmanagerowner_t hold
) {
float done;
uint8_t i, j, c;
assetmanageritem_t *item;
done = 0.0f;
c = 0x00;
for(i = 0; i < manager->itemCount; i++) {
//Is this held by this holder?
item = manager->items + i;
for(j = 0; j < item->holderCount; j++) {
if(item->holders[j] != hold) continue;
c++;
done += assetManagerItemIsFinished(
item, ASSET_MANAGER_LOADERS + item->type
) ? 1 : 0;
break;
}
}
// Is this thing even holding any assets to begin with?
if(c == 0x00) return 1.0f;
return done / (float)c;
}
assetmanagerowner_t assetManagerHolderCreate(assetmanager_t *man) {
@ -215,328 +237,4 @@ void assetManagerUpdate(assetmanager_t *manager) {
}
manager->finished = assetManagerProgressGet(manager) >= 1.0f;
}
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_NOT_READY;
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, 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;
}
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;
}
bool _assetManagerLoaderFontDispose(assetmanageritem_t *item) {
fontDispose(&item->data.font.font);
return true;
}
// Texture
assetmanageritem_t * assetManagerLoadTexture(
assetmanager_t *manager, assetmanagerowner_t owner, char *fileName
) {
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;
}
assetManagerItemGetOrAddHolder(item, owner);
return item;
}
bool _assetManagerLoaderTextureAsync(assetmanageritem_t *item) {
assetbuffer_t *buffer;
int channels;
stbi_io_callbacks OPENGL_STBI_CALLBACKS;
buffer = assetBufferOpen(item->data.texture.fileName);
if(buffer == NULL) return false;
// Setup the interface for STBI
OPENGL_STBI_CALLBACKS.read = &assetBufferRead;
OPENGL_STBI_CALLBACKS.skip = &assetBufferSkip;
OPENGL_STBI_CALLBACKS.eof = &assetBufferEnd;
// Buffer the image
channels = 0;
item->data.texture.data = (pixel_t *)stbi_load_from_callbacks(
&OPENGL_STBI_CALLBACKS, buffer,
&item->data.texture.width, &item->data.texture.height,
&channels, STBI_rgb_alpha
);
// Close the buffer
assetBufferClose(buffer);
if(item->data.texture.data == NULL) return false;
return true;
}
bool _assetManagerLoaderTextureSync(assetmanageritem_t *item) {
// Turn into a texture.
textureInit(
&item->data.texture.texture,
item->data.texture.width,
item->data.texture.height,
item->data.texture.data
);
// Cleanup
stbi_image_free(item->data.texture.data);
return true;
}
bool _assetManagerLoaderTextureDispose(assetmanageritem_t *item) {
textureDispose(&item->data.texture.texture);
return true;
}
// Scaled Texture
assetmanageritem_t * assetManagerLoadScaledTexture(
assetmanager_t *manager, assetmanagerowner_t owner, char *path, char *file
) {
assetmanageritem_t *item;
scaledtexture_t *st;
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;
st = &item->data.scaledTexture.scaledTexture;
st->scaleCount = 0;
st->baseWidth = 0;
st->baseHeight = 0;
st->path = path;
st->file = file;
}
assetManagerItemGetOrAddHolder(item, owner);
return item;
}
bool _assetManagerLoaderScaledTextureAsync(assetmanageritem_t *item) {
char buffer[128];
char *xmlData;
xml_t xml;
xml_t *child;
int16_t i, j;
scaledtexture_t *st;
st = &item->data.scaledTexture.scaledTexture;
// Begin loading texture XML
sprintf(buffer, "%s/%s.xml", st->path, st->file);
xmlData = assetStringLoad(buffer);
if(xmlData == NULL) return false;
xmlLoad(&xml, xmlData);
free(xmlData);
// Parse root texture info
i = xmlGetAttributeByName(&xml, "channels");
st->channels = (uint8_t)atoi(xml.attributeDatas[i]);
i = xmlGetAttributeByName(&xml, "width");
st->baseWidth = (int16_t)atoi(xml.attributeDatas[i]);
i = xmlGetAttributeByName(&xml, "height");
st->baseHeight = (int16_t)atoi(xml.attributeDatas[i]);
for(j = 0; j < xml.childrenCount; j++) {
child = xml.children + j;
i = xmlGetAttributeByName(child, "scale");
st->scales[st->scaleCount].scale = (uint8_t)atoi(child->attributeDatas[i]);
i = xmlGetAttributeByName(child, "width");
st->scales[st->scaleCount].width = (int16_t)atoi(child->attributeDatas[i]);
i = xmlGetAttributeByName(child, "height");
st->scales[st->scaleCount].height = (int16_t)atoi(child->attributeDatas[i]);
st->scaleCount++;
}
// Cleanup XML
xmlDispose(&xml);
return true;
}
// Texture Scale
assetmanageritem_t * assetManagerLoadTextureScale(
assetmanager_t *manager, assetmanagerowner_t owner,
scaledtexture_t *st, uint8_t scale
) {
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.scaledTexture = st;
}
assetManagerItemGetOrAddHolder(item, owner);
return item;
}
bool _assetManagerLoaderTextureScaleAsync(assetmanageritem_t *item) {
char buffer[128];
scaledtexture_t *st;
scaledtexturescale_t *sts;
size_t length;
st = item->data.scaleTexture.scaledTexture;
sts = st->scales + item->data.scaleTexture.scale;
// Get filename
sprintf(buffer, "%s/%s_%i.texture", st->path, st->file, sts->scale);
// Create some space
length = assetRawLoad(buffer, NULL);
if(length == 0) return false;
item->data.scaleTexture.data = malloc(sizeof(pixel_t) * length);
// Load
length = assetRawLoad(buffer, (uint8_t *)item->data.scaleTexture.data);
if(length == 0) {
free(item->data.scaleTexture.data);
return false;
}
return true;
}
bool _assetManagerLoaderTextureScaleSync(assetmanageritem_t *item) {
scaledtexture_t *st;
scaledtexturescale_t *sts;
st = item->data.scaleTexture.scaledTexture;
sts = st->scales + item->data.scaleTexture.scale;
textureInit(
&item->data.scaleTexture.texture,
sts->width, sts->height,
item->data.scaleTexture.data
);
free(item->data.scaleTexture.data);
return true;
}
bool _assetManagerLoaderTextureScaleDispose(assetmanageritem_t *item) {
textureDispose(&item->data.scaleTexture.texture);
return true;
}
// Shader
assetmanageritem_t * assetManagerLoadShader(
assetmanager_t *manager, assetmanagerowner_t owner,
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.fileVert = fileVert;
item->data.shader.fileFrag = fileFrag;
}
assetManagerItemGetOrAddHolder(item, owner);
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;
}
bool _assetManagerLoaderShaderDispose(assetmanageritem_t *item) {
shaderDispose(&item->data.shader.shader);
return true;
}

View File

@ -7,107 +7,12 @@
#pragma once
#include "../libs.h"
#include "../display/font.h"
#include "../display/texture.h"
#include "../display/scaledtexture.h"
#include "../display/shader/shader.h"
#include "../engine/thread.h"
#include "../util/array.h"
#include "types/common.h"
#include "loaders/font.h"
#include "loaders/scaledtexture.h"
#include "loaders/shader.h"
#include "loaders/texture.h"
#include "asset.h"
#include "xml.h"
#define ASSET_MANAGER_ITEMS_MAX 64
#define ASSET_MANAGER_ITEM_NAME_MAX 96
#define ASSET_MANAGER_HOLDERS_MAX 8
#define ASSET_MANAGER_STATE_NOT_READY 0x00
#define ASSET_MANAGER_STATE_PENDING 0x01
#define ASSET_MANAGER_STATE_ASYNC_LOADING 0x02
#define ASSET_MANAGER_STATE_ASYNC_ERROR 0x03
#define ASSET_MANAGER_STATE_ASYNC_DONE 0x04
#define ASSET_MANAGER_STATE_SYNC_LOADING 0x05
#define ASSET_MANAGER_STATE_SYNC_ERROR 0x06
#define ASSET_MANAGER_STATE_SYNC_DONE 0x07
#define ASSET_MANAGER_TYPE_TEXTURE 0x00
#define ASSET_MANAGER_TYPE_FONT 0x01
#define ASSET_MANAGER_TYPE_SHADER 0x02
#define ASSET_MANAGER_TYPE_SCALED_TEXTURE 0x03
#define ASSET_MANAGER_TYPE_SCALE_TEXTURE 0x04
// Loader Types
typedef struct {
font_t font;
char *fileName;
char *data;
} assetmanagerfont_t;
typedef struct {
texture_t texture;
char *fileName;
int32_t width, height;
pixel_t *data;
} assetmanagertexture_t;
typedef struct {
scaledtexture_t scaledTexture;
} assetmanagerscaledtexture_t;
typedef struct {
scaledtexture_t *scaledTexture;
texture_t texture;
uint8_t scale;
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;
typedef union {
assetmanagertexture_t texture;
assetmanagershader_t shader;
assetmanagerfont_t font;
assetmanagerscaledtexture_t scaledTexture;
assetmanagerscaletexture_t scaleTexture;
} assetmanagerassetdata_t;
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);
typedef struct {
assetmanagerloader_t *loadAsync;
assetmanagerloader_t *loadSync;
assetmanagerloader_t *dispose;
} assetmanagerloaderdefinition_t;
// Manager
typedef struct {
thread_t thread;
bool finished;
assetmanageritem_t items[ASSET_MANAGER_ITEMS_MAX];
uint8_t itemCount;
assetmanagerowner_t holders[ASSET_MANAGER_HOLDERS_MAX];
uint8_t holderCount;
bool running;
} assetmanager_t;
// Constants
extern assetmanagerloaderdefinition_t ASSET_MANAGER_LOADERS[];
@ -128,12 +33,52 @@ void assetManagerInit(assetmanager_t *manager);
*/
float assetManagerProgressGet(assetmanager_t *manager);
assetmanagerowner_t assetManagerHolderCreate(assetmanager_t *man);
void assetManagerHolderRelease(assetmanager_t *man, uint8_t hold);
void assetManagerDisposeReleased(assetmanager_t *man);
void assetManagerDispose(assetmanager_t *man);
/**
* Gets the progress of the assets for only those held by a specific holder.
*
* @param manager Manager to get the progress from
* @param hold Holder to get the items progress from.
* @return The percentage (0-1) of the loaded assets.
*/
float assetManagerProgressGetForHolder(
assetmanager_t *manager, assetmanagerowner_t hold
);
////////////////////////////////////////////////////////////////////////////////
/**
* Creates a holder for a given asset manager. Asset holders are kept track of
* so that those who requests assets are responsible for those who free them. It
* also ensures only the assets that are actually necessary are kept loaded in
* memory at all times.
*
* @param man Asset manager in question
* @return An asset manager owner ID.
*/
assetmanagerowner_t assetManagerHolderCreate(assetmanager_t *man);
/**
* Release a previously reserved asset manager holder. This will (in turn) cause
* all of the assets that manager was holding to also be released.
*
* @param man Asset manager holder to release for.
* @param hold Holder to release.
*/
void assetManagerHolderRelease(assetmanager_t *man, assetmanagerowner_t hold);
/**
* Disposes all assets that are not currently held (released assets). This can
* only happen from the main thread due to synchronous assets such as Textures.
*
* @param man Manager to dispose.
*/
void assetManagerDisposeReleased(assetmanager_t *man);
/**
* Completely dispose an asset manager. This will also completely dispose all
* of the assets that this asset manager is holding.
*
* @param man Asset manager to dispose
*/
void assetManagerDispose(assetmanager_t *man);
/**
* Begin asynchronously loading all of the assets
@ -153,132 +98,3 @@ int32_t _assetManagerThread(thread_t *thread);
* @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, char *key);
/**
* Add or get the index that a given holder has as a manager item.
*
* @param i Asset Item to check.
* @param o Owner to get/add.
* @return The index within the item that the owner is at.
*/
uint8_t assetManagerItemGetOrAddHolder(
assetmanageritem_t *i, assetmanagerowner_t o
);
/**
* 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, assetmanagerowner_t owner, char *fileName
);
bool _assetManagerLoaderFontAsync(assetmanageritem_t *item);
bool _assetManagerLoaderFontSync(assetmanageritem_t *item);
bool _assetManagerLoaderFontDispose(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, char *fileName
);
bool _assetManagerLoaderTextureAsync(assetmanageritem_t *item);
bool _assetManagerLoaderTextureSync(assetmanageritem_t *item);
bool _assetManagerLoaderTextureDispose(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 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, 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, uint8_t scale
);
bool _assetManagerLoaderTextureScaleAsync(assetmanageritem_t *item);
bool _assetManagerLoaderTextureScaleSync(assetmanageritem_t *item);
bool _assetManagerLoaderTextureScaleDispose(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, assetmanagerowner_t owner,
char *fileVert, char *fileFrag
);
bool _assetManagerLoaderShaderAsync(assetmanageritem_t *item);
bool _assetManagerLoaderShaderSync(assetmanageritem_t *item);
bool _assetManagerLoaderShaderDispose(assetmanageritem_t *item);

39
src/file/loaders/font.c Normal file
View File

@ -0,0 +1,39 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "font.h"
assetmanageritem_t * assetManagerLoadFont(
assetmanager_t *manager, assetmanagerowner_t owner, 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;
}
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;
}
bool _assetManagerLoaderFontDispose(assetmanageritem_t *item) {
fontDispose(&item->data.font.font);
return true;
}

27
src/file/loaders/font.h Normal file
View File

@ -0,0 +1,27 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "item.h"
#include "../asset.h"
/**
* 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, assetmanagerowner_t owner, char *fileName
);
bool _assetManagerLoaderFontAsync(assetmanageritem_t *item);
bool _assetManagerLoaderFontSync(assetmanageritem_t *item);
bool _assetManagerLoaderFontDispose(assetmanageritem_t *item);

57
src/file/loaders/item.c Normal file
View File

@ -0,0 +1,57 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "item.h"
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_NOT_READY;
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, assetmanagerloaderdefinition_t *def) {
// 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(def->loadSync == NULL) return true;
return false;
}

49
src/file/loaders/item.h Normal file
View File

@ -0,0 +1,49 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../types/common.h"
/**
* 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, char *key);
/**
* Add or get the index that a given holder has as a manager item.
*
* @param i Asset Item to check.
* @param o Owner to get/add.
* @return The index within the item that the owner is at.
*/
uint8_t assetManagerItemGetOrAddHolder(
assetmanageritem_t *i, assetmanagerowner_t o
);
/**
* Checks if a given asset item is finished or not.
*
* @param item Item to check.
* @param def Item type definition used for loading.
* @return True if finished, otherwise false.
*/
bool assetManagerItemIsFinished(
assetmanageritem_t *item, assetmanagerloaderdefinition_t *def
);

View File

@ -0,0 +1,123 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "scaledtexture.h"
assetmanageritem_t * assetManagerLoadScaledTexture(
assetmanager_t *manager, assetmanagerowner_t owner,
char *path, char *file, uint8_t scale
) {
assetmanageritem_t *item;
texturescale_t *st;
char buffer[ASSET_MANAGER_ITEM_NAME_MAX];
sprintf(buffer, "%s/%s_%u", path, file, scale);
item = assetManagerItemGet(manager, buffer);
if(item == NULL) {
item = assetManagerItemAdd(manager, buffer);
item->type = ASSET_MANAGER_TYPE_SCALED_TEXTURE;
item->data.scaledTexture.scale = scale;
st = &item->data.scaledTexture.textureScale;
st->scaleCount = 0;
st->baseWidth = 0;
st->baseHeight = 0;
st->path = path;
st->file = file;
}
assetManagerItemGetOrAddHolder(item, owner);
return item;
}
bool _assetManagerLoaderScaledTextureAsync(assetmanageritem_t *item) {
char buffer[128];
char *xmlData;
xml_t xml;
xml_t *child;
int16_t i, j;
texturescale_t *st;
texturescalescale_t *sts;
size_t length;
// TODO: This can be improved if we allow both asset dependencies and
// dependency sibling adding
st = &item->data.scaledTexture.textureScale;
// Begin loading texture XML
sprintf(buffer, "%s/%s.xml", st->path, st->file);
xmlData = assetStringLoad(buffer);
if(xmlData == NULL) return false;
xmlLoad(&xml, xmlData);
free(xmlData);
// Parse root texture info
i = xmlGetAttributeByName(&xml, "channels");
st->channels = (uint8_t)atoi(xml.attributeDatas[i]);
i = xmlGetAttributeByName(&xml, "width");
st->baseWidth = (int16_t)atoi(xml.attributeDatas[i]);
i = xmlGetAttributeByName(&xml, "height");
st->baseHeight = (int16_t)atoi(xml.attributeDatas[i]);
for(j = 0; j < xml.childrenCount; j++) {
child = xml.children + j;
i = xmlGetAttributeByName(child, "scale");
st->scales[st->scaleCount].scale = (uint8_t)atoi(child->attributeDatas[i]);
i = xmlGetAttributeByName(child, "width");
st->scales[st->scaleCount].width = (int16_t)atoi(child->attributeDatas[i]);
i = xmlGetAttributeByName(child, "height");
st->scales[st->scaleCount].height = (int16_t)atoi(child->attributeDatas[i]);
st->scaleCount++;
}
// Cleanup XML
xmlDispose(&xml);
// Get the scale
sts = st->scales + item->data.scaledTexture.scale;
// Get filename
sprintf(buffer, "%s/%s_%i.texture", st->path, st->file, sts->scale);
// Create some space
length = assetRawLoad(buffer, NULL);
if(length == 0) return false;
item->data.scaledTexture.data = malloc(sizeof(pixel_t) * length);
// Load
length = assetRawLoad(buffer, (uint8_t *)item->data.scaledTexture.data);
if(length == 0) {
free(item->data.scaledTexture.data);
return false;
}
return true;
}
bool _assetManagerLoaderScaledTextureSync(assetmanageritem_t *item) {
texturescale_t *st;
texturescalescale_t *sts;
st = &item->data.scaledTexture.textureScale;
sts = st->scales + item->data.scaledTexture.scale;
textureInit(
&item->data.scaledTexture.texture,
sts->width, sts->height,
item->data.scaledTexture.data
);
free(item->data.scaledTexture.data);
return true;
}
bool _assetManagerLoaderScaledTextureDispose(assetmanageritem_t *item) {
textureDispose(&item->data.scaledTexture.texture);
return true;
}

View File

@ -0,0 +1,30 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "item.h"
#include "../xml.h"
#include "../asset.h"
/**
* 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 path Path of the texture size sets
* @param file Name of the texture that was generated.
* @param scale Scale to load.
* @return A pointer to the asset manager item for tracking.
*/
assetmanageritem_t * assetManagerLoadScaledTexture(
assetmanager_t *manager, assetmanagerowner_t owner,
char *path, char *file, uint8_t scale
);
bool _assetManagerLoaderScaledTextureAsync(assetmanageritem_t *item);
bool _assetManagerLoaderScaledTextureSync(assetmanageritem_t *item);
bool _assetManagerLoaderScaledTextureDispose(assetmanageritem_t *item);

55
src/file/loaders/shader.c Normal file
View File

@ -0,0 +1,55 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "shader.h"
assetmanageritem_t * assetManagerLoadShader(
assetmanager_t *manager, assetmanagerowner_t owner,
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.fileVert = fileVert;
item->data.shader.fileFrag = fileFrag;
}
assetManagerItemGetOrAddHolder(item, owner);
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;
}
bool _assetManagerLoaderShaderDispose(assetmanageritem_t *item) {
shaderDispose(&item->data.shader.shader);
return true;
}

29
src/file/loaders/shader.h Normal file
View File

@ -0,0 +1,29 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "item.h"
#include "../asset.h"
/**
* 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, assetmanagerowner_t owner,
char *fileVert, char *fileFrag
);
bool _assetManagerLoaderShaderAsync(assetmanageritem_t *item);
bool _assetManagerLoaderShaderSync(assetmanageritem_t *item);
bool _assetManagerLoaderShaderDispose(assetmanageritem_t *item);

View File

@ -0,0 +1,69 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "texture.h"
assetmanageritem_t * assetManagerLoadTexture(
assetmanager_t *manager, assetmanagerowner_t owner, char *fileName
) {
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;
}
assetManagerItemGetOrAddHolder(item, owner);
return item;
}
bool _assetManagerLoaderTextureAsync(assetmanageritem_t *item) {
assetbuffer_t *buffer;
int channels;
stbi_io_callbacks OPENGL_STBI_CALLBACKS;
buffer = assetBufferOpen(item->data.texture.fileName);
if(buffer == NULL) return false;
// Setup the interface for STBI
OPENGL_STBI_CALLBACKS.read = &assetBufferRead;
OPENGL_STBI_CALLBACKS.skip = &assetBufferSkip;
OPENGL_STBI_CALLBACKS.eof = &assetBufferEnd;
// Buffer the image
channels = 0;
item->data.texture.data = (pixel_t *)stbi_load_from_callbacks(
&OPENGL_STBI_CALLBACKS, buffer,
&item->data.texture.width, &item->data.texture.height,
&channels, STBI_rgb_alpha
);
// Close the buffer
assetBufferClose(buffer);
if(item->data.texture.data == NULL) return false;
return true;
}
bool _assetManagerLoaderTextureSync(assetmanageritem_t *item) {
// Turn into a texture.
textureInit(
&item->data.texture.texture,
item->data.texture.width,
item->data.texture.height,
item->data.texture.data
);
// Cleanup
stbi_image_free(item->data.texture.data);
return true;
}
bool _assetManagerLoaderTextureDispose(assetmanageritem_t *item) {
textureDispose(&item->data.texture.texture);
return true;
}

View File

@ -0,0 +1,27 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "item.h"
#include "../asset.h"
/**
* 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, char *fileName
);
bool _assetManagerLoaderTextureAsync(assetmanageritem_t *item);
bool _assetManagerLoaderTextureSync(assetmanageritem_t *item);
bool _assetManagerLoaderTextureDispose(assetmanageritem_t *item);

80
src/file/types/common.h Normal file
View File

@ -0,0 +1,80 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../../libs.h"
#include "../engine/thread.h"
#include "texture.h"
#include "font.h"
#include "shader.h"
#include "scaledtexture.h"
#define ASSET_MANAGER_ITEMS_MAX 64
#define ASSET_MANAGER_ITEM_NAME_MAX 96
#define ASSET_MANAGER_HOLDERS_MAX 8
/** States */
#define ASSET_MANAGER_STATE_NOT_READY 0x00
#define ASSET_MANAGER_STATE_PENDING 0x01
#define ASSET_MANAGER_STATE_ASYNC_LOADING 0x02
#define ASSET_MANAGER_STATE_ASYNC_ERROR 0x03
#define ASSET_MANAGER_STATE_ASYNC_DONE 0x04
#define ASSET_MANAGER_STATE_SYNC_LOADING 0x05
#define ASSET_MANAGER_STATE_SYNC_ERROR 0x06
#define ASSET_MANAGER_STATE_SYNC_DONE 0x07
/** Type IDs */
#define ASSET_MANAGER_TYPE_TEXTURE 0x00
#define ASSET_MANAGER_TYPE_FONT 0x01
#define ASSET_MANAGER_TYPE_SHADER 0x02
#define ASSET_MANAGER_TYPE_SCALED_TEXTURE 0x03
// Owner
typedef uint8_t assetmanagerowner_t;
// Union of all the manager types
typedef union {
assetmanagertexture_t texture;
assetmanagershader_t shader;
assetmanagerfont_t font;
assetmanagerscaledtexture_t scaledTexture;
} assetmanagerassetdata_t;
// Item Type
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);
// Loader Definition
typedef struct {
assetmanagerloader_t *loadAsync;
assetmanagerloader_t *loadSync;
assetmanagerloader_t *dispose;
} assetmanagerloaderdefinition_t;
// Manager
typedef struct {
thread_t thread;
bool finished;
bool running;
assetmanageritem_t items[ASSET_MANAGER_ITEMS_MAX];
uint8_t itemCount;
assetmanagerowner_t holders[ASSET_MANAGER_HOLDERS_MAX];
uint8_t holderCount;
} assetmanager_t;

15
src/file/types/font.h Normal file
View File

@ -0,0 +1,15 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../../display/font.h"
typedef struct {
font_t font;
char *fileName;
char *data;
} assetmanagerfont_t;

View File

@ -0,0 +1,18 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../../libs.h"
#include "../../display/texture.h"
#include "../../display/texturescale.h"
typedef struct {
texturescale_t textureScale;
texture_t texture;
uint8_t scale;
pixel_t *data;
} assetmanagerscaledtexture_t;

16
src/file/types/shader.h Normal file
View File

@ -0,0 +1,16 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../../libs.h"
#include "../../display/shader/shader.h"
typedef struct {
shader_t shader;
char *fileVert;
char *fileFrag;
char *dataVert;
char *dataFrag;
} assetmanagershader_t;

15
src/file/types/texture.h Normal file
View File

@ -0,0 +1,15 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../../libs.h"
#include "../../display/texture.h"
typedef struct {
texture_t texture;
char *fileName;
int32_t width, height;
pixel_t *data;
} assetmanagertexture_t;