The BTimeSource
class represents a clock to which nodes can be slaved. By
slaving all your nodes to a single master time source, they can be kept
in sync with each other.
If a node can, either by design or as a side benefit of the underlying
hardware, provide reliable timing services, it might make sense for it to
be derived from
BTimeSource
as well as from whatever other classes it might be derived from, such as
BBufferProducer
or
BBufferConsumer
. Doing
so will allow other nodes to be slaved to your node's conception of time.
Note that although a
BTimeSource
is implemented as a real object (and is
therefore not a purely abstract class), other nodes won't call your
BTimeSource
's
member functions directly—instead, your
BTimeSource
will provide data that other nodes will then read.
There are invisible system implementations of the
BTimeSource
protocol
that serve as stand-ins for other nodes, so if you call
BMediaRoster::SetTimeSourceFor()
to make one of your nodes (which is derived
from BTimeSource
)
a time source for some other node, the other node might
see a system stand-in object, not the actual
BTimeSource
-derived
object.
This abstraction layer serves a valuable purpose: it enforces the desire to prevent any two nodes from having to know anything about each other beyond the Media Kit protocols defined in this chapter; this sort of low-level interdependency is discouraged, because it decreases interoperability.
Although it can be confusing at first, keep in mind that a node derived
from both BTimeSource
and BBufferProducer
(or
BBufferConsumer
)—which
is therefore a time source, as well as a producer or consumer of buffers—has
to deal with two different time concepts. As a
BTimeSource
,
it needs to understand requests in real time, while as a
BBufferProducer
or
BBufferConsumer
,
it needs to accept requests in performance time.
Real time refers to the actual passage of time, as reported by
system_time()
or the
BTimeSource::RealTime()
function. It's measured in microseconds.
Performance time runs in "time units" which aren't necessarily directly
related to real time. Since your code will have to deal with both kinds
of time, you need to be sure to convert between the two time systems when
it's necessary to do so. Use the
BTimeSource::RealTimeFor()
function to do this.
For example, to calculate a timeout value, given a desired performance time, and an estimated latency on the connection, you might use the following code:
bigtime_ttimeout
=TimeSource
()->RealTimeFor
(performance_time
,estimated_latency
) -TimeSource
()->RealTime
();
This code converts the performance_time
into the driving time source's
units, then subtracts the current real time, which results in the desired
timeout value.