Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/realtime/atomic_control.h
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2013 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 MARSYAS_THREAD_ATOMIC_CONTROL_INCLUDED
00020 #define MARSYAS_THREAD_ATOMIC_CONTROL_INCLUDED
00021 
00022 #include <marsyas/realtime/any.h>
00023 #include <marsyas/realtime/stage.h>
00024 
00025 #include <marsyas/common_header.h>
00026 #include <marsyas/realvec.h>
00027 #include <marsyas/system/MarControl.h>
00028 
00029 #include <atomic>
00030 #include <string>
00031 #include <cstring>
00032 
00033 namespace Marsyas {
00034 namespace RealTime {
00035 
00036 using std::atomic;
00037 
00038 using Marsyas::MarControl;
00039 using Marsyas::MarControlPtr;
00040 
00045 class AtomicControl
00046 {
00047 public:
00048   AtomicControl( const MarControlPtr & control ):
00049     m_control(control)
00050   {}
00051 
00052   virtual ~AtomicControl() {}
00053 
00057   virtual any value() = 0;
00058 
00062   virtual void push() = 0;
00063 
00064   MarControlPtr & systemControl() { return m_control; }
00065 
00066 protected:
00067   MarControlPtr m_control;
00068 };
00069 
00070 template<typename T>
00071 class AtomicControlT : public AtomicControl
00072 {
00073 public:
00074   AtomicControlT( const MarControlPtr & control ):
00075     AtomicControl(control),
00076     m_value(T())
00077   {}
00078 
00079   any value()
00080   {
00081     return any(m_value.load());
00082   }
00083 
00084   void push()
00085   {
00086     m_value = m_control->to<T>();
00087   }
00088 
00089 private:
00090   atomic<T> m_value;
00091 };
00092 
00093 template<>
00094 class AtomicControlT<mrs_string> : public AtomicControl
00095 {
00096 public:
00097   AtomicControlT( const MarControlPtr & control ):
00098     AtomicControl(control)
00099   {}
00100 
00101   any value()
00102   {
00103     MRSERR("AtomicControlT<mrs_string>::value(): not yet implemented!");
00104     return any(mrs_string());
00105   }
00106 
00107   void push()
00108   {
00109     // FIXME: not real-time safe!
00110     // m_value = m_control->to<mrs_string>();
00111   }
00112 };
00113 
00114 template<>
00115 class AtomicControlT<mrs_realvec> : public AtomicControl
00116 {
00117 public:
00118   AtomicControlT( const MarControlPtr & control ):
00119     AtomicControl(control)
00120   {
00121     resizeToFit();
00122   }
00123 
00124   void resizeToFit()
00125   {
00126     const mrs_realvec & vector = m_control->to<mrs_realvec>();
00127     m_rows = vector.getRows();
00128     m_columns = vector.getCols();
00129     m_value.create( m_rows, m_columns );
00130     m_stage.clear( m_value );
00131   }
00132 
00133   any value()
00134   {
00135     const_cast<stage<mrs_realvec>&>(m_stage).pop();
00136     if (m_stage.has_front())
00137       m_value = m_stage.front();
00138     return any(m_value);
00139   }
00140 
00141   void push()
00142   {
00143     const mrs_realvec & value = m_control->to<mrs_realvec>();
00144     if (value.getRows() == m_rows && value.getCols() == m_columns)
00145     {
00146       mrs_realvec & stage_value = m_stage.back();
00147       std::memcpy( stage_value.getData(),
00148                    value.getData(),
00149                    sizeof(mrs_real) * value.getSize() );
00150       m_stage.push();
00151     }
00152     else
00153     {
00154       MRSERR("AtomicControlT<mrs_realvec>::push(): realvec format mismatch!");
00155     }
00156   }
00157 
00158 private:
00159   mrs_natural m_rows;
00160   mrs_natural m_columns;
00161   mrs_realvec m_value;
00162   stage<mrs_realvec> m_stage;
00163 };
00164 
00165 
00166 } // namespace RealTime
00167 } // namespace Marsyas
00168 
00169 #endif // MARSYAS_THREAD_ATOMIC_CONTROL_INCLUDED