#ifndef _MODELBASE_H #define _MODELBASE_H #include "Engine.h" #include "EntityBase.h" // #include "Timer.h" namespace Engine { class Module; class PhysicsBase; class Events; class EntityFactoryBase; class OverlayManager; #ifdef max #undef max #endif const unsigned int NullEntityId = std::numeric_limits::max() - 1; struct EntityBase; /** \brief Represents the current state of the Engine * * Represents the State of the Engine and is unaware of anything except itself. * It manages all Entities, Physics, etc. * * It has the following subsystems: * - Events * - Physics * - Variables * * \note * To create an Entity one must call Engine::CreateEntity() which will * allocate the Entity and performs all the required registrations by calling * Model::RegisterEntity(). */ class ModelBase : public Module { public: /** Performs simulation, gamelogic, etc */ virtual void Process (); /** Updates the timer */ void UpdateTimer () { static float last_frame = 0; float current_frame = static_cast (SDL_GetTicks ()) * 1.0e-3; mDeltaSec = current_frame - last_frame; last_frame = current_frame; } float GetFrameDuration () { return mDeltaSec; } /** Adds the given Entity to the Model */ void RegisterEntity (EntityBase *entity); /** Removes the Entity with the given id */ void UnregisterEntity (const unsigned int id); /** Marks an Engine::Entity as killed so that it gets removed after the * simulation */ void KillEntity (const unsigned int id); /** Creates an Entity of the given type * * This calls the CreateEntity() function on the Model::mEntityFactory to * create the proper Entity and registers it to the required submodules * (so far only Model::mPhysics). */ EntityBase* CreateEntity (int type); /** Returns the Entity with the given id */ EntityBase* GetEntity (const unsigned int id); /** Returns a unused id for an Entity */ unsigned int CreateEntityId (); /** Removes all Entities */ void ClearEntities (); /** Returns the id of the entity the player is currently controlling */ unsigned int GetPlayerEntityId (); /** \brief Assigns the player to an Entity. All controls will be redirected to that player * * This can be used to disable the controls of of the player by assinging * the special entity id of NullEntityId */ void SetPlayerEntityId(unsigned int entity_id); /** Notifies the gamelogic of a collision event */ void SendEntityCollisionEvent (const unsigned int reference_entity_id, const unsigned int incidence_entity_id, float collision_time, vector3d normal); virtual void SetGameState (const unsigned int &state) { mLastGameState = mGameState; mGameState = state; }; unsigned int GetGameState () { return mGameState; }; /* void StartTimer(const std::string &id, float msec) { TimerIter cur_timer = mTimers.find(id); if (cur_timer != mTimers.end()) { cur_timer->second.Set(msec); cur_timer->second.Start(); return; } mTimers[id] = Timer(id, msec); assert (mTimers.size() > 0); assert (mTimers[id].IsActive() == true); } bool CheckTimer(const std::string &id) { TimerIter cur_timer = mTimers.find(id); if (cur_timer == mTimers.end()) { return false; } return cur_timer->second.Query(); } */ protected: /** \brief Initializes the system */ virtual int OnInit (int argc, char* argv[]); /** \brief Destroys the system (must be called!) */ virtual void OnDestroy (); /** \brief Gets called when an entity of the given type is being created */ virtual void OnCreateEntity (const int type, const unsigned int id) {}; /** \brief Gets called when an entity is marked to be killed */ virtual void OnKillEntity (const EntityBase *entity) {}; PhysicsBase *mPhysics; Events *mEvents; /** \brief Creates Entities */ EntityFactoryBase *mEntityFactory; /** \brief contains all Engine::Entities */ std::map mEntities; typedef std::map::iterator EntityIter; /** \brief contains all Engine::Entities that ceased to exist */ std::vector mKilledEntities; /* std::map mTimers; typedef std::map::iterator TimerIter; */ unsigned int mEntityIdCounter; unsigned int mPlayerEntityId; unsigned int mGameState; unsigned int mLastGameState; float mDeltaSec; friend class ViewBase; friend class OverlayManager; friend class Engine; friend class Controller; }; /** \brief Creates an Entity of the given type and registers at the required modules * * * It allocates the memory needed to represent that specific type of Entity. * At also performs the required registrations at the various Modules. * * All Entities that are created with this function get also destroyed in * Model::Destroy () by calling DestroyEntity () for this Entity. * * \note All Entities must be created with this function if you intend to keep * the different Modules in sync! */ EntityBase * CreateEntity (int type); /** \brief Frees the Memory required by the Entity and unregisters it * * This function also frees the memory the Entity is using in its * different representitions such as EntityVisualState and EntityPhysicState. * * It also unregisters the Entity from the different Modules where it was * registered by CreateEntity. */ void DestroyEntity (unsigned int id); /** \brief Tells the model that the entity is no more existant in the game * world */ void KillEntity (unsigned int id); /** \brief Returns the Entity with the given id, NULL otherwise */ EntityBase * GetEntity (unsigned int id); /** \brief Returns the physical state of the Entity with the given id, NULL otherwise */ EntityPhysicState * GetEntityPhysicState (unsigned int id); } #endif // _MODEL_H