Marsyas  0.5.0-beta1
/Users/jleben/code/marsyas/src/marsyas/system/MarControlValue.h
Go to the documentation of this file.
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