aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLoïc Blot <nerzhul@users.noreply.github.com>2018-03-30 18:32:52 +0200
committerGitHub <noreply@github.com>2018-03-30 18:32:52 +0200
commitce873108aa91d19104f46c5acd3350385e7a4541 (patch)
tree58672a3c803469de71c9ae270beb9a052ba5559a /src
parent2c490dddc037d7d1cf211bbf28309e31b0abdadd (diff)
downloadhax-minetest-server-ce873108aa91d19104f46c5acd3350385e7a4541.tar.gz
hax-minetest-server-ce873108aa91d19104f46c5acd3350385e7a4541.zip
Client eventmanager refactor (#7179)
* Drop EventManager from GameDef & do some client cleanups * EventManager is only used by Client. Don't expose it on Server & GameDef for nothing * Drop Client::event() in favor of direct calls to getEventManager * Cleanup some event put from new + put to put(new) * MtEvent: add Type(u8) enum * This will enhance event performance & ensure stricter type * Drop MtEvent::checkIs (unused) * clang-tidy reported fixes * Code style * Move event_manager.h to the client directory as it's only used by client Add EventManager unittests + switch to unordered_map as order is not important here Drop a unused function
Diffstat (limited to 'src')
-rw-r--r--src/camera.cpp17
-rw-r--r--src/client.h3
-rw-r--r--src/client/event_manager.h86
-rw-r--r--src/clientenvironment.cpp5
-rw-r--r--src/event.h43
-rw-r--r--src/event_manager.h108
-rw-r--r--src/game.cpp31
-rw-r--r--src/gamedef.h5
-rw-r--r--src/localplayer.cpp10
-rw-r--r--src/server.cpp8
-rw-r--r--src/server.h1
-rw-r--r--src/unittest/CMakeLists.txt1
-rw-r--r--src/unittest/test.cpp2
-rw-r--r--src/unittest/test_eventmanager.cpp112
14 files changed, 249 insertions, 183 deletions
diff --git a/src/camera.cpp b/src/camera.cpp
index 09ff93886..cf96f3308 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -160,15 +160,13 @@ void Camera::step(f32 dtime)
(was < 0.5f && m_view_bobbing_anim >= 0.5f) ||
(was > 0.5f && m_view_bobbing_anim <= 0.5f));
if(step) {
- MtEvent *e = new SimpleTriggerEvent("ViewBobbingStep");
- m_client->event()->put(e);
+ m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::VIEW_BOBBING_STEP));
}
}
}
- if (m_digging_button != -1)
- {
- f32 offset = dtime * 3.5;
+ if (m_digging_button != -1) {
+ f32 offset = dtime * 3.5f;
float m_digging_anim_was = m_digging_anim;
m_digging_anim += offset;
if (m_digging_anim >= 1)
@@ -179,13 +177,10 @@ void Camera::step(f32 dtime)
float lim = 0.15;
if(m_digging_anim_was < lim && m_digging_anim >= lim)
{
- if(m_digging_button == 0)
- {
- MtEvent *e = new SimpleTriggerEvent("CameraPunchLeft");
- m_client->event()->put(e);
+ if (m_digging_button == 0) {
+ m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::CAMERA_PUNCH_LEFT));
} else if(m_digging_button == 1) {
- MtEvent *e = new SimpleTriggerEvent("CameraPunchRight");
- m_client->event()->put(e);
+ m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::CAMERA_PUNCH_RIGHT));
}
}
}
diff --git a/src/client.h b/src/client.h
index 2034a1f9c..5c07d043e 100644
--- a/src/client.h
+++ b/src/client.h
@@ -370,10 +370,9 @@ public:
ICraftDefManager* getCraftDefManager() override;
ITextureSource* getTextureSource();
virtual IShaderSource* getShaderSource();
- IShaderSource *shsrc() { return getShaderSource(); }
u16 allocateUnknownNodeId(const std::string &name) override;
virtual ISoundManager* getSoundManager();
- MtEventManager* getEventManager() override;
+ MtEventManager* getEventManager();
virtual ParticleManager* getParticleManager();
bool checkLocalPrivilege(const std::string &priv)
{ return checkPrivilege(priv); }
diff --git a/src/client/event_manager.h b/src/client/event_manager.h
new file mode 100644
index 000000000..3762e89bf
--- /dev/null
+++ b/src/client/event_manager.h
@@ -0,0 +1,86 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+
+#include "event.h"
+#include <list>
+#include <map>
+
+class EventManager : public MtEventManager
+{
+ static void receiverReceive(MtEvent *e, void *data)
+ {
+ MtEventReceiver *r = (MtEventReceiver *)data;
+ r->onEvent(e);
+ }
+ struct FuncSpec
+ {
+ event_receive_func f;
+ void *d;
+ FuncSpec(event_receive_func f, void *d) : f(f), d(d) {}
+ };
+
+ struct Dest
+ {
+ std::list<FuncSpec> funcs{};
+ };
+ std::map<MtEvent::Type, Dest> m_dest{};
+
+public:
+ ~EventManager() override = default;
+
+ void put(MtEvent *e) override
+ {
+ std::map<MtEvent::Type, Dest>::iterator i = m_dest.find(e->getType());
+ if (i != m_dest.end()) {
+ std::list<FuncSpec> &funcs = i->second.funcs;
+ for (FuncSpec &func : funcs) {
+ (*(func.f))(e, func.d);
+ }
+ }
+ delete e;
+ }
+ void reg(MtEvent::Type type, event_receive_func f, void *data) override
+ {
+ std::map<MtEvent::Type, Dest>::iterator i = m_dest.find(type);
+ if (i != m_dest.end()) {
+ i->second.funcs.emplace_back(f, data);
+ } else {
+ Dest dest;
+ dest.funcs.emplace_back(f, data);
+ m_dest[type] = dest;
+ }
+ }
+ void dereg(MtEvent::Type type, event_receive_func f, void *data) override
+ {
+ std::map<MtEvent::Type, Dest>::iterator i = m_dest.find(type);
+ if (i != m_dest.end()) {
+ std::list<FuncSpec> &funcs = i->second.funcs;
+ auto j = funcs.begin();
+ while (j != funcs.end()) {
+ bool remove = (j->f == f && (!data || j->d == data));
+ if (remove)
+ funcs.erase(j++);
+ else
+ ++j;
+ }
+ }
+ }
+};
diff --git a/src/clientenvironment.cpp b/src/clientenvironment.cpp
index 8de073258..76ac080d4 100644
--- a/src/clientenvironment.cpp
+++ b/src/clientenvironment.cpp
@@ -227,7 +227,7 @@ void ClientEnvironment::step(float dtime)
get(m_map->getNodeNoEx(info.node_p));
// Determine fall damage multiplier
int addp = itemgroup_get(f.groups, "fall_damage_add_percent");
- pre_factor = 1.0 + (float)addp/100.0;
+ pre_factor = 1.0f + (float)addp / 100.0f;
}
float speed = pre_factor * speed_diff.getLength();
if (speed > tolerance && !player_immortal) {
@@ -235,8 +235,7 @@ void ClientEnvironment::step(float dtime)
u8 damage = (u8)MYMIN(damage_f + 0.5, 255);
if (damage != 0) {
damageLocalPlayer(damage, true);
- MtEvent *e = new SimpleTriggerEvent("PlayerFallingDamage");
- m_client->event()->put(e);
+ m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_FALLING_DAMAGE));
}
}
}
diff --git a/src/event.h b/src/event.h
index 488152855..ae200978c 100644
--- a/src/event.h
+++ b/src/event.h
@@ -19,31 +19,36 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
+#import "irrlichttypes.h"
+
class MtEvent
{
public:
- virtual ~MtEvent() = default;
- //virtual MtEvent* clone(){ return new IEvent; }
- virtual const char* getType() const = 0;
-
- MtEvent* checkIs(const std::string &type)
+ enum Type : u8
{
- if(type == getType())
- return this;
- return NULL;
- }
+ VIEW_BOBBING_STEP = 0,
+ CAMERA_PUNCH_LEFT,
+ CAMERA_PUNCH_RIGHT,
+ PLAYER_FALLING_DAMAGE,
+ PLAYER_DAMAGE,
+ NODE_DUG,
+ PLAYER_JUMP,
+ PLAYER_REGAIN_GROUND,
+ TYPE_MAX,
+ };
+
+ virtual ~MtEvent() = default;
+ virtual Type getType() const = 0;
};
// An event with no parameters and customizable name
-class SimpleTriggerEvent: public MtEvent
+class SimpleTriggerEvent : public MtEvent
{
- const char *type;
+ Type type;
+
public:
- SimpleTriggerEvent(const char *type):
- type(type)
- {}
- const char* getType() const
- {return type;}
+ SimpleTriggerEvent(Type type) : type(type) {}
+ Type getType() const override { return type; }
};
class MtEventReceiver
@@ -60,9 +65,7 @@ class MtEventManager
public:
virtual ~MtEventManager() = default;
virtual void put(MtEvent *e) = 0;
- virtual void reg(const char *type, event_receive_func f, void *data) = 0;
+ virtual void reg(MtEvent::Type type, event_receive_func f, void *data) = 0;
// If data==NULL, every occurence of f is deregistered.
- virtual void dereg(const char *type, event_receive_func f, void *data) = 0;
- virtual void reg(MtEventReceiver *r, const char *type) = 0;
- virtual void dereg(MtEventReceiver *r, const char *type) = 0;
+ virtual void dereg(MtEvent::Type type, event_receive_func f, void *data) = 0;
};
diff --git a/src/event_manager.h b/src/event_manager.h
deleted file mode 100644
index f64d05869..000000000
--- a/src/event_manager.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-Minetest
-Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#pragma once
-
-#include "event.h"
-#include <list>
-#include <map>
-
-class EventManager: public MtEventManager
-{
- static void receiverReceive(MtEvent *e, void *data)
- {
- MtEventReceiver *r = (MtEventReceiver*)data;
- r->onEvent(e);
- }
- struct FuncSpec{
- event_receive_func f;
- void *d;
- FuncSpec(event_receive_func f, void *d):
- f(f), d(d)
- {}
- };
- struct Dest{
- std::list<FuncSpec> funcs;
- };
- std::map<std::string, Dest> m_dest;
-
-public:
- ~EventManager() = default;
-
- void put(MtEvent *e)
- {
- std::map<std::string, Dest>::iterator i = m_dest.find(e->getType());
- if(i != m_dest.end()){
- std::list<FuncSpec> &funcs = i->second.funcs;
- for (FuncSpec &func : funcs) {
- (*(func.f))(e, func.d);
- }
- }
- delete e;
- }
- void reg(const char *type, event_receive_func f, void *data)
- {
- std::map<std::string, Dest>::iterator i = m_dest.find(type);
- if(i != m_dest.end()){
- i->second.funcs.emplace_back(f, data);
- } else{
- std::list<FuncSpec> funcs;
- Dest dest;
- dest.funcs.emplace_back(f, data);
- m_dest[type] = dest;
- }
- }
- void dereg(const char *type, event_receive_func f, void *data)
- {
- if(type != NULL){
- std::map<std::string, Dest>::iterator i = m_dest.find(type);
- if(i != m_dest.end()){
- std::list<FuncSpec> &funcs = i->second.funcs;
- std::list<FuncSpec>::iterator j = funcs.begin();
- while(j != funcs.end()){
- bool remove = (j->f == f && (!data || j->d == data));
- if(remove)
- funcs.erase(j++);
- else
- ++j;
- }
- }
- } else{
- for (auto &dest : m_dest) {
- std::list<FuncSpec> &funcs = dest.second.funcs;
- std::list<FuncSpec>::iterator j = funcs.begin();
- while(j != funcs.end()){
- bool remove = (j->f == f && (!data || j->d == data));
- if(remove)
- funcs.erase(j++);
- else
- ++j;
- }
- }
- }
- }
- void reg(MtEventReceiver *r, const char *type)
- {
- reg(type, EventManager::receiverReceive, r);
- }
- void dereg(MtEventReceiver *r, const char *type)
- {
- dereg(type, EventManager::receiverReceive, r);
- }
-};
diff --git a/src/game.cpp b/src/game.cpp
index 3103d1f2d..9a7f4e6d7 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clouds.h"
#include "config.h"
#include "content_cao.h"
-#include "event_manager.h"
+#include "client/event_manager.h"
#include "fontengine.h"
#include "itemdef.h"
#include "log.h"
@@ -246,9 +246,9 @@ public:
p(p),
n(n)
{}
- const char *getType() const
+ MtEvent::Type getType() const
{
- return "NodeDug";
+ return MtEvent::NODE_DUG;
}
};
@@ -331,14 +331,14 @@ public:
void registerReceiver(MtEventManager *mgr)
{
- mgr->reg("ViewBobbingStep", SoundMaker::viewBobbingStep, this);
- mgr->reg("PlayerRegainGround", SoundMaker::playerRegainGround, this);
- mgr->reg("PlayerJump", SoundMaker::playerJump, this);
- mgr->reg("CameraPunchLeft", SoundMaker::cameraPunchLeft, this);
- mgr->reg("CameraPunchRight", SoundMaker::cameraPunchRight, this);
- mgr->reg("NodeDug", SoundMaker::nodeDug, this);
- mgr->reg("PlayerDamage", SoundMaker::playerDamage, this);
- mgr->reg("PlayerFallingDamage", SoundMaker::playerFallingDamage, this);
+ mgr->reg(MtEvent::VIEW_BOBBING_STEP, SoundMaker::viewBobbingStep, this);
+ mgr->reg(MtEvent::PLAYER_REGAIN_GROUND, SoundMaker::playerRegainGround, this);
+ mgr->reg(MtEvent::PLAYER_JUMP, SoundMaker::playerJump, this);
+ mgr->reg(MtEvent::CAMERA_PUNCH_LEFT, SoundMaker::cameraPunchLeft, this);
+ mgr->reg(MtEvent::CAMERA_PUNCH_RIGHT, SoundMaker::cameraPunchRight, this);
+ mgr->reg(MtEvent::NODE_DUG, SoundMaker::nodeDug, this);
+ mgr->reg(MtEvent::PLAYER_DAMAGE, SoundMaker::playerDamage, this);
+ mgr->reg(MtEvent::PLAYER_FALLING_DAMAGE, SoundMaker::playerFallingDamage, this);
}
void step(float dtime)
@@ -2491,15 +2491,15 @@ void Game::handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation
}
runData.damage_flash += 95.0 + 3.2 * event->player_damage.amount;
- runData.damage_flash = MYMIN(runData.damage_flash, 127.0);
+ runData.damage_flash = MYMIN(runData.damage_flash, 127.0f);
LocalPlayer *player = client->getEnv().getLocalPlayer();
player->hurt_tilt_timer = 1.5;
player->hurt_tilt_strength =
- rangelim(event->player_damage.amount / 4, 1.0, 4.0);
+ rangelim(event->player_damage.amount / 4, 1.0f, 4.0f);
- client->event()->put(new SimpleTriggerEvent("PlayerDamage"));
+ client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_DAMAGE));
}
void Game::handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam)
@@ -3586,8 +3586,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
// Send event to trigger sound
- MtEvent *e = new NodeDugEvent(nodepos, wasnode);
- client->event()->put(e);
+ client->getEventManager()->put(new NodeDugEvent(nodepos, wasnode));
}
if (runData.dig_time_complete < 100000.0) {
diff --git a/src/gamedef.h b/src/gamedef.h
index f86eb13cd..bc0ee14c3 100644
--- a/src/gamedef.h
+++ b/src/gamedef.h
@@ -28,7 +28,6 @@ class NodeDefManager;
class ICraftDefManager;
class ITextureSource;
class IShaderSource;
-class MtEventManager;
class IRollbackManager;
class EmergeManager;
class Camera;
@@ -58,8 +57,6 @@ public:
// Used for keeping track of names/ids of unknown nodes
virtual u16 allocateUnknownNodeId(const std::string &name)=0;
- virtual MtEventManager* getEventManager()=0;
-
// Only usable on the server, and NOT thread-safe. It is usable from the
// environment thread.
virtual IRollbackManager* getRollbackManager() { return NULL; }
@@ -68,8 +65,6 @@ public:
IItemDefManager *idef() { return getItemDefManager(); }
const NodeDefManager *ndef() { return getNodeDefManager(); }
ICraftDefManager *cdef() { return getCraftDefManager(); }
-
- MtEventManager *event() { return getEventManager(); }
IRollbackManager *rollback() { return getRollbackManager(); }
virtual const std::vector<ModSpec> &getMods() const = 0;
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index a8bd21839..de200910c 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -417,8 +417,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
*/
if(!result.standing_on_object && !touching_ground_was && touching_ground) {
- MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround");
- m_client->event()->put(e);
+ m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_REGAIN_GROUND));
// Set camera impact value to be used for view bobbing
camera_impact = getSpeed().Y * -1;
@@ -634,9 +633,7 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
if(speedJ.Y >= -0.5 * BS) {
speedJ.Y = movement_speed_jump * physics_override_jump;
setSpeed(speedJ);
-
- MtEvent *e = new SimpleTriggerEvent("PlayerJump");
- m_client->event()->put(e);
+ m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_JUMP));
}
}
else if(in_liquid)
@@ -1013,8 +1010,7 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
}
if (!result.standing_on_object && !touching_ground_was && touching_ground) {
- MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround");
- m_client->event()->put(e);
+ m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_REGAIN_GROUND));
// Set camera impact value to be used for view bobbing
camera_impact = getSpeed().Y * -1;
}
diff --git a/src/server.cpp b/src/server.cpp
index ca2743ad2..e0a15ab87 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -50,7 +50,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_nodemeta.h"
#include "content_sao.h"
#include "mods.h"
-#include "event_manager.h"
#include "modchannels.h"
#include "serverlist.h"
#include "util/string.h"
@@ -168,7 +167,6 @@ Server::Server(
m_itemdef(createItemDefManager()),
m_nodedef(createNodeDefManager()),
m_craftdef(createCraftDefManager()),
- m_event(new EventManager()),
m_uptime(0),
m_clients(m_con),
m_admin_chat(iface),
@@ -335,7 +333,6 @@ Server::~Server()
delete m_env;
delete m_rollback;
delete m_banmanager;
- delete m_event;
delete m_itemdef;
delete m_nodedef;
delete m_craftdef;
@@ -3296,11 +3293,6 @@ u16 Server::allocateUnknownNodeId(const std::string &name)
return m_nodedef->allocateDummy(name);
}
-MtEventManager *Server::getEventManager()
-{
- return m_event;
-}
-
IWritableItemDefManager *Server::getWritableItemDefManager()
{
return m_itemdef;
diff --git a/src/server.h b/src/server.h
index 2d813630c..2442140c8 100644
--- a/src/server.h
+++ b/src/server.h
@@ -263,7 +263,6 @@ public:
virtual const NodeDefManager* getNodeDefManager();
virtual ICraftDefManager* getCraftDefManager();
virtual u16 allocateUnknownNodeId(const std::string &name);
- virtual MtEventManager* getEventManager();
IRollbackManager *getRollbackManager() { return m_rollback; }
virtual EmergeManager *getEmergeManager() { return m_emerge; }
diff --git a/src/unittest/CMakeLists.txt b/src/unittest/CMakeLists.txt
index aca736f3e..733eabae3 100644
--- a/src/unittest/CMakeLists.txt
+++ b/src/unittest/CMakeLists.txt
@@ -31,6 +31,7 @@ set (UNITTEST_SRCS
PARENT_SCOPE)
set (UNITTEST_CLIENT_SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/test_eventmanager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_gameui.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_keycode.cpp
PARENT_SCOPE)
diff --git a/src/unittest/test.cpp b/src/unittest/test.cpp
index 18215a947..7a0ef16b1 100644
--- a/src/unittest/test.cpp
+++ b/src/unittest/test.cpp
@@ -51,7 +51,6 @@ public:
ITextureSource *getTextureSource() { return m_texturesrc; }
IShaderSource *getShaderSource() { return m_shadersrc; }
ISoundManager *getSoundManager() { return m_soundmgr; }
- MtEventManager *getEventManager() { return m_eventmgr; }
scene::ISceneManager *getSceneManager() { return m_scenemgr; }
IRollbackManager *getRollbackManager() { return m_rollbackmgr; }
EmergeManager *getEmergeManager() { return m_emergemgr; }
@@ -86,7 +85,6 @@ private:
ITextureSource *m_texturesrc = nullptr;
IShaderSource *m_shadersrc = nullptr;
ISoundManager *m_soundmgr = nullptr;
- MtEventManager *m_eventmgr = nullptr;
scene::ISceneManager *m_scenemgr = nullptr;
IRollbackManager *m_rollbackmgr = nullptr;
EmergeManager *m_emergemgr = nullptr;
diff --git a/src/unittest/test_eventmanager.cpp b/src/unittest/test_eventmanager.cpp
new file mode 100644
index 000000000..bb0e59336
--- /dev/null
+++ b/src/unittest/test_eventmanager.cpp
@@ -0,0 +1,112 @@
+/*
+Minetest
+Copyright (C) 2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <unordered_map>
+#include "test.h"
+#include "client/event_manager.h"
+
+class TestEventManager : public TestBase
+{
+public:
+ TestEventManager() { TestManager::registerTestModule(this); }
+ const char *getName() override { return "TestEventManager"; }
+
+ void runTests(IGameDef *gamedef) override;
+
+ void testRegister();
+ void testDeregister();
+ void testRealEvent();
+ void testRealEventAfterDereg();
+};
+
+// EventManager test class
+class EventManagerTest : public EventManager
+{
+public:
+ static void eventTest(MtEvent *e, void *data)
+ {
+ UASSERT(e->getType() >= 0);
+ UASSERT(e->getType() < MtEvent::TYPE_MAX);
+ EventManagerTest *emt = (EventManagerTest *)data;
+ emt->m_test_value = e->getType();
+ }
+
+ u64 getTestValue() const { return m_test_value; }
+ void resetValue() { m_test_value = 0; }
+
+private:
+ u64 m_test_value = 0;
+};
+
+static TestEventManager g_test_instance;
+
+void TestEventManager::runTests(IGameDef *gamedef)
+{
+ TEST(testRegister);
+ TEST(testDeregister);
+ TEST(testRealEvent);
+ TEST(testRealEventAfterDereg);
+}
+
+void TestEventManager::testRegister()
+{
+ EventManager ev;
+ ev.reg(MtEvent::PLAYER_DAMAGE, nullptr, nullptr);
+ ev.reg(MtEvent::PLAYER_DAMAGE, nullptr, nullptr);
+}
+
+void TestEventManager::testDeregister()
+{
+ EventManager ev;
+ ev.dereg(MtEvent::NODE_DUG, nullptr, nullptr);
+ ev.reg(MtEvent::PLAYER_DAMAGE, nullptr, nullptr);
+ ev.dereg(MtEvent::PLAYER_DAMAGE, nullptr, nullptr);
+}
+
+void TestEventManager::testRealEvent()
+{
+ EventManager ev;
+ std::unique_ptr<EventManagerTest> emt(new EventManagerTest());
+ ev.reg(MtEvent::PLAYER_REGAIN_GROUND, EventManagerTest::eventTest, emt.get());
+
+ // Put event & verify event value
+ ev.put(new SimpleTriggerEvent(MtEvent::PLAYER_REGAIN_GROUND));
+ UASSERT(emt->getTestValue() == MtEvent::PLAYER_REGAIN_GROUND);
+}
+
+void TestEventManager::testRealEventAfterDereg()
+{
+ EventManager ev;
+ std::unique_ptr<EventManagerTest> emt(new EventManagerTest());
+ ev.reg(MtEvent::PLAYER_REGAIN_GROUND, EventManagerTest::eventTest, emt.get());
+
+ // Put event & verify event value
+ ev.put(new SimpleTriggerEvent(MtEvent::PLAYER_REGAIN_GROUND));
+ UASSERT(emt->getTestValue() == MtEvent::PLAYER_REGAIN_GROUND);
+
+ // Reset internal value
+ emt->resetValue();
+
+ // Remove the registered event
+ ev.dereg(MtEvent::PLAYER_REGAIN_GROUND, EventManagerTest::eventTest, emt.get());
+
+ // Push the new event & ensure we target the default value
+ ev.put(new SimpleTriggerEvent(MtEvent::PLAYER_REGAIN_GROUND));
+ UASSERT(emt->getTestValue() == 0);
+} \ No newline at end of file