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