moved event handling into Modules instead of having seperate event listener objects

main
Martin Felis (schakeline) 2010-07-29 00:02:12 +08:00
parent 91cdebd33a
commit b86d28541a
19 changed files with 152 additions and 165 deletions

View File

@ -9,7 +9,7 @@ Makefile
start start
runtests runtests
hasteroids run_asteroids
./doc/html/* ./doc/html/*

View File

@ -3,7 +3,7 @@
#include "Controller.h" #include "Controller.h"
#include "Model.h" #include "Model.h"
#include "EntityBase.h" #include "EntityBase.h"
#include "EventsBase.h" #include "EventBase.h"
#include "Controller.h" #include "Controller.h"
#include "ShipEntity.h" #include "ShipEntity.h"

View File

@ -57,17 +57,33 @@ int Model::OnInit (int argc, char* argv[]) {
} }
// initialize event handlers and register them // initialize event handlers and register them
mLevelCompleteEventHandler = new LevelCompleteEventHandler (this); Engine::RegisterListener (this, EventLevelComplete);
Engine::RegisterListener (mLevelCompleteEventHandler, EventLevelComplete); Engine::RegisterListener (this, EventGameOver);
mGameOverEventHandler = new GameOverEventHandler (this);
Engine::RegisterListener (mGameOverEventHandler, EventGameOver);
mPlayerName = "Player"; mPlayerName = "Player";
return result; return result;
} }
bool Model::OnReceiveEvent (const Engine::EventBasePtr &event) {
switch (event->mEventType) {
case EventLevelComplete:
return OnLevelComplete();
break;
case EventGameOver:
return OnGameOver();
break;
default: Engine::LogWarning ("Received Event with type %d but don't know what to do with it!", event->mEventType);
break;
}
return false;
}
/*
* Module specific functions
*/
void Model::Process () { void Model::Process () {
if (mLastGameState == mGameState) { if (mLastGameState == mGameState) {
if (mGameState == GameStateRunning) { if (mGameState == GameStateRunning) {

View File

@ -50,8 +50,6 @@ class Model : public Engine::ModelBase {
mAsteroids.clear(); mAsteroids.clear();
mLevelList.clear(); mLevelList.clear();
SaveHighscoreList(); SaveHighscoreList();
delete mLevelCompleteEventHandler;
delete mGameOverEventHandler;
}; };
virtual void OnRegisterCommands (); virtual void OnRegisterCommands ();
@ -70,32 +68,7 @@ class Model : public Engine::ModelBase {
std::string mPlayerName; std::string mPlayerName;
std::vector<std::string> mLevelList; std::vector<std::string> mLevelList;
/* event handler class definitions */ virtual bool OnReceiveEvent (const Engine::EventBasePtr &event);
class LevelCompleteEventHandler : public Engine::EventListenerBase {
public:
explicit LevelCompleteEventHandler (Model *view) : mModel (view) {};
virtual bool HandleEvent (const Engine::EventBasePtr &event) const {
return mModel->OnLevelComplete();
}
private:
LevelCompleteEventHandler() {};
Model *mModel;
};
class GameOverEventHandler : public Engine::EventListenerBase {
public:
explicit GameOverEventHandler (Model *view) : mModel (view) {};
virtual bool HandleEvent (const Engine::EventBasePtr &event) const {
return mModel->OnGameOver();
}
private:
GameOverEventHandler() {};
Model *mModel;
};
/* event handler member variables */
LevelCompleteEventHandler *mLevelCompleteEventHandler;
GameOverEventHandler *mGameOverEventHandler;
friend class View; friend class View;
}; };

View File

@ -6,7 +6,7 @@
#include "Engine.h" #include "Engine.h"
#include "Physics.h" #include "Physics.h"
#include "Model.h" #include "Model.h"
#include "EventsBase.h" #include "EventBase.h"
#include "ShipEntity.h" #include "ShipEntity.h"
#include "AsteroidEntity.h" #include "AsteroidEntity.h"
@ -78,61 +78,64 @@ int View::OnInit (int argc, char* argv[]) {
mShipPartsSprite.LoadFromPNG ("./data/textures/ship_parts.png"); mShipPartsSprite.LoadFromPNG ("./data/textures/ship_parts.png");
mShipPartsSprite.SetSubSpriteCount (10); mShipPartsSprite.SetSubSpriteCount (10);
mAccelerateEventHandler = new AccelerateEventHandler (this); Engine::RegisterListener (this, EventAccelerateStart);
Engine::RegisterListener (mAccelerateEventHandler, EventAccelerateStart); Engine::RegisterListener (this, EventAccelerateStop);
Engine::RegisterListener (mAccelerateEventHandler, EventAccelerateStop); Engine::RegisterListener (this, EventShipExplode);
mShipExplodeEventHandler = new ShipExplodeEventHandler (this);
Engine::RegisterListener (mShipExplodeEventHandler, EventShipExplode);
return 0; return 0;
} }
void View::OnDestroy() { void View::OnDestroy() {
delete mAccelerateEventHandler;
delete mShipExplodeEventHandler;
mBackgroundStars.clear(); mBackgroundStars.clear();
mShipPartsEntityIds.clear(); mShipPartsEntityIds.clear();
Engine::ViewBase::OnDestroy(); Engine::ViewBase::OnDestroy();
} }
/* bool View::OnReceiveEvent (const Engine::EventBasePtr &event) {
* Event Handlers switch (event->mEventType) {
*/ case EventAccelerateStart:
bool View::AccelerateEventHandler::HandleEvent (const Engine::EventBasePtr &event) const { case EventAccelerateStop:
if (event->mEventType == EventAccelerateStart) if (event->mEventType == EventAccelerateStart)
mView->mShipThrustSprite.ResetAnimation(); mShipThrustSprite.ResetAnimation();
Engine::LogDebug ("Received Acceleration Event: %d", event->mEventType); Engine::LogDebug ("Received Acceleration Event: %d", event->mEventType);
return true; return true;
}
bool View::ShipExplodeEventHandler::HandleEvent (const Engine::EventBasePtr &event) const { break;
if (event->mEventType == EventShipExplode) { case EventShipExplode:
Engine::EntityBase *ship_entity = Engine::GetEntity (event->mEventUnsignedInt); if (event->mEventType == EventShipExplode) {
vector3d position = ship_entity->mPhysicState->mPosition; Engine::EntityBase *ship_entity = Engine::GetEntity (event->mEventUnsignedInt);
vector3d orientation = ship_entity->mPhysicState->mOrientation; vector3d position = ship_entity->mPhysicState->mPosition;
vector3d velocity = ship_entity->mPhysicState->mVelocity; vector3d orientation = ship_entity->mPhysicState->mOrientation;
vector3d velocity = ship_entity->mPhysicState->mVelocity;
unsigned int i; unsigned int i;
mView->mShipPartsEntityIds.clear(); mShipPartsEntityIds.clear();
for (i = 0; i < mView->mShipPartsSprite.GetSubSpriteCount(); i++) { for (i = 0; i < mShipPartsSprite.GetSubSpriteCount(); i++) {
Engine::EntityBase* part_sprite_particle = Engine::CreateEntity (GameEntityTypeShipPart); Engine::EntityBase* part_sprite_particle = Engine::CreateEntity (GameEntityTypeShipPart);
part_sprite_particle->mPhysicState->mPosition = position; part_sprite_particle->mPhysicState->mPosition = position;
part_sprite_particle->mPhysicState->mOrientation = orientation; part_sprite_particle->mPhysicState->mOrientation = orientation;
part_sprite_particle->mPhysicState->mVelocity = velocity; part_sprite_particle->mPhysicState->mVelocity = velocity;
part_sprite_particle->mPhysicState->mVelocity = vector3d (velocity[0] * (rand()/float(RAND_MAX)) * 1.7, 0., velocity[2] * (rand()/float(RAND_MAX)) * 1.5); part_sprite_particle->mPhysicState->mVelocity = vector3d (velocity[0] * (rand()/float(RAND_MAX)) * 1.7, 0., velocity[2] * (rand()/float(RAND_MAX)) * 1.5);
part_sprite_particle->mPhysicState->mAngleVelocity = (rand()/float(RAND_MAX) - 0.5 ) * 100.; part_sprite_particle->mPhysicState->mAngleVelocity = (rand()/float(RAND_MAX) - 0.5 ) * 100.;
mView->mShipPartsEntityIds.push_back(part_sprite_particle->mId); mShipPartsEntityIds.push_back(part_sprite_particle->mId);
} }
}
Engine::LogDebug ("Received Ship Explode Event: %d", event->mEventType);
return true;
break;
default: Engine::LogWarning ("Received Event with type %d but don't know what to do with it!", event->mEventType);
break;
} }
Engine::LogDebug ("Received Ship Explode Event: %d", event->mEventType); return false;
return true;
} }
/* /*

View File

@ -54,26 +54,7 @@ class View : public Engine::ViewBase {
Engine::Sprite mShipThrustSprite; Engine::Sprite mShipThrustSprite;
Engine::Sprite mShipPartsSprite; Engine::Sprite mShipPartsSprite;
class AccelerateEventHandler : public Engine::EventListenerBase { virtual bool OnReceiveEvent (const Engine::EventBasePtr &event);
public:
explicit AccelerateEventHandler (View *view) : mView (view) {};
virtual bool HandleEvent (const Engine::EventBasePtr &event) const;
private:
View *mView;
};
class ShipExplodeEventHandler : public Engine::EventListenerBase {
public:
explicit ShipExplodeEventHandler (View *view) : mView (view) {};
virtual bool HandleEvent (const Engine::EventBasePtr &event) const;
private:
View *mView;
};
AccelerateEventHandler *mAccelerateEventHandler;
ShipExplodeEventHandler *mShipExplodeEventHandler;
friend class AccelerateEventHandler;
}; };
} }

View File

@ -22,7 +22,7 @@ SET ( ENGINE_SRCS
PhysicsBase.cc PhysicsBase.cc
PhysicsEntityBase.cc PhysicsEntityBase.cc
ViewBase.cc ViewBase.cc
EventsBase.cc EventBase.cc
OverlayBase.cc OverlayBase.cc
Commands.cc Commands.cc

View File

@ -11,7 +11,7 @@
#include "ControllerBase.h" #include "ControllerBase.h"
#include "EntityFactoryBase.h" #include "EntityFactoryBase.h"
#include "EventsBase.h" #include "EventManager.h"
#include <iostream> #include <iostream>
#include <cstdio> #include <cstdio>

View File

@ -154,6 +154,6 @@ ControllerBase* EngineGetController ();
#include "CommandsGlobal.h" #include "CommandsGlobal.h"
#include "ModelBaseGlobal.h" #include "ModelBaseGlobal.h"
#include "ViewBaseGlobal.h" #include "ViewBaseGlobal.h"
#include "EventsBaseGlobal.h" #include "EventBaseGlobal.h"
#endif // _ENGINE_H #endif // _ENGINE_H

View File

@ -1,4 +1,5 @@
#include "EventsBase.h" #include "EventBase.h"
#include "EventManager.h"
#include "Logging.h" #include "Logging.h"
namespace Engine { namespace Engine {
@ -15,10 +16,10 @@ void EventManager::OnDestroy() {
EventManagerInstance = NULL; EventManagerInstance = NULL;
} }
bool EventManager::RegisterListener (const EventListenerBase *listener, const int event_type) { bool EventManager::RegisterListener (Module *listener_module, const int event_type) {
LogDebug ("Registering Event listener %x for event type %d", listener, event_type); LogDebug ("Registering Event listener %x for event type %d", listener_module, event_type);
mEventTypeListeners[event_type].push_back(listener); mEventTypeListeners[event_type].push_back(listener_module);
return true; return true;
} }
@ -42,9 +43,9 @@ bool EventManager::TriggerEvent (const EventBasePtr &event) {
if (!HasEventTypeListener (event->mEventType)) if (!HasEventTypeListener (event->mEventType))
return false; return false;
std::vector<const EventListenerBase*>::iterator listener_iter = mEventTypeListeners[event->mEventType].begin(); std::vector<Module*>::iterator listener_iter = mEventTypeListeners[event->mEventType].begin();
for ( ; listener_iter != mEventTypeListeners[event->mEventType].end(); listener_iter++) { for ( ; listener_iter != mEventTypeListeners[event->mEventType].end(); listener_iter++) {
if ((*listener_iter)->HandleEvent (event)) if ((*listener_iter)->SendEvent (event))
return true; return true;
} }
@ -55,13 +56,13 @@ bool EventManager::TriggerEvent (const EventBasePtr &event) {
* Global Functions * Global Functions
*/ */
/** \brief Registers a listener to a given event type */ /** \brief Registers a listener to a given event type */
bool RegisterListener (const EventListenerBase *listener, const int event_type) { bool RegisterListener (Module *listener_module, const int event_type) {
if (!EventManagerInstance) { if (!EventManagerInstance) {
LogError ("Could not register EventListenerBase: EventManager not initialized!"); LogError ("Could not register Module: EventManager not initialized!");
return false; return false;
} }
return EventManagerInstance->RegisterListener (listener, event_type); return EventManagerInstance->RegisterListener (listener_module, event_type);
} }
/** \brief Calls all event listeners to handle the events */ /** \brief Calls all event listeners to handle the events */

32
engine/EventBase.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef EVENTSBASE_H
#define EVENTSBASE_H
// #include "Module.h"
#include <boost/shared_ptr.hpp>
#include <string>
#include <map>
#include <vector>
#include <queue>
namespace Engine {
class Module;
/** \brief Contains all information relevant to the Event */
struct EventBase {
int mEventType;
/** \brief This might later be used for de-/serializing of the event data */
std::string mEventData;
float mEventFloat;
int mEventInt;
unsigned int mEventUnsignedInt;
};
typedef boost::shared_ptr<EventBase> EventBasePtr;
}
#endif /* EVENTSBASE_H */

View File

@ -1,12 +1,12 @@
#ifndef EVENTSBASEGLOBAL_H #ifndef EVENTSBASEGLOBAL_H
#define EVENTSBASEGLOBAL_H #define EVENTSBASEGLOBAL_H
#include "EventsBase.h" #include "EventBase.h"
namespace Engine { namespace Engine {
/** \brief Registers a listener to a given event type */ /** \brief Registers a listener to a given event type */
bool RegisterListener (const EventListenerBase *listener, const int event_type); bool RegisterListener (Module *listener_module, const int event_type);
/** \brief Calls all event listeners to handle the events */ /** \brief Calls all event listeners to handle the events */
bool QueueEvent (const EventBasePtr &event); bool QueueEvent (const EventBasePtr &event);
/** \brief Calls the listener handlers immediately */ /** \brief Calls the listener handlers immediately */

View File

@ -1,7 +1,7 @@
#ifndef EVENTSBASE_H #ifndef EVENTSMANAGER_H
#define EVENTSBASE_H #define EVENTSMANAGER_H
#include "Module.h" // #include "Module.h"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
@ -10,47 +10,20 @@
#include <vector> #include <vector>
#include <queue> #include <queue>
#include "EventBase.h"
#include "Module.h"
namespace Engine { namespace Engine {
/** \brief Contains all information relevant to the Event */ /** \brief Keeps track of all the Modules that registered for a given event type
struct EventBase {
int mEventType;
/** \brief This might later be used for de-/serializing of the event data */
std::string mEventData;
float mEventFloat;
int mEventInt;
unsigned int mEventUnsignedInt;
};
typedef boost::shared_ptr<EventBase> EventBasePtr;
/** \brief Takes care of the handling of the Event
* *
* Processing of the Event is done in the EventListenerBase::HandleEvent()
* function.
*/
class EventListenerBase {
public:
virtual ~EventListenerBase() {};
/** \brief Handles the Event */
virtual bool HandleEvent (const EventBasePtr &event) const = 0;
void just_for_the_vtable() {};
/** \brief For debugging */
std::string mName;
};
typedef boost::shared_ptr<EventListenerBase> EventListenerPtr;
/** \brief Keeps track of all the EventListenerBase objects and receives Event notifications.
*/ */
class EventManager : public Module { class EventManager : public Module {
public: public:
virtual ~EventManager() {}; virtual ~EventManager() {};
/** \brief Registers a listener to a given event type */ /** \brief Registers a listener to a given event type */
bool RegisterListener (const EventListenerBase *listener, const int event_type); bool RegisterListener (Module *listener_module, const int event_type);
/** \brief Calls all event listeners to handle the events */ /** \brief Calls all event listeners to handle the events */
void Process (); void Process ();
/** \brief Queues the until Process() gets called */ /** \brief Queues the until Process() gets called */
@ -79,10 +52,10 @@ class EventManager : public Module {
private: private:
/** \brief Contains for each event type the list of listeners */ /** \brief Contains for each event type the list of listeners */
std::map <int, std::vector<const EventListenerBase*> > mEventTypeListeners; std::map <int, std::vector<Module*> > mEventTypeListeners;
std::queue <EventBasePtr> mQueuedEvents; std::queue <EventBasePtr> mQueuedEvents;
}; };
} }
#endif /* EVENTSBASE_H */ #endif /* EVENTSMANAGER_H */

View File

@ -1,6 +1,8 @@
#ifndef MODULE_H #ifndef MODULE_H
#define MODULE_H #define MODULE_H
#include "EventBase.h"
namespace Engine { namespace Engine {
/** \brief Base class for the separate modules /** \brief Base class for the separate modules
@ -36,6 +38,7 @@ class Module {
/** \brief Calls the function that registers its commands to the /** \brief Calls the function that registers its commands to the
* Commandsystem */ * Commandsystem */
virtual void RegisterCommands () { OnRegisterCommands (); } virtual void RegisterCommands () { OnRegisterCommands (); }
virtual bool SendEvent (const EventBasePtr &event) { return OnReceiveEvent (event); }
protected: protected:
/** \brief The actual function being called when Init () is called */ /** \brief The actual function being called when Init () is called */
@ -44,6 +47,8 @@ class Module {
virtual void OnDestroy () { }; virtual void OnDestroy () { };
/** \brief Registers the commands of the Module */ /** \brief Registers the commands of the Module */
virtual void OnRegisterCommands () { }; virtual void OnRegisterCommands () { };
/** \brief Reacts on a event that was sent to the module */
virtual bool OnReceiveEvent (const EventBasePtr &event) { return false; };
}; };
} }

View File

@ -17,5 +17,5 @@ SET_TARGET_PROPERTIES ( ${PROJECT_EXECUTABLES} PROPERTIES
SUBDIRS (tests) SUBDIRS (tests)
ADD_LIBRARY ( coll2d ${COLL2D_SRCS} ) ADD_LIBRARY ( coll2d SHARED ${COLL2D_SRCS} )

View File

@ -6,5 +6,4 @@ SET ( SRCS
mathlib.cc mathlib.cc
main.cc main.cc
) )
ADD_LIBRARY ( mathlib SHARED mathlib.cc mathlib.h)
ADD_LIBRARY ( mathlib mathlib.cc mathlib.h)

View File

@ -23,7 +23,7 @@ IF( WIN32 )
ADD_DEFINITIONS( -DOGLFT_BUILD ) ADD_DEFINITIONS( -DOGLFT_BUILD )
ENDIF( WIN32 ) ENDIF( WIN32 )
ADD_LIBRARY( oglft STATIC ${sources} ) ADD_LIBRARY( oglft SHARED ${sources} )
TARGET_LINK_LIBRARIES( TARGET_LINK_LIBRARIES(
oglft oglft
${FREETYPE2_LIBRARIES} ${FREETYPE2_LIBRARIES}

View File

@ -9,7 +9,7 @@ SET ( TESTS_SRCS
main.cc main.cc
CommandsTests.cc CommandsTests.cc
EntityTests.cc EntityTests.cc
EventsBaseTests.cc EventBaseTests.cc
PhysicsTests.cc PhysicsTests.cc
ControllerBaseTests.cc ControllerBaseTests.cc
) )

View File

@ -1,7 +1,8 @@
#include <UnitTest++.h> #include <UnitTest++.h>
#include "Logging.h" #include "Logging.h"
#include "EventsBase.h" #include "Module.h"
#include "EventManager.h"
using namespace std; using namespace std;
using namespace Engine; using namespace Engine;
@ -9,18 +10,21 @@ using namespace Engine;
int global_event_type = -1; int global_event_type = -1;
string global_event_string = ""; string global_event_string = "";
class TestEventListener : public EventListenerBase { struct EventsFixture;
public:
TestEventListener() {
mName = "TestEventListener";
}
virtual bool HandleEvent (const EventBasePtr &event) const { class TestEventModule : public Module {
private:
virtual int OnInit (int argc, char* argv[]) {
return 0;
};
virtual bool OnReceiveEvent (const EventBasePtr &event) {
global_event_type = event->mEventType; global_event_type = event->mEventType;
global_event_string = event->mEventData; global_event_string = event->mEventData;
return true; return true;
} }
friend class EventsFixture;
}; };
struct EventsFixture { struct EventsFixture {
@ -43,17 +47,17 @@ struct EventsFixture {
Logging LoggingModule; Logging LoggingModule;
TestEventListener Listener; TestEventModule TestModule;
EventManager *TestEventManager; EventManager *TestEventManager;
}; };
TEST_FIXTURE ( EventsFixture, TestEventListenerHandleEvent ) { TEST_FIXTURE ( EventsFixture, TestEventModuleSendEvent ) {
EventBasePtr event (new EventBase); EventBasePtr event (new EventBase);
event->mEventType = 1; event->mEventType = 1;
event->mEventData = "test"; event->mEventData = "test";
Listener.HandleEvent (event); TestModule.SendEvent (event);
CHECK_EQUAL (1, global_event_type); CHECK_EQUAL (1, global_event_type);
CHECK_EQUAL ("test", global_event_string); CHECK_EQUAL ("test", global_event_string);
@ -65,17 +69,17 @@ TEST_FIXTURE ( EventsFixture, TestTestEventManagerZeroListeners ) {
} }
TEST_FIXTURE ( EventsFixture, TestTestEventManagerAddListener ) { TEST_FIXTURE ( EventsFixture, TestTestEventManagerAddListener ) {
TestEventManager->RegisterListener (&Listener, 1); TestEventManager->RegisterListener (&TestModule, 1);
CHECK_EQUAL (true, TestEventManager->HasEventTypeListener(1)); CHECK_EQUAL (true, TestEventManager->HasEventTypeListener(1));
CHECK_EQUAL (false, TestEventManager->HasEventTypeListener(2)); CHECK_EQUAL (false, TestEventManager->HasEventTypeListener(2));
TestEventManager->RegisterListener (&Listener, 1); TestEventManager->RegisterListener (&TestModule, 1);
CHECK_EQUAL (2, TestEventManager->GetEventTypeListenerCount(1)); CHECK_EQUAL (2, TestEventManager->GetEventTypeListenerCount(1));
} }
TEST_FIXTURE ( EventsFixture, TestTestEventManagerTriggerEvent ) { TEST_FIXTURE ( EventsFixture, TestTestEventManagerTriggerEvent ) {
TestEventManager->RegisterListener (&Listener, 1); TestEventManager->RegisterListener (&TestModule, 1);
CHECK_EQUAL (true, TestEventManager->HasEventTypeListener(1)); CHECK_EQUAL (true, TestEventManager->HasEventTypeListener(1));
@ -94,7 +98,7 @@ TEST_FIXTURE ( EventsFixture, TestTestEventManagerTriggerEvent ) {
} }
TEST_FIXTURE ( EventsFixture, TestTestEventManagerQueueEvent ) { TEST_FIXTURE ( EventsFixture, TestTestEventManagerQueueEvent ) {
TestEventManager->RegisterListener (&Listener, 1); TestEventManager->RegisterListener (&TestModule, 1);
EventBasePtr event (new EventBase); EventBasePtr event (new EventBase);
@ -111,7 +115,7 @@ TEST_FIXTURE ( EventsFixture, TestTestEventManagerQueueEvent ) {
} }
TEST_FIXTURE ( EventsFixture, TestTestEventManagerProcess ) { TEST_FIXTURE ( EventsFixture, TestTestEventManagerProcess ) {
TestEventManager->RegisterListener (&Listener, 1); TestEventManager->RegisterListener (&TestModule, 1);
EventBasePtr event (new EventBase); EventBasePtr event (new EventBase);