Esempio n. 1
0
	void CmdDeleteSO::recordSO(const HSceneObject& sceneObject)
	{
		MemorySerializer serializer;
		mSerializedObject = serializer.encode(mSceneObject.get(), mSerializedObjectSize);

		HSceneObject parent = mSceneObject->getParent();
		if (parent != nullptr)
			mSerializedObjectParentId = parent->getInstanceId();

		mSceneObjectProxy = CmdUtility::createProxy(mSceneObject);
	}
Esempio n. 2
0
	void CmdBreakPrefab::revert()
	{
		if (mPrefabRoot == nullptr || mPrefabRoot.isDestroyed())
			return;

		mPrefabRoot->_setPrefabLinkUUID(mPrefabLinkUUID);
		mPrefabRoot->_setPrefabDiff(mPrefabDiff);

		Stack<HSceneObject> todo;
		todo.push(mPrefabRoot);

		while (!todo.empty())
		{
			HSceneObject currentSO = todo.top();
			todo.pop();

			const Vector<HComponent>& components = currentSO->getComponents();
			for (auto& component : components)
			{
				auto iterFind = mLinkIds.find(component->getInstanceId());
				if (iterFind != mLinkIds.end())
					component->_setLinkId(iterFind->second);
			}

			UINT32 numChildren = (UINT32)currentSO->getNumChildren();
			for (UINT32 i = 0; i < numChildren; i++)
			{
				HSceneObject child = currentSO->getChild(i);

				auto iterFind = mLinkIds.find(child->getInstanceId());
				if (iterFind != mLinkIds.end())
					child->_setLinkId(iterFind->second);

				if (child->_getPrefabLinkUUID().empty())
					todo.push(child);
			}
		}
	}
Esempio n. 3
0
	void CmdBreakPrefab::commit()
	{
		clear();

		if (mSceneObject == nullptr || mSceneObject.isDestroyed())
			return;

		HSceneObject rootObj = mSceneObject;

		while (rootObj != nullptr)
		{
			if (!rootObj->_getPrefabLinkUUID().empty())
				break;

			if (rootObj->getParent() != nullptr)
				rootObj = rootObj->getParent();
			else
				rootObj = nullptr;
		}

		if (rootObj != nullptr)
		{
			mPrefabRoot = rootObj;
			mPrefabLinkUUID = rootObj->_getPrefabLinkUUID();
			mPrefabDiff = rootObj->_getPrefabDiff();

			Stack<HSceneObject> todo;
			todo.push(mPrefabRoot);

			while (!todo.empty())
			{
				HSceneObject currentSO = todo.top();
				todo.pop();

				const Vector<HComponent>& components = currentSO->getComponents();
				for (auto& component : components)
				{
					UINT32 linkId = component->getLinkId();

					if (linkId != (UINT32)-1)
						mLinkIds[component->getInstanceId()] = linkId;

					mLinkIds[component->getInstanceId()] = component->getLinkId();
				}

				UINT32 numChildren = (UINT32)currentSO->getNumChildren();
				for (UINT32 i = 0; i < numChildren; i++)
				{
					HSceneObject child = currentSO->getChild(i);
					UINT32 linkId = child->getLinkId();

					if (linkId != (UINT32)-1)
						mLinkIds[child->getInstanceId()] = linkId;

					if (child->_getPrefabLinkUUID().empty())
						todo.push(child);
				}
			}
		}

		mSceneObject->breakPrefabLink();
	}
Esempio n. 4
0
	void PrefabDiff::renameInstanceIds(const HSceneObject& prefab, const HSceneObject& instance, Vector<RenamedGameObject>& output)
	{
		UnorderedMap<String, UnorderedMap<UINT32, UINT64>> linkToInstanceId;

		struct StackEntry
		{
			HSceneObject so;
			String uuid;
		};

		// When renaming it is important to rename the prefab and not the instance, since the diff will otherwise
		// contain prefab's IDs, but will be used for the instance.

		Stack<StackEntry> todo;
		todo.push({ instance, "root" });

		while (!todo.empty())
		{
			StackEntry current = todo.top();
			todo.pop();

			String childParentUUID;
			if (current.so->mPrefabLinkUUID.empty())
				childParentUUID = current.uuid;
			else
				childParentUUID = current.so->mPrefabLinkUUID;

			UnorderedMap<UINT32, UINT64>& idMap = linkToInstanceId[childParentUUID];

			const Vector<HComponent>& components = current.so->getComponents();
			for (auto& component : components)
			{
				if (component->getLinkId() != (UINT32)-1)
					idMap[component->getLinkId()] = component->getInstanceId();
			}

			UINT32 numChildren = current.so->getNumChildren();
			for (UINT32 i = 0; i < numChildren; i++)
			{
				HSceneObject child = current.so->getChild(i);

				if (child->getLinkId() != (UINT32)-1)
					idMap[child->getLinkId()] = child->getInstanceId();

				todo.push({ child, childParentUUID });
			}
		}

		// Root has link ID from its parent so we handle it separately
		{
			output.push_back(RenamedGameObject());
			RenamedGameObject& renamedGO = output.back();
			renamedGO.instanceData = instance->mInstanceData;
			renamedGO.originalId = instance->getInstanceId();

			prefab->mInstanceData->mInstanceId = instance->getInstanceId();
		}

		todo.push({ prefab, "root" });
		while (!todo.empty())
		{
			StackEntry current = todo.top();
			todo.pop();

			String childParentUUID;
			if (current.so->mPrefabLinkUUID.empty())
				childParentUUID = current.uuid;
			else
				childParentUUID = current.so->mPrefabLinkUUID;

			auto iterFind = linkToInstanceId.find(childParentUUID);
			if (iterFind != linkToInstanceId.end())
			{
				UnorderedMap<UINT32, UINT64>& idMap = iterFind->second;

				const Vector<HComponent>& components = current.so->getComponents();
				for (auto& component : components)
				{
					auto iterFind2 = idMap.find(component->getLinkId());
					if (iterFind2 != idMap.end())
					{
						output.push_back(RenamedGameObject());
						RenamedGameObject& renamedGO = output.back();
						renamedGO.instanceData = component->mInstanceData;
						renamedGO.originalId = component->getInstanceId();

						component->mInstanceData->mInstanceId = iterFind2->second;
					}
				}
			}

			UINT32 numChildren = current.so->getNumChildren();
			for (UINT32 i = 0; i < numChildren; i++)
			{
				HSceneObject child = current.so->getChild(i);

				if (iterFind != linkToInstanceId.end())
				{
					if (child->getLinkId() != -1)
					{
						UnorderedMap<UINT32, UINT64>& idMap = iterFind->second;

						auto iterFind2 = idMap.find(child->getLinkId());
						if (iterFind2 != idMap.end())
						{
							output.push_back(RenamedGameObject());
							RenamedGameObject& renamedGO = output.back();
							renamedGO.instanceData = child->mInstanceData;
							renamedGO.originalId = child->getInstanceId();

							child->mInstanceData->mInstanceId = iterFind2->second;
						}
					}
				}

				todo.push({ child, childParentUUID });
			}
		}
	}