#pragma once #include "domain/control_logic_model.h" #include #include class ProjectService; enum class LogicEditorError { None, LogicNotFound, RungNotFound, ExpressionNotFound, NodeNotFound, InvalidNode, InvalidOperation, UnsupportedNodeChange, DuplicateName, LastLogicRequired }; struct LogicEditorResult { bool succeeded = false; LogicEditorError error = LogicEditorError::None; std::string message; std::string id; }; class LogicEditorService { public: explicit LogicEditorService(ProjectService &project_service); const ControlLogic *findLogic(const std::string &logic_id) const; const LadderRung *findRung( const std::string &logic_id, const std::string &rung_id) const; const LogicNode *findNode( const std::string &logic_id, const std::string &node_id) const; const ConditionExpression *findExpression( const std::string &logic_id, const std::string &rung_id, const std::string &expression_id) const; std::string firstLogicId() const; std::string firstRungId(const std::string &logic_id) const; std::string rungIdForNode( const std::string &logic_id, const std::string &node_id) const; LogicEditorResult ensureDefaultLogic(); LogicEditorResult addLogic(const std::string &name); LogicEditorResult renameLogic( const std::string &logic_id, const std::string &name); LogicEditorResult removeLogic(const std::string &logic_id); LogicEditorResult moveLogic(const std::string &logic_id, int offset); LogicEditorResult setLogicEnabled(const std::string &logic_id, bool enabled); LogicEditorResult addRung(const std::string &logic_id); LogicEditorResult removeRung( const std::string &logic_id, const std::string &rung_id); LogicEditorResult appendCondition( const std::string &logic_id, const std::string &rung_id, const LogicNodeConfig &config); LogicEditorResult insertConditionAfter( const std::string &logic_id, const std::string &rung_id, const std::string &target_node_id, const LogicNodeConfig &config); LogicEditorResult addParallelBranch( const std::string &logic_id, const std::string &rung_id, const std::vector &selected_node_ids, const LogicNodeConfig &config); LogicEditorResult setOutput( const std::string &logic_id, const std::string &rung_id, const LogicNodeConfig &config); LogicEditorResult updateNodeConfig( const std::string &logic_id, const std::string &node_id, const LogicNodeConfig &config); LogicEditorResult removeNode( const std::string &logic_id, const std::string &node_id); LogicEditorResult removeExpression( const std::string &logic_id, const std::string &rung_id, const std::string &expression_id); private: static bool isConditionConfig(const LogicNodeConfig &config); static bool isOutputConfig(const LogicNodeConfig &config); static std::string nodePrefix(const LogicNodeConfig &config); static std::string makeUniqueNodeId( const ControlLogic &logic, const std::string &prefix); static std::string makeUniqueExpressionId(const ControlLogic &logic); static std::string makeUniqueRungId(const ControlLogic &logic); static LogicEditorResult failure( LogicEditorError error, const std::string &message); ProjectService &project_service_; };