attach method

Stream<AutoExpResult> attach(
  1. Stream<List<int>> dataResponse
)

Attach this RxAutoExpResult to the Frame's dataResponse characteristic stream.

Implementation

Stream<AutoExpResult> attach(Stream<List<int>> dataResponse) {
  // TODO check for illegal state - attach() already called on this RxAutoExpResult etc?
  // might be possible though after a clean close(), do I want to prevent it?

  // the subscription to the underlying data stream
  StreamSubscription<List<int>>? dataResponseSubs;

  // Our stream controller that transforms/accumulates the raw tap events into multi-taps
  _controller = StreamController();

  _controller!.onListen = () {
    dataResponseSubs = dataResponse
      .where((data) => data[0] == autoExpFlag)
      .listen((data) {
        // parse the metering data from the raw data
        _log.finer('auto exposure result detected');

        // Ensure the data length is sufficient
        if (data.length < 65) {
          _log.warning('Insufficient data length for AutoExpResult: ${data.length}');
          return;
        }

        // Extract the relevant data (bytes 1 to 65)
        List<int> relevantData = data.sublist(1, 65);

        // Create a ByteData object from the relevant data
        ByteData byteData = ByteData.sublistView(Uint8List.fromList(relevantData));

        // Unpack the data as 16 float32 values
        List<double> unpacked = List.generate(16, (i) => byteData.getFloat32(i * 4, Endian.little));

        _controller!.add(AutoExpResult(
          error: unpacked[0],
          shutter: unpacked[1],
          analogGain: unpacked[2],
          redGain: unpacked[3],
          greenGain: unpacked[4],
          blueGain: unpacked[5],
          brightness: Brightness(
            centerWeightedAverage: unpacked[6],
            scene: unpacked[7],
            matrix: Matrix(
              r: unpacked[8],
              g: unpacked[9],
              b: unpacked[10],
              average: unpacked[11],
            ),
            spot: Spot(
              r: unpacked[12],
              g: unpacked[13],
              b: unpacked[14],
              average: unpacked[15],
            ),
          ),
        ));
    }, onDone: _controller!.close, onError: _controller!.addError);
    _log.fine('AutoExposureResultDataResponse stream subscribed');
  };

  _controller!.onCancel = () {
    _log.fine('AutoExposureResultDataResponse stream unsubscribed');
    dataResponseSubs?.cancel();
    _controller!.close();
  };

  return _controller!.stream;
}