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_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