handleClassEnd method

Future<bool> handleClassEnd(
  1. Object? event
)

切换入口:preparing → switching → (retrying)* → idle / failed。

返回 true 表示切换流程已接管;返回 false 表示调用方应继续原有结束课堂流程。

event 仅作日志/扩展占位,当前未使用。

Implementation

Future<bool> handleClassEnd(Object? event) async {
  final env = _env;
  if (env == null) return false;

  if (status.value.state != SwitchState.idle) return false;
  if (!env.classSwitchEnabled()) return false;

  final from = env.currentClassId().trim();
  final next = env.nextClassId()?.trim();
  if (next == null || next.isEmpty) return false;
  if (next == from) return false;

  // preparing
  status.value = status.value.copyWith(
    state: SwitchState.preparing,
    currentClassId: from,
    targetClassId: next,
    retryCount: 0,
    clearError: true,
  );

  _cancelled = false;

  // switching(首次)
  status.value = status.value.copyWith(state: SwitchState.switching);
  final firstErr = await _tryPerform(env, next);
  if (firstErr == null) {
    status.value = status.value.copyWith(
      state: SwitchState.idle,
      currentClassId: next,
      clearError: true,
    );
    return true;
  }
  if (shouldFallbackToClassEnd(firstErr)) {
    reset();
    return false;
  }
  if (!firstErr.retryable) {
    return _markFailedAndFallback(firstErr);
  }
  if (_cancelled) {
    _markFailed(firstErr);
    return true;
  }

  // 重试循环(最多 maxRetry 次)
  ClassSwitchError lastErr = firstErr;
  for (int i = 1; i <= maxRetry; i++) {
    if (_cancelled) {
      _markFailed(lastErr);
      return true;
    }
    await Future.delayed(retryDelay);
    if (_cancelled) {
      _markFailed(lastErr);
      return true;
    }
    status.value = status.value.copyWith(
      state: SwitchState.retrying,
      retryCount: i,
      errorCode: lastErr.code,
      errorMessage: lastErr.message,
    );
    final err = await _tryPerform(env, next);
    if (err == null) {
      status.value = status.value.copyWith(
        state: SwitchState.idle,
        currentClassId: next,
        clearError: true,
      );
      return true;
    }
    if (shouldFallbackToClassEnd(err)) {
      reset();
      return false;
    }
    lastErr = err;
    if (!err.retryable) {
      return _markFailedAndFallback(err);
    }
  }

  return _markFailedAndFallback(lastErr);
}