From ed7c9c4cb83da887a2a7f1b7f5fc1656057977e7 Mon Sep 17 00:00:00 2001 From: gregorycu Date: Sat, 24 Jan 2015 20:40:27 +1100 Subject: [PATCH] Settings fixes Make the GameGlobalShaderConstantSetter use the settings callback (8% perf improvement in game loop) Ensure variable is set Ensure settings callback is threadsafe --- src/fontengine.cpp | 26 +++++++++++++------------- src/game.cpp | 23 +++++++++++++++++++++-- src/settings.cpp | 37 ++++++++++++++++++++++++------------- src/settings.h | 14 +++++++++----- 4 files changed, 67 insertions(+), 33 deletions(-) diff --git a/src/fontengine.cpp b/src/fontengine.cpp index 79d53c989..3b82a3c47 100644 --- a/src/fontengine.cpp +++ b/src/fontengine.cpp @@ -36,7 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., FontEngine* g_fontengine = NULL; /** callback to be used on change of font size setting */ -static void font_setting_changed(const std::string) { +static void font_setting_changed(const std::string, void *userdata) { g_fontengine->readSettings(); } @@ -91,22 +91,22 @@ FontEngine::FontEngine(Settings* main_settings, gui::IGUIEnvironment* env) : updateSkin(); if (m_currentMode == FM_Standard) { - m_settings->registerChangedCallback("font_size", font_setting_changed); - m_settings->registerChangedCallback("font_path", font_setting_changed); - m_settings->registerChangedCallback("font_shadow", font_setting_changed); - m_settings->registerChangedCallback("font_shadow_alpha", font_setting_changed); + m_settings->registerChangedCallback("font_size", font_setting_changed, NULL); + m_settings->registerChangedCallback("font_path", font_setting_changed, NULL); + m_settings->registerChangedCallback("font_shadow", font_setting_changed, NULL); + m_settings->registerChangedCallback("font_shadow_alpha", font_setting_changed, NULL); } else if (m_currentMode == FM_Fallback) { - m_settings->registerChangedCallback("fallback_font_size", font_setting_changed); - m_settings->registerChangedCallback("fallback_font_path", font_setting_changed); - m_settings->registerChangedCallback("fallback_font_shadow", font_setting_changed); - m_settings->registerChangedCallback("fallback_font_shadow_alpha", font_setting_changed); + m_settings->registerChangedCallback("fallback_font_size", font_setting_changed, NULL); + m_settings->registerChangedCallback("fallback_font_path", font_setting_changed, NULL); + m_settings->registerChangedCallback("fallback_font_shadow", font_setting_changed, NULL); + m_settings->registerChangedCallback("fallback_font_shadow_alpha", font_setting_changed, NULL); } - m_settings->registerChangedCallback("mono_font_path", font_setting_changed); - m_settings->registerChangedCallback("mono_font_size", font_setting_changed); - m_settings->registerChangedCallback("screen_dpi", font_setting_changed); - m_settings->registerChangedCallback("gui_scaling", font_setting_changed); + m_settings->registerChangedCallback("mono_font_path", font_setting_changed, NULL); + m_settings->registerChangedCallback("mono_font_size", font_setting_changed, NULL); + m_settings->registerChangedCallback("screen_dpi", font_setting_changed, NULL); + m_settings->registerChangedCallback("gui_scaling", font_setting_changed, NULL); } /******************************************************************************/ diff --git a/src/game.cpp b/src/game.cpp index ec025b73f..b496cf3bf 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -809,16 +809,35 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter bool *m_force_fog_off; f32 *m_fog_range; Client *m_client; + bool m_fogEnabled; public: + void onSettingsChange(const std::string &name) + { + if (name == "enable_fog") + m_fogEnabled = g_settings->getBool("enable_fog"); + } + + static void SettingsCallback(const std::string name, void *userdata) + { + reinterpret_cast(userdata)->onSettingsChange(name); + } + GameGlobalShaderConstantSetter(Sky *sky, bool *force_fog_off, f32 *fog_range, Client *client) : m_sky(sky), m_force_fog_off(force_fog_off), m_fog_range(fog_range), m_client(client) - {} - ~GameGlobalShaderConstantSetter() {} + { + g_settings->registerChangedCallback("enable_fog", SettingsCallback, this); + m_fogEnabled = g_settings->getBool("enable_fog"); + } + + ~GameGlobalShaderConstantSetter() + { + g_settings->deregisterChangedCallback("enable_fog", SettingsCallback, this); + } virtual void onSetConstants(video::IMaterialRendererServices *services, bool is_highlevel) diff --git a/src/settings.cpp b/src/settings.cpp index 2f515caba..7339af62b 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -963,28 +963,39 @@ void Settings::clearNoLock() m_defaults.clear(); } - void Settings::registerChangedCallback(std::string name, - setting_changed_callback cbf) + setting_changed_callback cbf, void *userdata) { - m_callbacks[name].push_back(cbf); + JMutexAutoLock lock(m_callbackMutex); + m_callbacks[name].push_back(std::make_pair(cbf, userdata)); } +void Settings::deregisterChangedCallback(std::string name, setting_changed_callback cbf, void *userdata) +{ + JMutexAutoLock lock(m_callbackMutex); + std::map > >::iterator iterToVector = m_callbacks.find(name); + if (iterToVector != m_callbacks.end()) + { + std::vector > &vector = iterToVector->second; + + std::vector >::iterator position = + std::find(vector.begin(), vector.end(), std::make_pair(cbf, userdata)); + + if (position != vector.end()) + vector.erase(position); + } +} void Settings::doCallbacks(const std::string name) { - std::vector tempvector; + JMutexAutoLock lock(m_callbackMutex); + std::map > >::iterator iterToVector = m_callbacks.find(name); + if (iterToVector != m_callbacks.end()) { - JMutexAutoLock lock(m_mutex); - if (m_callbacks.find(name) != m_callbacks.end()) + std::vector >::iterator iter; + for (iter = iterToVector->second.begin(); iter != iterToVector->second.end(); iter++) { - tempvector = m_callbacks[name]; + (iter->first)(name, iter->second); } } - - std::vector::iterator iter; - for (iter = tempvector.begin(); iter != tempvector.end(); iter++) - { - (*iter)(name); - } } diff --git a/src/settings.h b/src/settings.h index 89f7589df..1a7d9ab96 100644 --- a/src/settings.h +++ b/src/settings.h @@ -32,7 +32,7 @@ class Settings; struct NoiseParams; /** function type to register a changed callback */ -typedef void (*setting_changed_callback)(const std::string); +typedef void (*setting_changed_callback)(const std::string, void*); enum ValueType { VALUETYPE_STRING, @@ -204,7 +204,8 @@ public: void clear(); void updateValue(const Settings &other, const std::string &name); void update(const Settings &other); - void registerChangedCallback(std::string name, setting_changed_callback cbf); + void registerChangedCallback(std::string name, setting_changed_callback cbf, void *userdata = NULL); + void deregisterChangedCallback(std::string name, setting_changed_callback cbf, void *userdata = NULL); private: @@ -215,9 +216,12 @@ private: std::map m_settings; std::map m_defaults; - std::map > m_callbacks; - // All methods that access m_settings/m_defaults directly should lock this. - mutable JMutex m_mutex; + + std::map > > m_callbacks; + + mutable JMutex m_callbackMutex; + mutable JMutex m_mutex; // All methods that access m_settings/m_defaults directly should lock this. + }; #endif