Async chunk loading
This commit is contained in:
@@ -286,7 +286,9 @@ errorret_t assetUpdate(void) {
|
|||||||
"Loader did not set entry state to error on failed load."
|
"Loader did not set entry state to error on failed load."
|
||||||
);
|
);
|
||||||
} else if(loading->entry->state == ASSET_ENTRY_STATE_LOADED) {
|
} else if(loading->entry->state == ASSET_ENTRY_STATE_LOADED) {
|
||||||
eventInvoke(&loading->entry->onLoaded, loading->entry);
|
assetentry_t *loadedEntry = loading->entry;
|
||||||
|
loading->entry = NULL;
|
||||||
|
eventInvoke(&loadedEntry->onLoaded, loadedEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
loading++;
|
loading++;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#define ASSET_FILE_NAME "dusk.dsk"
|
#define ASSET_FILE_NAME "dusk.dsk"
|
||||||
#define ASSET_HEADER_SIZE 3
|
#define ASSET_HEADER_SIZE 3
|
||||||
|
|
||||||
#define ASSET_LOADING_COUNT_MAX 4
|
#define ASSET_LOADING_COUNT_MAX 20
|
||||||
#define ASSET_ENTRY_COUNT_MAX 128
|
#define ASSET_ENTRY_COUNT_MAX 128
|
||||||
|
|
||||||
typedef struct asset_s {
|
typedef struct asset_s {
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
#include "util/endian.h"
|
#include "util/endian.h"
|
||||||
#include "asset/loader/assetloading.h"
|
#include "asset/loader/assetloading.h"
|
||||||
#include "asset/loader/assetentry.h"
|
#include "asset/loader/assetentry.h"
|
||||||
|
#include "asset/loader/assetloader.h"
|
||||||
|
#include "asset/asset.h"
|
||||||
|
|
||||||
errorret_t assetChunkLoaderAsync(assetloading_t *loading) {
|
errorret_t assetChunkLoaderAsync(assetloading_t *loading) {
|
||||||
assertNotNull(loading, "Loading cannot be NULL");
|
assertNotNull(loading, "Loading cannot be NULL");
|
||||||
@@ -48,16 +50,44 @@ errorret_t assetChunkLoaderSync(assetloading_t *loading) {
|
|||||||
assertTrue(loading->type == ASSET_LOADER_TYPE_CHUNK, "Invalid type.");
|
assertTrue(loading->type == ASSET_LOADER_TYPE_CHUNK, "Invalid type.");
|
||||||
assertIsMainThread("Must be called from the main thread.");
|
assertIsMainThread("Must be called from the main thread.");
|
||||||
|
|
||||||
|
assetchunkoutput_t *out = &loading->entry->data.chunk;
|
||||||
|
|
||||||
switch(loading->loading.chunk.state) {
|
switch(loading->loading.chunk.state) {
|
||||||
case ASSET_CHUNK_LOADING_STATE_INITIAL:
|
case ASSET_CHUNK_LOADING_STATE_INITIAL:
|
||||||
loading->loading.chunk.state = ASSET_CHUNK_LOADING_STATE_READ_FILE;
|
loading->loading.chunk.state = ASSET_CHUNK_LOADING_STATE_READ_FILE;
|
||||||
loading->entry->state = ASSET_ENTRY_STATE_PENDING_ASYNC;
|
loading->entry->state = ASSET_ENTRY_STATE_PENDING_ASYNC;
|
||||||
errorOk();
|
errorOk();
|
||||||
break;
|
|
||||||
|
|
||||||
case ASSET_CHUNK_LOADING_STATE_PARSE:
|
case ASSET_CHUNK_LOADING_STATE_PARSE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ASSET_CHUNK_LOADING_STATE_LOAD_MODELS:
|
||||||
|
while(loading->loading.chunk.modelIndex < out->meshCount) {
|
||||||
|
uint8_t m = loading->loading.chunk.modelIndex;
|
||||||
|
if(out->modelEntries[m] == NULL) {
|
||||||
|
out->modelEntries[m] = assetLock(
|
||||||
|
out->modelNames[m], ASSET_LOADER_TYPE_MODEL, NULL
|
||||||
|
);
|
||||||
|
assertNotNull(
|
||||||
|
out->modelEntries[m], "Failed to lock model."
|
||||||
|
);
|
||||||
|
loading->entry->state = ASSET_ENTRY_STATE_PENDING_SYNC;
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
if(out->modelEntries[m]->state == ASSET_ENTRY_STATE_ERROR) {
|
||||||
|
assetLoaderErrorThrow(
|
||||||
|
loading, "Model failed to load: %s", out->modelNames[m]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if(out->modelEntries[m]->state != ASSET_ENTRY_STATE_LOADED) {
|
||||||
|
loading->entry->state = ASSET_ENTRY_STATE_PENDING_SYNC;
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
loading->loading.chunk.modelIndex++;
|
||||||
|
}
|
||||||
|
loading->entry->state = ASSET_ENTRY_STATE_LOADED;
|
||||||
|
errorOk();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -78,7 +108,6 @@ errorret_t assetChunkLoaderSync(assetloading_t *loading) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assetchunkoutput_t *out = &loading->entry->data.chunk;
|
|
||||||
size_t offset = 8;
|
size_t offset = 8;
|
||||||
|
|
||||||
size_t tileSize = CHUNK_TILE_COUNT * sizeof(tile_t);
|
size_t tileSize = CHUNK_TILE_COUNT * sizeof(tile_t);
|
||||||
@@ -104,17 +133,22 @@ errorret_t assetChunkLoaderSync(assetloading_t *loading) {
|
|||||||
out->modelNames[m][nameLen] = '\0';
|
out->modelNames[m][nameLen] = '\0';
|
||||||
offset += nameLen + 1;
|
offset += nameLen + 1;
|
||||||
|
|
||||||
memoryCopy(
|
memoryCopy(out->meshOffsets[m], data + offset, sizeof(vec3));
|
||||||
out->meshOffsets[m], data + offset, sizeof(vec3)
|
|
||||||
);
|
|
||||||
offset += sizeof(vec3);
|
offset += sizeof(vec3);
|
||||||
}
|
}
|
||||||
|
|
||||||
memoryFree(data);
|
memoryFree(data);
|
||||||
loading->loading.chunk.data = NULL;
|
loading->loading.chunk.data = NULL;
|
||||||
|
|
||||||
|
if(out->meshCount == 0) {
|
||||||
loading->entry->state = ASSET_ENTRY_STATE_LOADED;
|
loading->entry->state = ASSET_ENTRY_STATE_LOADED;
|
||||||
errorOk();
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
loading->loading.chunk.state = ASSET_CHUNK_LOADING_STATE_LOAD_MODELS;
|
||||||
|
loading->loading.chunk.modelIndex = 0;
|
||||||
|
loading->entry->state = ASSET_ENTRY_STATE_PENDING_SYNC;
|
||||||
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t assetChunkDispose(assetentry_t *entry) {
|
errorret_t assetChunkDispose(assetentry_t *entry) {
|
||||||
@@ -122,5 +156,11 @@ errorret_t assetChunkDispose(assetentry_t *entry) {
|
|||||||
assertTrue(entry->type == ASSET_LOADER_TYPE_CHUNK, "Invalid type.");
|
assertTrue(entry->type == ASSET_LOADER_TYPE_CHUNK, "Invalid type.");
|
||||||
assertIsMainThread("Must be called from the main thread.");
|
assertIsMainThread("Must be called from the main thread.");
|
||||||
|
|
||||||
|
assetchunkoutput_t *out = &entry->data.chunk;
|
||||||
|
for(uint8_t m = 0; m < out->meshCount; m++) {
|
||||||
|
if(out->modelEntries[m] == NULL) continue;
|
||||||
|
assetUnlockEntry(out->modelEntries[m]);
|
||||||
|
out->modelEntries[m] = NULL;
|
||||||
|
}
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ typedef enum {
|
|||||||
ASSET_CHUNK_LOADING_STATE_INITIAL,
|
ASSET_CHUNK_LOADING_STATE_INITIAL,
|
||||||
ASSET_CHUNK_LOADING_STATE_READ_FILE,
|
ASSET_CHUNK_LOADING_STATE_READ_FILE,
|
||||||
ASSET_CHUNK_LOADING_STATE_PARSE,
|
ASSET_CHUNK_LOADING_STATE_PARSE,
|
||||||
|
ASSET_CHUNK_LOADING_STATE_LOAD_MODELS,
|
||||||
ASSET_CHUNK_LOADING_STATE_DONE
|
ASSET_CHUNK_LOADING_STATE_DONE
|
||||||
} assetchunkloadingstate_t;
|
} assetchunkloadingstate_t;
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ typedef struct {
|
|||||||
assetfile_t file;
|
assetfile_t file;
|
||||||
assetchunkloadingstate_t state;
|
assetchunkloadingstate_t state;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
|
uint8_t modelIndex;
|
||||||
} assetchunkloaderloading_t;
|
} assetchunkloaderloading_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -36,6 +38,7 @@ typedef struct {
|
|||||||
uint8_t meshCount;
|
uint8_t meshCount;
|
||||||
char_t modelNames[CHUNK_MESH_COUNT_MAX][CHUNK_MESH_NAME_MAX];
|
char_t modelNames[CHUNK_MESH_COUNT_MAX][CHUNK_MESH_NAME_MAX];
|
||||||
vec3 meshOffsets[CHUNK_MESH_COUNT_MAX];
|
vec3 meshOffsets[CHUNK_MESH_COUNT_MAX];
|
||||||
|
assetentry_t *modelEntries[CHUNK_MESH_COUNT_MAX];
|
||||||
} assetchunkoutput_t;
|
} assetchunkoutput_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,9 +10,10 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "asset/asset.h"
|
#include "asset/asset.h"
|
||||||
#include "asset/loader/assetloader.h"
|
#include "asset/loader/assetloader.h"
|
||||||
|
#include "console/console.h"
|
||||||
|
#include "event/event.h"
|
||||||
#include "rpg/entity/entity.h"
|
#include "rpg/entity/entity.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
map_t MAP;
|
map_t MAP;
|
||||||
|
|
||||||
@@ -113,8 +114,8 @@ errorret_t mapPositionSet(const chunkpos_t newPos) {
|
|||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapUpdate() {
|
errorret_t mapUpdate() {
|
||||||
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t mapDispose() {
|
errorret_t mapDispose() {
|
||||||
@@ -143,6 +144,8 @@ void mapChunkUnload(chunk_t *chunk) {
|
|||||||
memorySet(chunk->entities, 0xFF, sizeof(chunk->entities));
|
memorySet(chunk->entities, 0xFF, sizeof(chunk->entities));
|
||||||
|
|
||||||
if(chunk->dcfEntry != NULL) {
|
if(chunk->dcfEntry != NULL) {
|
||||||
|
eventUnsubscribe(&chunk->dcfEntry->onLoaded, mapChunkLoaded);
|
||||||
|
eventUnsubscribe(&chunk->dcfEntry->onError, mapChunkLoadError);
|
||||||
assetUnlockEntry(chunk->dcfEntry);
|
assetUnlockEntry(chunk->dcfEntry);
|
||||||
chunk->dcfEntry = NULL;
|
chunk->dcfEntry = NULL;
|
||||||
}
|
}
|
||||||
@@ -158,9 +161,15 @@ void mapChunkUnload(chunk_t *chunk) {
|
|||||||
errorret_t mapChunkLoad(chunk_t *chunk) {
|
errorret_t mapChunkLoad(chunk_t *chunk) {
|
||||||
if(!mapIsLoaded()) errorThrow("No map loaded");
|
if(!mapIsLoaded()) errorThrow("No map loaded");
|
||||||
|
|
||||||
|
if(chunk->dcfEntry != NULL) {
|
||||||
|
eventUnsubscribe(&chunk->dcfEntry->onLoaded, mapChunkLoaded);
|
||||||
|
eventUnsubscribe(&chunk->dcfEntry->onError, mapChunkLoadError);
|
||||||
|
assetUnlockEntry(chunk->dcfEntry);
|
||||||
|
chunk->dcfEntry = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
memorySet(chunk->entities, 0xFF, sizeof(chunk->entities));
|
memorySet(chunk->entities, 0xFF, sizeof(chunk->entities));
|
||||||
chunk->meshCount = 0;
|
chunk->meshCount = 0;
|
||||||
chunk->dcfEntry = NULL;
|
|
||||||
|
|
||||||
char_t name[64];
|
char_t name[64];
|
||||||
stringFormat(
|
stringFormat(
|
||||||
@@ -178,85 +187,12 @@ errorret_t mapChunkLoad(chunk_t *chunk) {
|
|||||||
|
|
||||||
assetentry_t *entry = assetLock(name, ASSET_LOADER_TYPE_CHUNK, NULL);
|
assetentry_t *entry = assetLock(name, ASSET_LOADER_TYPE_CHUNK, NULL);
|
||||||
assertNotNull(entry, "Failed to get chunk asset entry");
|
assertNotNull(entry, "Failed to get chunk asset entry");
|
||||||
|
eventSubscribe(&entry->onLoaded, mapChunkLoaded, chunk);
|
||||||
|
eventSubscribe(&entry->onError, mapChunkLoadError, chunk);
|
||||||
chunk->dcfEntry = entry;
|
chunk->dcfEntry = entry;
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t mapWaitForChunks() {
|
|
||||||
// Phase 1: Wait for all DCF entries to finish loading.
|
|
||||||
bool_t anyPending;
|
|
||||||
do {
|
|
||||||
anyPending = false;
|
|
||||||
errorChain(assetUpdate());
|
|
||||||
|
|
||||||
for(chunkindex_t i = 0; i < MAP_CHUNK_COUNT; i++) {
|
|
||||||
chunk_t *chunk = &MAP.chunks[i];
|
|
||||||
if(chunk->dcfEntry == NULL) continue;
|
|
||||||
|
|
||||||
assetentrystate_t state = chunk->dcfEntry->state;
|
|
||||||
if(state == ASSET_ENTRY_STATE_LOADED) {
|
|
||||||
uint8_t meshCount = chunk->dcfEntry->data.chunk.meshCount;
|
|
||||||
memoryCopy(
|
|
||||||
chunk->tiles,
|
|
||||||
chunk->dcfEntry->data.chunk.tiles,
|
|
||||||
sizeof(chunk->tiles)
|
|
||||||
);
|
|
||||||
worldpos_t wp;
|
|
||||||
chunkPosToWorldPos(&chunk->position, &wp);
|
|
||||||
vec3 wpf = { (float_t)wp.x, (float_t)wp.y, (float_t)wp.z };
|
|
||||||
|
|
||||||
for(uint8_t m = 0; m < meshCount; m++) {
|
|
||||||
stringCopy(
|
|
||||||
chunk->modelNames[m],
|
|
||||||
chunk->dcfEntry->data.chunk.modelNames[m],
|
|
||||||
CHUNK_MESH_NAME_MAX
|
|
||||||
);
|
|
||||||
glm_vec3_copy(
|
|
||||||
chunk->dcfEntry->data.chunk.meshOffsets[m],
|
|
||||||
chunk->meshOffsets[m]
|
|
||||||
);
|
|
||||||
vec3 pos;
|
|
||||||
glm_vec3_add(wpf, chunk->meshOffsets[m], pos);
|
|
||||||
glm_translate_make(chunk->meshModels[m], pos);
|
|
||||||
}
|
|
||||||
assetUnlockEntry(chunk->dcfEntry);
|
|
||||||
chunk->dcfEntry = NULL;
|
|
||||||
chunk->meshCount = meshCount;
|
|
||||||
} else if(state == ASSET_ENTRY_STATE_ERROR) {
|
|
||||||
assetUnlockEntry(chunk->dcfEntry);
|
|
||||||
chunk->dcfEntry = NULL;
|
|
||||||
memorySet(chunk->tiles, TILE_SHAPE_GROUND, sizeof(chunk->tiles));
|
|
||||||
} else {
|
|
||||||
anyPending = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(anyPending) usleep(1000);
|
|
||||||
} while(anyPending);
|
|
||||||
|
|
||||||
// Phase 2: Load model entries one at a time.
|
|
||||||
// Models are locked and waited on sequentially so that only one model
|
|
||||||
// entry occupies a loading slot at a time. This leaves the remaining
|
|
||||||
// slots free for the model's mesh and texture sub-assets, preventing
|
|
||||||
// the slot-exhaustion deadlock that occurs when multiple models are
|
|
||||||
// assigned slots simultaneously and each blocks waiting for sub-assets
|
|
||||||
// that have nowhere to run.
|
|
||||||
for(chunkindex_t i = 0; i < MAP_CHUNK_COUNT; i++) {
|
|
||||||
chunk_t *chunk = &MAP.chunks[i];
|
|
||||||
for(uint8_t m = 0; m < chunk->meshCount; m++) {
|
|
||||||
if(chunk->modelEntries[m] != NULL) continue;
|
|
||||||
chunk->modelEntries[m] = assetLock(
|
|
||||||
chunk->modelNames[m], ASSET_LOADER_TYPE_MODEL, NULL
|
|
||||||
);
|
|
||||||
if(chunk->modelEntries[m] == NULL) {
|
|
||||||
errorThrow("Failed to lock model: %s", chunk->modelNames[m]);
|
|
||||||
}
|
|
||||||
errorChain(assetRequireLoaded(chunk->modelEntries[m]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) {
|
chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) {
|
||||||
if(!mapIsLoaded()) return -1;
|
if(!mapIsLoaded()) return -1;
|
||||||
@@ -298,3 +234,61 @@ tile_t mapGetTile(const worldpos_t position) {
|
|||||||
chunktileindex_t tileIndex = worldPosToChunkTileIndex(&position);
|
chunktileindex_t tileIndex = worldPosToChunkTileIndex(&position);
|
||||||
return chunk->tiles[tileIndex];
|
return chunk->tiles[tileIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mapChunkLoadError(void *params, void *user) {
|
||||||
|
assertNotNull(params, "mapChunkLoadError: params cannot be NULL");
|
||||||
|
assertNotNull(user, "mapChunkLoadError: user cannot be NULL");
|
||||||
|
chunk_t *chunk = (chunk_t *)user;
|
||||||
|
if(chunk->dcfEntry != (assetentry_t *)params) return;
|
||||||
|
consolePrint(
|
||||||
|
"Chunk load error: %d %d %d",
|
||||||
|
(int32_t)chunk->position.x,
|
||||||
|
(int32_t)chunk->position.y,
|
||||||
|
(int32_t)chunk->position.z
|
||||||
|
);
|
||||||
|
assetUnlockEntry(chunk->dcfEntry);
|
||||||
|
chunk->dcfEntry = NULL;
|
||||||
|
memorySet(chunk->tiles, TILE_SHAPE_GROUND, sizeof(chunk->tiles));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mapChunkLoaded(void *params, void *user) {
|
||||||
|
assertNotNull(params, "mapChunkLoaded: params cannot be NULL");
|
||||||
|
assertNotNull(user, "mapChunkLoaded: user cannot be NULL");
|
||||||
|
assetentry_t *entry = (assetentry_t *)params;
|
||||||
|
chunk_t *chunk = (chunk_t *)user;
|
||||||
|
if(chunk->dcfEntry != entry) return;
|
||||||
|
consolePrint(
|
||||||
|
"Chunk loaded: %d %d %d",
|
||||||
|
(int32_t)chunk->position.x,
|
||||||
|
(int32_t)chunk->position.y,
|
||||||
|
(int32_t)chunk->position.z
|
||||||
|
);
|
||||||
|
uint8_t meshCount = entry->data.chunk.meshCount;
|
||||||
|
memoryCopy(
|
||||||
|
chunk->tiles,
|
||||||
|
entry->data.chunk.tiles,
|
||||||
|
sizeof(chunk->tiles)
|
||||||
|
);
|
||||||
|
worldpos_t wp;
|
||||||
|
chunkPosToWorldPos(&chunk->position, &wp);
|
||||||
|
vec3 wpf = { (float_t)wp.x, (float_t)wp.y, (float_t)wp.z };
|
||||||
|
for(uint8_t m = 0; m < meshCount; m++) {
|
||||||
|
stringCopy(
|
||||||
|
chunk->modelNames[m],
|
||||||
|
entry->data.chunk.modelNames[m],
|
||||||
|
CHUNK_MESH_NAME_MAX
|
||||||
|
);
|
||||||
|
glm_vec3_copy(
|
||||||
|
entry->data.chunk.meshOffsets[m],
|
||||||
|
chunk->meshOffsets[m]
|
||||||
|
);
|
||||||
|
vec3 pos;
|
||||||
|
glm_vec3_add(wpf, chunk->meshOffsets[m], pos);
|
||||||
|
glm_translate_make(chunk->meshModels[m], pos);
|
||||||
|
chunk->modelEntries[m] = entry->data.chunk.modelEntries[m];
|
||||||
|
entry->data.chunk.modelEntries[m] = NULL;
|
||||||
|
}
|
||||||
|
assetUnlockEntry(chunk->dcfEntry);
|
||||||
|
chunk->dcfEntry = NULL;
|
||||||
|
chunk->meshCount = meshCount;
|
||||||
|
}
|
||||||
|
|||||||
@@ -52,8 +52,10 @@ bool_t mapIsLoaded();
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the map.
|
* Updates the map.
|
||||||
|
*
|
||||||
|
* @return An error code.
|
||||||
*/
|
*/
|
||||||
void mapUpdate();
|
errorret_t mapUpdate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disposes of the map.
|
* Disposes of the map.
|
||||||
@@ -78,8 +80,7 @@ errorret_t mapPositionSet(const chunkpos_t newPos);
|
|||||||
void mapChunkUnload(chunk_t* chunk);
|
void mapChunkUnload(chunk_t* chunk);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a chunk. Starts async loading without blocking; call
|
* Loads a chunk. Starts async loading without blocking.
|
||||||
* mapWaitForChunks() to block until all pending chunks are ready.
|
|
||||||
*
|
*
|
||||||
* @param chunk The chunk to load.
|
* @param chunk The chunk to load.
|
||||||
* @return An error code.
|
* @return An error code.
|
||||||
@@ -87,13 +88,23 @@ void mapChunkUnload(chunk_t* chunk);
|
|||||||
errorret_t mapChunkLoad(chunk_t* chunk);
|
errorret_t mapChunkLoad(chunk_t* chunk);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blocks the calling thread until every chunk in the active window has
|
* Callback invoked when a chunk DCF asset fails to load. Fills the
|
||||||
* fully loaded its DCF data and all referenced DMF meshes. Intended to
|
* chunk tiles with TILE_SHAPE_GROUND as a fallback.
|
||||||
* be called once at the start of each RPG update tick.
|
* Always invoked on the main thread.
|
||||||
*
|
*
|
||||||
* @return An error code.
|
* @param params The failed assetentry_t.
|
||||||
|
* @param user The chunk_t that owns the entry.
|
||||||
*/
|
*/
|
||||||
errorret_t mapWaitForChunks();
|
void mapChunkLoadError(void *params, void *user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback invoked when a chunk DCF asset finishes loading.
|
||||||
|
* Always invoked on the main thread.
|
||||||
|
*
|
||||||
|
* @param params The loaded assetentry_t.
|
||||||
|
* @param user The chunk_t that owns the entry.
|
||||||
|
*/
|
||||||
|
void mapChunkLoaded(void *params, void *user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the index of a chunk, within the world, at the given position.
|
* Gets the index of a chunk, within the world, at the given position.
|
||||||
|
|||||||
+1
-3
@@ -77,10 +77,8 @@ errorret_t rpgUpdate(void) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
errorChain(mapWaitForChunks());
|
|
||||||
|
|
||||||
// TODO: Do not update if the scene is not the map scene?
|
// TODO: Do not update if the scene is not the map scene?
|
||||||
mapUpdate();
|
errorChain(mapUpdate());
|
||||||
|
|
||||||
// Update overworld ents.
|
// Update overworld ents.
|
||||||
entity_t *ent = &ENTITIES[0];
|
entity_t *ent = &ENTITIES[0];
|
||||||
|
|||||||
Reference in New Issue
Block a user