|
- #pragma once
-
- #include "domain/control_logic_model.h"
- #include "domain/register_repository.h"
-
- #include <chrono>
- #include <cstdint>
- #include <map>
- #include <string>
- #include <unordered_map>
- #include <utility>
- #include <vector>
-
- 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<std::string, bool> nodeValues;
- std::unordered_map<std::string, bool> nodePowerValues;
- std::unordered_map<std::string, bool> expressionValues;
- std::unordered_map<std::string, bool> expressionInputValues;
- std::unordered_map<std::string, bool> expressionPowerValues;
- std::unordered_map<std::string, bool> rungValues;
- std::unordered_map<std::string, TonTraceValue> tonValues;
- std::unordered_map<std::string, CounterTraceValue> counterValues;
- std::unordered_map<std::string, WordTraceValue> wordValues;
-
- void clear();
- };
-
- struct LogicTraceSnapshot : LogicTraceValues
- {
- std::unordered_map<std::string, LogicTraceValues> 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<ControlLogic> &logics) const;
- void resetRuntime();
- LogicScanResult executeScan(
- const std::vector<ControlLogic> &logics,
- RegisterRepository &repository,
- LogicTraceSnapshot *trace = nullptr);
- LogicScanResult executeScanAt(
- const std::vector<ControlLogic> &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<std::pair<std::string, std::string>, bool> previous_edge_inputs_;
- std::map<std::pair<std::string, std::string>, bool> previous_counter_inputs_;
- std::unordered_map<int, TonRuntimeState> ton_states_;
- struct CounterRuntimeState
- {
- bool done = false;
- };
- std::unordered_map<int, CounterRuntimeState> counter_states_;
- };
|