From 9258c9f8587ffaa2c1d6b61845464f088a499322 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 11 Jul 2017 13:34:50 -0400 Subject: [PATCH 1/3] Update Kameleon submodule --- modules/kameleon/ext/kameleon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/kameleon/ext/kameleon b/modules/kameleon/ext/kameleon index 3de739a553..1b4549edc7 160000 --- a/modules/kameleon/ext/kameleon +++ b/modules/kameleon/ext/kameleon @@ -1 +1 @@ -Subproject commit 3de739a55387051fb6fdfd327ad761dffa317420 +Subproject commit 1b4549edc74ef371730ef9d39c1ffa0efe90a985 From 314c6c0848a48f2b455164fdf2f8b6bdff910697 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 11 Jul 2017 14:23:17 -0400 Subject: [PATCH 2/3] Enable Property to have multiple callbacks --- include/openspace/properties/property.h | 34 +++++++++++++++++---- src/properties/property.cpp | 39 +++++++++++++++++++++---- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/include/openspace/properties/property.h b/include/openspace/properties/property.h index 5fbc8e6a78..80b446b5a3 100644 --- a/include/openspace/properties/property.h +++ b/include/openspace/properties/property.h @@ -73,6 +73,14 @@ public: User = 0 ///< Visible in User mode }; + /// An OnChangeHandle is returned by the onChange method to uniquely identify an + /// onChange callback + using OnChangeHandle = uint32_t; + + /// This OnChangeHandle can be used to remove all onChange callbacks from this + /// Property + static OnChangeHandle OnChangeHandleAll; + /** * The constructor for the property. The identifier needs to be unique * for each PropertyOwner. The guiName will be stored in the metaData @@ -92,7 +100,7 @@ public: * The destructor taking care of deallocating all unused memory. This method will not * remove the Property from the PropertyOwner. */ - virtual ~Property(); + virtual ~Property() = default; /** * This method returns the class name of the Property. The method is used by the @@ -191,12 +199,25 @@ public: * This method registers a callback function that will be called every * time if either Property:set or Property::setLuaValue was called with a value that * is different from the previously stored value. The callback can be removed by - * passing an empty std::function object. + * calling the removeOnChange method with the OnChangeHandle that was returned here. * \param callback The callback function that is called when the encapsulated type has * been successfully changed by either the Property::set or Property::setLuaValue * methods. + * \pre The callback must not be empty + * \return An OnChangeHandle that can be used in subsequent calls to remove a callback */ - virtual void onChange(std::function callback); + OnChangeHandle onChange(std::function callback); + + /** + * This method deregisters a callback that was previously registered with the onChange + * method. If OnChangeHandleAll is passed to this function, all registered callbacks + * are removed. + * \param handle An OnChangeHandle that was returned from a previous call to onChange + * by this property or OnChangeHandleAll if all callbacks should be removed. + * \pre handle must refer to a callback that has been previously registred + * \pre handle must refer to a callback that has not been removed previously + */ + void removeOnChange(OnChangeHandle handle); /** * This method returns the unique identifier of this Property. @@ -389,8 +410,11 @@ protected: /// The Dictionary containing all meta data necessary for external applications ghoul::Dictionary _metaData; - /// The callback function that will be invoked whenever the encapsulated value changes - std::function _onChangeCallback; + /// The callback function sthat will be invoked whenever the value changes + std::vector>> _onChangeCallbacks; + +private: + OnChangeHandle _currentHandleValue; }; } // namespace properties diff --git a/src/properties/property.cpp b/src/properties/property.cpp index 0c5cd0d967..237fed2092 100644 --- a/src/properties/property.cpp +++ b/src/properties/property.cpp @@ -40,6 +40,9 @@ namespace { const char* _metaDataKeyViewPrefix = "view."; } +Property::OnChangeHandle Property::OnChangeHandleAll = + std::numeric_limits::max(); + const char* Property::ViewOptions::Color = "color"; const char* Property::ViewOptions::LightPosition = "lightPosition"; @@ -51,6 +54,7 @@ const char* Property::MetaDataKey = "MetaData"; Property::Property(std::string identifier, std::string guiName, Visibility visibility) : _owner(nullptr) , _identifier(std::move(identifier)) + , _currentHandleValue(0) { ghoul_assert(!_identifier.empty(), "Identifier must not be empty"); ghoul_assert(!guiName.empty(), "guiName must not be empty"); @@ -59,8 +63,6 @@ Property::Property(std::string identifier, std::string guiName, Visibility visib _metaData.setValue(MetaDataKeyGuiName, std::move(guiName)); } -Property::~Property() {} - const std::string& Property::identifier() const { return _identifier; } @@ -163,8 +165,33 @@ const ghoul::Dictionary& Property::metaData() const { return _metaData; } -void Property::onChange(std::function callback) { - _onChangeCallback = std::move(callback); +Property::OnChangeHandle Property::onChange(std::function callback) { + ghoul_assert(callback, "The callback must not be empty"); + OnChangeHandle handle = _currentHandleValue++; + _onChangeCallbacks.emplace_back(handle, std::move(callback)); + return handle; +} + +void Property::removeOnChange(OnChangeHandle handle) { + if (handle == OnChangeHandleAll) { + _onChangeCallbacks.clear(); + } + else { + auto it = std::find_if( + _onChangeCallbacks.begin(), + _onChangeCallbacks.end(), + [handle](const std::pair>& p) { + return p.first == handle; + } + ); + + ghoul_assert( + it != _onChangeCallbacks.end(), + "handle must be a valid callback handle" + ); + + _onChangeCallbacks.erase(it); + } } PropertyOwner* Property::owner() const { @@ -176,8 +203,8 @@ void Property::setPropertyOwner(PropertyOwner* owner) { } void Property::notifyListener() { - if (_onChangeCallback) { - _onChangeCallback(); + for (const std::pair>& p : _onChangeCallbacks) { + p.second(); } } From 6d0c80cc91587cc82180990d061462a194f404fb Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 11 Jul 2017 14:35:39 -0400 Subject: [PATCH 3/3] Change the mouse scroll callback to accept two dimensional arguments --- apps/OpenSpace/main.cpp | 4 ++-- include/openspace/engine/openspaceengine.h | 8 +++++--- modules/onscreengui/onscreenguimodule.cpp | 4 ++-- src/engine/openspaceengine.cpp | 8 ++++---- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index c280bef68e..91ea574cd2 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -442,10 +442,10 @@ void mainMousePosCallback(double x, double y) { } } -void mainMouseScrollCallback(double, double posY) { +void mainMouseScrollCallback(double posX, double posY) { LTRACE("main::mainMouseScrollCallback(begin"); if (SgctEngine->isMaster()) { - OsEng.mouseScrollWheelCallback(posY); + OsEng.mouseScrollWheelCallback(posX, posY); } LTRACE("main::mainMouseScrollCallback(end)"); } diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index e21a72773e..00de495380 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -96,7 +96,7 @@ public: void charCallback(unsigned int codepoint, KeyModifier mod); void mouseButtonCallback(MouseButton button, MouseAction action); void mousePositionCallback(double x, double y); - void mouseScrollWheelCallback(double pos); + void mouseScrollWheelCallback(double posX, double posY); void externalControlCallback(const char* receivedChars, int size, int clientId); void encode(); void decode(); @@ -162,7 +162,9 @@ public: std::function function); // Registers a callback that is called when a scroll wheel change is received - void registerModuleMouseScrollWheelCallback(std::function function); + void registerModuleMouseScrollWheelCallback( + std::function function + ); /** * Returns the Lua library that contains all Lua functions available to affect the @@ -223,7 +225,7 @@ private: std::vector> mouseButton; std::vector> mousePosition; - std::vector> mouseScrollWheel; + std::vector> mouseScrollWheel; } _moduleCallbacks; double _runTime; diff --git a/modules/onscreengui/onscreenguimodule.cpp b/modules/onscreengui/onscreenguimodule.cpp index 53a547e294..5386e96493 100644 --- a/modules/onscreengui/onscreenguimodule.cpp +++ b/modules/onscreengui/onscreenguimodule.cpp @@ -195,9 +195,9 @@ OnScreenGUIModule::OnScreenGUIModule() ); OsEng.registerModuleMouseScrollWheelCallback( - [](double pos) -> bool { + [](double, double posY) -> bool { if (gui.isEnabled()) { - return gui.mouseWheelCallback(pos); + return gui.mouseWheelCallback(posY); } else { return false; diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index a0e932332c..b5bb91a702 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -1194,15 +1194,15 @@ void OpenSpaceEngine::mousePositionCallback(double x, double y) { _interactionHandler->mousePositionCallback(x, y); } -void OpenSpaceEngine::mouseScrollWheelCallback(double pos) { +void OpenSpaceEngine::mouseScrollWheelCallback(double posX, double posY) { for (const auto& func : _moduleCallbacks.mouseScrollWheel) { - bool consumed = func(pos); + bool consumed = func(posX, posY); if (consumed) { return; } } - _interactionHandler->mouseScrollWheelCallback(pos); + _interactionHandler->mouseScrollWheelCallback(posY); } void OpenSpaceEngine::encode() { @@ -1352,7 +1352,7 @@ void OpenSpaceEngine::registerModuleMousePositionCallback( } void OpenSpaceEngine::registerModuleMouseScrollWheelCallback( - std::function function) + std::function function) { _moduleCallbacks.mouseScrollWheel.push_back(std::move(function)); }