|
- /**
- * @file runtime_mode_service.h
- * @brief 定义面向 UI 的运行模式服务契约
- * @version 0.1.0
- * @author suyu
- * @date 2026-08-08
- */
-
- #pragma once
-
- #include "domain/runtime_state.h"
- #include "offline_simulation_service.h"
- #include "online_logic_monitor_service.h"
- #include "plc_communication_gateway.h"
-
- #include <cstdint>
- #include <functional>
- #include <vector>
-
- class ProjectService;
- class ActiveRegisterRepository;
- class RegisterRepository;
-
- // 隔离 UI 与领域状态机,并编排寄存器仓库切换和进入真机的前置条件
- class RuntimeModeService
- {
- public:
- /**
- * @brief 创建运行模式服务
- * @param project_service 只读工程服务,用于运行前校验和收集轮询地址
- * @param offline_simulation_service 离线仿真服务,由应用层负责其生命周期
- */
- RuntimeModeService(
- const ProjectService &project_service,
- OfflineSimulationService &offline_simulation_service,
- OnlineLogicMonitorService &online_logic_monitor_service);
-
- /**
- * @brief 解除 PLC 网关回调绑定
- */
- ~RuntimeModeService();
-
- /** @brief 获取当前应用运行模式 */
- ApplicationMode mode() const;
- /**
- * @brief 获取当前模式下允许的工程编辑和寄存器使用策略
- * @return 与当前运行模式对应的能力策略
- */
- ModePolicy policy() const;
-
- /**
- * @brief 退出离线或真机运行态并返回编辑态
- * @return 已处于编辑态或状态机拒绝切换时返回失败结果
- */
- ModeTransitionResult enterEditing();
- /**
- * @brief 从编辑态进入离线运行态
- * @return 非编辑态进入时返回必须先回到编辑态的失败结果
- */
- ModeTransitionResult enterOfflineRunning();
- /**
- * @brief 从编辑态进入真机运行态
- * @return 未完成 PLC 初次读取或非编辑态进入时返回失败结果
- */
- ModeTransitionResult enterOnlineRunning();
-
- /**
- * @brief 更新 PLC 是否已完成首次有效读取
- * @param completed 为 true 时允许在编辑态进入真机运行模式
- *
- * 由 PLC 通信服务在首次读取成功或缓存失效时调用
- */
- void setInitialPlcReadCompleted(bool completed);
- /**
- * @brief 查询 PLC 是否已完成首次有效读取
- * @return 已建立可用于进入真机运行态的 PLC 缓存时返回 true
- */
- bool initialPlcReadCompleted() const;
-
- /** @brief 获取离线仿真当前状态 */
- SimulationState simulationState() const;
- /** @brief 获取离线仿真成功完成的扫描轮数 */
- std::uint64_t successfulScanCount() const;
- /** @brief 获取离线仿真最近一次扫描错误 */
- const LogicScanResult &simulationError() const;
- /** @brief 返回服务持有的离线仿真服务引用 */
- OfflineSimulationService &offlineSimulationService();
- OnlineLogicMonitorService &onlineLogicMonitorService();
-
- /**
- * @brief 注入 PLC 网关、活动仓库和两种实际数据源
- *
- * 应用生命周期内只调用一次;真机模式使用 PLC 仓库,编辑/离线模式使用虚拟仓库
- */
- void configurePlc(
- PlcCommunicationGateway &gateway,
- ActiveRegisterRepository &active_repository,
- RegisterRepository &virtual_repository,
- RegisterRepository &plc_repository);
- /**
- * @brief 连接 PLC 并开始异步通信
- * @param configuration 串口、Modbus 和轮询配置
- * @return 连接请求受理结果,不阻塞 UI 等待首读完成
- */
- PlcCommunicationResult connectPlc(const PlcSerialConfiguration &configuration);
-
- /**
- * @brief 设置自由监控引用的地址并刷新 PLC 轮询集合
- * @param addresses 自由监控当前需要读取的 M/D 地址
- */
- void setMonitorAddresses(const std::vector<RegisterAddress> &addresses);
- void setMonitorAddresses(
- const std::vector<RegisterAddress> &addresses,
- const std::vector<RegisterAddress> &float32_starts);
-
- /**
- * @brief 汇总工程和自由监控引用并刷新 PLC 轮询地址
- * @return 网关未配置或地址数量超限时返回失败结果
- */
- PlcCommunicationResult refreshPlcPollAddresses();
-
- /**
- * @brief 退出真机运行、断开 PLC 并清除首读资格
- */
- void disconnectPlc();
-
- /** @brief 获取当前 PLC 连接状态;网关未配置时返回 Disconnected */
- PlcConnectionState plcConnectionState() const;
-
- /** @brief 获取 PLC 最近一次通信错误文本;网关未配置时返回空字符串 */
- const std::string &plcError() const;
-
- /**
- * @brief 设置 PLC 状态变化通知回调
- * @param callback 状态、首读资格或通信错误变化时调用的函数;可传空函数取消通知
- */
- void setPlcStatusChangedCallback(std::function<void()> callback);
-
- private:
- const ProjectService &project_service_; // 不拥有的只读工程服务
- OfflineSimulationService &offline_simulation_service_; // 不拥有的离线仿真服务
- OnlineLogicMonitorService &online_logic_monitor_service_; // 不拥有的真机只读轨迹服务
- RuntimeState state_; // 编辑、离线和真机模式状态机
- // PLC 缓存是否已通过有效首读建立,通信故障时清除
- bool initial_plc_read_completed_ = false;
- PlcCommunicationGateway *plc_gateway_ = nullptr; // 不拥有的 PLC 通信网关
- ActiveRegisterRepository *active_repository_ = nullptr; // 当前模式使用的仓库代理
- RegisterRepository *virtual_repository_ = nullptr; // 离线/编辑模式的虚拟仓库
- RegisterRepository *plc_repository_ = nullptr; // 真机模式的 PLC 缓存仓库
- std::function<void()> plc_status_changed_callback_; // PLC 状态变化通知
- std::vector<RegisterAddress> monitor_addresses_; // 自由监控额外引用的地址
- std::vector<RegisterAddress> monitor_float32_starts_; // 自由监控中的 Float32 起始地址
- };
|