aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoïc Blot <nerzhul@users.noreply.github.com>2017-08-28 20:02:23 +0200
committerGitHub <noreply@github.com>2017-08-28 20:02:23 +0200
commit5f38fe33f89e87b56ab95370c2f07fe6117b5eb0 (patch)
treee2a497bb99f37ce6baae56d2979a2ae957829dc2
parent6fd8a27c91b09f51693243586af3615f962d1730 (diff)
downloadminetest-5f38fe33f89e87b56ab95370c2f07fe6117b5eb0.tar.gz
minetest-5f38fe33f89e87b56ab95370c2f07fe6117b5eb0.tar.bz2
minetest-5f38fe33f89e87b56ab95370c2f07fe6117b5eb0.zip
Clientevent refactor (#6320)
* Refactor clientevent structure * Move structure outside of client header * Create client events on heap not stack, this remove the ClientEvent object copy * Use clientEventHandler to route events
-rw-r--r--src/client.cpp16
-rw-r--r--src/client.h141
-rw-r--r--src/client/clientevent.h170
-rw-r--r--src/game.cpp496
-rw-r--r--src/network/clientpackethandler.cpp206
-rw-r--r--src/particles.cpp1
-rw-r--r--src/script/lua_api/l_client.cpp9
7 files changed, 571 insertions, 468 deletions
diff --git a/src/client.cpp b/src/client.cpp
index 658b10393..6fd007181 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "network/connection.h"
#include "network/networkpacket.h"
#include "threading/mutex_auto_lock.h"
+#include "client/clientevent.h"
#include "client/renderingengine.h"
#include "util/auth.h"
#include "util/directiontables.h"
@@ -425,9 +426,9 @@ void Client::step(float dtime)
sendDamage(damage);
// Add to ClientEvent queue
- ClientEvent event;
- event.type = CE_PLAYER_DAMAGE;
- event.player_damage.amount = damage;
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_PLAYER_DAMAGE;
+ event->player_damage.amount = damage;
m_client_event_queue.push(event);
}
}
@@ -1661,12 +1662,12 @@ void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool ur
}
}
-ClientEvent Client::getClientEvent()
+ClientEvent *Client::getClientEvent()
{
FATAL_ERROR_IF(m_client_event_queue.empty(),
"Cannot getClientEvent, queue is empty.");
- ClientEvent event = m_client_event_queue.front();
+ ClientEvent *event = m_client_event_queue.front();
m_client_event_queue.pop();
return event;
}
@@ -1865,6 +1866,11 @@ bool Client::shouldShowMinimap() const
return !m_minimap_disabled_by_server;
}
+void Client::pushToEventQueue(ClientEvent *event)
+{
+ m_client_event_queue.push(event);
+}
+
void Client::showGameChat(const bool show)
{
m_game_ui_flags->show_chat = show;
diff --git a/src/client.h b/src/client.h
index 2ee81ea09..6f2d3371d 100644
--- a/src/client.h
+++ b/src/client.h
@@ -41,6 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f
+struct ClientEvent;
struct MeshMakeData;
struct ChatMessage;
class MapBlockMesh;
@@ -68,137 +69,6 @@ enum LocalClientState {
LC_Ready
};
-enum ClientEventType
-{
- CE_NONE,
- CE_PLAYER_DAMAGE,
- CE_PLAYER_FORCE_MOVE,
- CE_DEATHSCREEN,
- CE_SHOW_FORMSPEC,
- CE_SHOW_LOCAL_FORMSPEC,
- CE_SPAWN_PARTICLE,
- CE_ADD_PARTICLESPAWNER,
- CE_DELETE_PARTICLESPAWNER,
- CE_HUDADD,
- CE_HUDRM,
- CE_HUDCHANGE,
- CE_SET_SKY,
- CE_OVERRIDE_DAY_NIGHT_RATIO,
- CE_CLOUD_PARAMS,
-};
-
-struct ClientEvent
-{
- ClientEventType type;
- union{
- //struct{
- //} none;
- struct{
- u8 amount;
- } player_damage;
- struct{
- f32 pitch;
- f32 yaw;
- } player_force_move;
- struct{
- bool set_camera_point_target;
- f32 camera_point_target_x;
- f32 camera_point_target_y;
- f32 camera_point_target_z;
- } deathscreen;
- struct{
- std::string *formspec;
- std::string *formname;
- } show_formspec;
- //struct{
- //} textures_updated;
- struct{
- v3f *pos;
- v3f *vel;
- v3f *acc;
- f32 expirationtime;
- f32 size;
- bool collisiondetection;
- bool collision_removal;
- bool vertical;
- std::string *texture;
- struct TileAnimationParams animation;
- u8 glow;
- } spawn_particle;
- struct{
- u16 amount;
- f32 spawntime;
- v3f *minpos;
- v3f *maxpos;
- v3f *minvel;
- v3f *maxvel;
- v3f *minacc;
- v3f *maxacc;
- f32 minexptime;
- f32 maxexptime;
- f32 minsize;
- f32 maxsize;
- bool collisiondetection;
- bool collision_removal;
- u16 attached_id;
- bool vertical;
- std::string *texture;
- u32 id;
- struct TileAnimationParams animation;
- u8 glow;
- } add_particlespawner;
- struct{
- u32 id;
- } delete_particlespawner;
- struct{
- u32 id;
- u8 type;
- v2f *pos;
- std::string *name;
- v2f *scale;
- std::string *text;
- u32 number;
- u32 item;
- u32 dir;
- v2f *align;
- v2f *offset;
- v3f *world_pos;
- v2s32 * size;
- } hudadd;
- struct{
- u32 id;
- } hudrm;
- struct{
- u32 id;
- HudElementStat stat;
- v2f *v2fdata;
- std::string *sdata;
- u32 data;
- v3f *v3fdata;
- v2s32 * v2s32data;
- } hudchange;
- struct{
- video::SColor *bgcolor;
- std::string *type;
- std::vector<std::string> *params;
- bool clouds;
- } set_sky;
- struct{
- bool do_override;
- float ratio_f;
- } override_day_night_ratio;
- struct {
- f32 density;
- u32 color_bright;
- u32 color_ambient;
- f32 height;
- f32 thickness;
- f32 speed_x;
- f32 speed_y;
- } cloud_params;
- };
-};
-
/*
Packet counter
*/
@@ -450,7 +320,7 @@ public:
bool hasClientEvents() const { return !m_client_event_queue.empty(); }
// Get event from queue. If queue is empty, it triggers an assertion failure.
- ClientEvent getClientEvent();
+ ClientEvent * getClientEvent();
bool accessDenied() const { return m_access_denied; }
@@ -530,10 +400,7 @@ public:
ClientScripting *getScript() { return m_script; }
const bool moddingEnabled() const { return m_modding_enabled; }
- inline void pushToEventQueue(const ClientEvent &event)
- {
- m_client_event_queue.push(event);
- }
+ void pushToEventQueue(ClientEvent *event);
void showGameChat(bool show = true);
void showGameHud(bool show = true);
@@ -662,7 +529,7 @@ private:
bool m_access_denied = false;
bool m_access_denied_reconnect = false;
std::string m_access_denied_reason = "";
- std::queue<ClientEvent> m_client_event_queue;
+ std::queue<ClientEvent *> m_client_event_queue;
bool m_itemdef_received = false;
bool m_nodedef_received = false;
ClientMediaDownloader *m_media_downloader;
diff --git a/src/client/clientevent.h b/src/client/clientevent.h
new file mode 100644
index 000000000..67125cce6
--- /dev/null
+++ b/src/client/clientevent.h
@@ -0,0 +1,170 @@
+/*
+Minetest
+Copyright (C) 2017 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.
+*/
+
+#pragma once
+
+#include <string>
+#include "irrlichttypes_bloated.h"
+#include "hud.h"
+
+enum ClientEventType : u8
+{
+ CE_NONE,
+ CE_PLAYER_DAMAGE,
+ CE_PLAYER_FORCE_MOVE,
+ CE_DEATHSCREEN,
+ CE_SHOW_FORMSPEC,
+ CE_SHOW_LOCAL_FORMSPEC,
+ CE_SPAWN_PARTICLE,
+ CE_ADD_PARTICLESPAWNER,
+ CE_DELETE_PARTICLESPAWNER,
+ CE_HUDADD,
+ CE_HUDRM,
+ CE_HUDCHANGE,
+ CE_SET_SKY,
+ CE_OVERRIDE_DAY_NIGHT_RATIO,
+ CE_CLOUD_PARAMS,
+ CLIENTEVENT_MAX,
+};
+
+struct ClientEvent
+{
+ ClientEventType type;
+ union
+ {
+ // struct{
+ //} none;
+ struct
+ {
+ u8 amount;
+ } player_damage;
+ struct
+ {
+ f32 pitch;
+ f32 yaw;
+ } player_force_move;
+ struct
+ {
+ bool set_camera_point_target;
+ f32 camera_point_target_x;
+ f32 camera_point_target_y;
+ f32 camera_point_target_z;
+ } deathscreen;
+ struct
+ {
+ std::string *formspec;
+ std::string *formname;
+ } show_formspec;
+ // struct{
+ //} textures_updated;
+ struct
+ {
+ v3f *pos;
+ v3f *vel;
+ v3f *acc;
+ f32 expirationtime;
+ f32 size;
+ bool collisiondetection;
+ bool collision_removal;
+ bool vertical;
+ std::string *texture;
+ struct TileAnimationParams animation;
+ u8 glow;
+ } spawn_particle;
+ struct
+ {
+ u16 amount;
+ f32 spawntime;
+ v3f *minpos;
+ v3f *maxpos;
+ v3f *minvel;
+ v3f *maxvel;
+ v3f *minacc;
+ v3f *maxacc;
+ f32 minexptime;
+ f32 maxexptime;
+ f32 minsize;
+ f32 maxsize;
+ bool collisiondetection;
+ bool collision_removal;
+ u16 attached_id;
+ bool vertical;
+ std::string *texture;
+ u32 id;
+ struct TileAnimationParams animation;
+ u8 glow;
+ } add_particlespawner;
+ struct
+ {
+ u32 id;
+ } delete_particlespawner;
+ struct
+ {
+ u32 id;
+ u8 type;
+ v2f *pos;
+ std::string *name;
+ v2f *scale;
+ std::string *text;
+ u32 number;
+ u32 item;
+ u32 dir;
+ v2f *align;
+ v2f *offset;
+ v3f *world_pos;
+ v2s32 *size;
+ } hudadd;
+ struct
+ {
+ u32 id;
+ } hudrm;
+ struct
+ {
+ u32 id;
+ HudElementStat stat;
+ v2f *v2fdata;
+ std::string *sdata;
+ u32 data;
+ v3f *v3fdata;
+ v2s32 *v2s32data;
+ } hudchange;
+ struct
+ {
+ video::SColor *bgcolor;
+ std::string *type;
+ std::vector<std::string> *params;
+ bool clouds;
+ } set_sky;
+ struct
+ {
+ bool do_override;
+ float ratio_f;
+ } override_day_night_ratio;
+ struct
+ {
+ f32 density;
+ u32 color_bright;
+ u32 color_ambient;
+ f32 height;
+ f32 thickness;
+ f32 speed_x;
+ f32 speed_y;
+ } cloud_params;
+ };
+};
diff --git a/src/game.cpp b/src/game.cpp
index 43495e8a6..17ab68e7c 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/renderingengine.h"
#include "camera.h"
#include "client.h"
+#include "client/clientevent.h"
#include "client/inputhandler.h"
#include "client/tile.h" // For TextureSource
#include "client/keys.h"
@@ -1181,6 +1182,13 @@ struct RunStats {
Jitter dtime_jitter, busy_time_jitter;
};
+class Game;
+
+struct ClientEventHandler
+{
+ void (Game::*handler)(ClientEvent *, CameraOrientation *);
+};
+
/****************************************************************************
THE GAME
****************************************************************************/
@@ -1361,6 +1369,25 @@ protected:
private:
void showPauseMenu();
+ // ClientEvent handlers
+ void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam);
+ void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam);
+ void handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam);
+ void handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam);
+ void handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam);
+ void handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam);
+ void handleClientEvent_HandleParticleEvent(ClientEvent *event,
+ CameraOrientation *cam);
+ void handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam);
+ void handleClientEvent_HudRemove(ClientEvent *event, CameraOrientation *cam);
+ void handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *cam);
+ void handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam);
+ void handleClientEvent_OverrideDayNigthRatio(ClientEvent *event,
+ CameraOrientation *cam);
+ void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
+
+ static const ClientEventHandler clientEventHandler[CLIENTEVENT_MAX];
+
InputHandler *input;
Client *client;
@@ -3125,272 +3152,301 @@ inline void Game::step(f32 *dtime)
}
}
+const ClientEventHandler Game::clientEventHandler[CLIENTEVENT_MAX] = {
+ {&Game::handleClientEvent_None},
+ {&Game::handleClientEvent_PlayerDamage},
+ {&Game::handleClientEvent_PlayerForceMove},
+ {&Game::handleClientEvent_Deathscreen},
+ {&Game::handleClientEvent_ShowFormSpec},
+ {&Game::handleClientEvent_ShowLocalFormSpec},
+ {&Game::handleClientEvent_HandleParticleEvent},
+ {&Game::handleClientEvent_HandleParticleEvent},
+ {&Game::handleClientEvent_HandleParticleEvent},
+ {&Game::handleClientEvent_HudAdd},
+ {&Game::handleClientEvent_HudRemove},
+ {&Game::handleClientEvent_HudChange},
+ {&Game::handleClientEvent_SetSky},
+ {&Game::handleClientEvent_OverrideDayNigthRatio},
+ {&Game::handleClientEvent_CloudParams},
+};
-void Game::processClientEvents(CameraOrientation *cam)
+void Game::handleClientEvent_None(ClientEvent *event, CameraOrientation *cam)
{
- LocalPlayer *player = client->getEnv().getLocalPlayer();
-
- while (client->hasClientEvents()) {
- ClientEvent event = client->getClientEvent();
-
- switch (event.type) {
- case CE_PLAYER_DAMAGE:
- if (client->getHP() == 0)
- break;
- if (client->moddingEnabled()) {
- client->getScript()->on_damage_taken(event.player_damage.amount);
- }
-
- runData.damage_flash += 95.0 + 3.2 * event.player_damage.amount;
- runData.damage_flash = MYMIN(runData.damage_flash, 127.0);
+ FATAL_ERROR("ClientEvent type None received");
+}
- player->hurt_tilt_timer = 1.5;
- player->hurt_tilt_strength =
- rangelim(event.player_damage.amount / 4, 1.0, 4.0);
+void Game::handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam)
+{
+ if (client->getHP() == 0)
+ return;
- client->event()->put(new SimpleTriggerEvent("PlayerDamage"));
- break;
+ if (client->moddingEnabled()) {
+ client->getScript()->on_damage_taken(event->player_damage.amount);
+ }
- case CE_PLAYER_FORCE_MOVE:
- cam->camera_yaw = event.player_force_move.yaw;
- cam->camera_pitch = event.player_force_move.pitch;
- break;
+ runData.damage_flash += 95.0 + 3.2 * event->player_damage.amount;
+ runData.damage_flash = MYMIN(runData.damage_flash, 127.0);
- case CE_DEATHSCREEN:
- // This should be enabled for death formspec in builtin
- client->getScript()->on_death();
+ LocalPlayer *player = client->getEnv().getLocalPlayer();
- /* Handle visualization */
- runData.damage_flash = 0;
- player->hurt_tilt_timer = 0;
- player->hurt_tilt_strength = 0;
- break;
+ player->hurt_tilt_timer = 1.5;
+ player->hurt_tilt_strength =
+ rangelim(event->player_damage.amount / 4, 1.0, 4.0);
- case CE_SHOW_FORMSPEC:
- if (event.show_formspec.formspec->empty()) {
- if (current_formspec && (event.show_formspec.formname->empty()
- || *(event.show_formspec.formname) == cur_formname)) {
- current_formspec->quitMenu();
- }
- } else {
- FormspecFormSource *fs_src =
- new FormspecFormSource(*(event.show_formspec.formspec));
- TextDestPlayerInventory *txt_dst =
- new TextDestPlayerInventory(client, *(event.show_formspec.formname));
-
- create_formspec_menu(&current_formspec, client, &input->joystick,
- fs_src, txt_dst);
- cur_formname = *(event.show_formspec.formname);
- }
-
- delete event.show_formspec.formspec;
- delete event.show_formspec.formname;
- break;
+ client->event()->put(new SimpleTriggerEvent("PlayerDamage"));
+}
- case CE_SHOW_LOCAL_FORMSPEC:
- {
- FormspecFormSource *fs_src = new FormspecFormSource(*event.show_formspec.formspec);
- LocalFormspecHandler *txt_dst = new LocalFormspecHandler(*event.show_formspec.formname, client);
- create_formspec_menu(&current_formspec, client, &input->joystick,
- fs_src, txt_dst);
- }
- delete event.show_formspec.formspec;
- delete event.show_formspec.formname;
- break;
+void Game::handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam)
+{
+ cam->camera_yaw = event->player_force_move.yaw;
+ cam->camera_pitch = event->player_force_move.pitch;
+}
- case CE_SPAWN_PARTICLE:
- case CE_ADD_PARTICLESPAWNER:
- case CE_DELETE_PARTICLESPAWNER:
- client->getParticleManager()->handleParticleEvent(&event, client, player);
- break;
+void Game::handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam)
+{
+ // This should be enabled for death formspec in builtin
+ client->getScript()->on_death();
- case CE_HUDADD:
- {
- u32 id = event.hudadd.id;
-
- HudElement *e = player->getHud(id);
-
- if (e != NULL) {
- delete event.hudadd.pos;
- delete event.hudadd.name;
- delete event.hudadd.scale;
- delete event.hudadd.text;
- delete event.hudadd.align;
- delete event.hudadd.offset;
- delete event.hudadd.world_pos;
- delete event.hudadd.size;
- continue;
- }
+ LocalPlayer *player = client->getEnv().getLocalPlayer();
- e = new HudElement;
- e->type = (HudElementType)event.hudadd.type;
- e->pos = *event.hudadd.pos;
- e->name = *event.hudadd.name;
- e->scale = *event.hudadd.scale;
- e->text = *event.hudadd.text;
- e->number = event.hudadd.number;
- e->item = event.hudadd.item;
- e->dir = event.hudadd.dir;
- e->align = *event.hudadd.align;
- e->offset = *event.hudadd.offset;
- e->world_pos = *event.hudadd.world_pos;
- e->size = *event.hudadd.size;
-
- u32 new_id = player->addHud(e);
- //if this isn't true our huds aren't consistent
- sanity_check(new_id == id);
- }
+ /* Handle visualization */
+ runData.damage_flash = 0;
+ player->hurt_tilt_timer = 0;
+ player->hurt_tilt_strength = 0;
+}
- delete event.hudadd.pos;
- delete event.hudadd.name;
- delete event.hudadd.scale;
- delete event.hudadd.text;
- delete event.hudadd.align;
- delete event.hudadd.offset;
- delete event.hudadd.world_pos;
- delete event.hudadd.size;
- break;
+void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam)
+{
+ if (event->show_formspec.formspec->empty()) {
+ if (current_formspec && (event->show_formspec.formname->empty()
+ || *(event->show_formspec.formname) == cur_formname)) {
+ current_formspec->quitMenu();
+ }
+ } else {
+ FormspecFormSource *fs_src =
+ new FormspecFormSource(*(event->show_formspec.formspec));
+ TextDestPlayerInventory *txt_dst =
+ new TextDestPlayerInventory(client, *(event->show_formspec.formname));
- case CE_HUDRM:
- {
- HudElement *e = player->removeHud(event.hudrm.id);
+ create_formspec_menu(&current_formspec, client, &input->joystick,
+ fs_src, txt_dst);
+ cur_formname = *(event->show_formspec.formname);
+ }
- delete e;
- }
- break;
+ delete event->show_formspec.formspec;
+ delete event->show_formspec.formname;
+}
- case CE_HUDCHANGE:
- {
- u32 id = event.hudchange.id;
- HudElement *e = player->getHud(id);
+void Game::handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam)
+{
+ FormspecFormSource *fs_src = new FormspecFormSource(*event->show_formspec.formspec);
+ LocalFormspecHandler *txt_dst =
+ new LocalFormspecHandler(*event->show_formspec.formname, client);
+ create_formspec_menu(&current_formspec, client, &input->joystick, fs_src, txt_dst);
- if (e == NULL) {
- delete event.hudchange.v3fdata;
- delete event.hudchange.v2fdata;
- delete event.hudchange.sdata;
- delete event.hudchange.v2s32data;
- continue;
- }
+ delete event->show_formspec.formspec;
+ delete event->show_formspec.formname;
+}
- switch (event.hudchange.stat) {
- case HUD_STAT_POS:
- e->pos = *event.hudchange.v2fdata;
- break;
+void Game::handleClientEvent_HandleParticleEvent(ClientEvent *event,
+ CameraOrientation *cam)
+{
+ LocalPlayer *player = client->getEnv().getLocalPlayer();
+ client->getParticleManager()->handleParticleEvent(event, client, player);
+}
- case HUD_STAT_NAME:
- e->name = *event.hudchange.sdata;
- break;
+void Game::handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam)
+{
+ LocalPlayer *player = client->getEnv().getLocalPlayer();
- case HUD_STAT_SCALE:
- e->scale = *event.hudchange.v2fdata;
- break;
+ u32 id = event->hudadd.id;
- case HUD_STAT_TEXT:
- e->text = *event.hudchange.sdata;
- break;
+ HudElement *e = player->getHud(id);
- case HUD_STAT_NUMBER:
- e->number = event.hudchange.data;
- break;
+ if (e != NULL) {
+ delete event->hudadd.pos;
+ delete event->hudadd.name;
+ delete event->hudadd.scale;
+ delete event->hudadd.text;
+ delete event->hudadd.align;
+ delete event->hudadd.offset;
+ delete event->hudadd.world_pos;
+ delete event->hudadd.size;
+ return;
+ }
- case HUD_STAT_ITEM:
- e->item = event.hudchange.data;
- break;
+ e = new HudElement;
+ e->type = (HudElementType)event->hudadd.type;
+ e->pos = *event->hudadd.pos;
+ e->name = *event->hudadd.name;
+ e->scale = *event->hudadd.scale;
+ e->text = *event->hudadd.text;
+ e->number = event->hudadd.number;
+ e->item = event->hudadd.item;
+ e->dir = event->hudadd.dir;
+ e->align = *event->hudadd.align;
+ e->offset = *event->hudadd.offset;
+ e->world_pos = *event->hudadd.world_pos;
+ e->size = *event->hudadd.size;
+
+ u32 new_id = player->addHud(e);
+ //if this isn't true our huds aren't consistent
+ sanity_check(new_id == id);
+
+ delete event->hudadd.pos;
+ delete event->hudadd.name;
+ delete event->hudadd.scale;
+ delete event->hudadd.text;
+ delete event->hudadd.align;
+ delete event->hudadd.offset;
+ delete event->hudadd.world_pos;
+ delete event->hudadd.size;
+}
- case HUD_STAT_DIR:
- e->dir = event.hudchange.data;
- break;
+void Game::handleClientEvent_HudRemove(ClientEvent *event, CameraOrientation *cam)
+{
+ LocalPlayer *player = client->getEnv().getLocalPlayer();
+ HudElement *e = player->removeHud(event->hudrm.id);
+ delete e;
+}
- case HUD_STAT_ALIGN:
- e->align = *event.hudchange.v2fdata;
- break;
+void Game::handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *cam)
+{
+ LocalPlayer *player = client->getEnv().getLocalPlayer();
- case HUD_STAT_OFFSET:
- e->offset = *event.hudchange.v2fdata;
- break;
+ u32 id = event->hudchange.id;
+ HudElement *e = player->getHud(id);
- case HUD_STAT_WORLD_POS:
- e->world_pos = *event.hudchange.v3fdata;
- break;
+ if (e == NULL) {
+ delete event->hudchange.v3fdata;
+ delete event->hudchange.v2fdata;
+ delete event->hudchange.sdata;
+ delete event->hudchange.v2s32data;
+ return;
+ }
- case HUD_STAT_SIZE:
- e->size = *event.hudchange.v2s32data;
- break;
- }
- }
+ switch (event->hudchange.stat) {
+ case HUD_STAT_POS:
+ e->pos = *event->hudchange.v2fdata;
+ break;
- delete event.hudchange.v3fdata;
- delete event.hudchange.v2fdata;
- delete event.hudchange.sdata;
- delete event.hudchange.v2s32data;
+ case HUD_STAT_NAME:
+ e->name = *event->hudchange.sdata;
break;
- case CE_SET_SKY:
- sky->setVisible(false);
- // Whether clouds are visible in front of a custom skybox
- sky->setCloudsEnabled(event.set_sky.clouds);
+ case HUD_STAT_SCALE:
+ e->scale = *event->hudchange.v2fdata;
+ break;
- if (skybox) {
- skybox->remove();
- skybox = NULL;
- }
+ case HUD_STAT_TEXT:
+ e->text = *event->hudchange.sdata;
+ break;
- // Handle according to type
- if (*event.set_sky.type == "regular") {
- sky->setVisible(true);
- sky->setCloudsEnabled(true);
- } else if (*event.set_sky.type == "skybox" &&
- event.set_sky.params->size() == 6) {
- sky->setFallbackBgColor(*event.set_sky.bgcolor);
- skybox = RenderingEngine::get_scene_manager()->addSkyBoxSceneNode(
- texture_src->getTextureForMesh((*event.set_sky.params)[0]),
- texture_src->getTextureForMesh((*event.set_sky.params)[1]),
- texture_src->getTextureForMesh((*event.set_sky.params)[2]),
- texture_src->getTextureForMesh((*event.set_sky.params)[3]),
- texture_src->getTextureForMesh((*event.set_sky.params)[4]),
- texture_src->getTextureForMesh((*event.set_sky.params)[5]));
- }
- // Handle everything else as plain color
- else {
- if (*event.set_sky.type != "plain")
- infostream << "Unknown sky type: "
- << (*event.set_sky.type) << std::endl;
+ case HUD_STAT_NUMBER:
+ e->number = event->hudchange.data;
+ break;
- sky->setFallbackBgColor(*event.set_sky.bgcolor);
- }
+ case HUD_STAT_ITEM:
+ e->item = event->hudchange.data;
+ break;
- delete event.set_sky.bgcolor;
- delete event.set_sky.type;
- delete event.set_sky.params;
+ case HUD_STAT_DIR:
+ e->dir = event->hudchange.data;
break;
- case CE_OVERRIDE_DAY_NIGHT_RATIO:
- client->getEnv().setDayNightRatioOverride(
- event.override_day_night_ratio.do_override,
- event.override_day_night_ratio.ratio_f * 1000);
+ case HUD_STAT_ALIGN:
+ e->align = *event->hudchange.v2fdata;
break;
- case CE_CLOUD_PARAMS:
- if (clouds) {
- clouds->setDensity(event.cloud_params.density);
- clouds->setColorBright(video::SColor(event.cloud_params.color_bright));
- clouds->setColorAmbient(video::SColor(event.cloud_params.color_ambient));
- clouds->setHeight(event.cloud_params.height);
- clouds->setThickness(event.cloud_params.thickness);
- clouds->setSpeed(v2f(
- event.cloud_params.speed_x,
- event.cloud_params.speed_y));
- }
+ case HUD_STAT_OFFSET:
+ e->offset = *event->hudchange.v2fdata;
break;
- default:
- // unknown or unhandled type
+ case HUD_STAT_WORLD_POS:
+ e->world_pos = *event->hudchange.v3fdata;
break;
- }
+ case HUD_STAT_SIZE:
+ e->size = *event->hudchange.v2s32data;
+ break;
}
+
+ delete event->hudchange.v3fdata;
+ delete event->hudchange.v2fdata;
+ delete event->hudchange.sdata;
+ delete event->hudchange.v2s32data;
+}
+
+void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam)
+{
+ sky->setVisible(false);
+ // Whether clouds are visible in front of a custom skybox
+ sky->setCloudsEnabled(event->set_sky.clouds);
+
+ if (skybox) {
+ skybox->remove();
+ skybox = NULL;
+ }
+
+ // Handle according to type
+ if (*event->set_sky.type == "regular") {
+ sky->setVisible(true);
+ sky->setCloudsEnabled(true);
+ } else if (*event->set_sky.type == "skybox" &&
+ event->set_sky.params->size() == 6) {
+ sky->setFallbackBgColor(*event->set_sky.bgcolor);
+ skybox = RenderingEngine::get_scene_manager()->addSkyBoxSceneNode(
+ texture_src->getTextureForMesh((*event->set_sky.params)[0]),
+ texture_src->getTextureForMesh((*event->set_sky.params)[1]),
+ texture_src->getTextureForMesh((*event->set_sky.params)[2]),
+ texture_src->getTextureForMesh((*event->set_sky.params)[3]),
+ texture_src->getTextureForMesh((*event->set_sky.params)[4]),
+ texture_src->getTextureForMesh((*event->set_sky.params)[5]));
+ }
+ // Handle everything else as plain color
+ else {
+ if (*event->set_sky.type != "plain")
+ infostream << "Unknown sky type: "
+ << (*event->set_sky.type) << std::endl;
+
+ sky->setFallbackBgColor(*event->set_sky.bgcolor);
+ }
+
+ delete event->set_sky.bgcolor;
+ delete event->set_sky.type;
+ delete event->set_sky.params;
}
+void Game::handleClientEvent_OverrideDayNigthRatio(ClientEvent *event,
+ CameraOrientation *cam)
+{
+ client->getEnv().setDayNightRatioOverride(
+ event->override_day_night_ratio.do_override,
+ event->override_day_night_ratio.ratio_f * 1000.0f);
+}
+
+void Game::handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam)
+{
+ if (!clouds)
+ return;
+
+ clouds->setDensity(event->cloud_params.density);
+ clouds->setColorBright(video::SColor(event->cloud_params.color_bright));
+ clouds->setColorAmbient(video::SColor(event->cloud_params.color_ambient));
+ clouds->setHeight(event->cloud_params.height);
+ clouds->setThickness(event->cloud_params.thickness);
+ clouds->setSpeed(v2f(event->cloud_params.speed_x, event->cloud_params.speed_y));
+}
+
+void Game::processClientEvents(CameraOrientation *cam)
+{
+ while (client->hasClientEvents()) {
+ std::unique_ptr<ClientEvent> event(client->getClientEvent());
+ FATAL_ERROR_IF(event->type >= CLIENTEVENT_MAX, "Invalid clientevent type");
+ const ClientEventHandler& evHandler = clientEventHandler[event->type];
+ (this->*evHandler.handler)(event.get(), cam);
+ }
+}
void Game::updateCamera(u32 busy_time, f32 dtime)
{
diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp
index f42f9219b..49dba7a91 100644
--- a/src/network/clientpackethandler.cpp
+++ b/src/network/clientpackethandler.cpp
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "serialization.h"
#include "server.h"
#include "util/strfnd.h"
+#include "client/clientevent.h"
#include "network/clientopcodes.h"
#include "network/connection.h"
#include "script/scripting_client.h"
@@ -577,9 +578,9 @@ void Client::handleCommand_HP(NetworkPacket* pkt)
if (hp < oldhp) {
// Add to ClientEvent queue
- ClientEvent event;
- event.type = CE_PLAYER_DAMAGE;
- event.player_damage.amount = oldhp - hp;
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_PLAYER_DAMAGE;
+ event->player_damage.amount = oldhp - hp;
m_client_event_queue.push(event);
}
}
@@ -620,10 +621,10 @@ void Client::handleCommand_MovePlayer(NetworkPacket* pkt)
it would just force the pitch and yaw values to whatever
the camera points to.
*/
- ClientEvent event;
- event.type = CE_PLAYER_FORCE_MOVE;
- event.player_force_move.pitch = pitch;
- event.player_force_move.yaw = yaw;
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_PLAYER_FORCE_MOVE;
+ event->player_force_move.pitch = pitch;
+ event->player_force_move.yaw = yaw;
m_client_event_queue.push(event);
// Ignore damage for a few seconds, so that the player doesn't
@@ -639,12 +640,12 @@ void Client::handleCommand_DeathScreen(NetworkPacket* pkt)
*pkt >> set_camera_point_target;
*pkt >> camera_point_target;
- ClientEvent event;
- event.type = CE_DEATHSCREEN;
- event.deathscreen.set_camera_point_target = set_camera_point_target;
- event.deathscreen.camera_point_target_x = camera_point_target.X;
- event.deathscreen.camera_point_target_y = camera_point_target.Y;
- event.deathscreen.camera_point_target_z = camera_point_target.Z;
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_DEATHSCREEN;
+ event->deathscreen.set_camera_point_target = set_camera_point_target;
+ event->deathscreen.camera_point_target_x = camera_point_target.X;
+ event->deathscreen.camera_point_target_y = camera_point_target.Y;
+ event->deathscreen.camera_point_target_z = camera_point_target.Z;
m_client_event_queue.push(event);
}
@@ -942,12 +943,12 @@ void Client::handleCommand_ShowFormSpec(NetworkPacket* pkt)
*pkt >> formname;
- ClientEvent event;
- event.type = CE_SHOW_FORMSPEC;
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_SHOW_FORMSPEC;
// pointer is required as event is a struct only!
// adding a std:string to a struct isn't possible
- event.show_formspec.formspec = new std::string(formspec);
- event.show_formspec.formname = new std::string(formname);
+ event->show_formspec.formspec = new std::string(formspec);
+ event->show_formspec.formname = new std::string(formname);
m_client_event_queue.push(event);
}
@@ -975,19 +976,19 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt)
glow = readU8(is);
} catch (...) {}
- ClientEvent event;
- event.type = CE_SPAWN_PARTICLE;
- event.spawn_particle.pos = new v3f (pos);
- event.spawn_particle.vel = new v3f (vel);
- event.spawn_particle.acc = new v3f (acc);
- event.spawn_particle.expirationtime = expirationtime;
- event.spawn_particle.size = size;
- event.spawn_particle.collisiondetection = collisiondetection;
- event.spawn_particle.collision_removal = collision_removal;
- event.spawn_particle.vertical = vertical;
- event.spawn_particle.texture = new std::string(texture);
- event.spawn_particle.animation = animation;
- event.spawn_particle.glow = glow;
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_SPAWN_PARTICLE;
+ event->spawn_particle.pos = new v3f (pos);
+ event->spawn_particle.vel = new v3f (vel);
+ event->spawn_particle.acc = new v3f (acc);
+ event->spawn_particle.expirationtime = expirationtime;
+ event->spawn_particle.size = size;
+ event->spawn_particle.collisiondetection = collisiondetection;
+ event->spawn_particle.collision_removal = collision_removal;
+ event->spawn_particle.vertical = vertical;
+ event->spawn_particle.texture = new std::string(texture);
+ event->spawn_particle.animation = animation;
+ event->spawn_particle.glow = glow;
m_client_event_queue.push(event);
}
@@ -1035,28 +1036,28 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
glow = readU8(is);
} catch (...) {}
- ClientEvent event;
- event.type = CE_ADD_PARTICLESPAWNER;
- event.add_particlespawner.amount = amount;
- event.add_particlespawner.spawntime = spawntime;
- event.add_particlespawner.minpos = new v3f (minpos);
- event.add_particlespawner.maxpos = new v3f (maxpos);
- event.add_particlespawner.minvel = new v3f (minvel);
- event.add_particlespawner.maxvel = new v3f (maxvel);
- event.add_particlespawner.minacc = new v3f (minacc);
- event.add_particlespawner.maxacc = new v3f (maxacc);
- event.add_particlespawner.minexptime = minexptime;
- event.add_particlespawner.maxexptime = maxexptime;
- event.add_particlespawner.minsize = minsize;
- event.add_particlespawner.maxsize = maxsize;
- event.add_particlespawner.collisiondetection = collisiondetection;
- event.add_particlespawner.collision_removal = collision_removal;
- event.add_particlespawner.attached_id = attached_id;
- event.add_particlespawner.vertical = vertical;
- event.add_particlespawner.texture = new std::string(texture);
- event.add_particlespawner.id = id;
- event.add_particlespawner.animation = animation;
- event.add_particlespawner.glow = glow;
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_ADD_PARTICLESPAWNER;
+ event->add_particlespawner.amount = amount;
+ event->add_particlespawner.spawntime = spawntime;
+ event->add_particlespawner.minpos = new v3f (minpos);
+ event->add_particlespawner.maxpos = new v3f (maxpos);
+ event->add_particlespawner.minvel = new v3f (minvel);
+ event->add_particlespawner.maxvel = new v3f (maxvel);
+ event->add_particlespawner.minacc = new v3f (minacc);
+ event->add_particlespawner.maxacc = new v3f (maxacc);
+ event->add_particlespawner.minexptime = minexptime;
+ event->add_particlespawner.maxexptime = maxexptime;
+ event->add_particlespawner.minsize = minsize;
+ event->add_particlespawner.maxsize = maxsize;
+ event->add_particlespawner.collisiondetection = collisiondetection;
+ event->add_particlespawner.collision_removal = collision_removal;
+ event->add_particlespawner.attached_id = attached_id;
+ event->add_particlespawner.vertical = vertical;
+ event->add_particlespawner.texture = new std::string(texture);
+ event->add_particlespawner.id = id;
+ event->add_particlespawner.animation = animation;
+ event->add_particlespawner.glow = glow;
m_client_event_queue.push(event);
}
@@ -1076,10 +1077,11 @@ void Client::handleCommand_DeleteParticleSpawner(NetworkPacket* pkt)
}
- ClientEvent event;
- event.type = CE_DELETE_PARTICLESPAWNER;
- event.delete_particlespawner.id =
- (pkt->getCommand() == TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY ? (u32) legacy_id : id);
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_DELETE_PARTICLESPAWNER;
+ event->delete_particlespawner.id =
+ (pkt->getCommand() == TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY ?
+ (u32) legacy_id : id);
m_client_event_queue.push(event);
}
@@ -1114,21 +1116,21 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
*pkt >> size;
} catch(SerializationError &e) {};
- ClientEvent event;
- event.type = CE_HUDADD;
- event.hudadd.id = id;
- event.hudadd.type = type;
- event.hudadd.pos = new v2f(pos);
- event.hudadd.name = new std::string(name);
- event.hudadd.scale = new v2f(scale);
- event.hudadd.text = new std::string(text);
- event.hudadd.number = number;
- event.hudadd.item = item;
- event.hudadd.dir = dir;
- event.hudadd.align = new v2f(align);
- event.hudadd.offset = new v2f(offset);
- event.hudadd.world_pos = new v3f(world_pos);
- event.hudadd.size = new v2s32(size);
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_HUDADD;
+ event->hudadd.id = id;
+ event->hudadd.type = type;
+ event->hudadd.pos = new v2f(pos);
+ event->hudadd.name = new std::string(name);
+ event->hudadd.scale = new v2f(scale);
+ event->hudadd.text = new std::string(text);
+ event->hudadd.number = number;
+ event->hudadd.item = item;
+ event->hudadd.dir = dir;
+ event->hudadd.align = new v2f(align);
+ event->hudadd.offset = new v2f(offset);
+ event->hudadd.world_pos = new v3f(world_pos);
+ event->hudadd.size = new v2s32(size);
m_client_event_queue.push(event);
}
@@ -1138,9 +1140,9 @@ void Client::handleCommand_HudRemove(NetworkPacket* pkt)
*pkt >> id;
- ClientEvent event;
- event.type = CE_HUDRM;
- event.hudrm.id = id;
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_HUDRM;
+ event->hudrm.id = id;
m_client_event_queue.push(event);
}
@@ -1168,15 +1170,15 @@ void Client::handleCommand_HudChange(NetworkPacket* pkt)
else
*pkt >> intdata;
- ClientEvent event;
- event.type = CE_HUDCHANGE;
- event.hudchange.id = id;
- event.hudchange.stat = (HudElementStat)stat;
- event.hudchange.v2fdata = new v2f(v2fdata);
- event.hudchange.v3fdata = new v3f(v3fdata);
- event.hudchange.sdata = new std::string(sdata);
- event.hudchange.data = intdata;
- event.hudchange.v2s32data = new v2s32(v2s32data);
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_HUDCHANGE;
+ event->hudchange.id = id;
+ event->hudchange.stat = (HudElementStat)stat;
+ event->hudchange.v2fdata = new v2f(v2fdata);
+ event->hudchange.v3fdata = new v3f(v3fdata);
+ event->hudchange.sdata = new std::string(sdata);
+ event->hudchange.data = intdata;
+ event->hudchange.v2s32data = new v2s32(v2s32data);
m_client_event_queue.push(event);
}
@@ -1261,12 +1263,12 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt)
clouds = readU8(is);
} catch (...) {}
- ClientEvent event;
- event.type = CE_SET_SKY;
- event.set_sky.bgcolor = bgcolor;
- event.set_sky.type = type;
- event.set_sky.params = params;
- event.set_sky.clouds = clouds;
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_SET_SKY;
+ event->set_sky.bgcolor = bgcolor;
+ event->set_sky.type = type;
+ event->set_sky.params = params;
+ event->set_sky.clouds = clouds;
m_client_event_queue.push(event);
}
@@ -1282,19 +1284,19 @@ void Client::handleCommand_CloudParams(NetworkPacket* pkt)
*pkt >> density >> color_bright >> color_ambient
>> height >> thickness >> speed;
- ClientEvent event;
- event.type = CE_CLOUD_PARAMS;
- event.cloud_params.density = density;
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_CLOUD_PARAMS;
+ event->cloud_params.density = density;
// use the underlying u32 representation, because we can't
// use struct members with constructors here, and this way
// we avoid using new() and delete() for no good reason
- event.cloud_params.color_bright = color_bright.color;
- event.cloud_params.color_ambient = color_ambient.color;
- event.cloud_params.height = height;
- event.cloud_params.thickness = thickness;
+ event->cloud_params.color_bright = color_bright.color;
+ event->cloud_params.color_ambient = color_ambient.color;
+ event->cloud_params.height = height;
+ event->cloud_params.thickness = thickness;
// same here: deconstruct to skip constructor
- event.cloud_params.speed_x = speed.X;
- event.cloud_params.speed_y = speed.Y;
+ event->cloud_params.speed_x = speed.X;
+ event->cloud_params.speed_y = speed.Y;
m_client_event_queue.push(event);
}
@@ -1307,10 +1309,10 @@ void Client::handleCommand_OverrideDayNightRatio(NetworkPacket* pkt)
float day_night_ratio_f = (float)day_night_ratio_u / 65536;
- ClientEvent event;
- event.type = CE_OVERRIDE_DAY_NIGHT_RATIO;
- event.override_day_night_ratio.do_override = do_override;
- event.override_day_night_ratio.ratio_f = day_night_ratio_f;
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_OVERRIDE_DAY_NIGHT_RATIO;
+ event->override_day_night_ratio.do_override = do_override;
+ event->override_day_night_ratio.ratio_f = day_night_ratio_f;
m_client_event_queue.push(event);
}
diff --git a/src/particles.cpp b/src/particles.cpp
index 815ae98c5..4839e45c4 100644
--- a/src/particles.cpp
+++ b/src/particles.cpp
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "particles.h"
#include "client.h"
#include "collision.h"
+#include "client/clientevent.h"
#include "client/renderingengine.h"
#include "util/numeric.h"
#include "light.h"
diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp
index 81bf49329..ba22a0424 100644
--- a/src/script/lua_api/l_client.cpp
+++ b/src/script/lua_api/l_client.cpp
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "l_client.h"
#include "chatmessage.h"
#include "client.h"
+#include "client/clientevent.h"
#include "clientenvironment.h"
#include "common/c_content.h"
#include "common/c_converter.h"
@@ -129,10 +130,10 @@ int ModApiClient::l_show_formspec(lua_State *L)
if (!lua_isstring(L, 1) || !lua_isstring(L, 2))
return 0;
- ClientEvent event;
- event.type = CE_SHOW_LOCAL_FORMSPEC;
- event.show_formspec.formname = new std::string(luaL_checkstring(L, 1));
- event.show_formspec.formspec = new std::string(luaL_checkstring(L, 2));
+ ClientEvent *event = new ClientEvent();
+ event->type = CE_SHOW_LOCAL_FORMSPEC;
+ event->show_formspec.formname = new std::string(luaL_checkstring(L, 1));
+ event->show_formspec.formspec = new std::string(luaL_checkstring(L, 2));
getClient(L)->pushToEventQueue(event);
lua_pushboolean(L, true);
return 1;