2010-04-05 23:38:59 +02:00
|
|
|
#ifndef _MODELBASE_H
|
|
|
|
#define _MODELBASE_H
|
|
|
|
|
|
|
|
#include "Engine.h"
|
|
|
|
#include "EntityBase.h"
|
|
|
|
|
|
|
|
namespace Engine {
|
|
|
|
|
|
|
|
class Module;
|
|
|
|
class PhysicsBase;
|
|
|
|
class Events;
|
|
|
|
class EntityFactoryBase;
|
2010-06-06 00:58:11 +02:00
|
|
|
class OverlayManager;
|
2010-04-05 23:38:59 +02:00
|
|
|
|
2010-11-28 00:20:58 +01:00
|
|
|
const unsigned int NullEntityId = std::numeric_limits<unsigned int>::max() - 1;
|
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
struct EntityBase;
|
|
|
|
|
2011-03-22 23:01:44 +01:00
|
|
|
struct Timer {
|
|
|
|
Timer() :
|
|
|
|
mRunning(false),
|
|
|
|
mCurrentValue(0.)
|
|
|
|
{}
|
|
|
|
Timer (float sec_value) :
|
|
|
|
mRunning(true),
|
|
|
|
mCurrentValue (sec_value)
|
|
|
|
{}
|
|
|
|
Timer (const Timer& timer) :
|
|
|
|
mRunning (timer.mRunning),
|
|
|
|
mCurrentValue (timer.mCurrentValue)
|
|
|
|
{}
|
|
|
|
Timer& operator= (const Timer& timer) {
|
|
|
|
if (this != &timer) {
|
|
|
|
mRunning = timer.mRunning;
|
|
|
|
mCurrentValue = timer.mCurrentValue;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Set (float sec_value) {
|
|
|
|
mCurrentValue = sec_value;
|
|
|
|
}
|
|
|
|
float Get () {
|
|
|
|
return mCurrentValue;
|
|
|
|
}
|
|
|
|
bool Query() {
|
|
|
|
if (mCurrentValue <= 0.)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
void Start() {
|
|
|
|
mRunning = true;
|
|
|
|
}
|
|
|
|
void Pause() {
|
|
|
|
mRunning = false;
|
|
|
|
}
|
|
|
|
bool Update(float sec_value) {
|
|
|
|
if (mRunning)
|
|
|
|
mCurrentValue -= sec_value;
|
|
|
|
|
|
|
|
return Query();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool mRunning;
|
|
|
|
float mCurrentValue;
|
|
|
|
};
|
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
/** \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<float> (SDL_GetTicks ()) * 1.0e-3;
|
2011-03-15 10:21:26 +01:00
|
|
|
mDurationApplicationStart = current_frame;
|
2010-04-05 23:38:59 +02:00
|
|
|
mDeltaSec = current_frame - last_frame;
|
|
|
|
last_frame = current_frame;
|
2011-03-22 23:01:44 +01:00
|
|
|
UpdateTimers (mDeltaSec);
|
2010-04-05 23:38:59 +02:00
|
|
|
}
|
|
|
|
float GetFrameDuration () {
|
|
|
|
return mDeltaSec;
|
|
|
|
}
|
2011-03-15 10:21:26 +01:00
|
|
|
float GetDurationApplicationStart () {
|
|
|
|
return mDurationApplicationStart;
|
|
|
|
}
|
2010-04-05 23:38:59 +02:00
|
|
|
|
|
|
|
/** 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);
|
2011-01-02 18:25:20 +01:00
|
|
|
|
|
|
|
/** Returns the Entity at the given world coordinates */
|
|
|
|
EntityBase* GetEntityAt (const vector3d &pos);
|
|
|
|
|
|
|
|
EntityBaseIter GetEntityIterBegin () {
|
|
|
|
return mEntities.begin();
|
|
|
|
}
|
|
|
|
EntityBaseIter GetEntityIterEnd() {
|
|
|
|
return mEntities.end();
|
|
|
|
}
|
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
/** 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 ();
|
2011-03-15 10:21:26 +01:00
|
|
|
/** \brief Assigns the player to an Entity. All controls will be redirected
|
|
|
|
* \brief to that player
|
2010-11-28 00:20:58 +01:00
|
|
|
*
|
|
|
|
* 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);
|
2010-04-05 23:38:59 +02:00
|
|
|
|
|
|
|
/** Notifies the gamelogic of a collision event */
|
|
|
|
void SendEntityCollisionEvent (const unsigned int reference_entity_id,
|
2011-03-15 10:21:26 +01:00
|
|
|
const unsigned int incidence_entity_id, float collision_time,
|
|
|
|
vector3d point, vector3d normal);
|
2010-04-05 23:38:59 +02:00
|
|
|
|
2010-09-11 02:28:50 +02:00
|
|
|
virtual void SetGameState (const unsigned int &state) {
|
2010-06-02 13:39:39 +02:00
|
|
|
mLastGameState = mGameState;
|
|
|
|
mGameState = state;
|
|
|
|
};
|
|
|
|
unsigned int GetGameState () { return mGameState; };
|
|
|
|
|
2011-03-22 23:01:44 +01:00
|
|
|
void StartTimer(const std::string &id, float sec) {
|
2010-11-27 08:38:32 +01:00
|
|
|
TimerIter cur_timer = mTimers.find(id);
|
|
|
|
if (cur_timer != mTimers.end()) {
|
2011-03-22 23:01:44 +01:00
|
|
|
cur_timer->second.Set(sec);
|
2010-11-27 08:38:32 +01:00
|
|
|
cur_timer->second.Start();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-03-22 23:01:44 +01:00
|
|
|
mTimers[id] = Timer(sec);
|
2010-11-27 08:38:32 +01:00
|
|
|
assert (mTimers.size() > 0);
|
|
|
|
}
|
|
|
|
bool CheckTimer(const std::string &id) {
|
|
|
|
TimerIter cur_timer = mTimers.find(id);
|
|
|
|
|
|
|
|
if (cur_timer == mTimers.end()) {
|
2011-03-22 23:01:44 +01:00
|
|
|
return true;
|
2010-11-27 08:38:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return cur_timer->second.Query();
|
|
|
|
}
|
2011-03-22 23:01:44 +01:00
|
|
|
|
|
|
|
float GetTimer (const std::string &id) {
|
|
|
|
TimerIter cur_timer = mTimers.find(id);
|
|
|
|
|
|
|
|
if (cur_timer == mTimers.end()) {
|
|
|
|
return 0.;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cur_timer->second.Get();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PauseTimers () {
|
|
|
|
for (TimerIter iter = mTimers.begin(); iter != mTimers.end(); iter++) {
|
|
|
|
iter->second.Pause();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ResumeTimers () {
|
|
|
|
for (TimerIter iter = mTimers.begin(); iter != mTimers.end(); iter++) {
|
|
|
|
iter->second.Start();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateTimers (float sec) {
|
|
|
|
TimerIter iter = mTimers.begin();
|
|
|
|
|
|
|
|
while (iter != mTimers.end()) {
|
|
|
|
bool timer_running = iter->second.Update(sec);
|
|
|
|
if (timer_running) {
|
|
|
|
LogDebug ("Erasing expired timer %s", iter->first.c_str());
|
|
|
|
mTimers.erase(iter++);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
++iter;
|
|
|
|
}
|
|
|
|
}
|
2010-11-27 08:38:32 +01:00
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
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<unsigned int, EntityBase *> mEntities;
|
2010-11-27 08:38:32 +01:00
|
|
|
typedef std::map<unsigned int, EntityBase *>::iterator EntityIter;
|
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
/** \brief contains all Engine::Entities that ceased to exist */
|
|
|
|
std::vector<unsigned int> mKilledEntities;
|
|
|
|
|
2010-11-27 08:38:32 +01:00
|
|
|
std::map<std::string, Timer> mTimers;
|
|
|
|
typedef std::map<std::string, Timer>::iterator TimerIter;
|
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
unsigned int mEntityIdCounter;
|
|
|
|
unsigned int mPlayerEntityId;
|
|
|
|
|
2010-06-02 13:39:39 +02:00
|
|
|
unsigned int mGameState;
|
|
|
|
unsigned int mLastGameState;
|
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
float mDeltaSec;
|
2011-03-15 10:21:26 +01:00
|
|
|
float mDurationApplicationStart;
|
2010-04-05 23:38:59 +02:00
|
|
|
|
|
|
|
friend class ViewBase;
|
2010-06-06 00:58:11 +02:00
|
|
|
friend class OverlayManager;
|
2010-04-05 23:38:59 +02:00
|
|
|
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
|