I'm having trouble implementing a resource and entity manager using std::map's in my game engine. I've been using std::vector's before and it worked fine, but now that I added Lua scripting, I want all my resources and entities to be accessible by their filenames and names respectively.
GetResource() and AddResource() seem to work fine, but as soon as I try to insert the newly created sound source (= entitiy) to the std::map in AddSoundSource(), my test application crashes.
GetResource(), AddResource() in class Resource:
typedef std::map<std::string, Resource *> Resources;
typedef std::pair<std::string, Resource *> KeyResourcePair;
typedef std::map<std::string, Resource *>::iterator ResourcesIterator;
Resource *ResourceManager::GetResource( const std::string &filename )
{
// look for resource
ResourcesIterator kIterator;
kIterator = m_hpkResources.find( filename );
// return 0 if not found
if( kIterator == m_hpkResources.end() )
return 0;
// return resource
return ((*kIterator).second);
}
Resource *ResourceManager::AddResource( const std::string &filename )
{
// look for resource, return if found
Resource *pkResource = GetResource( filename );
if( pkResource )
{
return pkResource;
}
// load resource
// so far the only entities available are sound buffers,
// so I can safely assume that the requested resource is
// a sound buffer. Later, I'll have to check the filename
// extension to create the appropiate entity
pkResource = new SoundBuffer( filename );
if( !pkResource->IsLoaded() )
{
return 0;
}
// add new resource to hash table
m_hpkResources.insert( KeyResourcePair(filename, pkResource) );
return pkResource;
}
GetSoundSource(), AddSoundSource() in class World:
typedef std::map<std::string, SoundSource *> SoundSources;
typedef std::pair<std::string, SoundSource *> KeySoundSourcePair;
typedef std::map<std::string, SoundSource *>::iterator SoundSourcesIterator;
SoundSource *World::GetSoundSource( const std::string &name )
{
// look for sound source
SoundSourcesIterator kIterator;
kIterator = m_hpkSoundSources.find( name );
// return 0 if not found
if( kIterator == m_hpkSoundSources.end() )
return 0;
// return resource
return ((*kIterator).second);
}
SoundSource *World::AddSoundSource( const std::string &name, const std::string &filename )
{
// load sound buffer if it's not yet loaded
SoundBuffer *pkBuffer = (SoundBuffer *)ResourceManager::GetSingleton().AddResource( filename );
if( !pkBuffer )
{
return 0;
}
// create new sound source
SoundSource *pkSource = new SoundSource( name, pkBuffer );
// add new sound source to hash table
m_hpkSoundSources.insert( KeySoundSourcePair(name, pkSource) ); // <- crashes here!
return pkSource;
}
in my test application, I then call:
SoundSource *pkSource = g_pkWorld->AddSoundSource( "test", "test.ogg" );
which is supposed to check if the requested resource "test.ogg" has already been loaded, load it if it hasn't, and then create a new sound source and attach the resource to it.
Any ideas what I'm doing wrong? I haven't worked with std::map's before, maybe I'm missing something? Thank you!