diff --git a/aegisub/build/libaegisub_vs2008/libaegisub_vs2008.vcproj b/aegisub/build/libaegisub_vs2008/libaegisub_vs2008.vcproj index 2da974d34..ca206a97d 100644 --- a/aegisub/build/libaegisub_vs2008/libaegisub_vs2008.vcproj +++ b/aegisub/build/libaegisub_vs2008/libaegisub_vs2008.vcproj @@ -205,6 +205,10 @@ RelativePath="..\..\libaegisub\common\option.cpp" > + + diff --git a/aegisub/libaegisub/Makefile.am b/aegisub/libaegisub/Makefile.am index 15a160a26..415962123 100644 --- a/aegisub/libaegisub/Makefile.am +++ b/aegisub/libaegisub/Makefile.am @@ -24,6 +24,7 @@ libaegisub_2_2_la_SOURCES = \ common/charset_ucd.cpp \ common/mru.cpp \ common/option.cpp \ + common/option_value.cpp \ common/option_visit.cpp \ common/log.cpp \ common/validator.cpp \ diff --git a/aegisub/libaegisub/common/option_value.cpp b/aegisub/libaegisub/common/option_value.cpp new file mode 100644 index 000000000..ac1a828de --- /dev/null +++ b/aegisub/libaegisub/common/option_value.cpp @@ -0,0 +1,41 @@ +// Copyright (c) 2010, Niels M Hansen +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +// $Id$ + +/// @file option_value.cpp +/// @brief Container for holding an actual option value. +/// @ingroup libaegisub + +#include "libaegisub/option_value.h" + +namespace agi { + +void OptionValue::NotifyChanged() { + for (ChangeListenerSet::const_iterator nfcb = listeners.begin(); nfcb != listeners.end(); ++nfcb) { + nfcb->first->*(nfcb->second); + } +} + +void OptionValue::Subscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent function) { + assert(listeners.find(listener) == listeners.end()); + listeners[listener] = function; +} + +void OptionValue::Unsubscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent function) { + assert(listeners.find(listener) != listeners.end() && listeners[listener] == function); + listeners.erase(listener); +} + +}; diff --git a/aegisub/libaegisub/include/libaegisub/option_value.h b/aegisub/libaegisub/include/libaegisub/option_value.h index 06aa063b4..0266a9b91 100644 --- a/aegisub/libaegisub/include/libaegisub/option_value.h +++ b/aegisub/libaegisub/include/libaegisub/option_value.h @@ -20,6 +20,7 @@ #ifndef LAGI_PRE #include +#include #include #include "libaegisub/cajun/reader.h" @@ -48,16 +49,16 @@ class ConfigVisitor; /// signature. class OptionValueListener { public: - // (I might have messed up the syntax here. It's supposed to be a pointer - // to a member function of an OptionValueListener-derived class.) - typedef void (OptionValueListener::*ChangeEvent)(const OptionValue *option); + /// @brief Type of a notification callback function for option value changes + typedef void (OptionValueListener::*ChangeEvent)(const OptionValue &option); }; /// @class OptionValue /// Holds an actual option. class OptionValue { - std::set listeners; + typedef std::map ChangeListenerSet; + ChangeListenerSet listeners; protected: void NotifyChanged(); @@ -125,11 +126,8 @@ public: virtual void GetDefaultListBool(std::vector &out) const { throw OptionValueErrorInvalidListType("Attempt to retrive string bool from non-bool list"); } - void Subscribe(OptionValueListener*); - void Unsubscribe(OptionValueListener*); - - void Subscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent handler); - void Unsubscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent handler); + void Subscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent function); + void Unsubscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent function); }; @@ -142,11 +140,11 @@ public: OptionValue##type_name(std::string member_name, type member_value): \ value(member_value), name(member_name) {} \ type Get##type_name() const { return value; } \ - void Set##type_name(const type new_val) { value = new_val; } \ + void Set##type_name(const type new_val) { value = new_val; NotifyChanged(); } \ type GetDefault##type_name() const { return value_default; } \ OptionType GetType() const { return OptionValue::Type_##type_name; } \ std::string GetName() const { return name; } \ - void Reset() { value = value_default; } \ + void Reset() { value = value_default; NotifyChanged(); } \ bool IsDefault() const { return (value == value_default) ? 1 : 0; } \ }; @@ -181,11 +179,11 @@ protected: virtual std::string GetString() const { return "";} \ OptionValueList##type_name(std::string member_name): name(member_name) {} \ void GetList##type_name(std::vector &out) const { out = array; } \ - void SetList##type_name(const std::vector val) { array = val;} \ + void SetList##type_name(const std::vector val) { array = val; NotifyChanged(); } \ void GetDefaultList##type_name(std::vector &out) const { out = array_default; } \ OptionType GetType() const { return OptionValue::Type_List_##type_name; } \ std::string GetName() const { return name; } \ - void Reset() { array = array_default; } \ + void Reset() { array = array_default; NotifyChanged(); } \ bool IsDefault() const { return (array == array_default) ? 1 : 0; } \ };