void PrefabUtility::restoreLinkedInstanceData(const HSceneObject& so, SceneObjectProxy& proxy, UnorderedMap<UINT32, GameObjectInstanceDataPtr>& linkedInstanceData) { Stack<HSceneObject> todo; todo.push(so); // Root is not in the instance data map because its link ID belongs to the parent prefab, if any so->_setInstanceData(proxy.instanceData); while (!todo.empty()) { HSceneObject current = todo.top(); todo.pop(); Vector<HComponent>& components = current->mComponents; for (auto& component : components) { if (component->getLinkId() != (UINT32)-1) { auto iterFind = linkedInstanceData.find(component->getLinkId()); if (iterFind != linkedInstanceData.end()) { component->_setInstanceData(iterFind->second); component._setHandleData(component.getInternalPtr()); } } } UINT32 numChildren = current->getNumChildren(); for (UINT32 i = 0; i < numChildren; i++) { HSceneObject child = current->getChild(i); if (child->getLinkId() != (UINT32)-1) { auto iterFind = linkedInstanceData.find(child->getLinkId()); if (iterFind != linkedInstanceData.end()) child->_setInstanceData(iterFind->second); } if (child->mPrefabLinkUUID.empty()) todo.push(child); } } }
void PrefabUtility::restoreUnlinkedInstanceData(const HSceneObject& so, SceneObjectProxy& proxy) { struct StackEntry { HSceneObject so; SceneObjectProxy* proxy; }; Stack<StackEntry> todo; todo.push(StackEntry()); StackEntry& topEntry = todo.top(); topEntry.so = so; topEntry.proxy = &proxy; while (!todo.empty()) { StackEntry current = todo.top(); todo.pop(); if (current.proxy->linkId == -1) current.so->_setInstanceData(current.proxy->instanceData); Vector<HComponent>& components = current.so->mComponents; UINT32 componentProxyIdx = 0; UINT32 numComponentProxies = (UINT32)current.proxy->components.size(); for (auto& component : components) { if (component->getLinkId() == (UINT32)-1) { bool foundInstanceData = false; for (; componentProxyIdx < numComponentProxies; componentProxyIdx++) { if (current.proxy->components[componentProxyIdx].linkId != -1) continue; component->_setInstanceData(current.proxy->components[componentProxyIdx].instanceData); component._setHandleData(component.getInternalPtr()); foundInstanceData = true; break; } assert(foundInstanceData); } } UINT32 numChildren = current.so->getNumChildren(); UINT32 childProxyIdx = 0; UINT32 numChildProxies = (UINT32)current.proxy->children.size(); for (UINT32 i = 0; i < numChildren; i++) { HSceneObject child = current.so->getChild(i); if (child->getLinkId() == (UINT32)-1) { bool foundInstanceData = false; for (; childProxyIdx < numChildProxies; childProxyIdx++) { if (current.proxy->children[childProxyIdx].linkId != -1) continue; assert(current.proxy->children[childProxyIdx].linkId == -1); child->_setInstanceData(current.proxy->children[childProxyIdx].instanceData); if (child->mPrefabLinkUUID.empty()) { todo.push(StackEntry()); StackEntry& newEntry = todo.top(); newEntry.so = child; newEntry.proxy = ¤t.proxy->children[childProxyIdx]; } foundInstanceData = true; break; } assert(foundInstanceData); } else { if (!child->mPrefabLinkUUID.empty()) continue; for (UINT32 j = 0; j < numChildProxies; j++) { if (child->getLinkId() == current.proxy->children[j].linkId) { todo.push(StackEntry()); StackEntry& newEntry = todo.top(); newEntry.so = child; newEntry.proxy = ¤t.proxy->children[j]; break; } } } } } }