From 12de6f6b58e15dca875fcc05819d290ae332629f Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 24 Feb 2003 19:30:06 +0000 Subject: [PATCH] Cort Stratton's latest updates adding cache limit support --- panda/src/audiotraits/fmodAudioManager.cxx | 142 ++++++++++++++++++--- panda/src/audiotraits/fmodAudioManager.h | 12 ++ 2 files changed, 135 insertions(+), 19 deletions(-) diff --git a/panda/src/audiotraits/fmodAudioManager.cxx b/panda/src/audiotraits/fmodAudioManager.cxx index bf92cb87c4..83168ddbc4 100644 --- a/panda/src/audiotraits/fmodAudioManager.cxx +++ b/panda/src/audiotraits/fmodAudioManager.cxx @@ -53,8 +53,10 @@ FmodAudioManager() { audio_debug(" audio_volume="<= (unsigned int)_cache_limit) { + uncache_a_sound(); + } + si = _sounds.insert(SoundMap::value_type(path, new_entry)).first; // It's important that we assign entry to the address of the entry @@ -193,6 +214,7 @@ get_sound(const string &file_name) { return 0; } inc_refcount(path); + most_recently_used(path); // determine length of sound float length = (float)FSOUND_Stream_GetLengthMs(stream) * 0.001f; @@ -218,8 +240,16 @@ get_sound(const string &file_name) { void FmodAudioManager:: uncache_sound(const string& file_name) { audio_debug("FmodAudioManager::uncache_sound(\""<resolve_filename(path, get_sound_path()); + } else { + path.resolve_filename(get_sound_path()); + } + audio_debug(" path=\""<refcount == 0) { + // If the refcount is already zero, it can be + // purged right now! audio_debug("FmodAudioManager::uncache_sound: purging "<data; + + // Erase the sound from the LRU list as well. + assert(_lru.size()>0); + LRU::iterator lru_i=find(_lru.begin(), _lru.end(), itor->first); + assert(lru_i != _lru.end()); + _lru.erase(lru_i); _sounds.erase(itor); } else { entry->stale = true; @@ -242,6 +279,48 @@ uncache_sound(const string& file_name) { assert(is_valid()); } +//////////////////////////////////////////////////////////////////// +// Function: FmodAudioManager::uncache_a_sound +// Access: Public +// Description: Uncaches the least recently used sound. +//////////////////////////////////////////////////////////////////// +void FmodAudioManager:: +uncache_a_sound() { + audio_debug("FmodAudioManager::uncache_a_sound()"); + assert(is_valid()); + // uncache least recently used: + assert(_lru.size()>0); + LRU::reference path=_lru.front(); + SoundMap::iterator i = _sounds.find(path); + assert(i != _sounds.end()); + _lru.pop_front(); + + if (i != _sounds.end()) { + audio_debug(" uncaching \""<first<<"\""); + uncache_sound(path); + } + assert(is_valid()); +} + +//////////////////////////////////////////////////////////////////// +// Function: FmodAudioManager::most_recently_used +// Access: Public +// Description: Indicates that the given sound was the most recently used. +//////////////////////////////////////////////////////////////////// +void FmodAudioManager:: +most_recently_used(const string& path) { + audio_debug("FmodAudioManager::most_recently_used(path=\"" + <data; + + // Erase the sound from the LRU list as well. + assert(_lru.size()>0); + LRU::iterator lru_i=find(_lru.begin(), _lru.end(), itor->first); + assert(lru_i != _lru.end()); + _lru.erase(lru_i); _sounds.erase(itor); + itor = _sounds.begin(); } else { entry->stale = true; @@ -277,8 +364,17 @@ clear_cache() { // Description: //////////////////////////////////////////////////////////////////// void FmodAudioManager:: -set_cache_limit(int) { - // intentionally blank. +set_cache_limit(int count) { + audio_debug("FmodAudioManager::set_cache_limit(count=" + < (unsigned int) count) { + uncache_a_sound(); + } + + _cache_limit = count; + assert(is_valid()); } //////////////////////////////////////////////////////////////////// @@ -288,8 +384,9 @@ set_cache_limit(int) { //////////////////////////////////////////////////////////////////// int FmodAudioManager:: get_cache_limit() { - // intentionally blank. - return 0; + audio_debug("FmodAudioManager::get_cache_limit() returning " + <<_cache_limit); + return _cache_limit; } //////////////////////////////////////////////////////////////////// @@ -377,16 +474,17 @@ stop_all_sounds(void) { void FmodAudioManager:: inc_refcount(const string& file_name) { Filename path = file_name; - SoundMap::iterator itor = _sounds.find(path.to_os_specific()); - if (itor != _sounds.end()) { - SoundCacheEntry *entry = &(*itor).second; - entry->refcount++; - entry->stale = false; // definitely not stale! - audio_debug("FmodAudioManager: "<refcount); - } else { + SoundMap::iterator itor = _sounds.find(path); + if (itor == _sounds.end()) { audio_debug("FmodAudioManager::inc_refcount: no such file "<refcount++; + entry->stale = false; // definitely not stale! + audio_debug("FmodAudioManager: "<refcount); } //////////////////////////////////////////////////////////////////// @@ -399,7 +497,7 @@ inc_refcount(const string& file_name) { void FmodAudioManager:: dec_refcount(const string& file_name) { Filename path = file_name; - SoundMap::iterator itor = _sounds.find(path.to_os_specific()); + SoundMap::iterator itor = _sounds.find(path); if (itor != _sounds.end()) { SoundCacheEntry *entry = &(*itor).second; entry->refcount--; @@ -408,6 +506,12 @@ dec_refcount(const string& file_name) { if (entry->refcount == 0 && entry->stale) { audio_debug("FmodAudioManager::dec_refcount: purging "<data; + + // Erase the sound from the LRU list as well. + assert(_lru.size()>0); + LRU::iterator lru_i=find(_lru.begin(), _lru.end(), itor->first); + assert(lru_i != _lru.end()); + _lru.erase(lru_i); _sounds.erase(itor); } } else { diff --git a/panda/src/audiotraits/fmodAudioManager.h b/panda/src/audiotraits/fmodAudioManager.h index 2428f074af..9aa3dfe298 100644 --- a/panda/src/audiotraits/fmodAudioManager.h +++ b/panda/src/audiotraits/fmodAudioManager.h @@ -26,6 +26,7 @@ #include "audioManager.h" class FmodAudioSound; #include "filename.h" +#include "pdeque.h" #include "pmap.h" #include "pset.h" @@ -48,6 +49,12 @@ public: virtual void set_cache_limit(int); virtual int get_cache_limit(); + // Indicates that the given sound was the most recently used. + void most_recently_used(const string& path); + + // Uncaches the least recently used sound. + void uncache_a_sound(); + virtual void set_volume(float); virtual float get_volume(); @@ -74,8 +81,13 @@ private: // The offspring of this manager: AudioSet _soundsOnLoan; + // The Least Recently Used mechanism: + typedef pdeque LRU; + LRU _lru; + void release_sound(FmodAudioSound *audioSound); + int _cache_limit; static int _active_managers; bool _is_valid; bool _active;