nux-1.14.0
|
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- 00002 /* 00003 * Copyright 2011 Inalogic® Inc. 00004 * 00005 * This program is free software: you can redistribute it and/or modify it 00006 * under the terms of the GNU Lesser General Public License, as 00007 * published by the Free Software Foundation; either version 2.1 or 3.0 00008 * of the License. 00009 * 00010 * This program is distributed in the hope that it will be useful, but 00011 * WITHOUT ANY WARRANTY; without even the implied warranties of 00012 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00013 * PURPOSE. See the applicable version of the GNU Lesser General Public 00014 * License for more details. 00015 * 00016 * You should have received a copy of both the GNU Lesser General Public 00017 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00018 * 00019 * Authored by: Tim Penhey <tim.penhey@canonical.com> 00020 * 00021 */ 00022 #ifndef NUXCORE_PROPERTY_H 00023 #define NUXCORE_PROPERTY_H 00024 00025 #include "PropertyTraits.h" 00026 00027 #include <string> 00028 #include <map> 00029 #include <sigc++/signal.h> 00030 00038 namespace nux { 00039 00040 00041 template <typename VALUE_TYPE> 00042 class PropertyChangedSignal 00043 { 00044 public: 00045 PropertyChangedSignal(); 00046 00047 sigc::signal<void, VALUE_TYPE const&> changed; 00048 00049 void DisableNotifications(); 00050 void EnableNotifications(); 00051 00052 void EmitChanged(VALUE_TYPE const& new_value); 00053 00054 private: 00055 bool notify_; 00056 }; 00057 00065 template <typename VALUE_TYPE> 00066 class Property : public PropertyChangedSignal<VALUE_TYPE> 00067 { 00068 public: 00069 typedef VALUE_TYPE ValueType; 00070 typedef PropertyChangedSignal<VALUE_TYPE> SignalBase; 00071 typedef sigc::slot<bool, VALUE_TYPE&, VALUE_TYPE const&> SetterFunction; 00072 00073 Property(); 00074 explicit Property(VALUE_TYPE const& initial); 00075 Property(VALUE_TYPE const& initial, SetterFunction setter_function); 00076 00077 VALUE_TYPE operator=(VALUE_TYPE const& value); 00078 operator VALUE_TYPE() const; 00079 00080 // function call access 00081 VALUE_TYPE operator()() const; 00082 VALUE_TYPE operator()(VALUE_TYPE const& value); 00083 00084 // get and set access 00085 VALUE_TYPE Get() const; 00086 VALUE_TYPE Set(VALUE_TYPE const& value); 00087 00088 void SetSetterFunction(SetterFunction setter_function); 00089 00090 private: 00091 // Properties themselves are not copyable. 00092 Property(Property const&); 00093 Property& operator=(Property const&); 00094 00095 bool DefaultSetter(VALUE_TYPE& target, VALUE_TYPE const& value); 00096 00097 private: 00098 VALUE_TYPE value_; 00099 SetterFunction setter_function_; 00100 }; 00101 00102 // We could easily add a Write Only Property if and when we need one. 00103 00110 template <typename VALUE_TYPE> 00111 class ROProperty : public PropertyChangedSignal<VALUE_TYPE> 00112 { 00113 public: 00114 typedef VALUE_TYPE ValueType; 00115 typedef sigc::slot<VALUE_TYPE> GetterFunction; 00116 00117 ROProperty(); 00118 explicit ROProperty(GetterFunction getter_function); 00119 00120 operator VALUE_TYPE() const; 00121 VALUE_TYPE operator()() const; 00122 VALUE_TYPE Get() const; 00123 00124 void SetGetterFunction(GetterFunction getter_function); 00125 00126 private: 00127 // ROProperties themselves are not copyable. 00128 ROProperty(ROProperty const&); 00129 ROProperty& operator=(ROProperty const&); 00130 00131 VALUE_TYPE DefaultGetter() const; 00132 00133 private: 00134 GetterFunction getter_function_; 00135 }; 00136 00151 template <typename VALUE_TYPE> 00152 class RWProperty : public PropertyChangedSignal<VALUE_TYPE> 00153 { 00154 public: 00155 typedef VALUE_TYPE ValueType; 00156 typedef PropertyChangedSignal<VALUE_TYPE> SignalBase; 00157 typedef sigc::slot<bool, VALUE_TYPE const&> SetterFunction; 00158 typedef sigc::slot<VALUE_TYPE> GetterFunction; 00159 00160 RWProperty(); 00161 RWProperty(GetterFunction getter_function, SetterFunction setter_function); 00162 00163 VALUE_TYPE operator=(VALUE_TYPE const& value); 00164 operator VALUE_TYPE() const; 00165 00166 // function call access 00167 VALUE_TYPE operator()() const; 00168 VALUE_TYPE operator()(VALUE_TYPE const& value); 00169 00170 // get and set access 00171 VALUE_TYPE Get() const; 00172 VALUE_TYPE Set(VALUE_TYPE const& value); 00173 00174 void SetGetterFunction(GetterFunction getter_function); 00175 void SetSetterFunction(SetterFunction setter_function); 00176 00177 private: 00178 // RWProperties themselves are not copyable. 00179 RWProperty(RWProperty const&); 00180 RWProperty& operator=(RWProperty const&); 00181 00182 VALUE_TYPE DefaultGetter() const; 00183 bool DefaultSetter(VALUE_TYPE const& value); 00184 00185 private: 00186 GetterFunction getter_function_; 00187 SetterFunction setter_function_; 00188 }; 00189 00190 00191 class PropertyBase 00192 { 00193 public: 00194 virtual bool SetValue(std::string const& serialized_form) = 0; 00195 virtual std::string GetSerializedValue() const = 0; 00196 }; 00197 00198 00199 class Introspectable 00200 { 00201 public: 00202 Introspectable(); 00203 // Needs to have a container of properties 00204 00207 bool SetProperty(std::string const& name, const char* value); 00208 00209 template <typename T> 00210 bool SetProperty(std::string const& name, T const& value); 00211 00212 template <typename T> 00213 T GetProperty(std::string const& name, T* foo = 0); 00214 00215 void AddProperty(std::string const& name, PropertyBase* property); 00216 00217 private: 00218 // Introspectable objects are not copyable. 00219 Introspectable(Introspectable const&); 00220 Introspectable& operator=(Introspectable const&); 00221 00222 private: 00223 typedef std::map<std::string, PropertyBase*> PropertyContainer; 00224 PropertyContainer properties_; 00225 }; 00226 00227 00228 template <typename VALUE_TYPE> 00229 class SerializableProperty : public Property<VALUE_TYPE>, public PropertyBase 00230 { 00231 public: 00232 typedef Property<VALUE_TYPE> Base; 00233 typedef typename type::PropertyTrait<VALUE_TYPE> TraitType; 00234 typedef typename TraitType::ValueType ValueType; 00235 00236 SerializableProperty(Introspectable* owner, 00237 std::string const& name); 00238 SerializableProperty(Introspectable* owner, 00239 std::string const& name, 00240 VALUE_TYPE const& initial); 00241 00242 virtual bool SetValue(std::string const& serialized_form); 00243 virtual std::string GetSerializedValue() const; 00244 00245 // Operator assignment is not inherited nicely, so redeclare it here. 00246 VALUE_TYPE operator=(VALUE_TYPE const& value); 00247 00248 private: 00249 std::string name_; 00250 }; 00251 00252 00253 00254 } 00255 00256 #include "Property-inl.h" 00257 #include "PropertyOperators.h" 00258 00259 #endif