-
Notifications
You must be signed in to change notification settings - Fork 3
ECS Event Handlers
An Event Handler is a piece of logic that can process an event with access to more modules than simple systems. Event Handlers operates on entities that have the required components. For example:
- A SwitchSceneEventHandler might process the "SwitchScene" event. So, the handler will catch the scene path in the values of the event, and will change the scene thanks to the scene manager.
- A ConnectServer might process the "ConnectServer" event. So, the handler will catch the needed settings from the event values, and use the network to connect to the server.
In our game engine, developers and the community can create custom systems and components. Components are written in C++.
If you haven’t already read the ECS Events section, please take a moment to review it.
In this tutorial, we'll create a SwitchScene event handler. This handler will change the current scene by the needed one.
First, create a SwitchSceneHandler.hpp
file. Include the following files:
#include "AEventHandler.hpp"
#include "../Error/AError.hpp"
-
AEventHandler
: Simply an abstract to avoid duplicating the same code for each handler. -
ISystem
: the interface class for system. To create a new system, it must inherit from this interface.
Now, let's create our system class. It must inherit from the AEventHandler
class.
class SwitchSceneHandler : public AEventHandler {
public:
SwitchSceneHandler(); // Constructor
~SwitchSceneHandler() = default; // Default destructor
};
Then, ISystem
has a single method to override, it's the method to get the function system:
class SwitchSceneHandler : public AEventHandler {
public:
bool processEvent(std::shared_ptr<IEvent> event, std::shared_ptr<SceneManager::ISceneManager> sceneManager, std::shared_ptr<ABINetwork::INetworkUnit> networkUnit, std::shared_ptr<IGraphic> graphicLib) override;
};
This method takes the Event, the SceneManager, the NetworkUnit and the GraphicLib. This allows us many access to modules of the application unlike simple systems. Now, let's implement the method
SwitchSceneHandler::SwitchSceneHandler(std::string eventType)
: AEventHandler("SwitchScene") {}
bool SwitchSceneHandler::processEvent(std::shared_ptr<IEvent> event,
std::shared_ptr<SceneManager::ISceneManager> sceneManager,
std::shared_ptr<ABINetwork::INetworkUnit> networkUnit,
std::shared_ptr<IGraphic> graphicLib)
{
try {
// Get the scene path from the event values
std::string sceneName = std::any_cast<std::string>(event->getValues()[0]);
std::pair<std::size_t, std::string> scenePair = std::make_pair(0, sceneName);
// Using the scene manager, change the scene to the wanted one
sceneManager->changeScene(scenePair);
} catch (const std::exception &e) {
throw SwitchSceneHandlerError("Error while processing the event: " + std::string(e.what()));
}
return true;
}
Here we are ! We have our first event Handler !
But that's not the end. How will the game Engine use our event handler ?
For that, we must create an entry point. When the handler will be loaded in the game Engine, it will call this entry point to get the Event Handler class.
For that, create a cpp
file named SwitchSceneHandler.cpp
put this on it:
#include "SwitchSceneHandler.hpp"
extern "C" {
EXPORT_SYMBOL ISystem* loadSystemInstance() {
return new SwitchSceneHandler();
}
}
This function will return our Event Handler class previously created, the EXPORT_SYMBOL
is a macro use to make windows able to open .dll
files.
Compile your Handler with this command in your terminal:
g++ -fPIC -shared -o theNameOfYourEventHandler.so yourFile.cpp
Replace theNameOfYourEventHandler
by the name you want to give to your Event Handler file
, and yourFile.cpp
by the SwitchSceneHandler.cpp
.
Finally, place your file .so
in the Game/Engine/ folder. The system will be automatically loaded when the game Engine will be running.