void OSSIADevice::removeNode(const State::Address& address) { using namespace OSSIA; if(!m_capas.canRemoveNode) return; if(!connected()) return; OSSIA::Node* node = getNodeFromPath(address.path, m_dev.get()); auto parent = node->getParent(); auto& parentChildren = node->getParent()->children(); auto it = std::find_if(parentChildren.begin(), parentChildren.end(), [&] (auto&& elt) { return elt.get() == node; }); if(it != parentChildren.end()) { /* If we are listening to this node, we recursively * remove listening to all the children. */ removeListening_impl(*it->get(), address); // TODO !! if we remove nodes while recording // (or anything involving a registered listening state), there will be crashes. // The Device Explorer should be locked for edition during recording / playing. parent->erase(it); } }
void OSSIADevice::updateAddress( const State::Address& currentAddr, const Device::FullAddressSettings &settings) { if(!connected()) return; OSSIA::Node* node = getNodeFromPath(currentAddr.path, m_dev.get()); auto newName = settings.address.path.last().toStdString(); if(newName != node->getName()) { node->setName(newName); } if(settings.value.val.which() == State::ValueType::NoValue) { removeOSSIAAddress(node); } else { auto currentAddr = node->getAddress(); if(currentAddr) updateOSSIAAddress(settings, node->getAddress()); else createOSSIAAddress(settings, node); } }
void OSSIADevice::updateAddress(const FullAddressSettings &settings) { using namespace OSSIA; QStringList path = settings.name.split("/"); path.removeFirst(); path.removeFirst(); OSSIA::Node* node = createNodeFromPath(path, m_dev.get()); updateOSSIAAddress(settings, node->getAddress()); }
auto add_setProperty(OSSIA::Node& n, const std::string& name, Callback cb) { constexpr const auto t = Ossia::convert::MatchingType<T>::val; std::shared_ptr<OSSIA::Node> node = *n.emplace( n.children().end(), name, t, OSSIA::AccessMode::SET); return make_setProperty<T>(node, node->getAddress(), cb); }
void OSSIADevice::removeAddress(const QString &address) { using namespace OSSIA; QStringList path = address.split("/"); path.removeFirst(); path.removeFirst(); OSSIA::Node* node = createNodeFromPath(path, m_dev.get()); auto& children = node->getParent()->children(); auto it = boost::range::find_if(children, [&] (auto&& elt) { return elt.get() == node; }); if(it != children.end()) children.erase(it); }
MetadataNamePropertyWrapper( OSSIA::Node& parent, ModelMetadata& arg_metadata, QObject* context ): metadata{arg_metadata} { node = *parent.emplace( parent.children().end(), arg_metadata.name().toStdString()); /* m_callbackIt = node->addCallback( [=] (const OSSIA::Node& node, const std::string& name, OSSIA::NodeChange t) { if(t == OSSIA::NodeChange::RENAMED) { auto str = QString::fromStdString(node.getName()); if(str != metadata.name()) metadata.setName(str); } }); */ auto setNameFun = [=] (const QString& newName_qstring) { auto newName = newName_qstring.toStdString(); auto curName = node->getName(); if(curName != newName) { node->setName(newName); auto real_newName = node->getName(); if(real_newName != newName) { metadata.setName(QString::fromStdString(real_newName)); } } }; QObject::connect( &metadata, &ModelMetadata::nameChanged, context, setNameFun, Qt::QueuedConnection); setNameFun(metadata.name()); }
OSSIA::Node* getNodeFromPath(const QStringList &path, OSSIA::Device *dev) { using namespace OSSIA; // Find the relevant node to add in the device OSSIA::Node* node = dev; for(int i = 0; i < path.size(); i++) { const auto& children = node->children(); auto it = boost::range::find_if(children, [&] (const auto& ossia_node) { return ossia_node->getName() == path[i].toStdString(); }); Q_ASSERT(it != children.end()); node = it->get(); } Q_ASSERT(node); return node; }
OSSIA::Node *createNodeFromPath(const QStringList &path, OSSIA::Device *dev) { using namespace OSSIA; // Find the relevant node to add in the device OSSIA::Node* node = dev; for(int i = 0; i < path.size(); i++) { const auto& children = node->children(); auto it = boost::range::find_if( children, [&] (const auto& ossia_node) { return ossia_node->getName() == path[i].toStdString(); }); if(it == children.end()) { // We have to start adding sub-nodes from here. OSSIA::Node* parentnode = node; for(int k = i; k < path.size(); k++) { auto newNodeIt = parentnode->emplace(parentnode->children().begin(), path[k].toStdString()); if(k == path.size() - 1) { node = newNodeIt->get(); } else { parentnode = newNodeIt->get(); } } break; } else { node = it->get(); } } return node; }
void OSSIADevice::removeListening_impl( OSSIA::Node& node, State::Address addr) { // Find & remove our callback auto it = m_callbacks.find(addr); if(it != m_callbacks.end()) { it->second.first->removeCallback(it->second.second); m_callbacks.erase(it); } // Recurse for(const auto& child : node.children()) { State::Address sub_addr = addr; sub_addr.path += QString::fromStdString(child->getName()); removeListening_impl(*child.get(), sub_addr); } }