| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "UndoRedo/BsCmdBreakPrefab.h"
- #include "Scene/BsSceneObject.h"
- namespace bs
- {
- CmdBreakPrefab::CmdBreakPrefab(const String& description, const HSceneObject& sceneObject)
- :EditorCommand(description), mSceneObject(sceneObject)
- { }
- CmdBreakPrefab::~CmdBreakPrefab()
- {
- mSceneObject = nullptr;
- }
-
- void CmdBreakPrefab::execute(const HSceneObject& sceneObject, const String& description)
- {
- // Register command and commit it
- CmdBreakPrefab* command = new (bs_alloc<CmdBreakPrefab>()) CmdBreakPrefab(description, sceneObject);
- SPtr<CmdBreakPrefab> commandPtr = bs_shared_ptr(command);
- UndoRedo::instance().registerCommand(commandPtr);
- commandPtr->commit();
- }
- 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();
- }
- 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);
- }
- }
- }
- void CmdBreakPrefab::clear()
- {
- mPrefabRoot = nullptr;
- mPrefabLinkUUID = UUID::EMPTY;
- mPrefabDiff = nullptr;
- mLinkIds.clear();
- }
- }
|