Started asset refact
This commit is contained in:
139
archive/asset/asset.c
Normal file
139
archive/asset/asset.c
Normal file
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "asset.h"
|
||||
#include "assetmanager.h"
|
||||
#include "util/memory.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
assetdef_t ASSET_DEFINITIONS[ASSET_TYPE_COUNT] = {
|
||||
[ASSET_TYPE_PALETTE_IMAGE] = {
|
||||
"DPI", assetPaletteImageLoad, assetPaletteImageDispose
|
||||
},
|
||||
[ASSET_TYPE_ALPHA_IMAGE] = {
|
||||
"DAI", assetAlphaImageLoad, assetAlphaImageDispose
|
||||
},
|
||||
};
|
||||
|
||||
errorret_t assetInit(asset_t *asset, const char_t *filename) {
|
||||
assertNotNull(asset, "Asset cannot be NULL.");
|
||||
assertNotNull(filename, "Filename cannot be NULL.");
|
||||
assertTrue(strlen(filename) < FILENAME_MAX, "Filename too long.");
|
||||
assertTrue(strlen(filename) > 0, "Filename cannot be empty.");
|
||||
|
||||
memoryZero(asset, sizeof(asset_t));
|
||||
memoryCopy(asset->filename, filename, strlen(filename) + 1);
|
||||
|
||||
// Initialze the reference list.
|
||||
refListInit(
|
||||
&asset->refList,
|
||||
asset->refListArray,
|
||||
ASSET_REFERENCE_COUNT_MAX
|
||||
);
|
||||
|
||||
// Test the file can be opened. In future I may make the handle stay open for
|
||||
// a while to see if it increases performance and stops disk thrashing.
|
||||
asset->file = zip_fopen(ASSET_MANAGER.zip, filename, 0);
|
||||
if(asset->file == NULL) errorThrow("Failed to open asset file: %s", filename);
|
||||
zip_fclose(asset->file);
|
||||
asset->file = NULL;
|
||||
errorOk();
|
||||
}
|
||||
|
||||
ref_t assetLock(asset_t *asset) {
|
||||
assertNotNull(asset, "Asset cannot be NULL.");
|
||||
|
||||
return refListLock(&asset->refList);
|
||||
}
|
||||
|
||||
void assetUnlock(asset_t *asset, const ref_t ref) {
|
||||
assertNotNull(asset, "Asset cannot be NULL.");
|
||||
|
||||
// Just unlock the reference in the reference list.
|
||||
refListUnlock(&asset->refList, ref);
|
||||
}
|
||||
|
||||
errorret_t assetLoad(asset_t *asset) {
|
||||
assertNotNull(asset, "Asset cannot be NULL.");
|
||||
assertTrue(
|
||||
asset->state == ASSET_STATE_NOT_LOADED,
|
||||
"Asset is already loaded or loading."
|
||||
);
|
||||
|
||||
// Mark as loading.
|
||||
asset->state = ASSET_STATE_LOADING;
|
||||
|
||||
// Open the file.
|
||||
if(asset->file == NULL) {
|
||||
asset->file = zip_fopen(ASSET_MANAGER.zip, asset->filename, 0);
|
||||
if(asset->file == NULL) {
|
||||
asset->state = ASSET_STATE_ERROR;
|
||||
errorThrow("Failed to open asset file: %s", asset->filename);
|
||||
}
|
||||
}
|
||||
|
||||
// Read header.
|
||||
char_t header[ASSET_HEADER_SIZE + 1];
|
||||
memoryZero(header, ASSET_HEADER_SIZE + 1);
|
||||
zip_int64_t bytesRead = zip_fread(asset->file, header, ASSET_HEADER_SIZE);
|
||||
if(bytesRead != ASSET_HEADER_SIZE) {
|
||||
asset->state = ASSET_STATE_ERROR;
|
||||
zip_fclose(asset->file);
|
||||
asset->file = NULL;
|
||||
errorThrow("Failed to read asset header for: %s", asset->filename);
|
||||
}
|
||||
|
||||
// Check header.
|
||||
if(strlen(header) != ASSET_HEADER_SIZE) {
|
||||
asset->state = ASSET_STATE_ERROR;
|
||||
zip_fclose(asset->file);
|
||||
asset->file = NULL;
|
||||
errorThrow("Invalid asset header for: %s", asset->filename);
|
||||
}
|
||||
|
||||
// Get the asset definition based on the header.
|
||||
assetdef_t *def;
|
||||
for(uint_fast8_t i = 0; i < ASSET_TYPE_COUNT; i++) {
|
||||
if(strcmp(header, ASSET_DEFINITIONS[i].header) == 0) {
|
||||
def = &ASSET_DEFINITIONS[i];
|
||||
asset->type = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertNotNull(def, "Failed to find asset definition for header.");
|
||||
|
||||
// Load the asset
|
||||
errorret_t ret = def->load(asset);
|
||||
if(ret.code != ERROR_OK) {
|
||||
asset->state = ASSET_STATE_ERROR;
|
||||
zip_fclose(asset->file);
|
||||
asset->file = NULL;
|
||||
errorChain(ret);
|
||||
}
|
||||
|
||||
// Finished loading.
|
||||
asset->state = ASSET_STATE_LOADED;
|
||||
zip_fclose(asset->file);
|
||||
asset->file = NULL;
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t assetDispose(asset_t *asset) {
|
||||
assertNotNull(asset, "Asset cannot be NULL.");
|
||||
|
||||
if(asset->state == ASSET_STATE_LOADED) {
|
||||
// Dispose of the asset based on its type.
|
||||
assetdef_t *def = &ASSET_DEFINITIONS[asset->type];
|
||||
if(def->dispose) errorChain(def->dispose(asset));
|
||||
asset->state = ASSET_STATE_NOT_LOADED;
|
||||
}
|
||||
|
||||
if(asset->file) {
|
||||
zip_fclose(asset->file);
|
||||
asset->file = NULL;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user