Client & ClientEnvirnment: don't create fake events (#5676)
authorLoïc Blot <nerzhul@users.noreply.github.com>
Sat, 29 Apr 2017 15:25:25 +0000 (17:25 +0200)
committerGitHub <noreply@github.com>
Sat, 29 Apr 2017 15:25:25 +0000 (17:25 +0200)
Instead of create fake events on the stack on each loop call (Game::run), verify is queue is empty or not and handle event directly if there is.

This prevents fake ClientEvent creation & memory allocations

Same fix is also applied on ClientEnvironment, & rename getClientEvent to getClientEnvEvent to match ClientEnvEvent object

src/client.cpp
src/client.h
src/clientenvironment.cpp
src/clientenvironment.h
src/game.cpp

index 48ebd2f2c2a3a941bb60e7cee495082e11e03ba1..3c5a70f212968400621bd83d60f3dbe7d16afb45 100644 (file)
@@ -411,16 +411,14 @@ void Client::step(float dtime)
        /*
                Get events
        */
-       for(;;) {
-               ClientEnvEvent event = m_env.getClientEvent();
-               if(event.type == CEE_NONE) {
-                       break;
-               }
-               else if(event.type == CEE_PLAYER_DAMAGE) {
-                       if(m_ignore_damage_timer <= 0) {
-                               u8 damage = event.player_damage.amount;
+       while (m_env.hasClientEnvEvents()) {
+               ClientEnvEvent envEvent = m_env.getClientEnvEvent();
+
+               if (envEvent.type == CEE_PLAYER_DAMAGE) {
+                       if (m_ignore_damage_timer <= 0) {
+                               u8 damage = envEvent.player_damage.amount;
 
-                               if(event.player_damage.send_to_server)
+                               if (envEvent.player_damage.send_to_server)
                                        sendDamage(damage);
 
                                // Add to ClientEvent queue
@@ -431,8 +429,8 @@ void Client::step(float dtime)
                        }
                }
                // Protocol v29 or greater obsoleted this event
-               else if (event.type == CEE_PLAYER_BREATH && m_proto_ver < 29) {
-                       u16 breath = event.player_breath.amount;
+               else if (envEvent.type == CEE_PLAYER_BREATH && m_proto_ver < 29) {
+                       u16 breath = envEvent.player_breath.amount;
                        sendBreath(breath);
                }
        }
@@ -1596,14 +1594,11 @@ void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool ur
 
 ClientEvent Client::getClientEvent()
 {
-       ClientEvent event;
-       if (m_client_event_queue.empty()) {
-               event.type = CE_NONE;
-       }
-       else {
-               event = m_client_event_queue.front();
-               m_client_event_queue.pop();
-       }
+       FATAL_ERROR_IF(m_client_event_queue.empty(),
+                       "Cannot getClientEvent, queue is empty.");
+
+       ClientEvent event = m_client_event_queue.front();
+       m_client_event_queue.pop();
        return event;
 }
 
index 699550eacec07b14329e8f6374041c6e45ab6630..f5b03f19df2a0689e2e45b56ac7ae8e64896083e 100644 (file)
@@ -414,7 +414,8 @@ public:
        void updateCameraOffset(v3s16 camera_offset)
        { m_mesh_update_thread.m_camera_offset = camera_offset; }
 
-       // Get event from queue. CE_NONE is returned if queue is empty.
+       bool hasClientEvents() const { return !m_client_event_queue.empty(); }
+       // Get event from queue. If queue is empty, it triggers an assertion failure.
        ClientEvent getClientEvent();
 
        bool accessDenied() const { return m_access_denied; }
index cc75fd2d639fde2c8a297b0f015d8eb8c7d241a7..36e4437b6cecc6dd3d53fe9847bc0adc2a8f1b93 100644 (file)
@@ -598,15 +598,13 @@ void ClientEnvironment::getActiveObjects(v3f origin, f32 max_d,
        }
 }
 
-ClientEnvEvent ClientEnvironment::getClientEvent()
+ClientEnvEvent ClientEnvironment::getClientEnvEvent()
 {
-       ClientEnvEvent event;
-       if(m_client_event_queue.empty())
-               event.type = CEE_NONE;
-       else {
-               event = m_client_event_queue.front();
-               m_client_event_queue.pop();
-       }
+       FATAL_ERROR_IF(m_client_event_queue.empty(),
+                       "ClientEnvironment::getClientEnvEvent(): queue is empty");
+
+       ClientEnvEvent event = m_client_event_queue.front();
+       m_client_event_queue.pop();
        return event;
 }
 
index c273ede54a278dff088f335d27f544b9ef85e016..79b4797ad07e9bc9483a4425aaf1d83b3a9ec084 100644 (file)
@@ -126,8 +126,9 @@ public:
        void getActiveObjects(v3f origin, f32 max_d,
                std::vector<DistanceSortedActiveObject> &dest);
 
-       // Get event from queue. CEE_NONE is returned if queue is empty.
-       ClientEnvEvent getClientEvent();
+       bool hasClientEnvEvents() const { return !m_client_event_queue.empty(); }
+       // Get event from queue. If queue is empty, it triggers an assertion failure.
+       ClientEnvEvent getClientEnvEvent();
 
        /*!
         * Gets closest object pointed by the shootline.
index 12fe6a6e9480b6ecfb73ec25755379ed7de2cf2f..a1cc1ab15e82abe18d02527c84b3270e38c2e49f 100644 (file)
@@ -3055,11 +3055,10 @@ inline void Game::step(f32 *dtime)
 
 void Game::processClientEvents(CameraOrientation *cam)
 {
-       ClientEvent event = client->getClientEvent();
-
        LocalPlayer *player = client->getEnv().getLocalPlayer();
 
-       for ( ; event.type != CE_NONE; event = client->getClientEvent()) {
+       while (client->hasClientEvents()) {
+               ClientEvent event = client->getClientEvent();
 
                switch (event.type) {
                case CE_PLAYER_DAMAGE: