#ifndef __BEHAVIOUR_DB_H__
#define __BEHAVIOUR_DB_H__

#include <map>

#include <MEngine.h>

// Behaviour
// A little wrapper around MBehaviour to take
// care of a little maintenance. For now just
// inter-behaviour interactions
class Behaviour : public MBehavior
	// typedef the ID so we could potentially
	// change how we refer to behaviours and
	// not have to change all our existing
	// behaviours
	typedef int ID;

	// standard MBehavior constructor, plus our ID
	// for the Behaviour Database
	Behaviour(MObject3d * parentObject, ID id);

	// This probably won't be used as we need the
	// Behaviour ID to be static
	virtual ID GetID() { return 0; }
	// This is where the magic happens
	// from within any custom behaviour, we should
	// now be able to call GetBehaviour<SomeBehaviour>()
	// and be given our sibling behaviour (if one of
	// that type exists on the object)
	template <typename T>
	T* GetBehaviour()
		return (T*)GetBehaviour(T::GetStaticID());
	Behaviour* GetBehaviour(ID behaviour);

// Some helpwe macros to keep things tidy.
// This one goes within the class definition
static void SetID(Behaviour::ID id) { m_ID = id; } 
static Behaviour::ID GetStaticID() { return m_ID; } 
static Behaviour::ID m_ID; 
virtual Behaviour::ID GetID() { return x::GetStaticID(); }
// This one goes at the top of the source file
Behaviour::ID x::m_ID = GetBehaviourDB()->GetBehaviourID(#x);

// BehaviourDB
// The behind-the-scenes magic worker.
// It actually does very little. We just need
// to make sure that it's kept up to date with
// the correct behaviours
class BehaviourDB
	// This is possibly the most important function here
	// It gives us a (semi) unique ID for each behaviour
	// without this, we wouldn't know which is which
	Behaviour::ID GetBehaviourID(const char* name);

	// This is the function that we're usually interested in
	// it will look up the correct behaviour and return it,
	// if one exists, otherwise returning null.
	Behaviour* GetBehaviour(MObject3d* obj, Behaviour::ID id);

	// In order for the database to know the behaviour exists, 
	// we need to register it, but also, afterwards, we'll need
	// to remove it, otherwise we could potentially be returning
	// old and corrupt information
	void RemoveBehaviour(MObject3d* obj, Behaviour* behaviour);
	void RegisterBehaviour(MObject3d* obj, Behaviour* behaviour, Behaviour::ID id);

	typedef std::map<Behaviour::ID, Behaviour*>	behaviourMap;
	typedef behaviourMap::iterator				behaviourMapIter;
	typedef std::map<MObject3d*, behaviourMap>	objectMap;
	typedef objectMap::iterator					objectMapIter;

	objectMap		m_Objects;

// The BehaviourDB is technically a singleton
// so we need a getter
BehaviourDB* GetBehaviourDB();

#endif /*__BEHAVIOUR_DB_H__*/

Leave a Reply

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

Diary of a Slacker