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 
62 
63 namespace mira {
64 
66 
71 {
72 public:
73 
75  virtual ~ChannelPropertyBase() {}
76 
77 public:
78 
80  const std::string& getID() const {
81  return mChannelID;
82  }
83 
85  void setName(const std::string& name) {
86  mName = name;
87  }
88 
90  const std::string& getName() const {
91  return mName;
92  }
93 
94 public:
95 
97  virtual bool isValid() const = 0;
98 
100  virtual uint32 getDataUpdateCount() const = 0;
101 
106  virtual std::list<std::pair<std::string, Typename>> getAvailableChannels() = 0;
107 
108 public:
109 
111  void setOptional() {
112  mOptional = true;
113  }
114 
116  bool isOptional() const {
117  return mOptional;
118  }
119 
120 public:
125  virtual void update() = 0;
126 
131  virtual void set(const std::string& id, IAuthorityProvider* authorityProvider)
132  {
133  mChannelID = id;
134  mAuthorityProvider = authorityProvider;
135  }
136 
137 protected:
138  std::string mName;
139  std::string mChannelID;
141  bool mOptional;
142 };
143 
145 
155 {
156 
157 public:
158 
160  ChannelPropertyProxy(const std::string& id, ChannelPropertyBase* p) :
161  channelID(id), property(p) {}
162 
163 public:
164 
165  template <typename Reflector>
166  void reflect(Reflector& r) {
167  r.member("Channel",channelID, "The ID of the channel");
168  }
169 
170 public:
171 
173  bool isValid() const {
174  assert(property);
175  return property->isValid();
176  }
177 
182  std::list<std::pair<std::string, Typename>> getAvailableChannels()
183  {
184  assert(property);
185  return property->getAvailableChannels();
186  }
187 
188 public:
189 
190  std::string channelID;
192 
193 };
194 
195 template<>
196 class IsObjectTrackable<ChannelPropertyProxy> : public std::false_type {};
197 
199 
213 template <typename T>
215 {
216 
217 public:
219  mDataUpdates(0),
220  mProcessedUpdates(0),
221  mDataChangedFn(NULL),
222  mDataIntervalChangedFn(NULL),
223  mChannelChangedFn(NULL)
224  {}
225 
226 public: // implementation of ChannelPropertyBase
227 
228  virtual bool isValid() const {
229  return mChannel.isValid();
230  }
231 
232  virtual uint32 getDataUpdateCount() const {
233  return mDataUpdates;
234  }
235 
236  virtual std::list<std::pair<std::string, Typename>> getAvailableChannels() {
237  return MIRA_FW.getChannelManager().getChannelsOfType<T>();
238  }
239 
240 public:
241 
242  // overwritten from ChannelPropertyBase
243  // will unsubscribe a set channel
244  virtual void set(const std::string& id, IAuthorityProvider* authorityProvider)
245  {
246  ChannelPropertyBase::set(id,authorityProvider);
247  mDataUpdates = 0;
248 
249  // unsubscribe and reset our channel
250  if(mChannel.isValid()) {
251  assert(mAuthorityProvider!=NULL);
252  Authority& authority = mAuthorityProvider->getAuthority();
253  authority.unsubscribe<T>(mChannel.getID());
254  mChannel.reset();
255  }
256 
257  if (mChannelChangedFn)
258  mChannelChangedFn();
259 
260  mProcessedUpdates = -1; // setting different from mDataUpdates ensures
261  // update() will immediately try to read from channel,
262  // before next channel update (channel may already hold data)
263  }
264 
265 public:
266  void setDataChangedCallback(boost::function<void (ChannelRead<T>)> dataChangedFn)
267  {
268  mDataChangedFn = dataChangedFn;
269  mDataIntervalChangedFn = NULL;
270  }
271 
272  template<typename Class>
274  {
275  mDataChangedFn = boost::bind(f, obj, _1);
276  mDataIntervalChangedFn = NULL;
277  }
278 
279  void setDataIntervalChangedCallback(boost::function<void (ChannelReadInterval<T>)> dataChangedFn)
280  {
281  mDataChangedFn = NULL;
282  mDataIntervalChangedFn = dataChangedFn;
283  }
284 
285  template<typename Class>
287  {
288  mDataChangedFn = NULL;
289  mDataIntervalChangedFn = boost::bind(f, obj, _1);
290  }
291 
292  void setChannelChangedCallback(boost::function<void ()> channelChangedFn)
293  {
294  mChannelChangedFn = channelChangedFn;
295  }
296 
297  template<typename Class>
298  void setChannelChangedCallback(void (Class::*f)(), Class* obj)
299  {
300  mChannelChangedFn = boost::bind(f, obj);
301  }
302 
311  {
312  if(mChannelID.empty())
313  MIRA_THROW(XRuntime, "No channel specified.");
314 
315  if(!mChannel.isValid() && mAuthorityProvider!=NULL) {
316  Authority& authority = mAuthorityProvider->getAuthority();
317 
318  // here we will set the channel by subscribing the channel with
319  // the specified id, however, we will subscribe only if the channel
320  // exists to prevent creating a new channel
321  if(MIRA_FW.getChannelManager().hasChannel(mChannelID))
322  {
323  mChannel = authority.subscribe<T>(mChannelID, &ChannelProperty::callback, this);
324  mDataUpdates = MIRA_FW.getChannelManager().getNrOfDataChanges(mChannelID);
325  }
326  else
327  MIRA_THROW(XRuntime, "The channel '" << mChannelID << "' does not exist.");
328  mProcessedUpdates = -1; // see set()
329  }
330  return mChannel;
331  }
332 
333  virtual void update()
334  {
335  getChannel();
336  int64 updates = mDataUpdates;
337 
338  // - after update, before processing it: mDataUpdates > mProcessedUpdates
339  // - when mDataUpdates has overflown (uint32): mDataUpdates < mProcessedUpdates
340  // - after (re)initialization: mDataUpdates > mProcessedUpdates
341  if ((updates != mProcessedUpdates) && (mDataChangedFn || mDataIntervalChangedFn) )
342  {
343  mProcessedUpdates = updates;
344  if ( mDataChangedFn )
345  mDataChangedFn(mChannel.read());
346  else {
347  if ( !mLastUpdate.isValid() ) {
348  try {
349  mLastUpdate = mChannel.read()->timestamp-Duration::milliseconds(1);
350  }
351  catch ( XInvalidRead& ) {
352  return;
353  }
354  }
355  ChannelReadInterval<T> tInterval = mChannel.readInterval(mLastUpdate);
356  // we have to check if there actually is new data, even though mDataChanged is true:
357  // it happens we already read the newest data (triggered by a previous callback),
358  // then callback for the new data is executed _afterwards_ and increments mDataUpdates
359  if (!tInterval.empty())
360  {
361  mDataIntervalChangedFn( tInterval );
362  typename ChannelReadInterval<T>::const_iterator it = tInterval.end();
363  it--;
364  mLastUpdate = ((ChannelRead<T>)it)->timestamp;
365  }
366  }
367  }
368 
369  }
370 
371  void callback(ChannelRead<T> channel)
372  {
373  ++mDataUpdates;
374  }
375 
376 public:
377 
378 
384  template<typename Reflector>
385  static void channelProperty(Reflector& r, const std::string& name,
386  ChannelProperty& channel,
387  const std::string& comment, IAuthorityProvider* authorityProvider)
388  {
389  r.property(name.c_str(),
390  getter<ChannelPropertyProxy>(
391  boost::bind(proxyGetter, &channel, authorityProvider)),
392  setter<ChannelPropertyProxy>(
393  boost::bind(proxySetter, &channel, _1, authorityProvider)),
394  comment.c_str());
395  }
396 
397 private:
398 
400  static void proxySetter(ChannelProperty* This, const ChannelPropertyProxy& proxy,
401  IAuthorityProvider* authorityProvider) {
402  This->set(proxy.channelID, authorityProvider);
403  }
404 
406  static ChannelPropertyProxy proxyGetter(ChannelProperty* This,
407  IAuthorityProvider* authorityProvider) {
408  This->mAuthorityProvider = authorityProvider;
409  return ChannelPropertyProxy(This->mChannelID, This);
410  }
411 
412 private:
413 
414  Channel<T> mChannel;
415  uint32 mDataUpdates;
416  int64 mProcessedUpdates;
417  boost::function<void (ChannelRead<T>)> mDataChangedFn;
418  boost::function<void (ChannelReadInterval<T>)> mDataIntervalChangedFn;
419  boost::function<void ()> mChannelChangedFn;
420  Time mLastUpdate;
421 };
422 
423 
425 
427 class ChannelPropertyDelegateLineEdit : public QLineEdit
428 {
429 Q_OBJECT
430 public:
431  ChannelPropertyDelegateLineEdit(PropertyNode* p, QWidget* parent);
432 public slots:
433  void slotSetValue();
434 public:
436 };
437 
439 
440 }
441 
442 #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:75
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:435
ChannelPropertyProxy(const std::string &id, ChannelPropertyBase *p)
Definition: ChannelProperty.h:160
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:385
ChannelPropertyDelegateLineEdit(PropertyNode *p, QWidget *parent)
tick_type milliseconds() const
Returns normalized number of milliseconds (0..999)
Definition: Time.h:288
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:266
bool isValid() const
Returns true if this contains a valid time.
Definition: Time.h:583
std::string channelID
Definition: ChannelProperty.h:190
Class object which supports some kind of class reflection.
Definition: Class.h:97
IAuthorityProvider * mAuthorityProvider
Definition: ChannelProperty.h:140
void unsubscribe(const std::string &channelID)
Unsubscribe from a given channel.
std::string mName
Definition: ChannelProperty.h:138
#define MIRA_FW
Macro for accessing the framework instance.
Definition: Framework.h:73
bool isOptional() const
For internal use only.
Definition: ChannelProperty.h:116
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:310
An object that allows read access to data of a channel.
Definition: ChannelReadWrite.h:435
virtual std::list< std::pair< std::string, Typename > > getAvailableChannels()=0
Returns list of (channelID,typename) pairs containing the channels that match the desired type...
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:244
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:81
ChannelPropertyProxy()
Definition: ChannelProperty.h:159
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:286
ChannelProperty()
Definition: ChannelProperty.h:218
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:228
const std::string & getName() const
Returns the name of the property.
Definition: ChannelProperty.h:90
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:80
void setName(const std::string &name)
Sets the name of the property.
Definition: ChannelProperty.h:85
Base class for ChannelProperty template class.
Definition: ChannelProperty.h:70
ChannelPropertyBase()
Definition: ChannelProperty.h:74
Authorities act as a facade to the framework.
Definition: Authority.h:93
virtual uint32 getDataUpdateCount() const
Returns the number of data updates the channel has received.
Definition: ChannelProperty.h:232
Const iterator for iterating over the interval.
Definition: ChannelReadInterval.h:85
void setDataIntervalChangedCallback(boost::function< void(ChannelReadInterval< T >)> dataChangedFn)
Definition: ChannelProperty.h:279
void reflect(Reflector &r)
Definition: ChannelProperty.h:166
ChannelPropertyBase * property
Definition: ChannelProperty.h:191
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:236
void setChannelChangedCallback(boost::function< void()> channelChangedFn)
Definition: ChannelProperty.h:292
virtual void update()
Tell the property to update the assigned channel.
Definition: ChannelProperty.h:333
std::string mChannelID
Definition: ChannelProperty.h:139
virtual bool isValid() const =0
Returns true, if an existing channel is set. Must be implemented in derived class.
bool mOptional
Definition: ChannelProperty.h:141
The concrete typed ChannelProperty template class.
Definition: ChannelProperty.h:214
FrameworkVis export macro declaration.
virtual Authority & getAuthority()=0
Return the authority as reference.
void setChannelChangedCallback(void(Class::*f)(), Class *obj)
Definition: ChannelProperty.h:298
void setOptional()
For internal use only.
Definition: ChannelProperty.h:111
Abstract interface for classes that can provide an authority.
Special LineEdit for ChannelProperty delegate for Property Editor.
Definition: ChannelProperty.h:427
Proxy class that is returned/set by the getter and setter methods of ChannelProperty.
Definition: ChannelProperty.h:154
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:131
void setDataChangedCallback(void(Class::*f)(ChannelRead< T >), Class *obj)
Definition: ChannelProperty.h:273
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:173
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:182
virtual uint32 getDataUpdateCount() const =0
Returns the number of data updates the channel has received.
void callback(ChannelRead< T > channel)
Definition: ChannelProperty.h:371