decodeSample method

  1. @override
IMessage<IMessageType>? decodeSample(
  1. Uint8List frame,
  2. String fromNodeUId
)
override

Builds a message from a binary sample frame sent by fromNodeUId.

The sender's identity is a parameter here rather than read out of the frame, as the WebSocket transport reads it out of the slot: the channel the frame arrived on already names its peer, exactly and without a lookup table.

Implementation

@override
IMessage? decodeSample(Uint8List frame, String fromNodeUId) {
  final channels = WsSampleFrame.decodeChannels(frame, config.channels);
  final timestamp = DateTime.now();
  final offsets = clockOffsets;
  final sourceClock = WsSampleFrame.senderMicrosOf(frame) / 1e6;
  // Null until the estimator has accepted a burst for this peer, which
  // keeps transitSeconds null rather than reporting the difference of two
  // unrelated monotonic clocks.
  var clockOffset = offsets?.offsetFor(fromNodeUId);
  var uncertainty = offsets?.uncertaintyFor(fromNodeUId);
  ClockChain? upstream;
  if (WsSampleFrame.isRelayed(frame)) {
    // Stamped by its origin: the way from there to the sender comes first,
    // and until the sender has said what it is the offset is unknown.
    upstream = _upstreams[fromNodeUId];
    clockOffset = upstream == null || clockOffset == null
        ? null
        : upstream.offsetAt(sourceClock) + clockOffset;
    uncertainty = upstream == null || uncertainty == null
        ? null
        : upstream.uncertainty + uncertainty;
  }
  final timing = MessageTiming(
    sourceClock: sourceClock,
    clockOffset: clockOffset,
    uncertainty: uncertainty,
    receivedClock: PeerClock.now(),
    sourceId: fromNodeUId,
    upstream: upstream,
  );
  switch (config.dataType) {
    case StreamDataType.float32:
    case StreamDataType.double64:
      return MessageFactory.double64Message(
        data: IList(channels.map((v) => (v! as num).toDouble())),
        channels: config.channels,
        timestamp: timestamp,
        timing: timing,
      );
    case StreamDataType.int8:
    case StreamDataType.int16:
    case StreamDataType.int32:
    case StreamDataType.int64:
      return MessageFactory.int64Message(
        data: IList(channels.cast<int>()),
        channels: config.channels,
        timestamp: timestamp,
        timing: timing,
      );
    case StreamDataType.string:
      return MessageFactory.stringMessage(
        data: IList(channels.cast<String>()),
        channels: config.channels,
        timestamp: timestamp,
        timing: timing,
      );
  }
}