void Namespace::connect(const scene::INodePtr& root) { // Now traverse the subgraph and connect the nodes ConnectNamespacedWalker firstWalker(this); root->traverse(firstWalker); ConnectNameObserverWalker secondWalker; root->traverse(secondWalker); }
void Namespace::disconnect(const scene::INodePtr& root) { // First, disconnect all NameObservers DisconnectNameObserverWalker firstWalker; root->traverse(firstWalker); // Second, remove all "names" from the namespace and clear the reference DisconnectNamespacedWalker secondWalker; root->traverse(secondWalker); }
void Namespace::ensureNoConflicts(const scene::INodePtr& root) { // Instantiate a new, temporary namespace for the nodes below root Namespace foreignNamespace; // Move all nodes below (and including) root into this temporary namespace foreignNamespace.connect(root); // Collect all namespaced items from the foreign root GatherNamespacedWalker walker; root->traverse(walker); rDebug() << "Namespace::ensureNoConflicts(): imported set of " << walker.result.size() << " namespaced nodes" << std::endl; // Build a union set containing all imported names and all existing names. // We need to know all existing names to ensure that newly created names are // unique in *both* namespaces UniqueNameSet allNames = _uniqueNames; allNames.merge(foreignNamespace._uniqueNames); // Process each object in the to-be-imported tree of nodes, ensuring that it // has a unique name for (const NamespacedPtr& n : walker.result) { // If the imported node conflicts with a name in THIS namespace, then it // needs to be given a new name which is unique in BOTH namespaces. if (_uniqueNames.nameExists(n->getName())) { // Name exists in the target namespace, get a new name std::string uniqueName = allNames.insertUnique(n->getName()); rMessage() << "Namespace::ensureNoConflicts(): '" << n->getName() << "' already exists in this namespace. Rename it to '" << uniqueName << "'\n"; // Change the name of the imported node, this should trigger all // observers in the foreign namespace n->changeName(uniqueName); } else { // Name does not exist yet, insert it into the local combined // namespace (but not our destination namespace, this will be // populated in the subsequent call to connect()). allNames.insert(n->getName()); } } // at this point, all names in the foreign namespace have been converted to // something unique in this namespace. The calling code can now move the // nodes into this namespace without name conflicts // Disconnect the root from the foreign namespace again, it will be destroyed now foreignNamespace.disconnect(root); }