launchWhenLifecycleStateAtLeast<T> method

Future<T> launchWhenLifecycleStateAtLeast<T>({
  1. LifecycleState targetState = LifecycleState.started,
  2. bool runWithDelayed = false,
  3. Cancellable? cancellable,
  4. required FutureOr<T> block(
    1. Cancellable cancellable
    ),
})

当高于某个状态时,执行一次给定的block

Implementation

Future<T> launchWhenLifecycleStateAtLeast<T>(
    {LifecycleState targetState = LifecycleState.started,
    bool runWithDelayed = false,
    Cancellable? cancellable,
    required FutureOr<T> Function(Cancellable cancellable) block}) {
  if (runWithDelayed == true && currentLifecycleState >= targetState) {
    Cancellable checkable = makeLiveCancellable(other: cancellable);
    if (checkable.isUnavailable) {
      return NeverExecFuture();
    }
    var result = block(checkable);
    if (result is Future<T>) {
      late final LifecycleObserver observer;
      observer = LifecycleObserver.stateChange((state) {
        if (state < targetState && checkable.isAvailable == true) {
          checkable.cancel();
          removeLifecycleObserver(observer, fullCycle: false);
        }
      });
      addLifecycleObserver(observer,
          fullCycle: true, startWith: currentLifecycleState);
      result.whenComplete(
          () => removeLifecycleObserver(observer, fullCycle: false));
      return result;
    } else {
      return Future.sync(() => result);
    }
  }

  Completer<T> completer = runWithDelayed ? Completer() : Completer.sync();

  Cancellable? checkable;
  late final LifecycleObserver observer;
  observer = LifecycleObserver.stateChange((state) async {
    if (state >= targetState && checkable == null) {
      checkable = makeLiveCancellable(other: cancellable);
      try {
        if (runWithDelayed) {
          await Future.delayed(Duration.zero);
        }
        if (checkable!.isUnavailable) {
          removeLifecycleObserver(observer, fullCycle: false);
          return;
        }
        checkable!.whenCancel.then(
            (value) => removeLifecycleObserver(observer, fullCycle: false));

        final result = block(checkable!);
        if (result is Future<T>) {
          await Future.delayed(Duration.zero);
          if (checkable?.isAvailable == true) {
            final r = await result;
            if (checkable?.isAvailable == true && !completer.isCompleted) {
              completer.complete(r);
            }
          }
        } else {
          completer.complete(result);
        }
      } catch (error, stackTree) {
        if (error != checkable?.reasonAsException && !completer.isCompleted) {
          completer.completeError(error, stackTree);
        }
      }
    } else if (state < targetState && checkable?.isAvailable == true) {
      checkable?.cancel();
    }
  });

  addLifecycleObserver(observer, fullCycle: true);
  final result = completer.future;
  result.whenComplete(
      () => removeLifecycleObserver(observer, fullCycle: false));
  return result;
}