handlePointerEventRecord method Null safety

  1. @override
Future<List<Duration>> handlePointerEventRecord(
  1. List<PointerEventRecord> records
)
override

A simulator of how the framework handles a series of PointerEvents received from the Flutter engine.

The PointerEventRecord.timeDelay is used as the time delay of the events injection relative to the starting point of the method call.

Returns a list of the difference between the real delay time when the PointerEventRecord.events are processed and PointerEventRecord.timeDelay.

The closer the return values are to zero the more faithful it is to the records.

See PointerEventRecord.

Implementation

@override
Future<List<Duration>> handlePointerEventRecord(List<PointerEventRecord> records) {
  assert(records != null);
  assert(records.isNotEmpty);
  return TestAsyncUtils.guard<List<Duration>>(() async {
    // hitTestHistory is an equivalence of _hitTests in [GestureBinding],
    // used as state for all pointers which are currently down.
    final Map<int, HitTestResult> hitTestHistory = <int, HitTestResult>{};
    final List<Duration> handleTimeStampDiff = <Duration>[];
    DateTime? startTime;
    for (final PointerEventRecord record in records) {
      final DateTime now = clock.now();
      startTime ??= now;
      // So that the first event is promised to receive a zero timeDiff
      final Duration timeDiff = record.timeDelay - now.difference(startTime);
      if (timeDiff.isNegative) {
        // This happens when something (e.g. GC) takes a long time during the
        // processing of the events.
        // Flush all past events
        handleTimeStampDiff.add(-timeDiff);
        record.events.forEach(binding.handlePointerEvent);
      } else {
        await Future<void>.delayed(timeDiff);
        handleTimeStampDiff.add(
          // Recalculating the time diff for getting exact time when the event
          // packet is sent. For a perfect Future.delayed like the one in a
          // fake async this new diff should be zero.
          clock.now().difference(startTime) - record.timeDelay,
        );
        record.events.forEach(binding.handlePointerEvent);
      }
    }
    // This makes sure that a gesture is completed, with no more pointers
    // active.
    assert(hitTestHistory.isEmpty);
    return handleTimeStampDiff;
  });
}