Files
kuaishai2/lib/features/device/services/mock_runner.dart
Developer 5d28bf631b chore(project): 初始化项目基础配置文件
- 添加 CodeGraph、Android 和通用 gitignore 配置
- 创建项目元数据文件跟踪 Flutter 项目属性
- 添加 Codex AI 指导文档 AGENTS.md 说明项目架构
- 配置代码分析选项 analysis_options.yaml
- 设置 Android 应用清单权限和 Kiosk 模式配置
- 实现中英文国际化支持 AppLocalizations
- 配置 GoRouter 应用路由导航
- 创建明亮工业控制风格的主题配置 AppTheme
2026-06-04 11:19:44 +08:00

190 lines
4.6 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:async';
import '../../programs/models/step.dart';
import '../../programs/models/program.dart';
/// 模拟运行器回调
typedef RunProgressCallback = void Function(
int currentStepIndex,
int remainingSeconds,
double progress,
String currentWell,
);
typedef RunCompleteCallback = void Function();
/// 模拟运行器
/// 用于在没有实际硬件连接时模拟程序执行过程
class MockRunner {
Timer? _timer;
Program? _currentProgram;
List<Step> _steps = [];
int _currentStepIndex = 0;
int _remainingSeconds = 0;
bool _isPaused = false;
RunProgressCallback? _onProgress;
RunCompleteCallback? _onComplete;
/// 是否正在运行
bool get isRunning => _timer != null && !_isPaused;
/// 是否已暂停
bool get isPaused => _isPaused;
/// 当前程序
Program? get currentProgram => _currentProgram;
/// 开始运行程序
void start(
Program program,
List<Step> steps,
RunProgressCallback onProgress,
RunCompleteCallback onComplete,
) {
_currentProgram = program;
_steps = steps;
_onProgress = onProgress;
_onComplete = onComplete;
_currentStepIndex = 0;
_isPaused = false;
if (steps.isEmpty) {
onComplete();
return;
}
// 开始执行第一个步骤
_startStep(steps[0]);
}
/// 暂停运行
void pause() {
if (_timer != null && !_isPaused) {
_isPaused = true;
_timer!.cancel();
_timer = null;
}
}
/// 继续运行
void resume() {
if (_isPaused && _currentProgram != null) {
_isPaused = false;
_resumeStep();
}
}
/// 停止运行
void stop() {
_timer?.cancel();
_timer = null;
_currentProgram = null;
_steps = [];
_currentStepIndex = 0;
_remainingSeconds = 0;
_isPaused = false;
}
/// 开始执行步骤
void _startStep(Step step) {
// 计算步骤总时间(混合时间 + 吸磁时间 + 吹气时间)
_remainingSeconds = step.mixTime + step.magnetTime + step.blowTime;
// 如果步骤时间为0设置最小演示时间5秒
if (_remainingSeconds == 0) {
_remainingSeconds = 5;
}
// 启动定时器,每秒更新
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
_remainingSeconds--;
// 计算总进度
final totalSeconds = _calculateTotalSeconds();
final elapsedSeconds = _calculateElapsedSeconds();
final progress = totalSeconds > 0 ? elapsedSeconds / totalSeconds : 0.0;
// 回调进度更新
_onProgress?.call(
_currentStepIndex,
_remainingSeconds,
progress,
step.position,
);
// 步骤完成
if (_remainingSeconds <= 0) {
timer.cancel();
_timer = null;
_nextStep();
}
});
}
/// 继续执行步骤(从暂停恢复)
void _resumeStep() {
if (_currentStepIndex >= _steps.length) return;
final step = _steps[_currentStepIndex];
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
_remainingSeconds--;
final totalSeconds = _calculateTotalSeconds();
final elapsedSeconds = _calculateElapsedSeconds();
final progress = totalSeconds > 0 ? elapsedSeconds / totalSeconds : 0.0;
_onProgress?.call(
_currentStepIndex,
_remainingSeconds,
progress,
step.position,
);
if (_remainingSeconds <= 0) {
timer.cancel();
_timer = null;
_nextStep();
}
});
}
/// 执行下一个步骤
void _nextStep() {
_currentStepIndex++;
if (_currentStepIndex >= _steps.length) {
// 所有步骤完成
_onComplete?.call();
stop();
} else {
// 执行下一个步骤
_startStep(_steps[_currentStepIndex]);
}
}
/// 计算总执行时间
int _calculateTotalSeconds() {
int total = 0;
for (final step in _steps) {
int stepTime = step.mixTime + step.magnetTime + step.blowTime;
if (stepTime == 0) stepTime = 5;
total += stepTime;
}
return total;
}
/// 计算已执行时间
int _calculateElapsedSeconds() {
int elapsed = 0;
for (int i = 0; i < _currentStepIndex; i++) {
int stepTime = _steps[i].mixTime + _steps[i].magnetTime + _steps[i].blowTime;
if (stepTime == 0) stepTime = 5;
elapsed += stepTime;
}
// 加上当前步骤已执行的时间
final currentStep = _steps[_currentStepIndex];
int currentStepTime = currentStep.mixTime + currentStep.magnetTime + currentStep.blowTime;
if (currentStepTime == 0) currentStepTime = 5;
elapsed += currentStepTime - _remainingSeconds;
return elapsed;
}
}