Skip to content

Commit

Permalink
Time: Remove serverside getter, and use atomic operations
Browse files Browse the repository at this point in the history
It isn't possible to use atomic operations for floats, so don't use them there.

Having a lock is good out of other reasons too, because this way the float time
and the integer time both match, and can't get different values in a race,
e.g. when two setTimeofDay() get executed simultaneously.
  • Loading branch information
est31 committed Nov 3, 2015
1 parent abc354a commit f9b0936
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 43 deletions.
38 changes: 15 additions & 23 deletions src/environment.cpp
Expand Up @@ -52,9 +52,8 @@ Environment::Environment():
m_time_of_day(9000),
m_time_of_day_f(9000./24000),
m_time_of_day_speed(0),
m_time_counter(0),
m_enable_day_night_ratio_override(false),
m_day_night_ratio_override(0.0f)
m_time_conversion_skew(0),
m_day_night_ratio_override_storage(0)
{
m_cache_enable_shaders = g_settings->getBool("enable_shaders");
}
Expand Down Expand Up @@ -180,53 +179,46 @@ std::vector<Player*> Environment::getPlayers(bool ignore_disconnected)

u32 Environment::getDayNightRatio()
{
MutexAutoLock(this->m_time_lock);
if (m_enable_day_night_ratio_override)
return m_day_night_ratio_override;
u64 day_night_st = m_day_night_ratio_override_storage;
if (day_night_st & ((u64)1 << 63))
return day_night_st & U32_MAX;
MutexAutoLock lock(this->m_time_floats_lock);
return time_to_daynight_ratio(m_time_of_day_f * 24000, m_cache_enable_shaders);
}

void Environment::setTimeOfDaySpeed(float speed)
{
MutexAutoLock(this->m_time_lock);
m_time_of_day_speed = speed;
}

float Environment::getTimeOfDaySpeed()
{
MutexAutoLock(this->m_time_lock);
float retval = m_time_of_day_speed;
return retval;
return m_time_of_day_speed;
}

void Environment::setTimeOfDay(u32 time)
{
MutexAutoLock(this->m_time_lock);
MutexAutoLock lock(this->m_time_floats_lock);
m_time_of_day = time;
m_time_of_day_f = (float)time / 24000.0;
}

u32 Environment::getTimeOfDay()
{
MutexAutoLock(this->m_time_lock);
u32 retval = m_time_of_day;
return retval;
return m_time_of_day;
}

float Environment::getTimeOfDayF()
{
MutexAutoLock(this->m_time_lock);
float retval = m_time_of_day_f;
return retval;
MutexAutoLock lock(this->m_time_floats_lock);
return m_time_of_day_f;
}

void Environment::stepTimeOfDay(float dtime)
{
MutexAutoLock(this->m_time_lock);

m_time_counter += dtime;
MutexAutoLock lock(this->m_time_floats_lock);
f32 speed = m_time_of_day_speed * 24000. / (24. * 3600);
u32 units = (u32)(m_time_counter * speed);
u32 units = (u32)((dtime + m_time_conversion_skew) * speed);
bool sync_f = false;
if (units > 0) {
// Sync at overflow
Expand All @@ -237,10 +229,10 @@ void Environment::stepTimeOfDay(float dtime)
m_time_of_day_f = (float)m_time_of_day / 24000.0;
}
if (speed > 0) {
m_time_counter -= (f32)units / speed;
m_time_conversion_skew -= (f32)units / speed;
}
if (!sync_f) {
m_time_of_day_f += m_time_of_day_speed / 24 / 3600 * dtime;
m_time_of_day_f += m_time_of_day_speed / (24. * 3600.) * dtime;
if (m_time_of_day_f > 1.0)
m_time_of_day_f -= 1.0;
if (m_time_of_day_f < 0.0)
Expand Down
30 changes: 16 additions & 14 deletions src/environment.h
Expand Up @@ -40,6 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapnode.h"
#include "mapblock.h"
#include "threading/mutex.h"
#include "threading/atomic.h"
#include "network/networkprotocol.h" // for AccessDeniedCode

class ServerEnvironment;
Expand Down Expand Up @@ -94,8 +95,7 @@ class Environment

void setDayNightRatioOverride(bool enable, u32 value)
{
m_enable_day_night_ratio_override = enable;
m_day_night_ratio_override = value;
m_day_night_ratio_override_storage = value | ((u64)enable << 63);
}

// counter used internally when triggering ABMs
Expand All @@ -105,23 +105,25 @@ class Environment
// peer_ids in here should be unique, except that there may be many 0s
std::vector<Player*> m_players;

// Time of day in milli-hours (0-23999); determines day and night
Atomic<u32> m_time_of_day;

/*
* Below: values under m_time_lock
*/
// Time of day in milli-hours (0-23999); determines day and night
u32 m_time_of_day;
* Below: values managed by m_time_floats_lock
*/
// Time of day in 0...1
float m_time_of_day_f;
float m_time_of_day_speed;
// Used to buffer dtime for adding to m_time_of_day
float m_time_counter;
// Overriding the day-night ratio is useful for custom sky visuals
bool m_enable_day_night_ratio_override;
u32 m_day_night_ratio_override;
// Stores the skew created by the float -> u32 conversion
// to be applied at next conversion, so that there is no real skew.
float m_time_conversion_skew;
/*
* Above: values under m_time_lock
*/
* Above: values managed by m_time_floats_lock
*/

// Overriding the day-night ratio is useful for custom sky visuals
// lowest 32 bits store the overriden ratio, highest bit stores whether its enabled
Atomic<u64> m_day_night_ratio_override_storage;

/* TODO: Add a callback function so these can be updated when a setting
* changes. At this point in time it doesn't matter (e.g. /set
Expand All @@ -135,7 +137,7 @@ class Environment
bool m_cache_enable_shaders;

private:
Mutex m_time_lock;
Mutex m_time_floats_lock;

DISABLE_CLASS_COPY(Environment);
};
Expand Down
5 changes: 0 additions & 5 deletions src/server.cpp
Expand Up @@ -1232,11 +1232,6 @@ void Server::setTimeOfDay(u32 time)
m_time_of_day_send_timer = 0;
}

u32 Server::getTimeOfDay()
{
return m_env->getTimeOfDay();
}

void Server::onMapEditEvent(MapEditEvent *event)
{
if(m_ignore_map_edit_events)
Expand Down
1 change: 0 additions & 1 deletion src/server.h
Expand Up @@ -223,7 +223,6 @@ class Server : public con::PeerHandler, public MapEventReceiver,
// Both setter and getter need no envlock,
// can be called freely from threads
void setTimeOfDay(u32 time);
inline u32 getTimeOfDay();

/*
Shall be called with the environment locked.
Expand Down

0 comments on commit f9b0936

Please sign in to comment.