MIRA
Public Member Functions | List of all members
Channel< T > Class Template Reference

An exception that occurs whenever a channel has no data. More...

#include <fw/Channel.h>

Public Member Functions

 Channel ()
 Create channel proxy that is not assigned to a channel. More...
 
 Channel (ConcreteChannel< T > *channel, ChannelAccessFlags accessFlags)
 Is used by Framework to create a channel proxy object. More...
 
void reset ()
 Reset the proxy object so that it becomes invalid. More...
 
bool isValid () const
 Returns true if the proxy object is valid. More...
 
void validate () const
 Checks if the channel is valid otherwise throws an exception. More...
 
Channel Information.

The following methods allow to obtain information on the channel (name, type, etc).

const std::string & getID () const
 Return the channel ID, its name. More...
 
int getTypeId () const
 Returns the type id of the channel. More...
 
bool isTyped () const
 Returns true, if the channel is typed and false, if it is untyped. More...
 
Typename getTypename () const
 Return the typename of the channel. More...
 
void setTypename (const Typename &type)
 Set the typename of this channel. More...
 
TypeMetaPtr getTypeMeta () const
 Return the type meta information for this channel. More...
 
void setTypeMeta (TypeMetaPtr meta)
 Set the type meta information for this channel. More...
 
Content information.

The following methods provide information on the channels content.

bool isEmpty () const
 Returns if the channel is empty (no data has been published) More...
 
bool hasSubscriber () const
 Returns true, if this channel has at least one subscriber. More...
 
bool hasPublisher () const
 Returns true, if this channel has at least one publisher. More...
 
bool hasSoloSlot () const
 Returns true, if this channel has one solo slot only. More...
 
std::size_t getMaxSlots () const
 Returns the upper limit of slots that are allowed for this channel. More...
 
std::size_t getMinSlots () const
 Returns the number slots that are guaranteed to be kept in the channel buffer. More...
 
Duration getStorageDuration () const
 Returns the timeframe that specifies how long a slot is guaranteed to be kept in the channel buffer. More...
 
bool isAutoIncreasingStorageDuration () const
 Returns whether the channel buffer is automatically increasing the storage duration. More...
 
std::size_t getNrOfSlots () const
 Returns how many slots (i.e. More...
 
Accessing the channels data.

The Channel provides different methods for reading and writing data in different flavors.

ChannelRead< T > waitForData (const Duration &timeout=Duration::infinity()) const
 Waits until data in this channel becomes available. More...
 
bool waitForPublisher (const Duration &timeout=Duration::infinity()) const
 Waits until this channel has at least one publisher. More...
 
ChannelRead< T > read ()
 Obtains read access to the latest data element of this channel. More...
 
ChannelRead< T > read (const Time &timestamp, SlotQueryMode mode=NEAREST_SLOT, const Duration &tolerance=Duration::infinity())
 Obtains read access to the element at the specified timestamp. More...
 
ChannelRead< T > read (uint32 sequenceID, const Duration &searchInterval=Duration::seconds(1))
 Obtains read access to the element with the specified sequenceID within the given search interval If no slot with the exact sequenceID exists within the search interval an XInvalidRead exception is thrown. More...
 
ChannelRead< T > read (const Time &timestamp, const Duration &tolerance)
 Same as above, but always takes the nearest slot. More...
 
ChannelReadInterval< T > readInterval (const Time &timestamp, std::size_t nrSlots, std::size_t olderSlots, std::size_t newerSlots, IntervalFillMode fillMode=PREFER_NEWER)
 Obtains read access to an interval of elements before and after the requested timestamp. More...
 
ChannelReadInterval< T > readInterval (const Time &from, const Time &to=Time::eternity())
 Obtains read access to an interval of elements in a given time span. More...
 
ChannelWrite< T > write ()
 Obtains exclusive write access to the next free data slot of this channel. More...
 
ChannelWrite< T > write (bool copyLatestData)
 Same as write above with an additional parameter copyLatestData that allows you to specify whether the channel should copy the latest data available into the write slot. More...
 
Stamped< T > get ()
 Returns the latest data from the channel by value. More...
 
Stamped< T > get (const Time &timestamp, SlotQueryMode mode=NEAREST_SLOT, const Duration &tolerance=Duration::infinity())
 Returns the data at the given time by value. More...
 
Stamped< T > get (const Time &timestamp, Duration tolerance)
 Same as above, but always takes the nearest slot. More...
 
template<typename Filter >
Stamped< T > get (const Time &timestamp, Filter &&filter)
 Returns the data at the given time by value. More...
 
template<typename U = void>
void post (const Stamped< T > &value)
 Writes the specified data into the channel. More...
 
template<typename U = void>
void post (Stamped< T > &&value)
 Same as above, for rvalue reference (move semantics) More...
 
template<typename U >
std::enable_if<!std::is_base_of_v< StampedHeader, std::decay_t< U > > >::type post (U &&value, const Time &timestamp=Time::now())
 Writes the specified data with the specified time stamp into the channel. More...
 
template<typename U = T>
std::enable_if<!std::is_void< U >::value >::type post (const typename ParamHelper< T >::type &value, const Time &timestamp=Time::now())
 This allows post({}, Time()); to deduce we want to post an object of the channel's type. More...
 
template<typename U = T>
std::enable_if<!std::is_void< U >::value >::type post (typename ParamHelper< T >::type &&value, const Time &timestamp=Time::now())
 Same as above, for rvalue reference (move semantics) More...
 

Detailed Description

template<typename T>
class mira::Channel< T >

An exception that occurs whenever a channel has no data.

A channel is a named data container that stores data of a certain type within a buffer.

forward decl for friend decl in Channel<T>

forward declaration

Each data element in the channel is called a slot. The channel manages the access to the data and ensures safe non-blocking access across different threads. Use read() and write() to obtain access to the channel data. Write access to the channel is non blocking. This means that data can be written to the channel while other threads still maintain read access to the data. For write access the channel returns the next free slot that is not locked by any pending write or read requests. Write and read access is allowed via ChannelRead and ChannelWrite objects only. They automatically take care that the data is unlocked at the right time and that the Channel is informed about changed data.

The signaling process is as follows:

  1. some Writing to Channels finished the write process (went out of scope, called its finish method etc.).
  2. the Channel calls ChannelSubscriber::signal() of all registered ChannelSubsribers to inform them that new data is available.
  3. Each ChannelSubscriber calls SubscriberHandler::signal() of its associated SubscriberHandler.
  4. The SubscriberHandler stores the ChannelSubscriber in an internal queue.
  5. Within the SubscriberHandler thread the SubscriberHandler calls ChannelSubscriber::invoke() of the ChannelSubscriber.
  6. the ChannelSubscriber finally calls the registered function that was assigned when it was constructed in Authority::subscribe()

This procedure ensures that type information won't get lost although the call. ChannelSubscriber are queued within the SubscriberHandler to decouple the threads.

Implementation notes:

This class is a proxy that allows restricted (based on access rights) access to ConcreteChannel to read or/and write data to channels.

Constructor & Destructor Documentation

◆ Channel() [1/2]

Channel ( )
inline

Create channel proxy that is not assigned to a channel.

◆ Channel() [2/2]

Channel ( ConcreteChannel< T > *  channel,
ChannelAccessFlags  accessFlags 
)
inline

Is used by Framework to create a channel proxy object.

Member Function Documentation

◆ reset()

void reset ( )
inline

Reset the proxy object so that it becomes invalid.

◆ isValid()

bool isValid ( ) const
inline

Returns true if the proxy object is valid.

Meaning if it points to a channel.

◆ validate()

void validate ( ) const
inline

Checks if the channel is valid otherwise throws an exception.

Exceptions
XAccessViolationIf channel is not valid.

◆ getID()

const std::string& getID ( ) const
inline

Return the channel ID, its name.

◆ getTypeId()

int getTypeId ( ) const
inline

Returns the type id of the channel.

The type id is unique only within the same process. Use getTypename() to get a portable type information.

◆ isTyped()

bool isTyped ( ) const
inline

Returns true, if the channel is typed and false, if it is untyped.

◆ getTypename()

Typename getTypename ( ) const
inline

Return the typename of the channel.

Used to obtain type of the contained binary data of untyped channels.

◆ setTypename()

void setTypename ( const Typename type)
inline

Set the typename of this channel.

Can be used when the channel is untyped to specify the type of contained binary data.

◆ getTypeMeta()

TypeMetaPtr getTypeMeta ( ) const
inline

Return the type meta information for this channel.

◆ setTypeMeta()

void setTypeMeta ( TypeMetaPtr  meta)
inline

Set the type meta information for this channel.

◆ isEmpty()

bool isEmpty ( ) const
inline

Returns if the channel is empty (no data has been published)

◆ hasSubscriber()

bool hasSubscriber ( ) const
inline

Returns true, if this channel has at least one subscriber.

◆ hasPublisher()

bool hasPublisher ( ) const
inline

Returns true, if this channel has at least one publisher.

◆ hasSoloSlot()

bool hasSoloSlot ( ) const
inline

Returns true, if this channel has one solo slot only.

◆ getMaxSlots()

std::size_t getMaxSlots ( ) const
inline

Returns the upper limit of slots that are allowed for this channel.

◆ getMinSlots()

std::size_t getMinSlots ( ) const
inline

Returns the number slots that are guaranteed to be kept in the channel buffer.

◆ getStorageDuration()

Duration getStorageDuration ( ) const
inline

Returns the timeframe that specifies how long a slot is guaranteed to be kept in the channel buffer.

◆ isAutoIncreasingStorageDuration()

bool isAutoIncreasingStorageDuration ( ) const
inline

Returns whether the channel buffer is automatically increasing the storage duration.

◆ getNrOfSlots()

std::size_t getNrOfSlots ( ) const
inline

Returns how many slots (i.e.

data objects) are currently stored in the channel buffer.

◆ waitForData()

ChannelRead<T> waitForData ( const Duration timeout = Duration::infinity()) const
inline

Waits until data in this channel becomes available.

If a timeout is specified, the method times out if no data becomes available after the given time.

Exceptions
XAccessViolationif channel has no read access rights
Parameters
[in]timeoutWait for this duration or forever if Duration::infinity() (default)
Returns
A valid ChannelRead, if data became available, or an invalid ChannelRead, if the method timed out or the thread was interrupted.

◆ waitForPublisher()

bool waitForPublisher ( const Duration timeout = Duration::infinity()) const
inline

Waits until this channel has at least one publisher.

If a timeout is specified, the method times out if no publisher becomes available after the given time.

Exceptions
XAccessViolationif channel has no read access rights
Parameters
[in]timeoutWait for this duration or forever if Duration::infinity() (default)
Returns
Returns true, if the wait was successfully and a publisher is available. If the wait timed out, false is returned.

◆ read() [1/4]

ChannelRead<T> read ( )
inline

Obtains read access to the latest data element of this channel.

Exceptions
XAccessViolationif channel has no read access rights
XInvalidReadwhen there is no data in the channel
Returns
ChannelRead object that has already locked the data. One can unlock the data manually or it is unlocked automatically when the ChannelRead object goes out of scope.

◆ read() [2/4]

ChannelRead<T> read ( const Time timestamp,
SlotQueryMode  mode = NEAREST_SLOT,
const Duration tolerance = Duration::infinity() 
)
inline

Obtains read access to the element at the specified timestamp.

If no slot with the exact timestamp exists (most of the time there will be no such slot) a slot will be chosen according to the query mode (see SlotQueryMode).

Internally calls ConcreteChannel::read().

Parameters
[in]timestampTimestamp of the desired slot.
[in]modeSpecifies whether the nearest, newer or older slot to the given timestamp should be used (default: nearest slot)
[in]toleranceThe max. allowed difference between the given timestamp and the best slot that was found (default: infinity)
Exceptions
XAccessViolationif channel has no read access rights
XInvalidReadwhen there is no data in the channel
Returns
ChannelRead object that has already locked the data. One can unlock the data manually or it is unlocked automatically when the ChannelRead object goes out of scope.

◆ read() [3/4]

ChannelRead<T> read ( uint32  sequenceID,
const Duration searchInterval = Duration::seconds(1) 
)
inline

Obtains read access to the element with the specified sequenceID within the given search interval If no slot with the exact sequenceID exists within the search interval an XInvalidRead exception is thrown.

Internally uses readInterval(newestSlotTime - searchInterval, newestSlotTime)

Parameters
[in]sequenceIDThe sequenceID of the desired slot.
[in]searchIntervalThe interval which is searched for the sequenceID (default: 1 second)
Exceptions
XAccessViolationif channel has no read access rights
XInvalidReadwhen there is no such sequenceID within the search interval the channel
Returns
ChannelRead object that has already locked the data. One can unlock the data manually or it is unlocked automatically when the ChannelRead object goes out of scope.

◆ read() [4/4]

ChannelRead<T> read ( const Time timestamp,
const Duration tolerance 
)
inline

Same as above, but always takes the nearest slot.

Internally calls ConcreteChannel::read().

◆ readInterval() [1/2]

ChannelReadInterval<T> readInterval ( const Time timestamp,
std::size_t  nrSlots,
std::size_t  olderSlots,
std::size_t  newerSlots,
IntervalFillMode  fillMode = PREFER_NEWER 
)
inline

Obtains read access to an interval of elements before and after the requested timestamp.

It is required that nrSlots >= olderSlots + newerSlots. The following the rules are applied:

  • The interval will contain nrSlots number of elements
  • The interval will contain olderSlots number of slots with a timestamp < requested timestamp (if they exist)
  • The interval will contain newerSlots number of slots with a timestamp >= requested timestamp (if they exist)
  • If the number of available older + newer slots is < nrSlots more slots are added according to the specified fillMode.
    • If fillMode == PREFER_OLDER, first older slots are added to the interval as needed. If there are not enough older slots, newer slots are added to the interval as needed.
    • If fillMode == PREFER_NEWER, first newer slots are added to the interval as needed. If there are not enough newer slots, older slots are added to the interval as needed.

Internally calls ConcreteChannel::readInterval().

Exceptions
XAccessViolationif channel has no read access rights
XRuntimewhen there are not enough slots available.
Returns
ChannelReadInterval object that has already locked all the data in the interval. One can unlock the data manually or it is unlocked automatically when the ChannelReadInterval object goes out of scope.

◆ readInterval() [2/2]

ChannelReadInterval<T> readInterval ( const Time from,
const Time to = Time::eternity() 
)
inline

Obtains read access to an interval of elements in a given time span.

  • The first element in the interval will be the first slot with a timestamp > from
  • The last element in the interval will be the last slot with a timestamp <= to So slot with timestamp = from is excluded and slot with timestamp = to is included in the interval.

Internally calls ConcreteChannel::readInterval().

Exceptions
XAccessViolationif channel has no read access rights
Returns
ChannelReadInterval object that has already locked all the data in the interval. One can unlock the data manually or it is unlocked automatically when the ChannelReadInterval object goes out of scope.

◆ write() [1/2]

ChannelWrite<T> write ( )
inline

Obtains exclusive write access to the next free data slot of this channel.

If no such slot exists the queue will grow until its maximum size. If all slots are locked and the queue has maximum size this method will block until a slot is released.

Internally calls ConcreteChannel::write().

Exceptions
XAccessViolationif channel has no write access rights
Returns
ChannelWrite object that has already locked the data. One can unlock the data manually or it is unlocked automatically when the ChannelWrite object goes out of scope. All subscribers will be notified.

◆ write() [2/2]

ChannelWrite<T> write ( bool  copyLatestData)
inline

Same as write above with an additional parameter copyLatestData that allows you to specify whether the channel should copy the latest data available into the write slot.

This is suitable whenever the caller wants to modify the latest data partially since it allows to omit an additional read call. To use this feature the caller must obtain read access, i.e. it must be a subscriber of the channel.

Internally calls ConcreteChannel::write().

Exceptions
XAccessViolationif channel has no write access rights
Returns
ChannelWrite object that has already locked the data. One can unlock the data manually or it is unlocked automatically when the ChannelWrite object goes out of scope. All subscribers will be notified.
Attention
If copyLatestData = true, this copies from the existing slot by creating a temporary copy (using copy construction), then assigning it to the new write slot (by operator=). Do not use this feature with channel types that need explicit deep copying (e.g. Img<> and subclasses)! In that case, get the ChannelRead explicitly and properly (deep) copy from it. In general, the internal copying is just for convenience, not efficiency.

◆ get() [1/4]

Stamped<T> get ( )
inline

Returns the latest data from the channel by value.

This method is provided to allow easy read access to the channel, however internally it leads to unnecessary copying of data and should be used for lightweight objects only. For large objects like range scans or images use the read() method to obtain read access without any performance penalties.

Internally calls ConcreteChannel::read().

Exceptions
XAccessViolationif channel has no read access rights
Returns
Latest stamped data from the channel

◆ get() [2/4]

Stamped<T> get ( const Time timestamp,
SlotQueryMode  mode = NEAREST_SLOT,
const Duration tolerance = Duration::infinity() 
)
inline

Returns the data at the given time by value.

This method is provided to allow easy read access to the channel, however internally it leads to unnecessary copying of data and should be used for lightweight objects only. For large objects like range scans or images use the read() method to obtain read access without any performance penalties.

Internally calls ConcreteChannel::read().

Exceptions
XAccessViolationif channel has no read access rights
Returns
Latest stamped data from the channel

◆ get() [3/4]

Stamped<T> get ( const Time timestamp,
Duration  tolerance 
)
inline

Same as above, but always takes the nearest slot.

Internally calls ConcreteChannel::read().

◆ get() [4/4]

Stamped<T> get ( const Time timestamp,
Filter &&  filter 
)
inline

Returns the data at the given time by value.

Moreover, this variant of the get method allows to specify a filter that is applied on the data, e.g. linear interpolation, etc.

The following example returns the value at timestamp t, where the value is linearly interpolated between two samples in the channel near the timestamp t:

myValue = myChannel.get(t, LinearInterpolator());

If you do not need filtering or interpolation you should use the get() method without a filter or the read() method for large objects to obtain direct read access without any performance penalties.

Exceptions
XAccessViolationif channel has no read access rights
Returns
Stamped interpolated data

◆ post() [1/5]

void post ( const Stamped< T > &  value)
inline

Writes the specified data into the channel.

This method is provided to allow easy write access to the channel, however internally it leads to unnecessary copying of data and should be used for lightweight objects only. For large objects like range scans or images use the write() method to obtain write access without any performance penalties.

Exceptions
XAccessViolationif channel has no write access rights

◆ post() [2/5]

void post ( Stamped< T > &&  value)
inline

Same as above, for rvalue reference (move semantics)

◆ post() [3/5]

std::enable_if<!std::is_base_of_v<StampedHeader, std::decay_t<U> > >::type post ( U &&  value,
const Time timestamp = Time::now() 
)
inline

Writes the specified data with the specified time stamp into the channel.

This method is provided to allow easy write access to the channel, however internally it leads to unnecessary copying of data and should be used for lightweight objects only. For large objects like range scans or images use the write() method to obtain write access without any performance penalties.

Exceptions
XAccessViolationif channel has no write access rights

◆ post() [4/5]

std::enable_if<!std::is_void<U>::value>::type post ( const typename ParamHelper< T >::type &  value,
const Time timestamp = Time::now() 
)
inline

This allows post({}, Time()); to deduce we want to post an object of the channel's type.

It will also make post({}) ambiguous instead of confidently posting a defaulted Stamped().

The ParamHelper indirection is required in order to avoid declaring a void reference as parameter type (for T=void).

◆ post() [5/5]

std::enable_if<!std::is_void<U>::value>::type post ( typename ParamHelper< T >::type &&  value,
const Time timestamp = Time::now() 
)
inline

Same as above, for rvalue reference (move semantics)


The documentation for this class was generated from the following file: