// EntityManager.h // // Mark Thompson mot20@cam.ac.uk / mark@wildfiregames.com // // Maintains entity id->object mappings. Does most of the work involved in creating an entity. // // Usage: Do not attempt to directly instantiate an entity class. // HEntity bob = g_EntityManager.create( unit_class_name, position, orientation ); // or HEntity jim = g_EntityManager.create( pointer_to_unit_class, position, orientation ); // // Perform updates on all world entities by g_EntityManager.updateAll( timestep ) // Dispatch an identical message to all world entities by g_EntityManager.dispatchAll( message_pointer ) // Get an STL vector container of all entities with a certain property with g_EntityManager.matches( predicate ) // or just get all entities with g_EntityManager.getExtant(). // // Those last two functions - caller has responsibility for deleting the collection when you're done with it. #ifndef ENTITY_MANAGER_INCLUDED #define ENTITY_MANAGER_INCLUDED #include "ps/Singleton.h" #include "EntityHandles.h" #include "EntityPredicate.h" #include "EntityMessage.h" #include "ps/Game.h" #include "ps/World.h" #include "ps/CStr.h" #include "maths/Vector3D.h" class CBaseEntity; #define MAX_HANDLES 4096 // collision patch size, in graphics units, not tiles (1 tile = 4 units) #define COLLISION_PATCH_SIZE 8 #define g_EntityManager (*(g_Game->GetWorld()->GetEntityManager())) class CEntityManager { friend class HEntity; friend class CHandle; CHandle m_entities[MAX_HANDLES]; std::vector m_reaper; int m_nextalloc; static bool m_extant; bool m_death; void destroy( u16 handle ); int m_collisionPatchesPerSide; std::vector* m_collisionPatches; public: CEntityManager(); ~CEntityManager(); HEntity create( CBaseEntity* base, CVector3D position, float orientation, const std::set& actorSelections ); HEntity create( CStrW templateName, CPlayer* player, CVector3D position, float orientation ); HEntity createFoundation( CStrW templateName, CPlayer* player, CVector3D position, float orientation ); HEntity* getByHandle( u16 index ); CHandle *getHandle( int index ); void updateAll( size_t timestep ); void interpolateAll( float relativeoffset ); void InitializeAll(); void TickAll(); void renderAll(); void conformAll(); void invalidateAll(); void deleteAll(); bool GetDeath() { return m_death; } void SetDeath(bool set) { m_death=set; } // Predicate functions typedef bool (*EntityPredicate)( CEntity* target, void* userdata ); template static bool EntityPredicateLogicalOr( CEntity* target, void* userdata ) { return( left( target, userdata ) || right( target, userdata ) ); } template static bool EntityPredicateLogicalAnd( CEntity* target, void* userdata ) { return( left( target, userdata ) && right( target, userdata ) ); } template static bool EntityPredicateLogicalNot( CEntity* target, void* userdata ) { return( !operand( target, userdata ) ); } std::vector* matches( EntityPredicate predicate, void* userdata = NULL ); std::vector* getExtant(); void GetExtant( std::vector& results ); // TODO: Switch most/all uses of getExtant() to this. static inline bool extant() // True if the singleton is actively maintaining handles. When false, system is shutting down, handles are quietly dumped. { return( m_extant ); } void GetInRange( float x, float z, float radius, std::vector& results ); std::vector* getCollisionPatch( CEntity* e ); }; #endif