Skip to content
Permalink
Browse files

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
  • Loading branch information
nerzhul committed Mar 30, 2018
1 parent 2c490dd commit ce873108aa91d19104f46c5acd3350385e7a4541
@@ -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));
}
}
}
@@ -370,10 +370,9 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
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); }
@@ -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;
}
}
}
};
@@ -227,16 +227,15 @@ 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) {
f32 damage_f = (speed - tolerance) / BS * post_factor;
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));
}
}
}
@@ -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;
};

This file was deleted.

0 comments on commit ce87310

Please sign in to comment.