std::vector<Port> resolvePortsFromTopology(const Pothos::Topology &t, const std::string &portName, const bool isSource) { std::vector<Port> ports; for (const auto &flow : t._impl->flows) { //recurse through sub topology flows std::vector<Port> subPorts; if (isSource and flow.dst.name == portName and not flow.dst.obj) { if (flow.src.obj) subPorts = resolvePorts(flow.src, isSource); else ports.push_back(flow.src); } if (not isSource and flow.src.name == portName and not flow.src.obj) { if (flow.dst.obj) subPorts = resolvePorts(flow.dst, isSource); else ports.push_back(flow.dst); } ports.insert(ports.end(), subPorts.begin(), subPorts.end()); } return ports; }
static bool flattenDump(Poco::JSON::Object::Ptr &topObj) { assert(topObj); bool hierFound = false; //create new blocks object that flattens any hierarchy to 1 depth //if this block is a hierarchy -- bring its blocks to the top level const auto blocksObj = topObj->getObject("blocks"); assert(blocksObj); Poco::JSON::Object::Ptr flatBlocksObj(new Poco::JSON::Object()); std::vector<std::string> blockUids; blocksObj->getNames(blockUids); for (const auto &uid : blockUids) { const auto blockObj = blocksObj->getObject(uid); assert(blockObj); if (blockIsHier(blockObj)) { hierFound = true; const auto subBlocksObj = blockObj->getObject("blocks"); assert(subBlocksObj); const auto thisName = blockObj->getValue<std::string>("name"); std::vector<std::string> subBlockUids; subBlocksObj->getNames(subBlockUids); for (const auto &subUid : subBlockUids) { auto subBlockObj = subBlocksObj->getObject(subUid); assert(subBlockObj); const auto subName = subBlockObj->getValue<std::string>("name"); subBlockObj->set("name", thisName+"/"+subName); //heritage name flatBlocksObj->set(subUid, subBlockObj); } } else flatBlocksObj->set(uid, blockObj); } //create new connections array folding out depth 1 hierarchies const auto connsArray = topObj->getArray("connections"); assert(connsArray); Poco::JSON::Array::Ptr flatConnsArray(new Poco::JSON::Array()); for (size_t c_i = 0; c_i < connsArray->size(); c_i++) { const auto connObj = connsArray->getObject(c_i); assert(connObj); for (const auto & resolvedSrc : resolvePorts(topObj, connObj->getValue<std::string>("srcId"), connObj->getValue<std::string>("srcName"), true)) { for (const auto & resolvedDst : resolvePorts(topObj, connObj->getValue<std::string>("dstId"), connObj->getValue<std::string>("dstName"), false)) { Poco::JSON::Object::Ptr flatConnObj(new Poco::JSON::Object()); flatConnsArray->add(flatConnObj); flatConnObj->set("srcId", resolvedSrc.first); flatConnObj->set("srcName", resolvedSrc.second); flatConnObj->set("dstId", resolvedDst.first); flatConnObj->set("dstName", resolvedDst.second); } } } //resolve pass-through connections and totally internal connections for (const auto &uid : blockUids) { const auto blockObj = blocksObj->getObject(uid); assert(blockObj); if (not blockIsHier(blockObj)) continue; const auto subConnsArray = blockObj->getArray("connections"); for (size_t c_i = 0; c_i < subConnsArray->size(); c_i++) { const auto subConnObj = subConnsArray->getObject(c_i); assert(subConnObj); const bool srcIsThis = subConnObj->getValue<std::string>("srcId") == uid; const bool dstIsThis = subConnObj->getValue<std::string>("dstId") == uid; //totally internal connection if (not srcIsThis and not dstIsThis) flatConnsArray->add(subConnObj); //otherwise not a pass-through if (not srcIsThis or not dstIsThis) continue; //find sources where the destination is this pass-through for (size_t c_s = 0; c_s < connsArray->size(); c_s++) { const auto connObj_s = connsArray->getObject(c_s); assert(connObj_s); if (connObj_s->getValue<std::string>("dstId") != uid) continue; if (connObj_s->getValue<std::string>("dstName") != subConnObj->getValue<std::string>("srcName")) continue; //find sources where the destination is this pass-through for (size_t c_d = 0; c_d < connsArray->size(); c_d++) { const auto connObj_d = connsArray->getObject(c_d); assert(connObj_d); if (connObj_d->getValue<std::string>("srcId") != uid) continue; if (connObj_d->getValue<std::string>("srcName") != subConnObj->getValue<std::string>("dstName")) continue; Poco::JSON::Object::Ptr flatConnObj(new Poco::JSON::Object()); flatConnsArray->add(flatConnObj); flatConnObj->set("srcId", connObj_s->get("srcId")); flatConnObj->set("srcName", connObj_s->get("srcName")); flatConnObj->set("dstId", connObj_d->get("dstId")); flatConnObj->set("dstName", connObj_d->get("dstName")); } } } } //set new flat data into the top object topObj = new Poco::JSON::Object(); topObj->set("blocks", flatBlocksObj); topObj->set("connections", flatConnsArray); return hierFound; }