\internal alreadyCalled stores the nodes that have been called at this node, and the inputExecIds it has been called at, to avoid infinite loops
| 143 | /// alreadyCalled stores the nodes that have been called at this node, and the inputExecIds it has |
| 144 | /// been called at, to avoid infinite loops |
| 145 | Result validatePath( |
| 146 | const NodeInstance& inst, int inExecId, |
| 147 | std::unordered_map<const NodeInstance*, std::vector<int> /*in Exec id*/> alreadyCalled) { |
| 148 | Result res; |
| 149 | |
| 150 | // if we've already been here, then return, it's a loop |
| 151 | { |
| 152 | auto iter = alreadyCalled.find(&inst); |
| 153 | if (iter != alreadyCalled.end() && |
| 154 | std::find(iter->second.begin(), iter->second.end(), inExecId) != iter->second.end()) { |
| 155 | return res; |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | // make sure the inputs are already in processed |
| 160 | auto id = 0ull; |
| 161 | for (const auto& conn : inst.inputDataConnections) { |
| 162 | if (conn.first == nullptr) { |
| 163 | res.addEntry("EUKN", "Node is missing an input data connection", |
| 164 | {{"Node ID", inst.stringId()}, |
| 165 | {"dataid", id}, |
| 166 | {"nodetype", inst.type().qualifiedName()}}); |
| 167 | ++id; |
| 168 | continue; |
| 169 | } |
| 170 | |
| 171 | if (!conn.first->type().pure() && alreadyCalled.find(conn.first) == alreadyCalled.end()) { |
| 172 | res.addEntry("EUKN", "Node that accepts data from another node is called first", |
| 173 | {{"Node ID", inst.stringId()}, {"othernodeid", conn.first->stringId()}}); |
| 174 | } |
| 175 | |
| 176 | ++id; |
| 177 | } |
| 178 | |
| 179 | alreadyCalled[&inst].push_back(inExecId); |
| 180 | |
| 181 | // call this on the nodes this calls |
| 182 | for (const auto& conn : inst.outputExecConnections) { |
| 183 | if (conn.first == nullptr) { continue; } |
| 184 | res += validatePath(*conn.first, conn.second, alreadyCalled); |
| 185 | } |
| 186 | |
| 187 | return res; |
| 188 | } |
| 189 | } // anonymous namespace |
| 190 | |
| 191 | Result validateFunctionNodeInputs(const GraphFunction& func) { |
no test coverage detected