Преглед изворни кода

Getting Play/Pause to work

BearishSun пре 10 година
родитељ
комит
10b54dfe89

+ 12 - 5
BansheeCore/Source/BsCoreSceneManager.cpp

@@ -46,14 +46,21 @@ namespace BansheeEngine
 		UINT32 numChildren = oldRoot->getNumChildren();
 		// Make sure to keep persistent objects
 
-		UINT32 curIdx = 0;
-		for (UINT32 i = 0; i < numChildren; i++)
+		bs_frame_mark();
 		{
-			HSceneObject child = oldRoot->getChild(curIdx);
+			FrameVector<HSceneObject> toRemove;
+			for (UINT32 i = 0; i < numChildren; i++)
+			{
+				HSceneObject child = oldRoot->getChild(i);
+
+				if (child->hasFlag(SOF_Persistent))
+					toRemove.push_back(child);
+			}
 
-			if (child->hasFlag(SOF_Persistent))
-				child->setParent(root, false);
+			for (auto& entry : toRemove)
+				entry->setParent(root, false);
 		}
+		bs_frame_clear();
 
 		mRootNode = root;
 		mRootNode->_setParent(HSceneObject());

+ 5 - 0
SBansheeEngine/Include/BsPlayInEditorManager.h

@@ -61,6 +61,11 @@ namespace BansheeEngine
 		 */
 		void setStateImmediate(PlayInEditorState state);
 
+		/**
+		 * @brief	Saves the current state of the scene in memory.
+		 */
+		void saveSceneInMemory();
+
 		PlayInEditorState mState;
 		PlayInEditorState mNextState;
 		bool mFrameStepActive;

+ 26 - 2
SBansheeEngine/Source/BsPlayInEditorManager.cpp

@@ -47,7 +47,7 @@ namespace BansheeEngine
 			}
 			else // Was stopped
 			{
-				mSavedScene = SceneManager::instance().getRootNode()->clone(false);
+				saveSceneInMemory();
 				ScriptGameObjectManager::instance().sendComponentInitializeEvents();
 			}
 		}
@@ -57,7 +57,7 @@ namespace BansheeEngine
 			mFrameStepActive = false;
 			if (oldState == PlayInEditorState::Stopped)
 			{
-				mSavedScene = SceneManager::instance().getRootNode()->clone(false);
+				saveSceneInMemory();
 				ScriptGameObjectManager::instance().sendComponentInitializeEvents();
 			}
 		}
@@ -97,4 +97,28 @@ namespace BansheeEngine
 			mFrameStepActive = false;
 		}
 	}
+
+	void PlayInEditorManager::saveSceneInMemory()
+	{
+		mSavedScene = SceneManager::instance().getRootNode()->clone(false);
+
+		// Remove objects with "dont save" flag
+		Stack<HSceneObject> todo;
+		todo.push(mSavedScene);
+
+		while (!todo.empty())
+		{
+			HSceneObject current = todo.top();
+			todo.pop();
+
+			if (current->hasFlag(SOF_DontSave))
+				current->destroy();
+			else
+			{
+				UINT32 numChildren = current->getNumChildren();
+				for (UINT32 i = 0; i < numChildren; i++)
+					todo.push(current->getChild(i));
+			}
+		}
+	}
 }

+ 8 - 5
SBansheeEngine/Source/BsScriptGameObjectManager.cpp

@@ -147,7 +147,7 @@ namespace BansheeEngine
 	{
 		UINT64 instanceId = component->getNativeHandle().getInstanceId();
 		mScriptComponents.erase(instanceId);
-		mUninitializedScriptComponents(instanceId);
+		mUninitializedScriptComponents.erase(instanceId);
 
 		bs_delete(component);
 	}
@@ -164,27 +164,30 @@ namespace BansheeEngine
 			ScriptComponent* scriptComponent = scriptObjectEntry.second;
 			HManagedComponent component = scriptComponent->getNativeHandle();
 
-			component->triggerOnReset();
+			if (!component.isDestroyed())
+				component->triggerOnReset();
 		}
 	}
 
 	void ScriptGameObjectManager::sendComponentInitializeEvents()
 	{
-		// Need to make a copy since successful calls will remove entries from mScriptComponents
-		UnorderedMap<UINT64, ScriptComponent*> componentsToInitialize = mScriptComponents;
+		// Need to make a copy since successful calls will remove entries from mUninitializedScriptComponents
+		UnorderedMap<UINT64, ScriptComponent*> componentsToInitialize = mUninitializedScriptComponents;
 
 		for (auto& scriptObjectEntry : componentsToInitialize)
 		{
 			ScriptComponent* scriptComponent = scriptObjectEntry.second;
 			HManagedComponent component = scriptComponent->getNativeHandle();
 
-			component->triggerOnInitialize();
+			if (!component.isDestroyed())
+				component->triggerOnInitialize();
 		}
 	}
 
 	void ScriptGameObjectManager::onGameObjectDestroyed(const HGameObject& go)
 	{
 		UINT64 instanceId = go.getInstanceId();
+		mUninitializedScriptComponents.erase(instanceId);
 
 		ScriptSceneObject* so = getScriptSceneObject(instanceId);
 		if (so == nullptr)