Skip to content

Commit

Permalink
Client & ClientEnvirnment: don't create fake events (#5676)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
nerzhul authored Apr 29, 2017
1 parent f727f54 commit 3db66b4
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 33 deletions.
33 changes: 14 additions & 19 deletions src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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;
}

Expand Down
3 changes: 2 additions & 1 deletion src/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,8 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
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; }
Expand Down
14 changes: 6 additions & 8 deletions src/clientenvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
5 changes: 3 additions & 2 deletions src/clientenvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,9 @@ class ClientEnvironment : public Environment
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.
Expand Down
5 changes: 2 additions & 3 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 3db66b4

Please sign in to comment.