63 lines
2.0 KiB
Dart
63 lines
2.0 KiB
Dart
import 'dart:async';
|
||
import 'dart:math' as math;
|
||
|
||
import '../domain/entities/reverse_camera_data.dart';
|
||
|
||
/// 倒车影像数据源抽象:UI/Cubit 只依赖这个流,不关心数据真假。
|
||
abstract class ReverseCameraSource {
|
||
Stream<ReverseCameraData> get dataStream;
|
||
void start();
|
||
Future<void> stop();
|
||
}
|
||
|
||
/// Mock 源:嵌入式未就绪前,制造会“动起来”的假数据用于联调动画。
|
||
///
|
||
/// 将来接入真实数据时,只需在 Cubit 里把这里换成基于
|
||
/// MQTT vehicleStream / TCP 0x02 回包解析的实现类,其余 UI / state 全不动。
|
||
class MockReverseCameraSource implements ReverseCameraSource {
|
||
final StreamController<ReverseCameraData> _controller =
|
||
StreamController<ReverseCameraData>.broadcast();
|
||
Timer? _timer;
|
||
final math.Random _rnd = math.Random();
|
||
int _tick = 0;
|
||
|
||
@override
|
||
Stream<ReverseCameraData> get dataStream => _controller.stream;
|
||
|
||
@override
|
||
void start() {
|
||
stop();
|
||
// ~15Hz 推送,动画足够顺滑;将来真数据 5~10Hz 也够用。
|
||
_timer = Timer.periodic(const Duration(milliseconds: 66), (Timer t) {
|
||
_tick++;
|
||
// 转向角做正弦摆动(模拟倒车打方向),速度小幅抖动,距离缓慢变化便于测颜色刻度。
|
||
final double sway = math.sin(_tick / 6.0) * 28.0; // -28° ~ +28°
|
||
final double speed = 0.3 + _rnd.nextDouble() * 0.5; // 0.3 ~ 0.8 m/s
|
||
final int dist = 40 + (_tick % 160); // 40 ~ 199cm,循环变化
|
||
_controller.add(
|
||
ReverseCameraData(
|
||
gear: 2, // 假数据默认处于“倒车挡”,进页面即可看到动画
|
||
steeringAngle: sway,
|
||
speed: speed,
|
||
rearDistanceCm: dist,
|
||
),
|
||
);
|
||
});
|
||
}
|
||
|
||
@override
|
||
Future<void> stop() async {
|
||
_timer?.cancel();
|
||
_timer = null;
|
||
if (!_controller.isClosed) {
|
||
_controller.add(const ReverseCameraData.idle());
|
||
}
|
||
}
|
||
|
||
/// 释放流控制器(Cubit close 时调用,避免资源泄漏)。
|
||
Future<void> dispose() async {
|
||
await stop();
|
||
await _controller.close();
|
||
}
|
||
}
|