Marsyas  0.5.0-beta1
/Users/jleben/code/marsyas/src/marsyas/system/MarControl.h
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2006 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 __MARCONTROL__
00020 #define __MARCONTROL__
00021 
00022 #include <marsyas/common_header.h>
00023 #include <marsyas/realvec.h>
00024 #include <marsyas/system/MarControlValue.h>
00025 
00026 #include <string>
00027 #include <iostream>
00028 #include <vector>
00029 #include <utility>
00030 #include <typeinfo>
00031 
00032 //#define TRACECONTROLS
00033 #ifdef TRACECONTROLS
00034 #include <set>
00035 #define TRACE_ADDCONTROL MarControlPtr::controlTracer.insert(control_);;
00036 #define TRACE_REMCONTROL if(control_->getRefCount() == 1) controlTracer.erase(control_);
00037 #else
00038 #define TRACE_ADDCONTROL
00039 #define TRACE_REMCONTROL
00040 #endif
00041 
00042 #define TRACE_ADDCONTROL
00043 #define TRACE_REMCONTROL
00044 
00045 #define WAS_INLINE
00046 
00047 namespace Marsyas
00048 {
00058 static const bool NOUPDATE = false;
00059 
00060 class MarSystem;
00061 class MarControl;
00062 class MarControlManager;
00063 
00065 //  MarControlPtr declaration
00067 class marsyas_EXPORT MarControlPtr
00068 {
00069 #ifdef TRACECONTROLS
00070 public:
00071   static std::set<MarControl*> controlTracer;
00072   static void printControlTracer();
00073 #endif
00074 
00075 protected:
00076   MarControl *control_;
00077 
00078 public:
00079   // default constructor
00080   MarControlPtr();
00081 
00082   // copy constructor
00083   WAS_INLINE MarControlPtr(const MarControlPtr& a);
00084 
00085   // basic types constructors / for compatibility purposes
00086   WAS_INLINE MarControlPtr(MarControl control);
00087   WAS_INLINE MarControlPtr(MarControlValue *value);
00088   WAS_INLINE MarControlPtr(int ne);
00089   WAS_INLINE MarControlPtr(float ne);
00090   WAS_INLINE MarControlPtr(mrs_natural ne);
00091   WAS_INLINE MarControlPtr(double re);
00092   WAS_INLINE MarControlPtr(const char *c);
00093   WAS_INLINE MarControlPtr(std::string st);
00094   WAS_INLINE MarControlPtr(bool be);
00095   WAS_INLINE MarControlPtr(realvec ve);
00096   WAS_INLINE MarControlPtr(unsigned int ne);
00097 
00098   // generic type constructor
00099   WAS_INLINE MarControlPtr(MarControl *control);
00100 
00101   // assignment operator
00102   WAS_INLINE MarControlPtr& operator=(const MarControlPtr& a);
00103 
00104   ~MarControlPtr();
00105 
00106   MarControl* operator()() const { return control_; }
00107   MarControl& operator*() const  { return *control_; }
00108   MarControl* operator->() const { return control_; }
00109 
00110   WAS_INLINE bool isInvalid() const;
00111   WAS_INLINE bool isEqual(const MarControlPtr& v1);
00112 
00113   marsyas_EXPORT
00114   friend WAS_INLINE std::ostream& operator<<(std::ostream& os, const MarControlPtr& ctrl);
00115   marsyas_EXPORT
00116   friend WAS_INLINE bool operator==(const MarControlPtr& v1, const MarControlPtr& v2);
00117   marsyas_EXPORT
00118   friend WAS_INLINE bool operator!=(const MarControlPtr& v1, const MarControlPtr& v2);
00119 
00120   marsyas_EXPORT
00121   friend WAS_INLINE mrs_real operator+(const MarControlPtr& v1, const mrs_real& v2);
00122   marsyas_EXPORT
00123   friend WAS_INLINE mrs_real operator+(const mrs_real& v1, const MarControlPtr& v2);
00124   marsyas_EXPORT
00125   friend WAS_INLINE mrs_real operator-(const MarControlPtr& v1, const mrs_real& v2);
00126   marsyas_EXPORT
00127   friend WAS_INLINE mrs_real operator-(const mrs_real& v1, const MarControlPtr& v2);
00128   marsyas_EXPORT
00129   friend WAS_INLINE mrs_real operator*(const MarControlPtr& v1, const mrs_real& v2);
00130   marsyas_EXPORT
00131   friend WAS_INLINE mrs_real operator*(const mrs_real& v1, const MarControlPtr& v2);
00132   marsyas_EXPORT
00133   friend WAS_INLINE mrs_real operator/(const MarControlPtr& v1, const mrs_real& v2);
00134   marsyas_EXPORT
00135   friend WAS_INLINE mrs_real operator/(const mrs_real& v1, const MarControlPtr& v2);
00136 
00137   marsyas_EXPORT
00138   friend WAS_INLINE MarControlPtr operator+(const MarControlPtr& v1, const MarControlPtr& v2);
00139   marsyas_EXPORT
00140   friend WAS_INLINE MarControlPtr operator-(const MarControlPtr& v1, const MarControlPtr& v2);
00141   marsyas_EXPORT
00142   friend WAS_INLINE MarControlPtr operator*(const MarControlPtr& v1, const MarControlPtr& v2);
00143   marsyas_EXPORT
00144   friend WAS_INLINE MarControlPtr operator/(const MarControlPtr& v1, const MarControlPtr& v2);
00145 
00146   marsyas_EXPORT friend bool operator<(const MarControlPtr& v1, const MarControlPtr& v2);
00147 };
00148 
00150 //  MarControl declaration
00152 class marsyas_EXPORT MarControl
00153 {
00154 public:
00155   friend class MarControlManager;
00156   friend class MarControlAccessor;
00157 
00158 private:
00159   int refCount_;
00160   MarControlValue *value_;
00161   MarSystem* msys_;
00162   std::string cname_;
00163   std::string id_;
00164   std::string desc_;
00165   bool state_;
00166   bool is_public_;
00167 
00168 private:
00169   // default constructor
00170   explicit MarControl(); // not allowed (yes but what about the friend classes then?)
00171 
00172 public:
00173 
00174   // copy constructor
00175   WAS_INLINE MarControl(const MarControl& a);
00176 
00177   // generic type constructor
00178   WAS_INLINE MarControl(MarControlValue *value, std::string cname = "", MarSystem* msys = 0, bool state = false);
00179 
00180   // basic types constructors / for compatibility purposes
00181   WAS_INLINE MarControl(double re, std::string cname = "", MarSystem* msys = 0, bool state = false);
00182   WAS_INLINE MarControl(float  re, std::string cname = "", MarSystem* msys = 0, bool state = false);
00183   WAS_INLINE MarControl(mrs_natural ne, std::string cname = "", MarSystem* msys = 0, bool state = false);
00184   WAS_INLINE MarControl(std::string st, std::string cname = "", MarSystem* msys = 0, bool state = false);
00185   WAS_INLINE MarControl(bool be, std::string cname = "", MarSystem* msys = 0, bool state = false);
00186   WAS_INLINE MarControl(realvec& ve, std::string cname = "", MarSystem* msys = 0, bool state = false);
00187 
00188   // destructor
00189   ~MarControl();
00190 
00191   MarControl& operator=(const MarControl& a);
00192 
00193   MarControl* clone();
00194 
00195   WAS_INLINE void ref();
00196   WAS_INLINE void unref();
00197   int getRefCount() const;
00198 
00199   void setMarSystem(MarSystem* msys);
00200   MarSystem* getMarSystem() const;
00201   void setName(const std::string & cname);
00202   const std::string & getName() const { return cname_; }
00203   const std::string & id() const { return id_; }
00204   void setState(bool state);
00205   bool hasState() const;
00206   std::string getType() const;
00207   std::string path() const;
00208   bool isPublic() const { return is_public_; }
00209   void setPublic(bool flag) { is_public_ = flag; }
00210 
00211 
00212   template<typename T>
00213   bool hasType()
00214   {
00215     return value_ && value_->hasType<T>();
00216   }
00217 
00218   // for link controls
00219   bool linkTo(MarControlPtr ctrl, bool update = true);
00220   void unlinkFromAll();
00221   void unlinkFromTarget();
00222   bool isLinked() const;
00223   std::vector<std::pair<MarControlPtr, MarControlPtr> > getLinks();
00224 
00225   // setters
00226   template<class T> WAS_INLINE bool setValue(const T& t, bool update = true);
00227   WAS_INLINE bool setValue(MarControlPtr mc, bool update = true);
00228   WAS_INLINE bool setValue(MarControlValue *mcv, bool update = true);
00229   WAS_INLINE bool setValue(const char *t, bool update = true);
00230   WAS_INLINE bool setValue(int t, bool update = true);
00231 
00232   // to avoid circular dependencies
00233   void callMarSystemUpdate();
00234 
00235   // getters by return (user must know the parameter's type)
00236   template<class T> WAS_INLINE const T& to() const;
00237 
00238   // type specific getters useful for SWIG bindings
00239   mrs_string to_string() const;
00240   mrs_real   to_real() const;
00241   mrs_natural to_natural() const;
00242   mrs_realvec to_realvec() const;
00243   mrs_bool to_bool() const;
00244 
00245 
00246   // bool-specific helper
00247   bool isTrue();
00248 
00249   friend WAS_INLINE std::ostream& operator<<(std::ostream& os, const MarControl& ctrl);
00250   friend WAS_INLINE bool operator==(const MarControl& v1, const MarControl& v2);
00251   friend WAS_INLINE bool operator!=(const MarControl& v1, const MarControl& v2);
00252 
00254   // helper operators
00255   friend WAS_INLINE mrs_real operator+(const MarControl& v1, const mrs_real& v2);
00256   friend WAS_INLINE mrs_real operator+(const mrs_real& v1, const MarControl& v2);
00257   friend WAS_INLINE mrs_real operator-(const MarControl& v1, const mrs_real& v2);
00258   friend WAS_INLINE mrs_real operator-(const mrs_real& v1, const MarControl& v2);
00259   friend WAS_INLINE mrs_real operator*(const MarControl& v1, const mrs_real& v2);
00260   friend WAS_INLINE mrs_real operator*(const mrs_real& v1, const MarControl& v2);
00261   friend WAS_INLINE mrs_real operator/(const MarControl& v1, const mrs_real& v2);
00262   friend WAS_INLINE mrs_real operator/(const mrs_real& v1, const MarControl& v2);
00263 
00264   friend WAS_INLINE MarControl operator+(const MarControl& v1, const MarControl& v2);
00265   friend WAS_INLINE MarControl operator-(const MarControl& v1, const MarControl& v2);
00266   friend WAS_INLINE MarControl operator*(const MarControl& v1, const MarControl& v2);
00267   friend WAS_INLINE MarControl operator/(const MarControl& v1, const MarControl& v2);
00268 
00269   bool operator== (const MarControl& rhs)
00270   {
00271     return value_->isEqual(rhs.value_);
00272   }
00273 
00274   bool operator!= (const MarControl& rhs)
00275   {
00276     return !(value_->isEqual(rhs.value_));
00277   }
00278 
00279   bool operator< (const MarControl & rhs)
00280   {
00281     return value_->isLessThan(rhs.value_);
00282   }
00283 };
00284 
00285 
00286 
00287 
00288 
00289 /************************************************************************/
00290 /* MarControl template implementation                                   */
00291 /************************************************************************/
00292 template<class T>
00293 const T&
00294 MarControl::to() const
00295 {
00296   const MarControlValueT<T> *ptr = dynamic_cast<const MarControlValueT<T>*>(value_);
00297   if(ptr)
00298   {
00299     return ptr->get();
00300   }
00301   else
00302   {
00303     static T invalidValue;
00304     MRSERR("MarControl::to() -  Incompatible type requested - " << "expected "
00305            << value_->getType() << " for control  " << this->getName()) ;
00306     return invalidValue;
00307   }
00308 }
00309 
00310 
00311 // setters
00312 template<class T>
00313 WAS_INLINE
00314 bool
00315 MarControl::setValue(const T& t, bool update)
00316 {
00317   MarControlValueT<T> *ptr = dynamic_cast<MarControlValueT<T>*>(value_);
00318   if(ptr)
00319   {
00320     if (ptr->get() == t)
00321       return true;
00322 
00323     ptr->set(t, update);
00324 
00325     return true;
00326   }
00327   else
00328   {
00329     std::ostringstream sstr;
00330     sstr << "MarControl::setValue() - Trying to set value of incompatible type "
00331          << "(expected " << value_->getType() << ", given " << typeid(T).name() << ")";
00332     MRSWARN(sstr.str());
00333     return false;
00334   }
00335 }
00336 
00337 
00338 
00339 
00340 
00341 }//namespace Marsyas
00342 
00343 //#include "MarControlAccessor.h" // ?? why after?
00344 
00345 #endif /* __MARCONTROL__ */