Pyrogenesis  trunk
Classes | Public Types | Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | Friends | List of all members
CComponentManager Class Reference

#include <ComponentManager.h>

Collaboration diagram for CComponentManager:
Collaboration graph
[legend]

Classes

struct  ComponentType
 
struct  FindJSONFilesCallbackData
 

Public Types

typedef int InterfaceId
 
typedef int ComponentTypeId
 
typedef int MessageTypeId
 
typedef std::pair< entity_id_t, IComponent * > InterfacePair
 
typedef std::vector< InterfacePairInterfaceList
 
typedef boost::unordered_map< entity_id_t, IComponent * > InterfaceListUnordered
 

Public Member Functions

 CComponentManager (CSimContext &, shared_ptr< ScriptRuntime > rt, bool skipScriptFunctions=false)
 
 ~CComponentManager ()
 
void LoadComponentTypes ()
 
bool LoadScript (const VfsPath &filename, bool hotload=false)
 Load a script and execute it in a new function scope. More...
 
void RegisterMessageType (MessageTypeId mtid, const char *name)
 
void RegisterComponentType (InterfaceId, ComponentTypeId, AllocFunc, DeallocFunc, const char *, const std::string &schema)
 
void RegisterComponentTypeScriptWrapper (InterfaceId, ComponentTypeId, AllocFunc, DeallocFunc, const char *, const std::string &schema)
 
void MarkScriptedComponentForSystemEntity (CComponentManager::ComponentTypeId cid)
 
void SubscribeToMessageType (MessageTypeId mtid)
 Subscribe the current component type to the given message type. More...
 
void SubscribeGloballyToMessageType (MessageTypeId mtid)
 Subscribe the current component type to all messages of the given message type. More...
 
void DynamicSubscriptionNonsync (MessageTypeId mtid, IComponent *component, bool enabled)
 Subscribe the given component instance to all messages of the given message type. More...
 
ComponentTypeId LookupCID (const std::string &cname) const
 
std::string LookupComponentTypeName (ComponentTypeId cid) const
 
void InitSystemEntity ()
 Set up an empty SYSTEM_ENTITY. More...
 
CEntityHandle GetSystemEntity ()
 Returns a CEntityHandle with id SYSTEM_ENTITY. More...
 
CEntityHandle LookupEntityHandle (entity_id_t ent, bool allowCreate=false)
 Returns a CEntityHandle with id ent. More...
 
entity_id_t AllocateNewEntity ()
 Returns a new entity ID that has never been used before. More...
 
entity_id_t AllocateNewLocalEntity ()
 Returns a new local entity ID that has never been used before. More...
 
entity_id_t AllocateNewEntity (entity_id_t preferredId)
 Returns a new entity ID that has never been used before. More...
 
bool AddComponent (CEntityHandle ent, ComponentTypeId cid, const CParamNode &paramNode)
 Constructs a component of type 'cid', initialised with data 'paramNode', and attaches it to entity 'ent'. More...
 
void AddSystemComponents (bool skipScriptedComponents, bool skipAI)
 Add all system components to the system entity (skip the scripted components or the AI components on demand) More...
 
void AddMockComponent (CEntityHandle ent, InterfaceId iid, IComponent &component)
 Adds an externally-created component, so that it is returned by QueryInterface but does not get destroyed and does not receive messages from the component manager. More...
 
IComponentConstructComponent (CEntityHandle ent, ComponentTypeId cid)
 Allocates a component object of type 'cid', and attaches it to entity 'ent'. More...
 
entity_id_t AddEntity (const std::wstring &templateName, entity_id_t ent)
 Constructs an entity based on the given template, and adds it the world with entity ID ent. More...
 
void DestroyComponentsSoon (entity_id_t ent)
 Destroys all the components belonging to the specified entity when FlushDestroyedComponents is called. More...
 
void FlushDestroyedComponents ()
 Does the actual destruction of components from DestroyComponentsSoon. More...
 
IComponentQueryInterface (entity_id_t ent, InterfaceId iid) const
 
InterfaceList GetEntitiesWithInterface (InterfaceId iid) const
 
const InterfaceListUnorderedGetEntitiesWithInterfaceUnordered (InterfaceId iid) const
 
void PostMessage (entity_id_t ent, const CMessage &msg)
 Send a message, targeted at a particular entity. More...
 
void BroadcastMessage (const CMessage &msg)
 Send a message, not targeted at any particular entity. More...
 
void ResetState ()
 Resets the dynamic simulation state (deletes all entities, resets entity ID counters; doesn't unload/reload component scripts). More...
 
void SetRNGSeed (u32 seed)
 Initializes the random number generator with a seed determined by the host. More...
 
bool ComputeStateHash (std::string &outHash, bool quick)
 
bool DumpDebugState (std::ostream &stream, bool includeDebugInfo)
 
bool SerializeState (std::ostream &stream)
 
bool DeserializeState (std::istream &stream)
 
std::string GenerateSchema ()
 
ScriptInterfaceGetScriptInterface ()
 

Private Types

enum  EComponentTypeType { CT_Native, CT_ScriptWrapper, CT_Script }
 
typedef IComponent *(* AllocFunc) (ScriptInterface &scriptInterface, JS::HandleValue ctor)
 
typedef void(* DeallocFunc) (IComponent *)
 

Private Member Functions

 NONCOPYABLE (CComponentManager)
 
CMessageConstructMessage (int mtid, JS::HandleValue data)
 
void SendGlobalMessage (entity_id_t ent, const CMessage &msg)
 
void FlattenDynamicSubscriptions ()
 
void RemoveComponentDynamicSubscriptions (IComponent *component)
 
ComponentTypeId GetScriptWrapper (InterfaceId iid)
 
CEntityHandle AllocateEntityHandle (entity_id_t ent)
 

Static Private Member Functions

static void Script_RegisterComponentType_Common (ScriptInterface::CxPrivate *pCxPrivate, int iid, const std::string &cname, JS::HandleValue ctor, bool reRegister, bool systemComponent)
 
static void Script_RegisterComponentType (ScriptInterface::CxPrivate *pCxPrivate, int iid, const std::string &cname, JS::HandleValue ctor)
 
static void Script_RegisterSystemComponentType (ScriptInterface::CxPrivate *pCxPrivate, int iid, const std::string &cname, JS::HandleValue ctor)
 
static void Script_ReRegisterComponentType (ScriptInterface::CxPrivate *pCxPrivate, int iid, const std::string &cname, JS::HandleValue ctor)
 
static void Script_RegisterInterface (ScriptInterface::CxPrivate *pCxPrivate, const std::string &name)
 
static void Script_RegisterMessageType (ScriptInterface::CxPrivate *pCxPrivate, const std::string &name)
 
static void Script_RegisterGlobal (ScriptInterface::CxPrivate *pCxPrivate, const std::string &name, JS::HandleValue value)
 
static IComponentScript_QueryInterface (ScriptInterface::CxPrivate *pCxPrivate, int ent, int iid)
 
static std::vector< int > Script_GetEntitiesWithInterface (ScriptInterface::CxPrivate *pCxPrivate, int iid)
 
static std::vector< IComponent * > Script_GetComponentsWithInterface (ScriptInterface::CxPrivate *pCxPrivate, int iid)
 
static void Script_PostMessage (ScriptInterface::CxPrivate *pCxPrivate, int ent, int mtid, JS::HandleValue data)
 
static void Script_BroadcastMessage (ScriptInterface::CxPrivate *pCxPrivate, int mtid, JS::HandleValue data)
 
static int Script_AddEntity (ScriptInterface::CxPrivate *pCxPrivate, const std::string &templateName)
 
static int Script_AddLocalEntity (ScriptInterface::CxPrivate *pCxPrivate, const std::string &templateName)
 
static void Script_DestroyEntity (ScriptInterface::CxPrivate *pCxPrivate, int ent)
 
static void Script_FlushDestroyedEntities (ScriptInterface::CxPrivate *pCxPrivate)
 
static JS::Value Script_ReadJSONFile (ScriptInterface::CxPrivate *pCxPrivate, const std::wstring &fileName)
 
static JS::Value Script_ReadCivJSONFile (ScriptInterface::CxPrivate *pCxPrivate, const std::wstring &fileName)
 
static std::vector< std::string > Script_FindJSONFiles (ScriptInterface::CxPrivate *pCxPrivate, const std::wstring &subPath, bool recursive)
 
static JS::Value ReadJSONFile (ScriptInterface::CxPrivate *pCxPrivate, const std::wstring &filePath, const std::wstring &fileName)
 
static Status FindJSONFilesCallback (const VfsPath &, const CFileInfo &, const uintptr_t)
 

Private Attributes

ScriptInterface m_ScriptInterface
 
CSimContextm_SimContext
 
CEntityHandle m_SystemEntity
 
ComponentTypeId m_CurrentComponent
 
bool m_CurrentlyHotloading
 
std::map< ComponentTypeId, ComponentTypem_ComponentTypesById
 
std::vector< CComponentManager::ComponentTypeIdm_ScriptedSystemComponents
 
std::vector< boost::unordered_map< entity_id_t, IComponent * > > m_ComponentsByInterface
 
std::map< ComponentTypeId, std::map< entity_id_t, IComponent * > > m_ComponentsByTypeId
 
std::map< MessageTypeId, std::vector< ComponentTypeId > > m_LocalMessageSubscriptions
 
std::map< MessageTypeId, std::vector< ComponentTypeId > > m_GlobalMessageSubscriptions
 
std::map< std::string, ComponentTypeIdm_ComponentTypeIdsByName
 
std::map< std::string, MessageTypeIdm_MessageTypeIdsByName
 
std::map< MessageTypeId, std::string > m_MessageTypeNamesById
 
std::map< std::string, InterfaceIdm_InterfaceIdsByName
 
std::map< MessageTypeId, CDynamicSubscriptionm_DynamicMessageSubscriptionsNonsync
 
std::map< IComponent *, std::set< MessageTypeId > > m_DynamicMessageSubscriptionsNonsyncByComponent
 
std::unordered_map< entity_id_t, SEntityComponentCache * > m_ComponentCaches
 
std::vector< entity_id_tm_DestructionQueue
 
ComponentTypeId m_NextScriptComponentTypeId
 
entity_id_t m_NextEntityId
 
entity_id_t m_NextLocalEntityId
 
boost::rand48 m_RNG
 

Friends

class TestComponentManager
 

Member Typedef Documentation

typedef IComponent*(* CComponentManager::AllocFunc) (ScriptInterface &scriptInterface, JS::HandleValue ctor)
private
typedef void(* CComponentManager::DeallocFunc) (IComponent *)
private

Member Enumeration Documentation

Enumerator
CT_Native 
CT_ScriptWrapper 
CT_Script 

Constructor & Destructor Documentation

CComponentManager::CComponentManager ( CSimContext context,
shared_ptr< ScriptRuntime rt,
bool  skipScriptFunctions = false 
)
CComponentManager::~CComponentManager ( )

Member Function Documentation

bool CComponentManager::AddComponent ( CEntityHandle  ent,
ComponentTypeId  cid,
const CParamNode paramNode 
)

Constructs a component of type 'cid', initialised with data 'paramNode', and attaches it to entity 'ent'.

Returns
true on success; false on failure, and logs an error message
entity_id_t CComponentManager::AddEntity ( const std::wstring &  templateName,
entity_id_t  ent 
)

Constructs an entity based on the given template, and adds it the world with entity ID ent.

There should not be any existing components with that entity ID.

Returns
ent, or INVALID_ENTITY on error
void CComponentManager::AddMockComponent ( CEntityHandle  ent,
InterfaceId  iid,
IComponent component 
)

Adds an externally-created component, so that it is returned by QueryInterface but does not get destroyed and does not receive messages from the component manager.

(This is intended for unit tests that need to add mock objects the tested components expect to exist.)

void CComponentManager::AddSystemComponents ( bool  skipScriptedComponents,
bool  skipAI 
)

Add all system components to the system entity (skip the scripted components or the AI components on demand)

CEntityHandle CComponentManager::AllocateEntityHandle ( entity_id_t  ent)
private
entity_id_t CComponentManager::AllocateNewEntity ( )

Returns a new entity ID that has never been used before.

This affects the simulation state so it must only be called in network-synchronised ways.

entity_id_t CComponentManager::AllocateNewEntity ( entity_id_t  preferredId)

Returns a new entity ID that has never been used before.

If possible, returns preferredId, and ensures this ID won't be allocated again. This affects the simulation state so it must only be called in network-synchronised ways.

entity_id_t CComponentManager::AllocateNewLocalEntity ( )

Returns a new local entity ID that has never been used before.

This entity will not be synchronised over the network, stored in saved games, etc.

void CComponentManager::BroadcastMessage ( const CMessage msg)

Send a message, not targeted at any particular entity.

The message will be received by any components that subscribed (either globally or not) to the message type.

bool CComponentManager::ComputeStateHash ( std::string &  outHash,
bool  quick 
)
IComponent * CComponentManager::ConstructComponent ( CEntityHandle  ent,
ComponentTypeId  cid 
)

Allocates a component object of type 'cid', and attaches it to entity 'ent'.

(The component's Init is not called here - either Init or Deserialize must be called before using the returned object.)

CMessage * CComponentManager::ConstructMessage ( int  mtid,
JS::HandleValue  data 
)
private
bool CComponentManager::DeserializeState ( std::istream &  stream)
void CComponentManager::DestroyComponentsSoon ( entity_id_t  ent)

Destroys all the components belonging to the specified entity when FlushDestroyedComponents is called.

Has no effect if the entity does not exist, or has already been added to the destruction queue.

bool CComponentManager::DumpDebugState ( std::ostream &  stream,
bool  includeDebugInfo 
)
void CComponentManager::DynamicSubscriptionNonsync ( MessageTypeId  mtid,
IComponent component,
bool  enabled 
)

Subscribe the given component instance to all messages of the given message type.

The component's HandleMessage will be called on any BroadcastMessage or PostMessage of this message type, regardless of the entity.

This can be called at any time (including inside the HandleMessage callback for this message type).

The component type must not have statically subscribed to this message type in its ClassInit.

The subscription status is not saved or network-synchronised. Components must remember to resubscribe in their Deserialize methods if they still want the message.

This is primarily intended for Interpolate and RenderSubmit messages, to avoid the cost of sending the message to components that do not currently need to do any rendering.

Status CComponentManager::FindJSONFilesCallback ( const VfsPath pathname,
const CFileInfo fileInfo,
const uintptr_t  cbData 
)
staticprivate
void CComponentManager::FlattenDynamicSubscriptions ( )
private
void CComponentManager::FlushDestroyedComponents ( )

Does the actual destruction of components from DestroyComponentsSoon.

This must not be called if the component manager is on the call stack (since it will break internal iterators).

std::string CComponentManager::GenerateSchema ( )
CComponentManager::InterfaceList CComponentManager::GetEntitiesWithInterface ( InterfaceId  iid) const
const CComponentManager::InterfaceListUnordered & CComponentManager::GetEntitiesWithInterfaceUnordered ( InterfaceId  iid) const
ScriptInterface& CComponentManager::GetScriptInterface ( )
inline
CComponentManager::ComponentTypeId CComponentManager::GetScriptWrapper ( InterfaceId  iid)
private
CEntityHandle CComponentManager::GetSystemEntity ( )
inline

Returns a CEntityHandle with id SYSTEM_ENTITY.

void CComponentManager::InitSystemEntity ( )

Set up an empty SYSTEM_ENTITY.

Must be called after ResetState() and before GetSystemEntity().

void CComponentManager::LoadComponentTypes ( )
bool CComponentManager::LoadScript ( const VfsPath filename,
bool  hotload = false 
)

Load a script and execute it in a new function scope.

Parameters
filenameVFS path to load
hotloadset to true if this script has been loaded before, and redefinitions of existing components should not be considered errors
CComponentManager::ComponentTypeId CComponentManager::LookupCID ( const std::string &  cname) const
Parameters
cnameRequested component type name (not including any "CID" or "CCmp" prefix)
Returns
The component type id, or CID__Invalid if not found
std::string CComponentManager::LookupComponentTypeName ( ComponentTypeId  cid) const
Returns
The name of the given component type, or "" if not found
CEntityHandle CComponentManager::LookupEntityHandle ( entity_id_t  ent,
bool  allowCreate = false 
)

Returns a CEntityHandle with id ent.

If allowCreate is true and there is no existing CEntityHandle, a new handle will be allocated.

void CComponentManager::MarkScriptedComponentForSystemEntity ( CComponentManager::ComponentTypeId  cid)
CComponentManager::NONCOPYABLE ( CComponentManager  )
private
void CComponentManager::PostMessage ( entity_id_t  ent,
const CMessage msg 
)

Send a message, targeted at a particular entity.

The message will be received by any components of that entity which subscribed to the message type, and by any other components that subscribed globally to the message type.

IComponent * CComponentManager::QueryInterface ( entity_id_t  ent,
InterfaceId  iid 
) const
JS::Value CComponentManager::ReadJSONFile ( ScriptInterface::CxPrivate pCxPrivate,
const std::wstring &  filePath,
const std::wstring &  fileName 
)
staticprivate
void CComponentManager::RegisterComponentType ( InterfaceId  iid,
ComponentTypeId  cid,
AllocFunc  alloc,
DeallocFunc  dealloc,
const char *  name,
const std::string &  schema 
)
void CComponentManager::RegisterComponentTypeScriptWrapper ( InterfaceId  iid,
ComponentTypeId  cid,
AllocFunc  alloc,
DeallocFunc  dealloc,
const char *  name,
const std::string &  schema 
)
void CComponentManager::RegisterMessageType ( MessageTypeId  mtid,
const char *  name 
)
void CComponentManager::RemoveComponentDynamicSubscriptions ( IComponent component)
private
void CComponentManager::ResetState ( )

Resets the dynamic simulation state (deletes all entities, resets entity ID counters; doesn't unload/reload component scripts).

int CComponentManager::Script_AddEntity ( ScriptInterface::CxPrivate pCxPrivate,
const std::string &  templateName 
)
staticprivate
int CComponentManager::Script_AddLocalEntity ( ScriptInterface::CxPrivate pCxPrivate,
const std::string &  templateName 
)
staticprivate
void CComponentManager::Script_BroadcastMessage ( ScriptInterface::CxPrivate pCxPrivate,
int  mtid,
JS::HandleValue  data 
)
staticprivate
void CComponentManager::Script_DestroyEntity ( ScriptInterface::CxPrivate pCxPrivate,
int  ent 
)
staticprivate
std::vector< std::string > CComponentManager::Script_FindJSONFiles ( ScriptInterface::CxPrivate pCxPrivate,
const std::wstring &  subPath,
bool  recursive 
)
staticprivate
void CComponentManager::Script_FlushDestroyedEntities ( ScriptInterface::CxPrivate pCxPrivate)
staticprivate
std::vector< IComponent * > CComponentManager::Script_GetComponentsWithInterface ( ScriptInterface::CxPrivate pCxPrivate,
int  iid 
)
staticprivate
std::vector< int > CComponentManager::Script_GetEntitiesWithInterface ( ScriptInterface::CxPrivate pCxPrivate,
int  iid 
)
staticprivate
void CComponentManager::Script_PostMessage ( ScriptInterface::CxPrivate pCxPrivate,
int  ent,
int  mtid,
JS::HandleValue  data 
)
staticprivate
IComponent * CComponentManager::Script_QueryInterface ( ScriptInterface::CxPrivate pCxPrivate,
int  ent,
int  iid 
)
staticprivate
JS::Value CComponentManager::Script_ReadCivJSONFile ( ScriptInterface::CxPrivate pCxPrivate,
const std::wstring &  fileName 
)
staticprivate
JS::Value CComponentManager::Script_ReadJSONFile ( ScriptInterface::CxPrivate pCxPrivate,
const std::wstring &  fileName 
)
staticprivate
void CComponentManager::Script_RegisterComponentType ( ScriptInterface::CxPrivate pCxPrivate,
int  iid,
const std::string &  cname,
JS::HandleValue  ctor 
)
staticprivate
void CComponentManager::Script_RegisterComponentType_Common ( ScriptInterface::CxPrivate pCxPrivate,
int  iid,
const std::string &  cname,
JS::HandleValue  ctor,
bool  reRegister,
bool  systemComponent 
)
staticprivate
void CComponentManager::Script_RegisterGlobal ( ScriptInterface::CxPrivate pCxPrivate,
const std::string &  name,
JS::HandleValue  value 
)
staticprivate
void CComponentManager::Script_RegisterInterface ( ScriptInterface::CxPrivate pCxPrivate,
const std::string &  name 
)
staticprivate
void CComponentManager::Script_RegisterMessageType ( ScriptInterface::CxPrivate pCxPrivate,
const std::string &  name 
)
staticprivate
void CComponentManager::Script_RegisterSystemComponentType ( ScriptInterface::CxPrivate pCxPrivate,
int  iid,
const std::string &  cname,
JS::HandleValue  ctor 
)
staticprivate
void CComponentManager::Script_ReRegisterComponentType ( ScriptInterface::CxPrivate pCxPrivate,
int  iid,
const std::string &  cname,
JS::HandleValue  ctor 
)
staticprivate
void CComponentManager::SendGlobalMessage ( entity_id_t  ent,
const CMessage msg 
)
private
bool CComponentManager::SerializeState ( std::ostream &  stream)
void CComponentManager::SetRNGSeed ( u32  seed)

Initializes the random number generator with a seed determined by the host.

void CComponentManager::SubscribeGloballyToMessageType ( MessageTypeId  mtid)

Subscribe the current component type to all messages of the given message type.

Each component's HandleMessage will be called on any BroadcastMessage or PostMessage of this message type, regardless of the entity. Must only be called by a component type's ClassInit.

void CComponentManager::SubscribeToMessageType ( MessageTypeId  mtid)

Subscribe the current component type to the given message type.

Each component's HandleMessage will be called on any BroadcastMessage of this message type, or on any PostMessage of this type targeted at the component's entity. Must only be called by a component type's ClassInit.

Friends And Related Function Documentation

friend class TestComponentManager
friend

Member Data Documentation

std::unordered_map<entity_id_t, SEntityComponentCache*> CComponentManager::m_ComponentCaches
private
std::vector<boost::unordered_map<entity_id_t, IComponent*> > CComponentManager::m_ComponentsByInterface
private
std::map<ComponentTypeId, std::map<entity_id_t, IComponent*> > CComponentManager::m_ComponentsByTypeId
private
std::map<std::string, ComponentTypeId> CComponentManager::m_ComponentTypeIdsByName
private
std::map<ComponentTypeId, ComponentType> CComponentManager::m_ComponentTypesById
private
ComponentTypeId CComponentManager::m_CurrentComponent
private
bool CComponentManager::m_CurrentlyHotloading
private
std::vector<entity_id_t> CComponentManager::m_DestructionQueue
private
std::map<MessageTypeId, CDynamicSubscription> CComponentManager::m_DynamicMessageSubscriptionsNonsync
private
std::map<IComponent*, std::set<MessageTypeId> > CComponentManager::m_DynamicMessageSubscriptionsNonsyncByComponent
private
std::map<MessageTypeId, std::vector<ComponentTypeId> > CComponentManager::m_GlobalMessageSubscriptions
private
std::map<std::string, InterfaceId> CComponentManager::m_InterfaceIdsByName
private
std::map<MessageTypeId, std::vector<ComponentTypeId> > CComponentManager::m_LocalMessageSubscriptions
private
std::map<std::string, MessageTypeId> CComponentManager::m_MessageTypeIdsByName
private
std::map<MessageTypeId, std::string> CComponentManager::m_MessageTypeNamesById
private
entity_id_t CComponentManager::m_NextEntityId
private
entity_id_t CComponentManager::m_NextLocalEntityId
private
ComponentTypeId CComponentManager::m_NextScriptComponentTypeId
private
boost::rand48 CComponentManager::m_RNG
private
std::vector<CComponentManager::ComponentTypeId> CComponentManager::m_ScriptedSystemComponents
private
ScriptInterface CComponentManager::m_ScriptInterface
private
CSimContext& CComponentManager::m_SimContext
private
CEntityHandle CComponentManager::m_SystemEntity
private

The documentation for this class was generated from the following files: