import 'dart:async'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/database/database_service.dart'; import '../models/serial_config.dart'; import '../services/auto_serial_connect.dart'; import '../services/device_message_service.dart'; import '../services/json_protocol.dart'; import '../services/runner_interface.dart'; import '../services/serial_port_service.dart'; import '../services/serial_runner.dart'; /// 串口服务单例 final serialPortServiceProvider = Provider((ref) { final service = SerialPortService(); ref.onDispose(service.dispose); return service; }); /// 串口连接状态(响应式) /// /// 直接 `ref.watch(serialPortServiceProvider).state` 不会触发 UI 重建, /// 因为 [SerialPortService] 内部 `_state` 的变化不会冒泡到 Provider 层。 /// 这里把状态抽出为独立的 StateNotifierProvider,让状态栏等 UI 能即时 /// 反映连接/断开事件,避免出现"标题栏显示已连接、实际下发失败"的错觉。 class SerialConnectionStateNotifier extends StateNotifier { SerialConnectionStateNotifier(this._service) : super(_service.state) { _sub = _service.connectionStateChanges.listen((s) => state = s); } final SerialPortService _service; late final StreamSubscription _sub; @override void dispose() { _sub.cancel(); super.dispose(); } } final serialConnectionStateProvider = StateNotifierProvider< SerialConnectionStateNotifier, SerialConnectionState>((ref) { final service = ref.watch(serialPortServiceProvider); return SerialConnectionStateNotifier(service); }); /// 启动自动连接服务 /// /// 通过 [main] 中的 ProviderContainer 在 runApp 之前触发一次, /// 服务内部立即尝试连接第一个 USB 串口设备,失败时按 3s 间隔重试。 final autoSerialConnectProvider = Provider((ref) { final service = ref.watch(serialPortServiceProvider); final auto = AutoSerialConnect(service); auto.start(); ref.onDispose(auto.dispose); return auto; }); /// JSON 协议编解码器(可在调试/真机协议不一致时整体替换) final jsonProtocolProvider = Provider((ref) { return JsonProtocolService(); }); /// 设备消息分发服务 /// /// 集中处理 JSON 消息的发送与订阅;下游 Provider 各自订阅感兴趣的类型。 final deviceMessageServiceProvider = Provider((ref) { final serial = ref.watch(serialPortServiceProvider); final protocol = ref.watch(jsonProtocolProvider); final service = DeviceMessageService(serial: serial, protocol: protocol); ref.onDispose(service.dispose); return service; }); /// 当前串口配置(设置页修改后通过 notifier 写入并持久化) class SerialConfigNotifier extends StateNotifier { final SettingsConfigRepository _repo; SerialConfigNotifier(this._repo) : super(SerialConfig.defaults) { _load(); } Future _load() async { state = await _repo.read(); } /// 修改并持久化 Future update(SerialConfig Function(SerialConfig) mutator) async { final next = mutator(state); state = next; await _repo.write(next); } /// 重置为默认值 Future reset() => update((_) => SerialConfig.defaults); } /// 串口配置仓库:把 [SerialConfig] 以 JSON 形式存到 settings 表 class SettingsConfigRepository { static const _key = 'serial_config'; final DatabaseService _db = DatabaseService.instance; Future read() async { final raw = await _db.readSetting(_key); return SerialConfig.fromJsonString(raw); } Future write(SerialConfig config) async { await _db.writeSetting(_key, config.toJsonString()); } } final serialConfigProvider = StateNotifierProvider((ref) { return SerialConfigNotifier(SettingsConfigRepository()); }); /// 运行器实例(基于 JSON 协议与设备消息服务) final runnerProvider = Provider((ref) { final msgService = ref.watch(deviceMessageServiceProvider); return JsonSerialRunner(messageService: msgService); });