Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2011 George Tzanetakis <gtzan@cs.uvic.ca> 00003 ** 00004 ** This program is free software; you can redistribute it and/or modify 00005 ** it under the terms of the GNU General Public License as published by 00006 ** the Free Software Foundation; either version 2 of the License, or 00007 ** (at your option) any later version. 00008 ** 00009 ** This program is distributed in the hope that it will be useful, 00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 ** GNU General Public License for more details. 00013 ** 00014 ** You should have received a copy of the GNU General Public License 00015 ** along with this program; if not, write to the Free Software 00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #ifndef __MARCONTROLVALUE__ 00020 #define __MARCONTROLVALUE__ 00021 00022 #include <marsyas/common_header.h> 00023 #include <marsyas/realvec.h> 00024 00025 #include <string> 00026 #include <vector> 00027 #include <utility> 00028 #include <typeinfo> 00029 #include <stdexcept> 00030 00031 namespace Marsyas 00032 { 00039 class marsyas_EXPORT MarControl; //forward declaration 00040 00041 template<class T> class MarControlValueT; 00042 00043 class marsyas_EXPORT MarControlValue 00044 { 00045 friend class MarControl; 00046 friend class MarControlAccessor; 00047 00048 protected: 00049 std::string type_; 00050 00051 std::string value_debug_; 00052 00053 //MarControls that use this MarControlValue 00054 //(i.e. linked MarControls) 00055 std::vector<std::pair<MarControl*, MarControl*> > links_; 00056 typedef std::vector<std::pair<MarControl*, MarControl*> > link_vector; 00057 00058 protected: 00059 MarControlValue() {} // can't be directly created (use MarControl or MarControlValueT) 00060 MarControlValue(const MarControlValue& a) 00061 { 00062 type_ = a.type_; 00063 }; 00064 00065 //for debugging purposes only 00066 void setDebugValue(); 00067 static void updateMarSystemFor( MarControl * ); 00068 00069 template<typename T> const T & as() const 00070 { 00071 return static_cast<const MarControlValueT<T>*>(this)->get(); 00072 } 00073 00074 public: 00075 virtual ~MarControlValue() {} 00076 00077 virtual MarControlValue* clone() = 0; 00078 virtual void copyValue(MarControlValue& value) = 0; 00079 virtual void callMarSystemsUpdate() = 0; 00080 virtual MarControlValue* create() = 0; 00081 00082 virtual std::string getTypeID() = 0; 00083 // workaround method to avoid circular dependencies 00084 std::string getRegisteredType(); 00085 00086 virtual std::string getType() const ; 00087 00088 template<typename T> bool hasType() 00089 { 00090 return (typeid(*this) == typeid(MarControlValueT<T>)); 00091 } 00092 00093 template<typename T> const T & get() const 00094 { 00095 if (!hasType<T>()) 00096 throw std::runtime_error("MarControlValue: Trying to convert to invalid type."); 00097 return static_cast<const MarControlValueT<T>*>(this)->get(); 00098 } 00099 00100 // workaround - virtual member functions to overload friend operators 00101 virtual void createFromStream(std::istream&) = 0; 00102 // for: friend std::ostream& operator<<(std::ostream&, const MarControl& ctrl); 00103 virtual std::ostream& serialize(std::ostream& os) = 0; 00104 // for: friend bool operator!=(MarControlValue& v1, MarControlValue& v2) 00105 virtual bool isEqual(MarControlValue *v) = 0; 00106 virtual bool isLessThan(MarControlValue *v) = 0; 00107 00108 virtual MarControlValue* sum(MarControlValue *v) = 0; 00109 virtual MarControlValue* subtract(MarControlValue *v) = 0; 00110 virtual MarControlValue* multiply(MarControlValue *v) = 0; 00111 virtual MarControlValue* divide(MarControlValue *v) = 0; 00112 00113 template<typename T> 00114 static MarControlValueT<T> * make( const T & val ) 00115 { 00116 return new MarControlValueT<T>(val); 00117 } 00118 00119 struct FalseTrait { static const bool value = false; }; 00120 struct TrueTrait { static const bool value = true; }; 00121 00122 template <typename T> struct IsArithmetic; 00123 template <typename T> struct IsArithmeticComparable; 00124 00125 template <typename T, bool enabled> 00126 struct Arithmetic; 00127 00128 template <typename T, bool enabled> 00129 struct ArithmeticCompare; 00130 00131 struct GenericArithmetic; 00132 }; 00133 00134 template <typename T> struct MarControlValue::IsArithmetic : FalseTrait {}; 00135 template<> struct MarControlValue::IsArithmetic<mrs_natural> : TrueTrait {}; 00136 template<> struct MarControlValue::IsArithmetic<mrs_real> : TrueTrait {}; 00137 template<> struct MarControlValue::IsArithmetic<mrs_realvec> : TrueTrait {}; 00138 00139 template <typename T> struct MarControlValue::IsArithmeticComparable : FalseTrait {}; 00140 template<> struct MarControlValue::IsArithmeticComparable<mrs_natural> : TrueTrait {}; 00141 template<> struct MarControlValue::IsArithmeticComparable<mrs_real> : TrueTrait {}; 00142 00144 00145 template<class T> 00146 class MarControlValueT : public MarControlValue 00147 { 00148 friend class MarControl; 00149 friend class MarControlAccessor; 00150 00151 protected: 00152 T value_; 00153 00154 public: 00155 MarControlValueT(); 00156 MarControlValueT(T value); 00157 MarControlValueT(const MarControlValueT& a); 00158 00159 virtual ~MarControlValueT() {} 00160 00161 MarControlValueT& operator=(const MarControlValueT& a); 00162 00163 virtual MarControlValue* clone() 00164 { 00165 return new MarControlValueT<T>(*this); 00166 } 00167 00168 virtual MarControlValue* create() 00169 { 00170 return new MarControlValueT<T>(); 00171 } 00172 00173 virtual void copyValue(MarControlValue& value); 00174 virtual void callMarSystemsUpdate(); 00175 00176 virtual std::string getTypeID(); 00177 00178 //setters 00179 //void set(MarControlValue *val, bool update); 00180 void set(const T &re, bool update); 00181 00182 //getters 00183 const T& get() const; 00184 T& getRef(); 00185 00186 virtual void createFromStream(std::istream&); 00187 virtual std::ostream& serialize(std::ostream& os); 00188 virtual bool isEqual(MarControlValue *v); 00189 virtual bool isLessThan(MarControlValue *v); 00190 virtual MarControlValue* sum(MarControlValue *v); 00191 virtual MarControlValue* subtract(MarControlValue *v); 00192 virtual MarControlValue* multiply(MarControlValue *v); 00193 virtual MarControlValue* divide(MarControlValue *v); 00194 }; 00195 00196 template<class T> 00197 MarControlValueT<T>::MarControlValueT() 00198 { 00199 value_ = T(); 00200 00201 // simple tests are previously done for basic types for efficiency purposes 00202 if (typeid(T) == typeid(mrs_real)) 00203 type_ = "mrs_real"; 00204 else if (typeid(T) == typeid(mrs_natural)) 00205 type_ = "mrs_natural"; 00206 else if (typeid(T) == typeid(std::string)) 00207 type_ = "mrs_string"; 00208 else if (typeid(T) == typeid(realvec)) 00209 type_ = "mrs_realvec"; 00210 else if (typeid(T) == typeid(bool)) 00211 type_ = "mrs_bool"; 00212 else 00213 { 00214 type_ = this->getRegisteredType(); 00215 } 00216 } 00217 00218 template<class T> 00219 MarControlValueT<T>::MarControlValueT(T value) 00220 { 00221 value_ = value; 00222 00223 setDebugValue(); 00224 00225 // simple tests are used for basic types for efficiency purposes 00226 if (typeid(T) == typeid(mrs_real)) 00227 type_ = "mrs_real"; 00228 else if (typeid(T) == typeid(mrs_natural)) 00229 type_ = "mrs_natural"; 00230 else if (typeid(T) == typeid(std::string)) 00231 type_ = "mrs_string"; 00232 else if (typeid(T) == typeid(realvec)) 00233 type_ = "mrs_realvec"; 00234 else if (typeid(T) == typeid(bool)) 00235 type_ = "mrs_bool"; 00236 else 00237 { 00238 type_ = this->getRegisteredType(); 00239 } 00240 } 00241 00242 template<class T> 00243 MarControlValueT<T>::MarControlValueT(const MarControlValueT& a):MarControlValue(a) 00244 { 00245 value_ = a.value_; 00246 type_ = a.type_; 00247 00248 setDebugValue(); 00249 } 00250 00251 template<class T> 00252 MarControlValueT<T>& 00253 MarControlValueT<T>::operator=(const MarControlValueT& a) 00254 { 00255 if (this != &a) 00256 { 00257 value_ = a.value_; 00258 type_ = a.type_; 00259 00260 setDebugValue(); 00261 00262 00263 //callMarSystemsUpdate(); //[?] 00264 } 00265 return *this; 00266 } 00267 00268 template<class T> 00269 void 00270 MarControlValueT<T>::copyValue(MarControlValue& value) 00271 { 00272 MarControlValueT<T> &v = dynamic_cast<MarControlValueT<T>&>(value); 00273 value_ = v.value_; 00274 } 00275 00276 template<class T> 00277 void 00278 MarControlValueT<T>::callMarSystemsUpdate() 00279 { 00280 //must keep a copy of the current value in case 00281 //this control is "toggled" in the following update calls 00282 //so it can be "reinjected" into all MarSystem::update() methods 00283 //(otherwise, only the first MarSystem in the loop below would 00284 //get the current value - all the remaining ones would get the value 00285 //"toggled" bu the first MarSystem update() call) 00286 T tempValue_ = value_; 00287 00288 //iterate over all the MarControls that own this MarControlValue 00289 //and call any necessary MarSystem updates after this value change 00290 for(link_vector::iterator it = links_.begin(); it != links_.end(); ++it) 00291 { 00292 value_ = tempValue_; //make sure to use the current value, not a "toggled" one 00293 MarControl * linked_control = it->first; 00294 updateMarSystemFor(linked_control); 00295 } 00296 } 00297 00298 template<class T> 00299 std::string 00300 MarControlValueT<T>::getTypeID() 00301 { 00302 return typeid(T).name(); 00303 } 00304 00305 template<class T> 00306 void 00307 MarControlValueT<T>::set(const T & val, bool update) 00308 { 00309 value_ = val; 00310 00311 setDebugValue(); 00312 00313 if(update) 00314 { 00315 callMarSystemsUpdate(); 00316 } 00317 } 00318 00319 template<class T> 00320 const T& 00321 MarControlValueT<T>::get() const 00322 { 00323 return value_; 00324 } 00325 00326 template<class T> 00327 void 00328 MarControlValueT<T>::createFromStream(std::istream& in) 00329 { 00330 in >> value_; 00331 00332 00333 setDebugValue(); 00334 00335 00336 //callMarSystemsUpdate();?!?!?!? [?] 00337 } 00338 00339 00340 template<class T> 00341 std::ostream& 00342 MarControlValueT<T>::serialize(std::ostream& os) 00343 { 00344 os << value_; 00345 return os; 00346 } 00347 00348 template<class T> 00349 MarControlValue* 00350 MarControlValueT<T>::sum(MarControlValue *v) 00351 { 00352 return Arithmetic<T, IsArithmetic<T>::value>::sum(this, v); 00353 } 00354 00355 template<class T> 00356 MarControlValue* 00357 MarControlValueT<T>::subtract(MarControlValue *v) 00358 { 00359 return Arithmetic<T, IsArithmetic<T>::value>::subtract(this, v); 00360 } 00361 00362 template<class T> 00363 MarControlValue* 00364 MarControlValueT<T>::multiply(MarControlValue *v) 00365 { 00366 return Arithmetic<T, IsArithmetic<T>::value>::multiply(this, v); 00367 } 00368 00369 template<class T> 00370 MarControlValue* 00371 MarControlValueT<T>::divide(MarControlValue *v) 00372 { 00373 return Arithmetic<T, IsArithmetic<T>::value>::divide(this, v); 00374 } 00375 00376 template<class T> 00377 bool MarControlValueT<T>::isEqual(MarControlValue *v) 00378 { 00379 return ArithmeticCompare<T, IsArithmeticComparable<T>::value>::isEqual(this, v); 00380 } 00381 00382 template<class T> 00383 bool MarControlValueT<T>::isLessThan(MarControlValue *v) 00384 { 00385 return ArithmeticCompare<T, IsArithmeticComparable<T>::value>::isLessThan(this, v); 00386 } 00387 00388 // Arithmetic for non-arithmetic types 00389 template <typename T> 00390 struct MarControlValue::Arithmetic<T, false> 00391 { 00392 static MarControlValue *sum( void*, void*) 00393 { throw std::runtime_error("Can not sum this."); } 00394 static MarControlValue *subtract( void*, void*) 00395 { throw std::runtime_error("Can not subtract this."); } 00396 static MarControlValue *multiply( void*, void*) 00397 { throw std::runtime_error("Can not multiply this."); } 00398 static MarControlValue *divide( void*, void*) 00399 { throw std::runtime_error("Can not divide this."); } 00400 }; 00401 00402 // Arithmetic comparison for non-arithmetic-comparable types 00403 template <typename T> 00404 struct MarControlValue::ArithmeticCompare<T, false> 00405 { 00406 static bool isEqual( MarControlValueT<T> *lhs, MarControlValue *rhs ) 00407 { 00408 if (lhs == rhs) 00409 return true; 00410 if (rhs->hasType<T>()) 00411 { 00412 return lhs->get() == static_cast<MarControlValueT<T>*>(rhs)->get(); 00413 } 00414 throw std::runtime_error("Can not compare this."); 00415 } 00416 00417 static bool isLessThan( void*, void*) 00418 { throw std::runtime_error("Can not compare this."); } 00419 }; 00420 00421 struct MarControlValue::GenericArithmetic 00422 { 00423 template<typename LHS, typename RHS> 00424 static MarControlValue *add( MarControlValue * lhs, MarControlValue * rhs ) 00425 { 00426 return MarControlValue::make(lhs->as<LHS>() + rhs->as<RHS>()); 00427 } 00428 00429 template<typename LHS, typename RHS> 00430 static MarControlValue *subtract( MarControlValue * lhs, MarControlValue * rhs ) 00431 { 00432 return MarControlValue::make(lhs->as<LHS>() - rhs->as<RHS>()); 00433 } 00434 00435 template<typename LHS, typename RHS> 00436 static MarControlValue *multiply( MarControlValue * lhs, MarControlValue * rhs ) 00437 { 00438 return MarControlValue::make(lhs->as<LHS>() * rhs->as<RHS>()); 00439 } 00440 00441 template<typename LHS, typename RHS> 00442 static MarControlValue *divide( MarControlValue * lhs, MarControlValue * rhs ) 00443 { 00444 return MarControlValue::make(lhs->as<LHS>() / rhs->as<RHS>()); 00445 } 00446 }; 00447 00448 template <typename T> 00449 struct MarControlValue::Arithmetic<T, true> 00450 { 00451 static MarControlValue *sum( MarControlValueT<T>*lhs, MarControlValue*rhs) 00452 { 00453 if (rhs->hasType<mrs_natural>()) 00454 { 00455 return GenericArithmetic::add<T,mrs_natural>(lhs, rhs); 00456 } 00457 else if (rhs->hasType<mrs_real>()) 00458 { 00459 return GenericArithmetic::add<T,mrs_real>(lhs, rhs); 00460 } 00461 else if (rhs->hasType<mrs_realvec>()) 00462 { 00463 return GenericArithmetic::add<T,mrs_realvec>(lhs, rhs); 00464 } 00465 else 00466 { 00467 throw std::runtime_error("Can not add that."); 00468 } 00469 } 00470 00471 static MarControlValue *subtract( MarControlValueT<T>*lhs, MarControlValue*rhs) 00472 { 00473 if (rhs->hasType<mrs_natural>()) 00474 { 00475 return GenericArithmetic::subtract<T,mrs_natural>(lhs, rhs); 00476 } 00477 else if (rhs->hasType<mrs_real>()) 00478 { 00479 return GenericArithmetic::subtract<T,mrs_real>(lhs, rhs); 00480 } 00481 else if (rhs->hasType<mrs_realvec>()) 00482 { 00483 return GenericArithmetic::subtract<T,mrs_realvec>(lhs, rhs); 00484 } 00485 else 00486 { 00487 throw std::runtime_error("Can not subtract that."); 00488 } 00489 } 00490 00491 static MarControlValue *multiply( MarControlValueT<T>*lhs, MarControlValue*rhs) 00492 { 00493 if (rhs->hasType<mrs_natural>()) 00494 { 00495 return GenericArithmetic::multiply<T,mrs_natural>(lhs, rhs); 00496 } 00497 else if (rhs->hasType<mrs_real>()) 00498 { 00499 return GenericArithmetic::multiply<T,mrs_real>(lhs, rhs); 00500 } 00501 else if (rhs->hasType<mrs_realvec>()) 00502 { 00503 return GenericArithmetic::multiply<T,mrs_realvec>(lhs, rhs); 00504 } 00505 else 00506 { 00507 throw std::runtime_error("Can not multiply with that."); 00508 } 00509 } 00510 00511 static MarControlValue *divide( MarControlValueT<T>*lhs, MarControlValue*rhs) 00512 { 00513 if (rhs->hasType<mrs_natural>()) 00514 { 00515 return GenericArithmetic::divide<T,mrs_natural>(lhs, rhs); 00516 } 00517 else if (rhs->hasType<mrs_real>()) 00518 { 00519 return GenericArithmetic::divide<T,mrs_real>(lhs, rhs); 00520 } 00521 else if (rhs->hasType<mrs_realvec>()) 00522 { 00523 return GenericArithmetic::divide<T,mrs_realvec>(lhs, rhs); 00524 } 00525 else 00526 { 00527 throw std::runtime_error("Can not divide by that."); 00528 } 00529 } 00530 }; 00531 00532 template <typename T> 00533 struct MarControlValue::ArithmeticCompare<T, true> 00534 { 00535 static bool isEqual( MarControlValueT<T>*lhs, MarControlValue*rhs ) 00536 { 00537 if (lhs == rhs) 00538 { 00539 return true; 00540 } 00541 else if (rhs->hasType<T>()) 00542 { 00543 return lhs->get() == static_cast<MarControlValueT<T>*>(rhs)->get(); 00544 } 00545 else if (rhs->hasType<mrs_natural>()) 00546 { 00547 return lhs->get() == static_cast<MarControlValueT<mrs_natural>*>(rhs)->get(); 00548 } 00549 else if (rhs->hasType<mrs_real>()) 00550 { 00551 return lhs->get() == static_cast<MarControlValueT<mrs_real>*>(rhs)->get(); 00552 } 00553 throw std::runtime_error("Can not compare to that."); 00554 } 00555 00556 static bool isLessThan( MarControlValueT<T>*lhs, MarControlValue*rhs ) 00557 { 00558 if (rhs->hasType<mrs_natural>()) 00559 { 00560 return lhs->get() < static_cast<MarControlValueT<mrs_natural>*>(rhs)->get(); 00561 } 00562 else if (rhs->hasType<mrs_real>()) 00563 { 00564 return lhs->get() < static_cast<MarControlValueT<mrs_real>*>(rhs)->get(); 00565 } 00566 else 00567 { 00568 throw std::runtime_error("Can not compare to that."); 00569 } 00570 } 00571 }; 00572 00573 } //namespace Marsyas 00574 00575 #endif