Precaching... The OO Way?

This topic is 4619 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hey all, When you load a level, you load only the neccessary textures for that level. On the other hand, a sound effect could play at any moment in time. These 'any time' resources need to be loaded (all of 'em) to prevent delays in gameplay when a new sound effect plays. "Precaching", as it's called. My experience with professional game source (Half-Life) has revealed the ancient mystic techniques of:
Game :: PrecacheSounds()
{
...

return;
}


Not very pretty... but are there any alternatives? How do you mark your files to be precached?

Share on other sites
Maybe something like:
class SoundCache {    std::map<std::string, Sound> soundMap;public    void cacheSound(std::string name, Sound sound);    Sound getSound(std::string name);};class AbstractFactory {public:    virtual SoundCache* getSoundCache() = 0;    // ... etc ...};// Monostate or singleton.class ConcreteFactory : public AbstractFactory {public:    SoundCache* getSoundCache();    // ... etc ...};// In implementation file for ConcreteFactory.SoundCache* ConcreteFactory::getSoundCache() {    // This is assuming ConcreteFactory is a singleton. For a monostate, this function would probably just have:    // return soundCache;    static std::auto_ptr<SoundCache*> soundCache = std::auto_ptr<SoundCache*>(new SoundCache);    return soundCache;}

Share on other sites
Sorry! I should of made more clear what the actual problem was. In the original example, assume that LOAD_SOUND() is a handy macro to add the sound to some sort of manager. The actual problem I was referring to was the neccessity to explicitly load every single wav file "by hand".

The only other solution I can think of is to use some sort of config file and read the list from that, but it's more or less the same as "hard coding" it.

I was looking to see what others did to solve this "giant list" problem.

(Appreciate the help all the same though.)

Share on other sites
The solution to the "by hand" problem is to not do it by hand :-).

This example depends on the Boost Libraries.

void Game::PrecacheSoundDirectory( boost::filesystem::path directory ) {    using namespace boost::filesystem;    for ( diretory_iterator i( directory ) , directory_iterator end ; i != end ; ++i ) {        if ( is_directory( *i ) ) {            PrecacheSoundDirectory( *i );        } else {            PrecacheSonudFile( *i );        }    }}void Game::PrecacheSoundFile( boost::filesystem::path file ) {    LOAD_SOUND( file );}Game :: PrecacheSounds() {    using namespace boost::filesystem;    path root_directory = ...; //from some config somewhere    path sounds_directory = root_directory / "sounds"; //or config or whatever    if ( ! exists( sounds_directory ) ) {        //throw an error or whatever you want    }    if ( ! is_directory( sounds_directory ) ) {        //throw an error or whatever you want    }    PrecacheSoundDirectory( sounds_directory );}

Share on other sites
Or, use .ogg files (or .cab, or .zip, or whichever other container mechanism you're comfortable with... roll your own, if you like) and simply precache the container file. When loading a container file, just load all the files that are in it.

This solution is similar to Mauling Monkey's suggestion, except maybe less cluttered and easier to distribute. Either option amounts to the same basic thing, but raises issues with files that are common to more than one level (Bullet sounds or jumping sounds or whatever). But this is easily solved without having to copy the file into every directory or container of each level ... just have a "common" directory or container and precache it along with the container for the current level.

[Edited by - void* on June 2, 2005 2:08:29 AM]

Share on other sites
Config file, my reasoning is that you don't want to bloat the executable with strings and the added flexability of not binding you to a particular file structure.

Share on other sites
Quote:
 Original post by Anonymous PosterConfig file, my reasoning is that you don't want to bloat the executable with strings and the added flexability of not binding you to a particular file structure.

The Gutenberg project's edition of "War and Peace" is only 3.3MB... even 16k is a lot of text, you know, so you've got some time to go until strings add untolerable "bloat" to your executable.

The reason I'd present for using a config file is that modifying it doesn't require a recompilation.

Share on other sites
Quote:
 Original post by void*This solution is similar to Mauling Monkey's suggestion example, except maybe less cluttered and easier to distribute.

Fixed.

My intent was not to say "Store each as a seperate file then load them using Boost.Filesystem", rather, it was to say "Don't write the filenames yourself - just read them from whatever".

This includes:

1) As per the example, reading the filenames from the filesystem.

2) Reading in the files from an archive format

3) Reading in the files from a scenario/level/weapon model/user interface/etc file which lists what sound files it triggers when.

4) Probably something else I havn't thought of.

Share on other sites
ah, yes, okay...

Then, reinterpret what I said as, "I agree with MaulingMonkey. You don't have to hardcode your file names, just the top-level directory/container/config-file/UI-descriptor-file, etc."

Share on other sites
@ Fruny

Good point about recompilation, but somehow I get the feeling that you just couldn't pass up the opportunity to mention "The Gutenberg project's edition of "War and Peace" is only 3.3MB" in a forum other than the lounge.

Share on other sites
Quote:
 Original post by FrunyThe Gutenberg project's edition of "War and Peace"

Damn, now i've just got to read that book.

From,
nice coder

Share on other sites
Quote:
 Original post by Anonymous PosterGood point about recompilation, but somehow I get the feeling that you just couldn't pass up the opportunity to mention "The Gutenberg project's edition of "War and Peace" is only 3.3MB" in a forum other than the lounge.

Guilty as charged. [looksaround]

Share on other sites
Quote:
 Original post by void*ah, yes, okay...Then, reinterpret what I said as, "I agree with MaulingMonkey. You don't have to hardcode your file names, just the top-level directory/container/config-file/UI-descriptor-file, etc."

You made a good point with bringing up the option of archive files, I simply was using your post to clarify what I meant, which could have been more clearly stated in the original post, and to agree with that as an option :-).