void NodeTree::handleException(NodeID nodeID, const NodeSocketTracer& tracer) { // Exception dispatcher pattern try { _executeListDirty = true; throw; } catch(ExecutionError&) { // Dummy but a must - if not std::exception handler would catch it throw; } catch(BadConnectionException& ex) { if (tracer.isLastOutput()) // Means node tried to acquired socket // with different type than declared in config throw BadConfigException(); ex.node = tracer.lastNode(); ex.socket = tracer.lastSocket(); throw; } catch(cv::Exception& ex) { throw ExecutionError(nodeName(nodeID), nodeTypeName(nodeID), std::string("OpenCV exception - ") + ex.what()); } catch(std::exception& ex) { throw ExecutionError(nodeName(nodeID), nodeTypeName(nodeID), ex.what()); } }
void NodeTree::execute(bool withInit) { if(_executeListDirty) prepareList(); NodeSocketTracer tracer; NodeSocketReader reader(this, tracer); NodeSocketWriter writer(tracer); // Traverse through just-built exec list and process each node for(NodeID nodeID : _executeList) { Node& node = _nodes[nodeID]; tracer.setNode(nodeID); reader.setNode(nodeID, node.numInputSockets()); try { if(withInit && _nodes[nodeID].flag(ENodeFlags::StateNode)) { // Try to restart node internal state if any if(!node.restart()) { throw ExecutionError{node.nodeName(), nodeTypeName(nodeID), "Error during node state restart"}; } } ExecutionStatus ret = node.execute(reader, writer); switch (ret.status) { case EStatus::Tag: // Tag for next execution tagNode(nodeID); break; case EStatus::Error: // If node reported an error tagNode(nodeID); throw ExecutionError{node.nodeName(), nodeTypeName(nodeID), ret.message}; break; case EStatus::Ok: default: break; } } catch(...) { handleException(nodeID, tracer); } } _executeListDirty = true; }
void doWork() override { if (!hasWork()) return; NodeID nodeID = currentNode(); Node& node = _nodeTree->_nodes[nodeID]; _tracer.setNode(nodeID); _reader.setNode(nodeID, node.numInputSockets()); try { if(_withInit && node.flag(ENodeFlags::StateNode)) { // Try to restart node internal state if any if(!node.restart()) { throw ExecutionError{node.nodeName(), nodeTypeName(nodeID), "Error during node state restart"}; } } ExecutionStatus ret = node.execute(_reader, _writer); switch (ret.status) { case EStatus::Tag: // Tag for next execution tagNode(nodeID); break; case EStatus::Error: // If node reported an error tagNode(nodeID); throw ExecutionError{node.nodeName(), nodeTypeName(nodeID), ret.message}; break; case EStatus::Ok: default: break; } ++_pos; } catch (...) { _nodeTree->handleException(nodeID, _tracer); } }
QJsonObject jsonObjectForNode(Node* node) { QJsonObject nodeJson; // re-format the type name so it matches the target name QString nodeTypeName(node->getTypeName()); nodeTypeName = nodeTypeName.toLower(); nodeTypeName.replace(' ', '-'); // add the node type nodeJson[JSON_KEY_TYPE] = nodeTypeName; // add the node socket information nodeJson[JSON_KEY_PUBLIC_SOCKET] = jsonForSocket(node->getPublicSocket()); nodeJson[JSON_KEY_LOCAL_SOCKET] = jsonForSocket(node->getLocalSocket()); // if the node has pool information, add it if (node->getLinkedData() && ((Assignment*) node->getLinkedData())->hasPool()) { nodeJson[JSON_KEY_POOL] = QString(((Assignment*) node->getLinkedData())->getPool()); } return nodeJson; }