diff --git a/src/dusk/asset/asset.c b/src/dusk/asset/asset.c index 76850bf6..161a449e 100644 --- a/src/dusk/asset/asset.c +++ b/src/dusk/asset/asset.c @@ -180,11 +180,11 @@ errorret_t assetUpdate(void) { // If an error occured these things need to be true, basically just // ensuring the sync loader is setting the error correctly. if(errorIsNotOk(ret)) { + errorCatch(errorPrint(ret)); assertTrue( loading->entry->state == ASSET_ENTRY_STATE_ERROR, "Loader did not set entry state to error on failed load." ); - errorCatch(errorPrint(ret)); } threadMutexUnlock(&loading->mutex); @@ -236,8 +236,22 @@ void assetUpdateAsync(thread_t *thread) { switch(loading->entry->state) { case ASSET_ENTRY_STATE_PENDING_ASYNC: loading->entry->state = ASSET_ENTRY_STATE_LOADING_ASYNC; - printf("Simulated async load\n"); - sleep(1); + assertNotNull( + ASSET_LOADER_CALLBACKS[loading->type].loadAsync, + "Loader does not support async loading." + ); + errorret_t ret = ( + ASSET_LOADER_CALLBACKS[loading->type].loadAsync(loading) + ); + + if(errorIsNotOk(ret)) { + errorCatch(errorPrint(ret)); + assertTrue( + loading->entry->state == ASSET_ENTRY_STATE_ERROR, + "Loader did not set entry state to error on failed load." + ); + } + threadMutexUnlock(&loading->mutex); loading++; break; diff --git a/src/dusk/asset/loader/assetloader.c b/src/dusk/asset/loader/assetloader.c index 2b7c9308..121ab02c 100644 --- a/src/dusk/asset/loader/assetloader.c +++ b/src/dusk/asset/loader/assetloader.c @@ -12,26 +12,31 @@ assetloadercallbacks_t ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_COUNT] = { [ASSET_LOADER_TYPE_MESH] = { .loadSync = assetMeshLoaderSync, + .loadAsync = NULL, .dispose = assetMeshDispose }, [ASSET_LOADER_TYPE_TEXTURE] = { .loadSync = assetTextureLoaderSync, + .loadAsync = assetTextureLoaderAsync, .dispose = assetTextureDispose }, [ASSET_LOADER_TYPE_TILESET] = { .loadSync = assetTilesetLoaderSync, + .loadAsync = NULL, .dispose = assetTilesetDispose }, [ASSET_LOADER_TYPE_LOCALE] = { .loadSync = assetLocaleLoaderSync, + .loadAsync = NULL, .dispose = assetLocaleDispose }, [ASSET_LOADER_TYPE_JSON] = { .loadSync = assetJsonLoaderSync, + .loadAsync = NULL, .dispose = assetJsonDispose }, }; diff --git a/src/dusk/asset/loader/assetloader.h b/src/dusk/asset/loader/assetloader.h index d6850aec..77b98978 100644 --- a/src/dusk/asset/loader/assetloader.h +++ b/src/dusk/asset/loader/assetloader.h @@ -52,10 +52,12 @@ typedef struct assetloading_s assetloading_t; typedef struct assetentry_s assetentry_t; typedef errorret_t (assetloadersynccallback_t)(assetloading_t *loading); +typedef errorret_t (assetloaderasynccallback_t)(assetloading_t *loading); typedef errorret_t (assetloaderdisposecallback_t)(assetentry_t *entry); typedef struct { assetloadersynccallback_t *loadSync; + assetloaderasynccallback_t *loadAsync; assetloaderdisposecallback_t *dispose; } assetloadercallbacks_t; diff --git a/src/dusk/asset/loader/display/assettextureloader.c b/src/dusk/asset/loader/display/assettextureloader.c index e6f0988f..1b264f8a 100644 --- a/src/dusk/asset/loader/display/assettextureloader.c +++ b/src/dusk/asset/loader/display/assettextureloader.c @@ -52,10 +52,19 @@ int assetTextureEOF(void *user) { return file->position >= file->size; } -errorret_t assetTextureLoaderSync(assetloading_t *loading) { +errorret_t assetTextureLoaderAsync(assetloading_t *loading) { assertNotNull(loading, "Loading cannot be NULL"); + // Only care about loading pixels. + if(loading->loading.texture.state != ASSET_TEXTURE_LOADING_STATE_LOAD_PIXELS){ + errorOk(); + } + // Init the file + assertNull( + loading->loading.texture.data, "Pixels already defined?" + ); + assetfile_t *file = &loading->loading.texture.file; assetLoaderErrorChain(loading, assetFileInit( file, @@ -77,13 +86,12 @@ errorret_t assetTextureLoaderSync(assetloading_t *loading) { } // Load image pixels. - int width, height, channels; loading->loading.texture.data = stbi_load_from_callbacks( &ASSET_TEXTURE_STB_CALLBACKS, file, - &width, - &height, - &channels, + &loading->loading.texture.width, + &loading->loading.texture.height, + &loading->loading.texture.channels, channelsDesired ); @@ -101,14 +109,43 @@ errorret_t assetTextureLoaderSync(assetloading_t *loading) { if(!isHostLittleEndian()) { stbi__vertical_flip( loading->loading.texture.data, - width, height, channelsDesired + loading->loading.texture.width, + loading->loading.texture.height, + loading->loading.texture.channels ); } + loading->loading.texture.state = ASSET_TEXTURE_LOADING_STATE_CREATE_TEXTURE; + loading->entry->state = ASSET_ENTRY_STATE_PENDING_SYNC; + errorOk(); +} + +errorret_t assetTextureLoaderSync(assetloading_t *loading) { + assertNotNull(loading, "Loading cannot be NULL"); + + switch(loading->loading.texture.state) { + case ASSET_TEXTURE_LOADING_STATE_INITIAL: + loading->loading.texture.state = ASSET_TEXTURE_LOADING_STATE_LOAD_PIXELS; + loading->entry->state = ASSET_ENTRY_STATE_PENDING_ASYNC; + errorOk(); + break; + + case ASSET_TEXTURE_LOADING_STATE_CREATE_TEXTURE: + break; + + default: + errorOk(); + } + // Create the texture. + assertNotNull( + loading->loading.texture.data, "Pixels should have been loaded by now." + ); + assetLoaderErrorChain(loading, textureInit( (texture_t*)&loading->entry->data.texture, - (int32_t)width, (int32_t)height, + loading->loading.texture.width, + loading->loading.texture.height, loading->entry->input->texture, (texturedata_t){ .rgbaColors = (color_t*)loading->loading.texture.data diff --git a/src/dusk/asset/loader/display/assettextureloader.h b/src/dusk/asset/loader/display/assettextureloader.h index 6cd557d6..b29ac5dc 100644 --- a/src/dusk/asset/loader/display/assettextureloader.h +++ b/src/dusk/asset/loader/display/assettextureloader.h @@ -13,8 +13,18 @@ typedef struct assetloading_s assetloading_t; typedef struct assetentry_s assetentry_t; typedef textureformat_t assettextureloaderinput_t; +typedef enum { + ASSET_TEXTURE_LOADING_STATE_INITIAL, + ASSET_TEXTURE_LOADING_STATE_LOAD_PIXELS, + ASSET_TEXTURE_LOADING_STATE_CREATE_TEXTURE, + ASSET_TEXTURE_LOADING_STATE_DONE +} assettextureloadingstate_t; + typedef struct { assetfile_t file; + assettextureloadingstate_t state; + + int channels, width, height; uint8_t *data; } assettextureloaderloading_t; @@ -46,6 +56,14 @@ void assetTextureSkipper(void *user, int n); */ int assetTextureEOF(void *user); +/** + * Synchronous loader for texture assets. + * + * @param loading Loading information for the asset being loaded. + * @return Error code indicating success or failure of the load operation. + */ +errorret_t assetTextureLoaderAsync(assetloading_t *loading); + /** * Synchronous loader for texture assets. *