00001
00002 #ifndef __DAQpp_Parameter_h__
00003 #define __DAQpp_Parameter_h__
00004 #include <iosfwd>
00005 #include <map>
00006 #include <vector>
00007 #include <DAQ++/DAQid.h>
00008 #include <DAQ++/ObserverModel.h>
00009 #include <DAQ++/exception.h>
00010
00011 namespace DAQpp
00012 {
00022 class Parameter : public Observable
00023 {
00024 private:
00026 std::string name;
00028 DAQid _id;
00029 public:
00031 Parameter() : name("unnamed"), _id("???")
00032 {}
00034 virtual ~Parameter()
00035 {}
00037 void set_name(const std::string &s)
00038 {
00039 name = s;
00040 }
00042 const std::string &get_name() const
00043 {
00044 return name;
00045 }
00046
00048 DAQid const & get_id() const
00049 {
00050 return _id;
00051 }
00053 void set_id( const DAQid &s )
00054 {
00055 _id = s;
00056 }
00061 virtual void set_from_string(const std::string &s, bool notify = false)
00062 {}
00063
00067 virtual std::string get_as_string()
00068 {
00069 return std::string("???");
00070 }
00071
00072 };
00073
00085 template <class T>
00086 class Par : public Parameter
00087 {
00088 private:
00090 T value;
00091 public:
00093 Par()
00094 {}
00096 Par(const T &v) : value(v)
00097 {}
00099 Par(const Par &v)
00100 {
00101 value = v.value;
00102 }
00104 Par &operator=(const Par &v)
00105 {
00106 if ( &v == this ) return *this;
00107 value = v.value;
00108
00109 }
00111 ~Par()
00112 {
00113 deleteObservers();
00114 }
00115
00117 void set_value( const T &x, bool notify = false)
00118 {
00119 value = x;
00120 if ( notify )
00121 {
00122 Arg<T> arg(value);
00123 notifyObservers(&arg);
00124 }
00125 }
00127 T const &operator()() const
00128 {
00129 return value;
00130 }
00132 T &operator()()
00133 {
00134 return value;
00135 }
00137 const T & get_value() const
00138 {
00139 return value;
00140 }
00142 T &get_value()
00143 {
00144 return value;
00145 }
00146
00147 };
00148
00152 template<class T>
00153 T &get_par_value(Parameter *p)
00154 throw( ParameterTypeDoesNotMatch )
00155 {
00156
00157 Par<T> *t = dynamic_cast<Par<T> * > (p);
00158 if ( t == 0 )
00159 throw ( ParameterTypeDoesNotMatch( p->get_name().c_str() ) );
00160
00161 return t->get_value();
00162 }
00163
00167 template<class T>
00168 void set_par_value(Parameter *p, const T &v, bool notify = false)
00169 throw( ParameterTypeDoesNotMatch )
00170 {
00171 Par<T> *t = dynamic_cast<Par<T> * > (p);
00172 if ( t == 0 )
00173 throw ( ParameterTypeDoesNotMatch( p->get_name().c_str() ) );
00174 t->set_value(v, notify);
00175 }
00176
00183 class ParameterHolder : public std::map<std::string, Parameter *>
00184 {
00185 public:
00186
00187 ParameterHolder()
00188 {}
00189
00190
00191 virtual ~ParameterHolder()
00192 {
00193 iterator ip;
00194 for (ip = begin();ip != end();++ip)
00195 {
00196 ip->second->deleteObservers();
00197 delete ip->second;
00198 }
00199 clear();
00200 }
00201
00203 Parameter *get_par(const char *par)
00204 throw( ParameterNonExistent )
00205 {
00206 iterator ip = find(par);
00207
00208 if (ip == end() )
00209 {
00210 throw ( DAQpp::ParameterNonExistent(par) );
00211 }
00212 else
00213 return ip->second;
00214 }
00215
00217 virtual void add_par(const char *pnam, Parameter *par, const DAQid *id = 0)
00218 {
00219 (*this)[pnam] = par;
00220 par->set_name(pnam);
00221 if (id)
00222 par->set_id(*id);
00223 }
00224
00226 template <class T>
00227 T &get_par_value(const char *par_name)
00228 throw( ParameterNonExistent, ParameterTypeDoesNotMatch )
00229 {
00230 Parameter *par = get_par(par_name);
00231 Par<T> *t = dynamic_cast<Par<T> * > (par);
00232 if ( t == 0 )
00233 throw ( ParameterTypeDoesNotMatch( par_name ) );
00234
00235 return t->get_value();
00236 }
00237
00239 template<class T>
00240 void set_par(const char *pnam, const T &value, bool notify = false)
00241 throw ( ParameterNonExistent, ParameterTypeDoesNotMatch )
00242 {
00243 try
00244 {
00245 Parameter *par = get_par(pnam);
00246 set_par_value<T>(par, value, notify);
00247 }
00248 catch (...)
00249 {
00250 throw;
00251 }
00252 }
00253 };
00254
00262 template<typename T, typename C>
00263 class ParameterObserver : public Observer
00264 {
00265 public:
00266 typedef void (C::*method_type)(const T&);
00267 private:
00268 C *module;
00269 void (C::*func)(const T &);
00270 DAQpp::Par< T > *par;
00271 public:
00272 ParameterObserver(C *m, void (C::*f)(const T&), DAQpp::Par< T > *p = 0)
00273 : module(m), func(f), par(0)
00274 {
00275 if (p)
00276 set_par(p);
00277 }
00278 ~ParameterObserver()
00279 {
00280 par->deleteObserver( *dynamic_cast<Observer *>(this) );
00281 }
00282 void set_par( DAQpp::Par< T > *p)
00283 {
00284 if (par)
00285 par->deleteObserver( *dynamic_cast<Observer *>(this) );
00286
00287 par = p;
00288 par->addObserver( *dynamic_cast<Observer *>(this) );
00289 }
00290 const C *get_module() const
00291 {
00292 return module;
00293 }
00294 void update(Observable *o, Argument *arg)
00295 {
00296 Arg<T> *v = static_cast< Arg<T> * > (arg);
00297 (module->*func)( v->get_value() );
00298 }
00299 };
00300
00307 template<typename C>
00308 class ParameterCollection : std::vector<Observer *>
00309 {
00310 private:
00311 C *module;
00312
00313 public:
00314 ParameterCollection(C *m) : module(m)
00315 {}
00316 ~ParameterCollection()
00317 {
00318 std::vector<Observer *>::iterator ip;
00319 for (ip = begin(); ip != end(); ++ip)
00320 {
00321 delete *ip;
00322 }
00323 }
00324 template<typename T>
00325 DAQpp::Par<T> *new_par( void (C::*f)(const T&), DAQpp::Par< T > *p = 0)
00326 {
00327 push_back( new ParameterObserver<T, C>(module, f, p) );
00328 return p;
00329 }
00330 };
00331
00332 }
00333
00334 #endif