#pragma once #include "domain/control_logic_model.h" #include "domain/register_repository.h" #include #include #include #include #include #include #include enum class LogicScanError { None, InvalidLogic, ConflictingOutput, RegisterReadFailed, RegisterWriteFailed }; struct LogicScanResult { bool succeeded = false; LogicScanError error = LogicScanError::None; std::string message; std::string logicId; std::string rungId; std::string nodeId; }; struct TonTraceValue { bool input = false; bool done = false; std::int64_t elapsedMs = 0; int presetMs = 0; }; struct CounterTraceValue { bool input = false; bool reset = false; bool done = false; std::int16_t value = 0; std::int16_t preset = 0; }; struct WordTraceValue { std::int16_t value = 0; bool overflow = false; }; struct LogicTraceValues { std::unordered_map nodeValues; std::unordered_map nodePowerValues; std::unordered_map expressionValues; std::unordered_map expressionInputValues; std::unordered_map expressionPowerValues; std::unordered_map rungValues; std::unordered_map tonValues; std::unordered_map counterValues; std::unordered_map wordValues; void clear(); }; struct LogicTraceSnapshot : LogicTraceValues { std::unordered_map logicValues; void clear(); LogicTraceSnapshot forLogic(const std::string &logic_id) const; }; // 按工程顺序执行受限梯形图的一次确定性扫描 class SoftwareLogicExecutor { public: using Clock = std::chrono::steady_clock; using TimePoint = Clock::time_point; LogicScanResult validate(const std::vector &logics) const; void resetRuntime(); LogicScanResult executeScan( const std::vector &logics, RegisterRepository &repository, LogicTraceSnapshot *trace = nullptr); LogicScanResult executeScanAt( const std::vector &logics, RegisterRepository &repository, TimePoint now, LogicTraceSnapshot *trace = nullptr); private: struct TonRuntimeState { bool timing = false; bool done = false; TimePoint startedAt{}; std::chrono::milliseconds elapsed{0}; }; LogicScanResult evaluateCondition( const std::string &logic_id, const LogicNode &node, RegisterRepository &repository, bool *value); LogicScanResult evaluateExpression( const std::string &logic_id, const ConditionExpression &expression, RegisterRepository &repository, LogicTraceValues *trace, bool input_power, bool *value); LogicScanResult executeOutput( const std::string &logic_id, const LogicNode &node, bool rung_value, RegisterRepository &repository, TimePoint now, LogicTraceValues *trace, bool *output_value); LogicScanResult readWordOperand( const WordOperand &operand, RegisterRepository &repository, std::int16_t *value, const std::string &node_id) const; std::map, bool> previous_edge_inputs_; std::map, bool> previous_counter_inputs_; std::unordered_map ton_states_; struct CounterRuntimeState { bool done = false; }; std::unordered_map counter_states_; };