# HG changeset patch # User Matti Hamalainen # Date 1350411946 -10800 # Node ID 59045853853d2bd81315ff04802f255a57778010 # Parent 3bdc776a4b336c5c1a9bb97bc5769bd7793c41c6 Make resource management re-entrant. diff -r 3bdc776a4b33 -r 59045853853d dmengine.c --- a/dmengine.c Tue Oct 16 21:24:48 2012 +0300 +++ b/dmengine.c Tue Oct 16 21:25:46 2012 +0300 @@ -198,7 +198,7 @@ void *engineGetResource(const char *name) { - DMResource *res = dmres_find(name); + DMResource *res = dmres_find(engine.resources, name); if (res != NULL && res->rdata != NULL) return res->rdata; else diff -r 3bdc776a4b33 -r 59045853853d dmengine.h --- a/dmengine.h Tue Oct 16 21:24:48 2012 +0300 +++ b/dmengine.h Tue Oct 16 21:25:46 2012 +0300 @@ -22,12 +22,20 @@ typedef struct { + int currFrame, endTime, startTime; +} DMFrameData; + + +typedef struct +{ + DMResourceLib *resources; + DMResource *timeline; DMTimeline *tl; DMPreparedTimeline *ptl; - int currFrame, endTime, startTime, - totalFrameTime, adjustTime, pauseTime; + DMFrameData frame; + int totalFrameTime, adjustTime, pauseTime; BOOL pauseFlag, paused, exitFlag; SDL_Surface *screen; @@ -44,7 +52,7 @@ #endif #ifdef DM_USE_TREMOR - DMResource *audio; + DMResource *audioRes; size_t audioPos; #endif @@ -58,14 +66,7 @@ } DMEngineData; -typedef struct -{ - int currFrame, endTime, startTime; -} DMFrameData; - - extern DMEngineData engine; -extern DMFrameData frame; #define engineGetResImage(x, name) \ diff -r 3bdc776a4b33 -r 59045853853d dmlib.h --- a/dmlib.h Tue Oct 16 21:24:48 2012 +0300 +++ b/dmlib.h Tue Oct 16 21:25:46 2012 +0300 @@ -482,4 +482,5 @@ #ifdef __cplusplus } #endif + #endif // DMLIB_H diff -r 3bdc776a4b33 -r 59045853853d dmres.c --- a/dmres.c Tue Oct 16 21:24:48 2012 +0300 +++ b/dmres.c Tue Oct 16 21:25:46 2012 +0300 @@ -8,31 +8,13 @@ #include -#define DMRES_LOCK(x) dmMutexLock(dfResourcesMutex) -#define DMRES_UNLOCK(x) dmMutexUnlock(dfResourcesMutex) - - -/* Global variables - */ -static BOOL dfResInitialized = FALSE; -static int dfResFlags = 0; -static char * dfResPath = NULL; -DMResource * dfResources = NULL; -DMMutex * dfResourcesMutex = NULL; - - -#ifdef DM_USE_PACKFS -static DMPackFile *dfResPackFile = NULL; -static char * dfResPackFilename = NULL; -#endif - - -DMResource *dmres_new(const char *filename, int flags, size_t size) +DMResource *dmres_new(DMResourceLib *lib, const char *filename, int flags, size_t size) { DMResource *node = dmMalloc0(sizeof(DMResource)); if (node == NULL) return NULL; + node->lib = lib; node->filename = dm_strdup(filename); node->flags = flags; node->dataSize = size; @@ -84,44 +66,55 @@ } -static void dmres_insert(DMResource * node) +void dmres_insert(DMResourceLib *lib, DMResource * node) { - if (dfResources != NULL) + if (lib == NULL) + return; + + node->lib = lib; + + if (lib->resources != NULL) { - node->prev = dfResources->prev; - dfResources->prev->next = node; - dfResources->prev = node; + node->prev = lib->resources->prev; + lib->resources->prev->next = node; + lib->resources->prev = node; } else { - dfResources = node->prev = node; + lib->resources = node->prev = node; } node->next = NULL; } -static void dmres_delete(DMResource * node) +void dmres_delete(DMResourceLib *lib, DMResource * node) { + if (lib == NULL) + return; + if (node->prev) node->prev->next = node->next; if (node->next) node->next->prev = node->prev; else - dfResources->prev = node->prev; + lib->resources->prev = node->prev; node->prev = node->next = NULL; } -DMResource * dmres_find(const char *filename) +DMResource * dmres_find(DMResourceLib *lib, const char *filename) { DMResource *node, *found = NULL; - DMRES_LOCK(); + if (lib == NULL) + return NULL; - for (node = dfResources; node != NULL; node = node->next) + dmMutexLock(lib->mutex); + + for (node = lib->resources; node != NULL; node = node->next) { if (strcmp(node->filename, filename) == 0) { @@ -130,7 +123,7 @@ } } - DMRES_UNLOCK(); + dmMutexUnlock(lib->mutex); return found; } @@ -322,8 +315,11 @@ z_stream cstream; Uint8 * cbuffer = NULL; + if (handle->lib == NULL || handle->lib->packFile == NULL) + return DMERR_NULLPTR; + // Search PACK nodelist for file - if ((node = dm_pack_find(dfResPackFile->entries, handle->filename)) == NULL) + if ((node = dm_pack_find(handle->lib->packFile->entries, handle->filename)) == NULL) { dmError("Entry '%s' not found in PACK file.\n", handle->filename); res = DMERR_NOT_FOUND; @@ -331,7 +327,7 @@ } // Seek to entry - if (fseek(dfResPackFile->file, node->offset, SEEK_SET) == -1) + if (fseek(handle->lib->packFile->file, node->offset, SEEK_SET) == -1) { dmError("Could not seek node position in PACK file.\n"); res = DMERR_FSEEK; @@ -378,7 +374,7 @@ cstream.avail_in = fread( cbuffer, sizeof(Uint8), (cdataLeft >= DPACK_TMPSIZE) ? DPACK_TMPSIZE : cdataLeft, - dfResPackFile->file); + handle->lib->packFile->file); cdataLeft -= cstream.avail_in; cstream.next_in = cbuffer; @@ -540,7 +536,7 @@ if (handle->fops == NULL) { #ifdef DM_USE_PACKFS - if (dfResFlags & DRF_USE_PACK) + if (handle->lib->flags & DRF_USE_PACK) handle->fops = &dfPackFileOps; #ifdef DM_USE_STDIO else @@ -562,7 +558,7 @@ // Check if we want to preload raw data? if (((handle->flags & DMF_PRELOAD_RAW) || - (dfResFlags & DRF_PRELOAD_ALL)) && + (handle->lib->flags & DRF_PRELOAD_ALL)) && (handle->flags & DMF_LOADED_RAW) == 0 && handle->fops->preload != NULL) { @@ -588,7 +584,7 @@ } // Check if resource data is to be preloaded - if (((handle->flags & DMF_PRELOAD_RES) || (dfResFlags & DRF_PRELOAD_RES)) && + if (((handle->flags & DMF_PRELOAD_RES) || (handle->lib->flags & DRF_PRELOAD_RES)) && (handle->flags & DMF_LOADED_RES) == 0 && handle->rops != NULL && handle->rops->load != NULL) @@ -609,22 +605,22 @@ } -DMResource *dmf_open(const char *filename) +DMResource *dmf_open(DMResourceLib *lib, const char *filename) { int ret; DMResource *handle; // Check master directory for resource - if ((handle = dmres_find(filename)) == NULL) + if ((handle = dmres_find(lib, filename)) == NULL) { #ifdef DM_USE_STDIO // Hmm.. does not exist? Fall back to a stdio file - handle = dmres_new(filename, 0, 0); + handle = dmres_new(lib, filename, 0, 0); if (handle == NULL) return NULL; handle->fops = &dfStdioFileOps; - dmres_insert(handle); + dmres_insert(lib, handle); #else // Stdio not enabled, fail return NULL; @@ -654,21 +650,21 @@ } -DMResource * dmf_open_memio(const char *filename, Uint8 *buf, size_t len) +DMResource * dmf_create_memio(DMResourceLib *lib, const char *filename, Uint8 *buf, size_t len) { DMResource *handle; // Check master directory for resource - if ((handle = dmres_find(filename)) == NULL) + if ((handle = dmres_find(lib, filename)) == NULL) { // Hmm.. does not exist? Fall back to a stdio file - handle = dmres_new(filename, DMF_LOADED_RAW, len); + handle = dmres_new(lib, filename, DMF_LOADED_RAW, len); if (handle == NULL) return NULL; handle->fops = &dfMemIOFileOps; handle->data = buf; - dmres_insert(handle); + dmres_insert(lib, handle); } // Increase refcount @@ -681,7 +677,7 @@ #ifdef DM_USE_STDIO DMResource * dmf_create_stdio(const char *filename, const char *mode) { - DMResource *handle = dmres_new(filename, 0, 0); + DMResource *handle = dmres_new(NULL, filename, 0, 0); if (handle == NULL) return NULL; @@ -705,7 +701,7 @@ DMResource * dmf_create_stdio_stream(FILE *fh) { - DMResource *handle = dmres_new("", 0, 0); + DMResource *handle = dmres_new(NULL, "", 0, 0); if (handle == NULL) return NULL; @@ -803,13 +799,12 @@ } - int dmres_ref(DMResource *node) { - DMRES_LOCK(); + if (node->lib != NULL) dmMutexLock(node->lib->mutex); node->atime = time(NULL); node->refcount++; - DMRES_UNLOCK(); + if (node->lib != NULL) dmMutexUnlock(node->lib->mutex); return node->refcount; } @@ -817,9 +812,9 @@ int dmres_unref(DMResource *node) { - DMRES_LOCK(); + if (node->lib != NULL) dmMutexLock(node->lib->mutex); node->refcount--; - DMRES_UNLOCK(); + if (node->lib != NULL) dmMutexUnlock(node->lib->mutex); return node->refcount; } @@ -861,7 +856,7 @@ } -int dmres_load_resfile(const char *filename) +int dmres_load_resfile(DMResourceLib *lib, const char *filename) { int ret = DMERR_OK; char line[256]; @@ -869,7 +864,7 @@ if (f == NULL) return DMERR_FOPEN; - DMRES_LOCK(); + dmMutexLock(lib->mutex); while (fgets(line, sizeof(line) - 1, f) != NULL) { @@ -883,23 +878,17 @@ line[i] = 0; for (i = fsep; isspace(line[i]); i++); - - if (sscanf(&line[i], "%x", &flags) == 1 && - strlen(&line[fnstart]) > 0) - { - - } } } - DMRES_UNLOCK(); + dmMutexUnlock(lib->mutex); fclose(f); return ret; } -int dmres_write_resfile(const char *filename) +int dmres_write_resfile(DMResourceLib *lib, const char *filename) { int ret; DMResource *node; @@ -907,11 +896,13 @@ if (f == NULL) return DMERR_FOPEN; - DMRES_LOCK(); + dmMutexLock(lib->mutex); - for (node = dfResources; node != NULL; node = node->next) + for (node = lib->resources; node != NULL; node = node->next) { - if (fprintf(f, "%s|%08x\n", node->filename, node->flags) < 0) + char tmp[64]; + dmres_flags_to_symbolic(tmp, sizeof(tmp), node->flags); + if (fprintf(f, "%s|%s\n", node->filename, tmp) < 0) { ret = DMERR_FWRITE; goto error; @@ -919,7 +910,7 @@ } error: - DMRES_UNLOCK(); + dmMutexUnlock(lib->mutex); fclose(f); return ret; } @@ -927,15 +918,18 @@ /* Resources subsystem initialization and shutdown routines */ -int dmres_init(const char *filename, const char *path, const int flags, int (*classifier)(DMResource *)) +int dmres_init(DMResourceLib **plib, const char *filename, const char *path, const int flags, int (*classifier)(DMResource *)) { - // Check if we are already initialized - if (dfResInitialized) - return DMERR_ALREADY_INIT; + DMResourceLib *lib; + + // Allocate the resource library structure + if ((*plib = lib = dmMalloc0(sizeof(DMResourceLib))) == NULL) + return DMERR_MALLOC; - dfResFlags = flags; - dfResPath = dm_strdup((path != NULL) ? path : DMRES_DATA_PATH); - dfResourcesMutex = dmCreateMutex(); + // Basic data + lib->mutex = dmCreateMutex(); + lib->flags = flags; + lib->resPath = dm_strdup((path != NULL) ? path : DMRES_DATA_PATH); if (flags & DRF_USE_PACK) @@ -944,22 +938,22 @@ int ret; DMPackEntry *node; - dfResPackFilename = dm_strdup((filename != NULL) ? filename : DMRES_DATA_PACK); + lib->packFilename = dm_strdup((filename != NULL) ? filename : DMRES_DATA_PACK); // Initialize PACK, open as read-only - ret = dm_pack_open(dfResPackFilename, &dfResPackFile, TRUE); + ret = dm_pack_open(lib->packFilename, &lib->packFile, TRUE); if (ret != DMERR_OK) { dmError("Error opening PACK file '%s', #%i: %s\n", - dfResPackFilename, ret, dmErrorStr(ret)); + lib->packFilename, ret, dmErrorStr(ret)); return DMERR_INIT_FAIL; } // Initialize resources from a PACK file - for (node = dfResPackFile->entries; node != NULL; node = node->next) + for (node = lib->packFile->entries; node != NULL; node = node->next) { - DMResource *res = dmres_new(node->filename, node->resFlags & DMF_MASK, node->size); + DMResource *res = dmres_new(lib, node->filename, node->resFlags & DMF_MASK, node->size); if (res == NULL) { dmError("Could not allocate memory for resource node '%s' [0x%08x], %d.\n", @@ -967,7 +961,7 @@ return DMERR_INIT_FAIL; } - dmres_insert(res); + dmres_insert(lib, res); } #else @@ -978,8 +972,8 @@ else { // Initialize resources from a resource directory - char *resFilename = dm_strdup_printf("%s%s", dfResPath, DMRES_RES_FILE); - int ret = dmres_load_resfile(resFilename); + char *resFilename = dm_strdup_printf("%s%s", lib->resPath, DMRES_RES_FILE); + int ret = dmres_load_resfile(lib, resFilename); dmFree(resFilename); if (ret != DMERR_OK) @@ -987,10 +981,10 @@ } // Okay, classify resources - if (dfResources != NULL && classifier != NULL) + if (lib->resources != NULL && classifier != NULL) { DMResource *node; - for (node = dfResources; node != NULL; node = node->next) + for (node = lib->resources; node != NULL; node = node->next) { int ret = classifier(node); if (ret != DMERR_OK) @@ -999,36 +993,36 @@ } // Initialization complete - dfResInitialized = TRUE; return DMERR_OK; } -void dmres_close(void) +int dmres_close(DMResourceLib *lib) { DMResource *node; - DMRES_LOCK(); + + if (lib == NULL) + return DMERR_NULLPTR; + + dmMutexLock(lib->mutex); - if (!dfResInitialized) - return; - // Shutdown possible subsystems #ifdef DM_USE_PACKFS - if (dfResFlags & DRF_USE_PACK) + if (lib->flags & DRF_USE_PACK) { - int res = dm_pack_close(dfResPackFile); + int res = dm_pack_close(lib->packFile); if (res != DMERR_OK) { dmError("Error closing PACK, #%i: %s\n", res, dmErrorStr(res)); } - dmFree(dfResPackFilename); + dmFree(lib->packFilename); } #endif // Free resource entries - node = dfResources; + node = lib->resources; while (node != NULL) { DMResource *next = node->next; @@ -1037,65 +1031,64 @@ } // Etc. - dmFree(dfResPath); - DMRES_UNLOCK(); - dmDestroyMutex(dfResourcesMutex); - dfResInitialized = FALSE; + dmFree(lib->resPath); + dmMutexUnlock(lib->mutex); + dmDestroyMutex(lib->mutex); + return DMERR_OK; } -int dmres_preload(BOOL start, int *loaded, int *total) +int dmres_preload(DMResourceLib *lib, BOOL start, int *loaded, int *total) { - static DMResource *dfPreload = NULL; int ret = DMERR_OK; - DMRES_LOCK(); + dmMutexLock(lib->mutex); // Initialize preloading - if (dfPreload == NULL || start) + if (lib->preload == NULL || start) { DMResource *node; - dfPreload = dfResources; + lib->preload = lib->resources; *loaded = 0; *total = 0; // Calculate total number of resources to be preloaded - for (node = dfResources; node != NULL; node = node->next) + for (node = lib->resources; node != NULL; node = node->next) { - if ((dfResFlags & (DRF_PRELOAD_ALL | DRF_PRELOAD_RES)) || + if ((lib->flags & (DRF_PRELOAD_ALL | DRF_PRELOAD_RES)) || (node->flags & (DMF_PRELOAD_RAW | DMF_PRELOAD_RES))) (*total)++; } } else - if (dfPreload != NULL) + if (lib->preload != NULL) { // Initialize fops and preload - dmf_init_fops(dfPreload); - if ((ret = dmf_preload(dfPreload)) != DMERR_OK) + dmf_init_fops(lib->preload); + if ((ret = dmf_preload(lib->preload)) != DMERR_OK) goto error; (*loaded)++; - dfPreload = dfPreload->next; + lib->preload = lib->preload->next; } - DMRES_UNLOCK(); - return (dfPreload == NULL) ? DMERR_OK : DMERR_PROGRESS; + dmMutexUnlock(lib->mutex); + return (lib->preload == NULL) ? DMERR_OK : DMERR_PROGRESS; error: - DMRES_UNLOCK(); + dmMutexUnlock(lib->mutex); return ret; } -void dmres_prune(int agems, int flags) +void dmres_prune(DMResourceLib *lib, int agems, int flags) { DMResource *node; int currtime = time(NULL); - DMRES_LOCK(); + dmMutexLock(lib->mutex); - for (node = dfResources; node != NULL; node = node->next) + for (node = lib->resources; node != NULL; node = node->next) { // Check if node has refcount of 0 and is // not marked as persistent resource @@ -1115,7 +1108,7 @@ } } - DMRES_UNLOCK(); + dmMutexUnlock(lib->mutex); } diff -r 3bdc776a4b33 -r 59045853853d dmres.h --- a/dmres.h Tue Oct 16 21:24:48 2012 +0300 +++ b/dmres.h Tue Oct 16 21:25:46 2012 +0300 @@ -49,6 +49,7 @@ /* Typedefs and structures */ +struct DMResourceLib; struct DMResourceDataOps; struct DMResourceOps; struct DMResource; @@ -70,6 +71,7 @@ int error; // Error code struct DMResourceOps *fops; // Pointer to file handling functions struct + struct DMResourceLib *lib; struct DMResource *next, *prev; void *rdata; @@ -88,6 +90,21 @@ } DMResourceDataOps; +typedef struct DMResourceLib +{ + int flags; + char *resPath; + + DMResource *resources, *preload; + DMMutex *mutex; + +#ifdef DM_USE_PACKFS + char *packFilename; + DMPackFile *packFile; +#endif +} DMResourceLib; + + typedef struct DMResourceOps { int (*ferror)(DMResource *); @@ -108,27 +125,29 @@ /* Functions */ -int dmres_init(const char *filename, const char *path, const int flags, int (*classifier)(DMResource *)); -void dmres_close(void); +int dmres_init(DMResourceLib **lib, const char *filename, const char *path, const int flags, int (*classifier)(DMResource *)); +int dmres_close(DMResourceLib *lib); -void dmres_prune(int agems, int flags); -int dmres_preload(BOOL start, int *loaded, int *total); +void dmres_prune(DMResourceLib *lib, int agems, int flags); +int dmres_preload(DMResourceLib *lib, BOOL start, int *loaded, int *total); void dmres_flags_to_symbolic(char *str, size_t size, int flags); int dmres_symbolic_to_flags(const char *str); -int dmres_load_resfile(const char *filename); -int dmres_write_resfile(const char *filename); +int dmres_load_resfile(DMResourceLib *lib, const char *filename); +int dmres_write_resfile(DMResourceLib *lib, const char *filename); -DMResource * dmres_new(const char *filename, int flags, size_t size); +DMResource * dmres_new(DMResourceLib *lib, const char *filename, int flags, size_t size); void dmres_free(DMResource *node); -DMResource * dmres_find(const char *filename); +void dmres_insert(DMResourceLib *lib, DMResource * node); +void dmres_delete(DMResourceLib *lib, DMResource * node); +DMResource * dmres_find(DMResourceLib *lib, const char *filename); int dmres_ref(DMResource *); int dmres_unref(DMResource *); // Opening and closing resources -DMResource * dmf_open(const char *); -DMResource * dmf_open_memio(const char *, Uint8 *buf, size_t len); +DMResource * dmf_open(DMResourceLib *lib, const char *); +DMResource * dmf_create_memio(DMResourceLib *lib, const char *, Uint8 *buf, size_t len); #ifdef DM_USE_STDIO DMResource * dmf_create_stdio(const char *filename, const char *mode); DMResource * dmf_create_stdio_stream(FILE *); diff -r 3bdc776a4b33 -r 59045853853d dmsimple.c --- a/dmsimple.c Tue Oct 16 21:24:48 2012 +0300 +++ b/dmsimple.c Tue Oct 16 21:25:46 2012 +0300 @@ -50,7 +50,7 @@ int engineGetTick() { - return (frame.startTime - engine.startTime) + engine.adjustTime; + return (engine.frame.startTime - engine.startTime) + engine.adjustTime; } @@ -144,9 +144,9 @@ { int err, loaded, total; - err = dmres_preload(TRUE, &loaded, &total); + err = dmres_preload(engine.resources, TRUE, &loaded, &total); - while ((err = dmres_preload(FALSE, &loaded, &total)) == DMERR_PROGRESS) + while ((err = dmres_preload(engine.resources, FALSE, &loaded, &total)) == DMERR_PROGRESS) { // Show a nice progress bar while loading if (total > 0 && (loaded % 2) == 0) @@ -213,7 +213,7 @@ // Initialize resource subsystem dmPrint(1, "Initializing resources subsystem.\n"); - if ((err = dmres_init(engine.optPackFilename, engine.optDataPath, engine.optResFlags, engineClassifier)) != DMERR_OK) + if ((err = dmres_init(&engine.resources, engine.optPackFilename, engine.optDataPath, engine.optResFlags, engineClassifier)) != DMERR_OK) { dmError("Could not initialize resource manager: %d, %s.\n", err, dmErrorStr(err)); goto error_exit; @@ -395,7 +395,7 @@ } // Draw frame - frame.startTime = SDL_GetTicks(); + engine.frame.startTime = SDL_GetTicks(); if (engine.pauseFlag != engine.paused) { engine.paused = engine.pauseFlag; @@ -404,7 +404,7 @@ if (engine.paused) { - engine.startTime = frame.startTime - engine.pauseTime; + engine.startTime = engine.frame.startTime - engine.pauseTime; } if (SDL_MUSTLOCK(engine.screen) != 0 && SDL_LockSurface(engine.screen) != 0) @@ -433,9 +433,9 @@ SDL_Delay(engine.paused ? 100 : 20); // Get frame time, etc - frame.endTime = SDL_GetTicks(); + engine.frame.endTime = SDL_GetTicks(); engine.currFrame++; - engine.totalFrameTime += frame.endTime - frame.startTime; + engine.totalFrameTime += engine.frame.endTime - engine.frame.startTime; } // Print benchmark results @@ -465,7 +465,7 @@ dmFreeTimeline(engine.tl); dmFreePreparedTimelineData(engine.ptl); dmShutdownEffects(); - dmres_close(); + dmres_close(engine.resources); if (engine.demoShutdown != NULL) engine.demoShutdown(); diff -r 3bdc776a4b33 -r 59045853853d ppl.c --- a/ppl.c Tue Oct 16 21:24:48 2012 +0300 +++ b/ppl.c Tue Oct 16 21:25:46 2012 +0300 @@ -633,7 +633,7 @@ // Get font // file = dmf_create_stdio("fnsmall.fnt", "rb"); - file = dmf_open_memio("pplfont.fnt", dmPlayerFont, sizeof(dmPlayerFont)); + file = dmf_create_memio(NULL, "pplfont.fnt", dmPlayerFont, sizeof(dmPlayerFont)); if (file == NULL) { dmError("Error opening font file 'pplfont.fnt'.\n");