755
// This is our simple game object handle class.
classGameObjectHandle
{
private:
U32 m_handleIndex; // index into the handle
// table
GameObjectId m_uniqueId; // unique id avoids stale
// handles
public:
explicit GameObjectHandle(GameObject& object) :
m_handleIndex(object.m_handleIndex),
m_uniqueId(object.m_uniqueId)
{
}
// This function dereferences the handle.
GameObject* ToObject() const
{
GameObject* pObject
= g_apGameObject[m_handleIndex];
if (pObject != NULL
&& pObject->m_uniqueId == m_uniqueId)
{
return pObject;
}
return NULL;
}
};
This example is functional but incomplete. We might want to implement copy
semantics, provide additional constructor variants, and so on. The entries in
the global handle table might contain additional information, not just a raw
pointer to each game object. And of course, a fi xed-size handle table imple-
mentation like this one isn’t the only possible design; handle systems vary
somewhat from engine to engine.
We should note that one fortunate side benefi t of a global handle table is
that it gives us a ready-made list of all active game objects in the system. The
global handle table can be used to quickly and effi ciently iterate over all game
objects in the world, for example. It can also make implementing other kinds
of queries easier in some cases.
14.5.4. Game Object Queries
Every game engine provides at least a few ways to fi nd game objects at run-
time. We’ll call these searches game object queries. The simplest type of query is
to fi nd a particular game object by its unique id. However, a real game engine
14.5. Object References and World Queries