Back to index

nux  3.0.0
Property.h
Go to the documentation of this file.
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