mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 01:05:48 +01:00 
			
		
		
		
	Client & ClientEnvirnment: don't create fake events (#5676)
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
This commit is contained in:
		@@ -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(event.player_damage.send_to_server)
 | 
			
		||||
		if (envEvent.type == CEE_PLAYER_DAMAGE) {
 | 
			
		||||
			if (m_ignore_damage_timer <= 0) {
 | 
			
		||||
				u8 damage = envEvent.player_damage.amount;
 | 
			
		||||
 | 
			
		||||
				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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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; }
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
 
 | 
			
		||||
@@ -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:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user