MIRA
ChannelProperty.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
47 #ifndef _MIRA_CHANNELPROPERTY_H_
48 #define _MIRA_CHANNELPROPERTY_H_
49 
50 #include <QLineEdit>
51 
57 
58 #include <fw/Framework.h>
59 #include <fw/AuthorityProvider.h>
60 
61 namespace mira {
62 
64 
69 {
70 public:
71 
73  virtual ~ChannelPropertyBase() {}
74 
75 public:
76 
78  const std::string& getID() const {
79  return mChannelID;
80  }
81 
83  void setName(const std::string& name) {
84  mName = name;
85  }
86 
88  const std::string& getName() const {
89  return mName;
90  }
91 
92 public:
93 
95  virtual bool isValid() const = 0;
96 
98  virtual uint32 getDataUpdateCount() const = 0;
99 
104  virtual std::list<std::pair<std::string, Typename>> getAvailableChannels() = 0;
105 
106 public:
107 
109  void setOptional() {
110  mOptional = true;
111  }
112 
114  bool isOptional() const {
115  return mOptional;
116  }
117 
118 public:
123  virtual void update() = 0;
124 
129  virtual void set(const std::string& id, IAuthorityProvider* authorityProvider)
130  {
131  mChannelID = id;
132  mAuthorityProvider = authorityProvider;
133  }
134 
135 protected:
136  std::string mName;
137  std::string mChannelID;
139  bool mOptional;
140 };
141 
143 
153 {
154 
155 public:
156 
158  ChannelPropertyProxy(const std::string& id, ChannelPropertyBase* p) :
159  channelID(id), property(p) {}
160 
161 public:
162 
163  template <typename Reflector>
164  void reflect(Reflector& r) {
165  r.member("Channel",channelID, "The ID of the channel");
166  }
167 
168 public:
169 
171  bool isValid() const {
172  assert(property);
173  return property->isValid();
174  }
175 
180  std::list<std::pair<std::string, Typename>> getAvailableChannels()
181  {
182  assert(property);
183  return property->getAvailableChannels();
184  }
185 
186 public:
187 
188  std::string channelID;
190 
191 };
192 
193 template<>
194 class IsObjectTrackable<ChannelPropertyProxy> : public std::false_type {};
195 
197 
211 template <typename T>
213 {
214 
215 public:
217  mDataUpdates(0),
218  mProcessedUpdates(0),
219  mDataChangedFn(NULL),
220  mDataIntervalChangedFn(NULL),
221  mChannelChangedFn(NULL)
222  {}
223 
224 public: // implementation of ChannelPropertyBase
225 
226  virtual bool isValid() const {
227  return mChannel.isValid();
228  }
229 
230  virtual uint32 getDataUpdateCount() const {
231  return mDataUpdates;
232  }
233 
234  virtual std::list<std::pair<std::string, Typename>> getAvailableChannels() {
235  return MIRA_FW.getChannelManager().getChannelsOfType<T>();
236  }
237 
238 public:
239 
240  // overwritten from ChannelPropertyBase
241  // will unsubscribe a set channel
242  virtual void set(const std::string& id, IAuthorityProvider* authorityProvider)
243  {
244  ChannelPropertyBase::set(id,authorityProvider);
245  mDataUpdates = 0;
246 
247  // unsubscribe and reset our channel
248  if(mChannel.isValid()) {
249  assert(mAuthorityProvider!=NULL);
250  Authority& authority = mAuthorityProvider->getAuthority();
251  authority.unsubscribe<T>(mChannel.getID());
252  mChannel.reset();
253  }
254 
255  if (mChannelChangedFn)
256  mChannelChangedFn();
257 
258  mProcessedUpdates = -1; // setting different from mDataUpdates ensures
259  // update() will immediately try to read from channel,
260  // before next channel update (channel may already hold data)
261  }
262 
263 public:
264  void setDataChangedCallback(boost::function<void (ChannelRead<T>)> dataChangedFn)
265  {
266  mDataChangedFn = dataChangedFn;
267  mDataIntervalChangedFn = NULL;
268  }
269 
270  template<typename Class>
272  {
273  mDataChangedFn = boost::bind(f, obj, _1);
274  mDataIntervalChangedFn = NULL;
275  }
276 
277  void setDataIntervalChangedCallback(boost::function<void (ChannelReadInterval<T>)> dataChangedFn)
278  {
279  mDataChangedFn = NULL;
280  mDataIntervalChangedFn = dataChangedFn;
281  }
282 
283  template<typename Class>
285  {
286  mDataChangedFn = NULL;
287  mDataIntervalChangedFn = boost::bind(f, obj, _1);
288  }
289 
290  void setChannelChangedCallback(boost::function<void ()> channelChangedFn)
291  {
292  mChannelChangedFn = channelChangedFn;
293  }
294 
295  template<typename Class>
296  void setChannelChangedCallback(void (Class::*f)(), Class* obj)
297  {
298  mChannelChangedFn = boost::bind(f, obj);
299  }
300 
309  {
310  if(mChannelID.empty())
311  MIRA_THROW(XRuntime, "No channel specified.");
312 
313  if(!mChannel.isValid() && mAuthorityProvider!=NULL) {
314  Authority& authority = mAuthorityProvider->getAuthority();
315 
316  // here we will set the channel by subscribing the channel with
317  // the specified id, however, we will subscribe only if the channel
318  // exists to prevent creating a new channel
319  if(MIRA_FW.getChannelManager().hasChannel(mChannelID))
320  {
321  mChannel = authority.subscribe<T>(mChannelID, &ChannelProperty::callback, this);
322  mDataUpdates = MIRA_FW.getChannelManager().getNrOfDataChanges(mChannelID);
323  }
324  else
325  MIRA_THROW(XRuntime, "The channel '" << mChannelID << "' does not exist.");
326  mProcessedUpdates = -1; // see set()
327  }
328  return mChannel;
329  }
330 
331  virtual void update()
332  {
333  getChannel();
334  int64 updates = mDataUpdates;
335 
336  // - after update, before processing it: mDataUpdates > mProcessedUpdates
337  // - when mDataUpdates has overflown (uint32): mDataUpdates < mProcessedUpdates
338  // - after (re)initialization: mDataUpdates > mProcessedUpdates
339  if ((updates != mProcessedUpdates) && (mDataChangedFn || mDataIntervalChangedFn) )
340  {
341  mProcessedUpdates = updates;
342  if ( mDataChangedFn )
343  try {
344  mDataChangedFn(mChannel.read());
345  }
346  catch(XInvalidRead&) {}
347  else {
348  ChannelReadInterval<T> tInterval;
349  if ( !mLastUpdate.isValid() ) {
350  bool increase = mChannel.isAutoIncreasingStorageDuration();
351 
352  // get all slots that are there, without affecting the storage duration
353  MIRA_FW.getChannelManager().setAutoIncreaseStorageDuration(mChannelID, false);
354  try {
355  tInterval = mChannel.readInterval(Time::unixEpoch());
356  }
357  catch(XInvalidRead&) {}
358  MIRA_FW.getChannelManager().setAutoIncreaseStorageDuration(mChannelID, increase);
359  }
360  else {
361  try {
362  tInterval = mChannel.readInterval(mLastUpdate);
363  }
364  catch(XInvalidRead&) {}
365  }
366 
367  // we have to check if there actually is new data, even though mDataUpdates changed:
368  // it happens we already read the newest data (triggered by a previous callback),
369  // then callback for the new data is executed _afterwards_ and increments mDataUpdates
370  if (tInterval.empty())
371  return;
372 
373  mDataIntervalChangedFn( tInterval );
374  typename ChannelReadInterval<T>::const_iterator it = tInterval.end();
375  it--;
376  mLastUpdate = ((ChannelRead<T>)it)->timestamp;
377  }
378  }
379 
380  }
381 
382  void callback(ChannelRead<T> channel)
383  {
384  ++mDataUpdates;
385  }
386 
387 public:
388 
389 
395  template<typename Reflector>
396  static void channelProperty(Reflector& r, const std::string& name,
397  ChannelProperty& channel,
398  const std::string& comment, IAuthorityProvider* authorityProvider)
399  {
400  r.property(name.c_str(),
401  getter<ChannelPropertyProxy>(
402  boost::bind(proxyGetter, &channel, authorityProvider)),
403  setter<ChannelPropertyProxy>(
404  boost::bind(proxySetter, &channel, _1, authorityProvider)),
405  comment.c_str());
406  }
407 
408 private:
409 
411  static void proxySetter(ChannelProperty* This, const ChannelPropertyProxy& proxy,
412  IAuthorityProvider* authorityProvider) {
413  This->set(proxy.channelID, authorityProvider);
414  }
415 
417  static ChannelPropertyProxy proxyGetter(ChannelProperty* This,
418  IAuthorityProvider* authorityProvider) {
419  This->mAuthorityProvider = authorityProvider;
420  return ChannelPropertyProxy(This->mChannelID, This);
421  }
422 
423 private:
424 
425  Channel<T> mChannel;
426  uint32 mDataUpdates;
427  int64 mProcessedUpdates;
428  boost::function<void (ChannelRead<T>)> mDataChangedFn;
429  boost::function<void (ChannelReadInterval<T>)> mDataIntervalChangedFn;
430  boost::function<void ()> mChannelChangedFn;
431  Time mLastUpdate;
432 };
433 
434 
436 
438 class ChannelPropertyDelegateLineEdit : public QLineEdit
439 {
440 Q_OBJECT
441 public:
442  ChannelPropertyDelegateLineEdit(PropertyNode* p, QWidget* parent);
443 public slots:
444  void slotSetValue();
445 public:
447 };
448 
450 
451 }
452 
453 #endif
An object that allows read access to a whole interval of channel data.
Definition: ChannelReadInterval.h:72
Type trait that indicates whether pointer tracking can be enabled for this type.
Definition: IsObjectTrackable.h:68
virtual ~ChannelPropertyBase()
Definition: ChannelProperty.h:73
bool empty() const
Definition: ChannelReadInterval.h:169
Abstract base class for all derived property node classes.
Definition: PropertyNode.h:202
TypedPropertyNode< ChannelPropertyProxy > * property
Definition: ChannelProperty.h:446
ChannelPropertyProxy(const std::string &id, ChannelPropertyBase *p)
Definition: ChannelProperty.h:158
static void channelProperty(Reflector &r, const std::string &name, ChannelProperty &channel, const std::string &comment, IAuthorityProvider *authorityProvider)
Special property-method that should be called within the reflect method to specify a ChannelProperty...
Definition: ChannelProperty.h:396
ChannelPropertyDelegateLineEdit(PropertyNode *p, QWidget *parent)
An exception that occurs whenever a channel has no data.
Definition: Channel.h:88
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
void setDataChangedCallback(boost::function< void(ChannelRead< T >)> dataChangedFn)
Definition: ChannelProperty.h:264
bool isValid() const
Returns true if this contains a valid time.
Definition: Time.h:575
std::string channelID
Definition: ChannelProperty.h:188
Class object which supports some kind of class reflection.
Definition: Class.h:97
IAuthorityProvider * mAuthorityProvider
Definition: ChannelProperty.h:138
uint32_t uint32
Definition: Types.h:64
std::string mName
Definition: ChannelProperty.h:136
#define MIRA_FW
Macro for accessing the framework instance.
Definition: Framework.h:74
bool isOptional() const
For internal use only.
Definition: ChannelProperty.h:114
Provides MIRA_SPLIT_REFLECT macros.
Provides type trait that indicates whether pointer/object tracking should be enabled for a certain ty...
Channel< T > getChannel()
Obtains the set or chosen channel.
Definition: ChannelProperty.h:308
static Time unixEpoch()
Returns the unix epoch 1.1.1970 0:0:0.000.
Definition: Time.h:506
An object that allows read access to data of a channel.
Definition: ChannelReadWrite.h:494
virtual std::list< std::pair< std::string, Typename > > getAvailableChannels()=0
Returns list of (channelID,typename) pairs containing the channels that match the desired type...
void unsubscribe(const std::string &channelID)
Unsubscribe from a given channel.
virtual void set(const std::string &id, IAuthorityProvider *authorityProvider)
Sets the channelID and a necessary authority provider that is used to obtain the authority for subscr...
Definition: ChannelProperty.h:242
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:78
ChannelPropertyProxy()
Definition: ChannelProperty.h:157
virtual void update()=0
Tell the property to update the assigned channel.
const_iterator end() const
Definition: ChannelReadInterval.h:164
Contains the base interface of all Reflectors, Serializers, etc.
void setDataIntervalChangedCallback(void(Class::*f)(ChannelReadInterval< T >), Class *obj)
Definition: ChannelProperty.h:284
ChannelProperty()
Definition: ChannelProperty.h:216
Serializer that handles properties and creates PropertyNodes.
virtual bool isValid() const
Returns true, if an existing channel is set. Must be implemented in derived class.
Definition: ChannelProperty.h:226
const std::string & getName() const
Returns the name of the property.
Definition: ChannelProperty.h:88
Abstract interface for classes that can provide an authority via the getAuthority() method...
Definition: AuthorityProvider.h:61
const std::string & getID() const
Returns the channelID that was set by the user.
Definition: ChannelProperty.h:78
void setName(const std::string &name)
Sets the name of the property.
Definition: ChannelProperty.h:83
Base class for ChannelProperty template class.
Definition: ChannelProperty.h:68
ChannelPropertyBase()
Definition: ChannelProperty.h:72
Authorities act as a facade to the framework.
Definition: Authority.h:94
virtual uint32 getDataUpdateCount() const
Returns the number of data updates the channel has received.
Definition: ChannelProperty.h:230
Const iterator for iterating over the interval.
Definition: ChannelReadInterval.h:85
void setDataIntervalChangedCallback(boost::function< void(ChannelReadInterval< T >)> dataChangedFn)
Definition: ChannelProperty.h:277
void reflect(Reflector &r)
Definition: ChannelProperty.h:164
ChannelPropertyBase * property
Definition: ChannelProperty.h:189
virtual std::list< std::pair< std::string, Typename > > getAvailableChannels()
Returns list of (channelID,typename) pairs containing the channels that match the desired type...
Definition: ChannelProperty.h:234
void setChannelChangedCallback(boost::function< void()> channelChangedFn)
Definition: ChannelProperty.h:290
virtual void update()
Tell the property to update the assigned channel.
Definition: ChannelProperty.h:331
std::string mChannelID
Definition: ChannelProperty.h:137
virtual bool isValid() const =0
Returns true, if an existing channel is set. Must be implemented in derived class.
bool mOptional
Definition: ChannelProperty.h:139
The concrete typed ChannelProperty template class.
Definition: ChannelProperty.h:212
int64_t int64
Definition: Types.h:61
virtual Authority & getAuthority()=0
Return the authority as reference.
void setChannelChangedCallback(void(Class::*f)(), Class *obj)
Definition: ChannelProperty.h:296
void setOptional()
For internal use only.
Definition: ChannelProperty.h:109
Abstract interface for classes that can provide an authority.
Special LineEdit for ChannelProperty delegate for Property Editor.
Definition: ChannelProperty.h:438
Proxy class that is returned/set by the getter and setter methods of ChannelProperty.
Definition: ChannelProperty.h:152
The framework that holds all manager classes and provides startup and shutdown of all framework relat...
virtual void set(const std::string &id, IAuthorityProvider *authorityProvider)
Sets the channelID and a necessary authority provider that is used to obtain the authority for subscr...
Definition: ChannelProperty.h:129
void setDataChangedCallback(void(Class::*f)(ChannelRead< T >), Class *obj)
Definition: ChannelProperty.h:271
Channel< T > subscribe(const std::string &channelID, const Duration &storageDuration=Duration::seconds(0))
Subscribes authority to a given channel.
Abstract base class for all typed property nodes.
Definition: PropertyNode.h:70
bool isValid() const
Returns true, if an existing channel is set.
Definition: ChannelProperty.h:171
Provides definition for getters and setters that are used with the serialization framework.
std::list< std::pair< std::string, Typename > > getAvailableChannels()
Returns list of (channelID,typename) pairs containing the channels that match the desired type...
Definition: ChannelProperty.h:180
virtual uint32 getDataUpdateCount() const =0
Returns the number of data updates the channel has received.
void callback(ChannelRead< T > channel)
Definition: ChannelProperty.h:382