소스 검색

Tested GameObject serialization/deserialization (And cloning)

Marko Pintera 12 년 전
부모
커밋
3f992cf16f

+ 2 - 1
BansheeEngine/Include/BsRenderableRTTI.h

@@ -3,6 +3,7 @@
 #include "BsPrerequisites.h"
 #include "CmRTTIType.h"
 #include "BsRenderable.h"
+#include "CmGameObjectRTTI.h"
 
 namespace BansheeEngine
 {
@@ -41,7 +42,7 @@ namespace BansheeEngine
 
 		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
 		{
-			return CM::cm_shared_ptr<Renderable, CM::PoolAlloc>(new (CM::cm_alloc<Renderable, CM::PoolAlloc>()) Renderable());
+			return CM::GameObjectRTTI::createGameObject<Renderable>();
 		}
 	};
 }

+ 3 - 0
CamelotClient/CamelotClient.vcxproj

@@ -257,6 +257,8 @@
   <ItemGroup>
     <ClInclude Include="Include\BsCmdEditPlainFieldGO.h" />
     <ClInclude Include="Include\BsCmdReparentSO.h" />
+    <ClInclude Include="Include\BsDbgTestGameObjectRef.h" />
+    <ClInclude Include="Include\BsDbgTestGameObjectRefRTTI.h" />
     <ClInclude Include="Include\BsDockManager.h" />
     <ClInclude Include="Include\BsEditorApplication.h" />
     <ClInclude Include="Include\BsEditorCommand.h" />
@@ -288,6 +290,7 @@
   <ItemGroup>
     <ClCompile Include="CamelotClient.cpp" />
     <ClCompile Include="Source\BsCmdReparentSO.cpp" />
+    <ClCompile Include="Source\BsDbgTestGameObjectRef.cpp" />
     <ClCompile Include="Source\BsDockManager.cpp" />
     <ClCompile Include="Source\BsEditorCommand.cpp" />
     <ClCompile Include="Source\BsEditorGUI.cpp" />

+ 9 - 0
CamelotClient/CamelotClient.vcxproj.filters

@@ -117,6 +117,12 @@
     <ClInclude Include="Include\BsCmdReparentSO.h">
       <Filter>Header Files\Editor\Commands</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsDbgTestGameObjectRef.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsDbgTestGameObjectRefRTTI.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="stdafx.cpp">
@@ -200,5 +206,8 @@
     <ClCompile Include="Source\BsCmdReparentSO.cpp">
       <Filter>Source Files\Editor\Command</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsDbgTestGameObjectRef.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 38 - 0
CamelotClient/Include/BsDbgTestGameObjectRef.h

@@ -0,0 +1,38 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "CmComponent.h"
+
+namespace BansheeEditor
+{
+	class DbgTestGameObjectRef : public CM::Component
+	{
+	public:
+		BS::HRenderable mRenderable;
+
+		/************************************************************************/
+		/* 							COMPONENT OVERRIDES                    		*/
+		/************************************************************************/
+
+	protected:
+		friend class CM::SceneObject;
+
+		/** Standard constructor.
+        */
+		DbgTestGameObjectRef(const CM::HSceneObject& parent);
+
+	public:
+		virtual void update() {}
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class DbgTestGameObjectRefRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+
+	protected:
+		DbgTestGameObjectRef() {} // Serialization only
+	};
+}

+ 41 - 0
CamelotClient/Include/BsDbgTestGameObjectRefRTTI.h

@@ -0,0 +1,41 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "CmRTTIType.h"
+#include "BsDbgTestGameObjectRef.h"
+#include "CmGameObjectRTTI.h"
+
+namespace BansheeEditor
+{
+	class DbgTestGameObjectRefRTTI : public CM::RTTIType<DbgTestGameObjectRef, CM::Component, DbgTestGameObjectRefRTTI>
+	{
+	private:
+		BS::HRenderable& getRenderable(DbgTestGameObjectRef* obj) { return obj->mRenderable; }
+		void setRenderable(DbgTestGameObjectRef* obj, BS::HRenderable& val) 
+		{ 
+			obj->mRenderable = val; 
+		} 
+
+	public:
+		DbgTestGameObjectRefRTTI()
+		{
+			addReflectableField("mRenderable", 0, &DbgTestGameObjectRefRTTI::getRenderable, &DbgTestGameObjectRefRTTI::setRenderable);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "DbgTestGameObjectRef";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return 600001; // NOTE: Just a debug value
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::GameObjectRTTI::createGameObject<DbgTestGameObjectRef>();
+		}
+	};
+}

+ 26 - 0
CamelotClient/Source/BsDbgTestGameObjectRef.cpp

@@ -0,0 +1,26 @@
+#include "BsDbgTestGameObjectRef.h"
+#include "BsDbgTestGameObjectRefRTTI.h"
+#include "CmSceneObject.h"
+#include "BsRenderable.h"
+
+using namespace CamelotFramework;
+using namespace BansheeEngine;
+
+namespace BansheeEditor
+{
+	DbgTestGameObjectRef::DbgTestGameObjectRef(const HSceneObject& parent)
+		:Component(parent)
+	{
+
+	}
+
+	RTTITypeBase* DbgTestGameObjectRef::getRTTIStatic()
+	{
+		return DbgTestGameObjectRefRTTI::instance();
+	}
+
+	RTTITypeBase* DbgTestGameObjectRef::getRTTI() const
+	{
+		return DbgTestGameObjectRef::getRTTIStatic();
+	}
+}

+ 10 - 0
CamelotClient/Source/BsEditorApplication.cpp

@@ -21,6 +21,7 @@
 #include "CmTechnique.h"
 #include "CmPass.h"
 #include "BsRenderable.h"
+#include "BsDbgTestGameObjectRef.h"
 
 using namespace CamelotFramework;
 using namespace BansheeEngine;
@@ -205,6 +206,15 @@ namespace BansheeEditor
 		testRenderable->setMesh(dbgMeshRef);
 		testRenderable->setMaterial(0, testMaterial);
 
+		GameObjectHandle<DbgTestGameObjectRef> dbgTestGameObjectRef = testModelGO->addComponent<DbgTestGameObjectRef>();
+		dbgTestGameObjectRef->mRenderable = testRenderable;
+
+		HSceneObject clone = testModelGO->clone();
+		GameObjectHandle<DbgTestGameObjectRef> clonedDbgTestGameObjectRef = clone->getComponent<DbgTestGameObjectRef>();
+		
+		testModelGO->destroy();
+
+
 		HTexture dbgCursor = static_resource_cast<Texture>(Importer::instance().import("C:\\CursorDbg.psd"));
 		PixelDataPtr cursorPixelData = dbgCursor->allocateSubresourceBuffer(0);
 

+ 1 - 1
CamelotClient/Source/CmTestTextSprite.cpp

@@ -68,7 +68,7 @@ namespace BansheeEditor
 		SceneObject::create("FILLER_K");
 		SceneObject::create("FILLER_L");
 
-		//area->getLayout().addElement(GUIRenderTexture::create(*this, sceneView, GUIOptions(GUIOption::fixedWidth(800), GUIOption::fixedHeight(600))));
+		area->getLayout().addElement(GUIRenderTexture::create(*this, sceneView, GUIOptions(GUIOption::fixedWidth(800), GUIOption::fixedHeight(600))));
 		//mLabel = GUILabel::create(*this, HString(L""));
 		//area->getLayout().addElement(mLabel);
 

+ 1 - 0
CamelotCore/Include/CmGameObject.h

@@ -35,6 +35,7 @@ namespace CamelotFramework
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
+
 	public:
 		friend class GameObjectRTTI;
 		static RTTITypeBase* getRTTIStatic();

+ 10 - 3
CamelotCore/Include/CmGameObjectHandle.h

@@ -13,7 +13,10 @@ namespace CamelotFramework
 		GameObjectHandleData(const std::shared_ptr<GameObjectInstanceData>& ptr)
 		{
 			mPtr = ptr;
-			mInstanceId = ptr->object->getInstanceId();
+			if(ptr != nullptr)
+				mInstanceId = ptr->object->getInstanceId();
+			else
+				mInstanceId = 0;
 		}
 
 		std::shared_ptr<GameObjectInstanceData> mPtr;
@@ -80,10 +83,14 @@ namespace CamelotFramework
 		
 		void destroy()
 		{
+			// We need to clear mData->mPtr before we clear mData->mPtr->object,
+			// as this handle could be stored within the "object" and destroyed when
+			// we set it to null 
+			std::shared_ptr<GameObjectInstanceData> instanceData = mData->mPtr;
+			mData->mPtr = nullptr;
+
 			if(mData->mPtr != nullptr)
 				mData->mPtr->object = nullptr;
-
-			mData->mPtr = nullptr;
 		}
 
 		std::shared_ptr<GameObjectHandleData> mData;

+ 8 - 0
CamelotCore/Include/CmGameObjectRTTI.h

@@ -3,6 +3,7 @@
 #include "CmPrerequisites.h"
 #include "CmRTTIType.h"
 #include "CmGameObject.h"
+#include "CmSceneObject.h"
 #include "CmGameObjectManager.h"
 
 namespace CamelotFramework
@@ -18,6 +19,13 @@ namespace CamelotFramework
 			GameObjectManager::instance().registerDeserializedId(instanceId, obj->getInstanceId());
 		}
 
+	public:
+		template <typename T>
+		static std::shared_ptr<T> createGameObject()
+		{
+			return SceneObject::createEmptyComponent<T>();
+		}
+
 	public:
 		GameObjectRTTI()
 		{

+ 12 - 0
CamelotCore/Include/CmSceneObject.h

@@ -341,6 +341,17 @@ namespace CamelotFramework
 		Vector<HComponent>::type& getComponents() { return mComponents; }
 
 	private:
+		template <typename T>
+		static std::shared_ptr<T> createEmptyComponent()
+		{
+			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::Component, T>::value), "Specified type is not a valid Component.");
+
+			std::shared_ptr<T> gameObject(new (cm_alloc<T, PoolAlloc>()) T(), &cm_delete<PoolAlloc, T>, StdAlloc<PoolAlloc>());
+			GameObjectHandle<T>(GameObjectManager::instance().registerObject(gameObject));
+
+			return gameObject;
+		}
+
 		void addComponentInternal(const std::shared_ptr<Component> component);
 
 		Vector<HComponent>::type mComponents;
@@ -349,6 +360,7 @@ namespace CamelotFramework
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 	public:
+		friend class GameObjectRTTI;
 		friend class SceneObjectRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		virtual RTTITypeBase* getRTTI() const;

+ 1 - 1
CamelotCore/Include/CmSceneObjectRTTI.h

@@ -49,7 +49,7 @@ namespace CamelotFramework
 
 		virtual std::shared_ptr<IReflectable> newRTTIObject()
 		{
-			HSceneObject newObject = SceneObject::createInternal("");
+			HSceneObject newObject = SceneObject::create("");
 
 			return newObject.getInternalPtr();
 		}

+ 7 - 4
CamelotCore/Source/CmGameObjectHandle.cpp

@@ -17,15 +17,18 @@ namespace CamelotFramework
 
 	GameObjectHandleBase::GameObjectHandleBase(std::nullptr_t ptr)
 	{
-		mData->mPtr = nullptr;
+		mData = cm_shared_ptr<GameObjectHandleData, PoolAlloc>(nullptr);
 	}
 
 	GameObjectHandleBase::GameObjectHandleBase()
-	{ }
+	{
+		mData = cm_shared_ptr<GameObjectHandleData, PoolAlloc>(nullptr);
+	}
 
 	void GameObjectHandleBase::resolve(const GameObjectHandleBase& object) 
 	{ 
-		mData = object.mData;
+		mData->mPtr = object.mData->mPtr;
+		mData->mInstanceId = object.mData->mInstanceId;
 	}
 
 	void GameObjectHandleBase::throwIfDestroyed() const
@@ -43,6 +46,6 @@ namespace CamelotFramework
 
 	RTTITypeBase* GameObjectHandleBase::getRTTI() const
 	{
-		return ResourceHandleBase::getRTTIStatic();
+		return GameObjectHandleBase::getRTTIStatic();
 	}
 }

+ 2 - 2
CamelotCore/Source/CmSceneObject.cpp

@@ -353,10 +353,10 @@ namespace CamelotFramework
 		UINT32 bufferSize = 0;
 
 		MemorySerializer serializer;
-		UINT8* buffer = serializer.encode(this, bufferSize, &stackAlloc);
+		UINT8* buffer = serializer.encode(this, bufferSize, &cm_alloc);
 
 		std::shared_ptr<SceneObject> cloneObj = std::static_pointer_cast<SceneObject>(serializer.decode(buffer, bufferSize));
-		stackDeallocLast(buffer);
+		cm_free(buffer);
 
 		return cloneObj->mThisHandle;
 	}