Back to index

nux  3.0.0
Property-inl.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_INL_H
00023 #define NUXCORE_PROPERTY_INL_H
00024 
00025 namespace nux {
00026 
00027 
00028 template <typename VALUE_TYPE>
00029 PropertyChangedSignal<VALUE_TYPE>::PropertyChangedSignal()
00030   : notify_(true)
00031 {}
00032 
00033 template <typename VALUE_TYPE>
00034 void PropertyChangedSignal<VALUE_TYPE>::DisableNotifications()
00035 {
00036   notify_ = false;
00037 }
00038 
00039 template <typename VALUE_TYPE>
00040 void PropertyChangedSignal<VALUE_TYPE>::EnableNotifications()
00041 {
00042   notify_ = true;
00043 }
00044 
00045 template <typename VALUE_TYPE>
00046 void PropertyChangedSignal<VALUE_TYPE>::EmitChanged(VALUE_TYPE const& new_value)
00047 {
00048   if (notify_)
00049     changed.emit(new_value);
00050 }
00051 
00052 
00053 template <typename VALUE_TYPE>
00054 Property<VALUE_TYPE>::Property()
00055   : value_(VALUE_TYPE())
00056   , setter_function_(sigc::mem_fun(this, &Property<VALUE_TYPE>::DefaultSetter))
00057 {}
00058 
00059 template <typename VALUE_TYPE>
00060 Property<VALUE_TYPE>::Property(VALUE_TYPE const& initial)
00061   : value_(initial)
00062   , setter_function_(sigc::mem_fun(this, &Property<VALUE_TYPE>::DefaultSetter))
00063 {}
00064 
00065 template <typename VALUE_TYPE>
00066 Property<VALUE_TYPE>::Property(VALUE_TYPE const& initial,
00067                                SetterFunction setter_function)
00068   : value_(initial)
00069   , setter_function_(setter_function)
00070 {}
00071 
00072 template <typename VALUE_TYPE>
00073 VALUE_TYPE Property<VALUE_TYPE>::operator=(VALUE_TYPE const& value)
00074 {
00075   return Set(value);
00076 }
00077 
00078 template <typename VALUE_TYPE>
00079 Property<VALUE_TYPE>::operator VALUE_TYPE() const
00080 {
00081   return value_;
00082 }
00083 
00084 template <typename VALUE_TYPE>
00085 VALUE_TYPE Property<VALUE_TYPE>::operator()() const
00086 {
00087   return value_;
00088 }
00089 
00090 template <typename VALUE_TYPE>
00091 VALUE_TYPE Property<VALUE_TYPE>::operator()(VALUE_TYPE const& value)
00092 {
00093   return Set(value);
00094 }
00095 
00096 template <typename VALUE_TYPE>
00097 VALUE_TYPE Property<VALUE_TYPE>::Get() const
00098 {
00099   return value_;
00100 }
00101 
00102 template <typename VALUE_TYPE>
00103 VALUE_TYPE Property<VALUE_TYPE>::Set(VALUE_TYPE const& value)
00104 {
00105   if (setter_function_(value_, value))
00106     SignalBase::EmitChanged(value_);
00107   return value_;
00108 }
00109 
00110 template <typename VALUE_TYPE>
00111 bool Property<VALUE_TYPE>::DefaultSetter(VALUE_TYPE& target,
00112                                          VALUE_TYPE const& value)
00113 {
00114   bool changed = false;
00115   if (target != value) {
00116     target = value;
00117     changed = true;
00118   }
00119   return changed;
00120 }
00121 
00122 template <typename VALUE_TYPE>
00123 void Property<VALUE_TYPE>::SetSetterFunction(SetterFunction setter_function)
00124 {
00125   setter_function_ = setter_function;
00126 }
00127 
00128 
00129 template <typename VALUE_TYPE>
00130 ROProperty<VALUE_TYPE>::ROProperty()
00131   : getter_function_(sigc::mem_fun(this, &ROProperty<VALUE_TYPE>::DefaultGetter))
00132 {}
00133 
00134 template <typename VALUE_TYPE>
00135 ROProperty<VALUE_TYPE>::ROProperty(GetterFunction getter_function)
00136   : getter_function_(getter_function)
00137 {}
00138 
00139 template <typename VALUE_TYPE>
00140 ROProperty<VALUE_TYPE>::operator VALUE_TYPE() const
00141 {
00142   return getter_function_();
00143 }
00144 
00145 template <typename VALUE_TYPE>
00146 VALUE_TYPE ROProperty<VALUE_TYPE>::operator()() const
00147 {
00148   return getter_function_();
00149 }
00150 
00151 template <typename VALUE_TYPE>
00152 VALUE_TYPE ROProperty<VALUE_TYPE>::Get() const
00153 {
00154   return getter_function_();
00155 }
00156 
00157 template <typename VALUE_TYPE>
00158 VALUE_TYPE ROProperty<VALUE_TYPE>::DefaultGetter() const
00159 {
00160   return VALUE_TYPE();
00161 }
00162 
00163 template <typename VALUE_TYPE>
00164 void ROProperty<VALUE_TYPE>::SetGetterFunction(GetterFunction getter_function)
00165 {
00166   getter_function_ = getter_function;
00167 }
00168 
00169 
00170 template <typename VALUE_TYPE>
00171 RWProperty<VALUE_TYPE>::RWProperty()
00172   : getter_function_(sigc::mem_fun(this, &RWProperty<VALUE_TYPE>::DefaultGetter))
00173   , setter_function_(sigc::mem_fun(this, &RWProperty<VALUE_TYPE>::DefaultSetter))
00174 {}
00175 
00176 template <typename VALUE_TYPE>
00177 RWProperty<VALUE_TYPE>::RWProperty(GetterFunction getter_function,
00178                                    SetterFunction setter_function)
00179   : getter_function_(getter_function)
00180   , setter_function_(setter_function)
00181 {}
00182 
00183 template <typename VALUE_TYPE>
00184 VALUE_TYPE RWProperty<VALUE_TYPE>::operator=(VALUE_TYPE const& value)
00185 {
00186   return Set(value);
00187 }
00188 
00189 template <typename VALUE_TYPE>
00190 RWProperty<VALUE_TYPE>::operator VALUE_TYPE() const
00191 {
00192   return getter_function_();
00193 }
00194 
00195 template <typename VALUE_TYPE>
00196 VALUE_TYPE RWProperty<VALUE_TYPE>::operator()() const
00197 {
00198   return getter_function_();
00199 }
00200 
00201 template <typename VALUE_TYPE>
00202 VALUE_TYPE RWProperty<VALUE_TYPE>::operator()(VALUE_TYPE const& value)
00203 {
00204   return Set(value);
00205 }
00206 
00207 template <typename VALUE_TYPE>
00208 VALUE_TYPE RWProperty<VALUE_TYPE>::Get() const
00209 {
00210   return getter_function_();
00211 }
00212 
00213 template <typename VALUE_TYPE>
00214 VALUE_TYPE RWProperty<VALUE_TYPE>::Set(VALUE_TYPE const& value)
00215 {
00216   if (setter_function_(value))
00217   {
00218     VALUE_TYPE new_value = getter_function_();
00219     SignalBase::EmitChanged(new_value);
00220     return new_value;
00221   }
00222   return getter_function_();
00223 }
00224 
00225 template <typename VALUE_TYPE>
00226 VALUE_TYPE RWProperty<VALUE_TYPE>::DefaultGetter() const
00227 {
00228   return VALUE_TYPE();
00229 }
00230 
00231 template <typename VALUE_TYPE>
00232 bool RWProperty<VALUE_TYPE>::DefaultSetter(VALUE_TYPE const& value)
00233 {
00234   return false;
00235 }
00236 
00237 template <typename VALUE_TYPE>
00238 void RWProperty<VALUE_TYPE>::SetSetterFunction(SetterFunction setter_function)
00239 {
00240   setter_function_ = setter_function;
00241 }
00242 
00243 template <typename VALUE_TYPE>
00244 void RWProperty<VALUE_TYPE>::SetGetterFunction(GetterFunction getter_function)
00245 {
00246   getter_function_ = getter_function;
00247 }
00248 
00249 
00250 // We need to provide a default constructor since we hide the copy ctor.
00251 inline Introspectable::Introspectable()
00252 {}
00253 
00254 inline void Introspectable::AddProperty(std::string const& name,
00255                                         PropertyBase* property)
00256 {
00257   // check to see if it exists and if it does barf horribly as we can't
00258   // have two properties with the same name;
00259   properties_[name] = property;
00260 }
00261 
00262 inline bool Introspectable::SetProperty(std::string const& name,
00263                                         const char* value)
00264 {
00265   PropertyContainer::iterator i = properties_.find(name);
00266   if (i == properties_.end())
00267     return false;
00268   else
00269     return i->second->SetValue(value);
00270 }
00271 
00272 template <typename T>
00273 bool Introspectable::SetProperty(std::string const& name, T const& value)
00274 {
00275   PropertyContainer::iterator i = properties_.find(name);
00276   if (i == properties_.end())
00277     return false;
00278   else
00279   {
00280     return i->second->SetValue(type::PropertyTrait<T>::to_string(value));
00281   }
00282 }
00283 
00284 template <typename T>
00285 T Introspectable::GetProperty(std::string const& name, T* foo)
00286 {
00287   PropertyContainer::iterator i = properties_.find(name);
00288   if (i == properties_.end())
00289     return T();
00290 
00291   std::string s = i->second->GetSerializedValue();
00292   std::pair<T, bool> result = type::PropertyTrait<T>::from_string(s);
00293   // If this is called with a template type that the property does not
00294   // support nice conversion to, you'll get no error, but will get
00295   // a default constructed T.  We could use an exception here.
00296   return result.first;
00297 }
00298 
00299 
00300 template <typename T>
00301 SerializableProperty<T>::SerializableProperty(Introspectable* owner,
00302                                               std::string const& name)
00303   : Base()
00304   , name_(name)
00305 {
00306   owner->AddProperty(name, this);
00307 }
00308 
00309 template <typename T>
00310 SerializableProperty<T>::SerializableProperty(Introspectable* owner,
00311                                               std::string const& name,
00312                                               T const& initial)
00313   : Base(initial)
00314   , name_(name)
00315 {
00316   owner->AddProperty(name, this);
00317 }
00318 
00319 template <typename T>
00320 bool SerializableProperty<T>::SetValue(std::string const& serialized_form)
00321 {
00322   std::pair<ValueType, bool> result = TraitType::from_string(serialized_form);
00323   if (result.second) {
00324     Base::Set(result.first);
00325   }
00326   return result.second;
00327 }
00328 
00329 template <typename T>
00330 std::string SerializableProperty<T>::GetSerializedValue() const
00331 {
00332   return TraitType::to_string(Base::Get());
00333 }
00334 
00335 template <typename T>
00336 T SerializableProperty<T>::operator=(T const& value)
00337 {
00338   Base::Set(value);
00339   // There are no arguments to ‘get’ that depend on a template parameter,
00340   // so we explicitly specify Base.
00341   return Base::Get();
00342 }
00343 
00344 
00345 
00346 }
00347 
00348 #endif