#include "project_model.h" #include namespace { void setError(std::string *error, const std::string &message) { if (error != nullptr) { *error = message; } } // 通过相邻区间查找避免为不同领域对象重复实现标识唯一性校验 template bool containsDuplicateId(const std::vector &items) { for (auto current = items.cbegin(); current != items.cend(); ++current) { const auto duplicate = std::find_if( current + 1, items.cend(), [¤t](const TItem &item) { return item.id == current->id; }); if (duplicate != items.cend()) { return true; } } return false; } } // namespace bool Project::validate(std::string *error) const { if (metadata.id.empty() || metadata.name.empty() || metadata.formatVersion.empty()) { setError(error, "project id, name and format version must not be empty"); return false; } if (containsDuplicateId(hmiPages)) { setError(error, "HMI page ids must be unique within a project"); return false; } if (containsDuplicateId(controlLogics)) { setError(error, "control logic ids must be unique within a project"); return false; } for (auto current = dataPoints.cbegin(); current != dataPoints.cend(); ++current) { if (!current->validate(error)) { return false; } const auto duplicate = std::find_if( current + 1, dataPoints.cend(), [¤t](const DataPoint &candidate) { return candidate.address == current->address || candidate.name == current->name; }); if (duplicate != dataPoints.cend()) { if (error != nullptr) { *error = "data point addresses and names must be unique"; } return false; } } for (const HmiPage &page : hmiPages) { // 工程聚合校验会向下委托页面和控件的完整规则 if (!page.validate(error)) { return false; } } for (const ControlLogic &logic : controlLogics) { if (!logic.validate(error)) { return false; } } return true; } bool Project::validateForRunning(std::string *error) const { if (!validate(error)) { return false; } for (const HmiPage &page : hmiPages) { if (!page.validateForRunning(error)) { return false; } } for (const ControlLogic &logic : controlLogics) { if (!logic.validateForRunning(error)) { return false; } } return true; }