BehaviourDB.cpp

#include "BehaviourDB.h"
#include "Util.h"

// BehaviourDB getter. These could have been static functions/members
// but I kept them external as it means one less function call within
// each Behaviour. A little pedantic, I know, but so what.
BehaviourDB g_BehaviourDB;
BehaviourDB* GetBehaviourDB() { return &g_BehaviourDB; }

//--------------------------------------------
// Behaviour
//--------------------------------------------
Behaviour::Behaviour(MObject3d * parentObject, ID id)
: MBehavior(parentObject) 
{
	// On creation, we need to register ourselves
	g_BehaviourDB.RegisterBehaviour(getParentObject(), this, id);
}
//--------------------------------------------
Behaviour::~Behaviour()
{
	// We're not needed any more? Make sure we don't stay in
	// the database
	g_BehaviourDB.RemoveBehaviour(getParentObject(), this);
}
//--------------------------------------------
Behaviour* Behaviour::GetBehaviour(ID behaviour)
{
	// Just pass the request onto the database
	return g_BehaviourDB.GetBehaviour(getParentObject(), behaviour);
}

//--------------------------------------------
// BehaviourDB
//--------------------------------------------
Behaviour::ID BehaviourDB::GetBehaviourID(const char* name)
{
	// There are a great many ways we could sort IDs. The
	// simple method used for the messages wouldn't work
	// here as potentially we will call GetBehaviourID
	// multiple times. We could keep a list of already
	// registered behaviours, but that's hassle. Instead
	// we'll just grab a hash of the name. That should
	// be unique enough
	return Util::Hash(name);
}
//--------------------------------------------
Behaviour* BehaviourDB::GetBehaviour(MObject3d* obj, Behaviour::ID id)
{
	// we could just use m_Objects[obj][id] at this point
	// it would even return 0 if there wasn't a behaviour
	// registered. The issue is that it will make empty 
	// entries in our map, which we don't want
	// instead, we'll use map::find to look through the
	// map and pull out what we want
	objectMapIter iObj = m_Objects.find(obj);
	if(iObj != m_Objects.end())
	{
		behaviourMapIter iBehaviour = iObj->second.find(id);
		if(iBehaviour != iObj->second.end())
		{
			return iBehaviour->second;
		}
	}
	return 0;
}
//--------------------------------------------
void BehaviourDB::RemoveBehaviour(MObject3d* obj, Behaviour* behaviour)
{
	// at this point, we can assume that m_Objects[obj] exists
	// so we shouldn't need to do a map::find on that, however
	// we could potentially be looking for a behaviour that
	// has already been removed. So we need to safeguard
	// against that.
	behaviourMapIter iBehaviour = m_Objects[obj].find(behaviour->GetID());
	if(iBehaviour != m_Objects[obj].end())
	{
		m_Objects[obj].erase(iBehaviour);
	}

	// If the object is now empty, we can remove it and save some space
	objectMapIter iObj = m_Objects.find(obj);
	if(iObj->second.size() == 0)
	{
		m_Objects.erase(iObj);
	}
}
//--------------------------------------------
void BehaviourDB::RegisterBehaviour(MObject3d* obj, Behaviour* behaviour, Behaviour::ID id)
{
	// absolutely no point in doing any kind of find behaviour here.
	// just stick it in the map, making new entries where needed
	m_Objects[obj][id] = behaviour;
}
//--------------------------------------------

Leave a Reply

Your email address will not be published. Required fields are marked *

Diary of a Slacker