WHISPER has a specific way to handle data. That means that both computing processes and data are some pre-defined WHISPER's objects.
A data handler (that processes data) has incoming and outgoing data streams
that consists of data blocks. Futhermore, each data handler is hold by a
chain (whisperChain
); introducing therefore another level of
flexibility.
Whenever a incoming block arrives, handler (which is a thread) is signaled,
and increments its waitingBlocks
shared variable. Then, each block
is readen through the incoming data stream's readNext(...)
method
and forwarded to one of the handle...
methods.
A data block is a typed array of characters with arbitrary length. Since
each data block can be read asynchronously by data handlers (inherited from
a nrtThread
), it has to be aware of the number of future reading
that are left.
When a block isn't useable anymore by any of its reading handlers, it is automaticaly deleted from the stream its belong to.
In WHISPER, a data stream consists of ordered independant data stream blocks.
Few methods are available to handle streams :
chain(int _type, char *_buffer, int _length)
and
*chain(rtDataStreamBlock *)
allows programmer to chain a new block
into the stream.
readNext(rtDataStreamBlock *)
returns the block following the given
block. But it hasn't to be called directly by programmer.
Some other facilities are providen to compute stream rate and such things.
A chain can hold many dependant data handlers. It has a name, and some convenience methods to report messages or errors.
Since whisperChain
class inherits nrtCyclicThread
, it
executes a virtual handle(void)
method periodicaly. By default,
this method does nothing.