2
0
Эх сурвалжийг харах

Added a method for finding all resource dependencies in an object

Marko Pintera 11 жил өмнө
parent
commit
3bcd068db3

+ 2 - 0
BansheeCore/BansheeCore.vcxproj

@@ -360,6 +360,7 @@
     <ClInclude Include="Include\BsTextData.h" />
     <ClInclude Include="Include\BsTextData.h" />
     <ClInclude Include="Include\BsTimerQuery.h" />
     <ClInclude Include="Include\BsTimerQuery.h" />
     <ClInclude Include="Include\BsTransientMesh.h" />
     <ClInclude Include="Include\BsTransientMesh.h" />
+    <ClInclude Include="Include\BsUtility.h" />
     <ClInclude Include="Include\BsUUID.h" />
     <ClInclude Include="Include\BsUUID.h" />
     <ClInclude Include="Include\BsVertexBuffer.h" />
     <ClInclude Include="Include\BsVertexBuffer.h" />
     <ClInclude Include="Include\BsGpuProgramManager.h" />
     <ClInclude Include="Include\BsGpuProgramManager.h" />
@@ -483,6 +484,7 @@
     <ClCompile Include="Source\BsTextData.cpp" />
     <ClCompile Include="Source\BsTextData.cpp" />
     <ClCompile Include="Source\BsTimerQuery.cpp" />
     <ClCompile Include="Source\BsTimerQuery.cpp" />
     <ClCompile Include="Source\BsTransientMesh.cpp" />
     <ClCompile Include="Source\BsTransientMesh.cpp" />
+    <ClCompile Include="Source\BsUtility.cpp" />
     <ClCompile Include="Source\BsUUID.cpp" />
     <ClCompile Include="Source\BsUUID.cpp" />
     <ClCompile Include="Source\BsVertexBuffer.cpp" />
     <ClCompile Include="Source\BsVertexBuffer.cpp" />
     <ClCompile Include="Source\BsGpuProgramManager.cpp" />
     <ClCompile Include="Source\BsGpuProgramManager.cpp" />

+ 9 - 0
BansheeCore/BansheeCore.vcxproj.filters

@@ -88,6 +88,9 @@
     <Filter Include="Source Files\RenderAPI">
     <Filter Include="Source Files\RenderAPI">
       <UniqueIdentifier>{e0bdc5fc-afd1-46f9-9e3e-f85ca3e220b8}</UniqueIdentifier>
       <UniqueIdentifier>{e0bdc5fc-afd1-46f9-9e3e-f85ca3e220b8}</UniqueIdentifier>
     </Filter>
     </Filter>
+    <Filter Include="Source Files\Utility">
+      <UniqueIdentifier>{0d63b345-0a58-4df2-9d01-f4da53fc40c9}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="Include\BsRenderStats.h">
     <ClInclude Include="Include\BsRenderStats.h">
@@ -522,6 +525,9 @@
     <ClInclude Include="Include\BsResourceListenerManager.h">
     <ClInclude Include="Include\BsResourceListenerManager.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsUtility.h">
+      <Filter>Header Files\Utility</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsCoreApplication.cpp">
     <ClCompile Include="Source\BsCoreApplication.cpp">
@@ -824,5 +830,8 @@
     <ClCompile Include="Source\BsResourceListenerManager.cpp">
     <ClCompile Include="Source\BsResourceListenerManager.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\BsUtility.cpp">
+      <Filter>Source Files\Utility</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 33 - 0
BansheeCore/Include/BsUtility.h

@@ -0,0 +1,33 @@
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Static class containing various utility methods that do not
+	 *			fit anywhere else.
+	 */
+	class BS_CORE_EXPORT Utility
+	{
+	public:
+		/**
+		 * @brief	Finds all resources referenced by the specified object.
+		 *
+		 * @param	object		Object to search for resource dependencies.
+		 * @param	recursive	Determines whether or not child objects will also be
+		 *						searched (if object has any children).
+		 *
+		 * @returns	A list of unique, non-null resources.
+		 */
+		static Vector<HResource> findResourceDependencies(IReflectable& object, bool recursive = true);
+
+	private:
+		/**
+		 * @brief	Helper method for for recursion when finding resource dependencies.
+		 *
+		 * @see	findDependencies
+		 */
+		static void findResourceDependenciesInternal(IReflectable& object, bool recursive, Map<String, HResource>& dependencies);
+	};
+}

+ 96 - 0
BansheeCore/Source/BsUtility.cpp

@@ -0,0 +1,96 @@
+#include "BsUtility.h"
+#include "BsRTTIType.h"
+
+namespace BansheeEngine
+{
+	Vector<HResource> Utility::findResourceDependencies(IReflectable& obj, bool recursive)
+	{
+		Map<String, HResource> dependencies;
+		findResourceDependenciesInternal(obj, recursive, dependencies);
+
+		Vector<HResource> dependencyList(dependencies.size());
+		UINT32 i = 0;
+		for (auto& entry : dependencies)
+		{
+			dependencyList[i] = entry.second;
+			i++;
+		}
+
+		return dependencyList;
+	}
+
+	void Utility::findResourceDependenciesInternal(IReflectable& obj, bool recursive, Map<String, HResource>& dependencies)
+	{
+		RTTITypeBase* rtti = obj.getRTTI();
+		rtti->onDeserializationStarted(&obj);
+
+		UINT32 numFields = rtti->getNumFields();
+		for (UINT32 i = 0; i < numFields; i++)
+		{
+			RTTIField* field = rtti->getField(i);
+
+			if (field->isReflectableType())
+			{
+				RTTIReflectableFieldBase* reflectableField = static_cast<RTTIReflectableFieldBase*>(field);
+
+				if (reflectableField->getType()->getRTTIId() == TID_ResourceHandle)
+				{
+					if (reflectableField->isArray())
+					{
+						UINT32 numElements = reflectableField->getArraySize(&obj);
+						for (UINT32 j = 0; i < numElements; j++)
+						{
+							HResource resource = (HResource&)reflectableField->getArrayValue(&obj, j);
+							if (resource != nullptr)
+								dependencies[resource.getUUID()] = resource;
+						}
+					}
+					else
+					{
+						HResource resource = (HResource&)reflectableField->getValue(&obj);
+						if (resource != nullptr)
+							dependencies[resource.getUUID()] = resource;
+					}
+				}
+				else if (recursive)
+				{
+					if (reflectableField->isArray())
+					{
+						UINT32 numElements = reflectableField->getArraySize(&obj);
+						for (UINT32 j = 0; i < numElements; j++)
+						{
+							IReflectable& childObj = reflectableField->getArrayValue(&obj, j);
+							findResourceDependenciesInternal(childObj, true, dependencies);
+						}
+					}
+					else
+					{
+						IReflectable& childObj = reflectableField->getValue(&obj);
+						findResourceDependenciesInternal(childObj, true, dependencies);
+					}
+				}
+			}
+			else if (field->isReflectablePtrType() && recursive)
+			{
+				RTTIReflectablePtrFieldBase* reflectablePtrField = static_cast<RTTIReflectablePtrFieldBase*>(field);
+
+				if (reflectablePtrField->isArray())
+				{
+					UINT32 numElements = reflectablePtrField->getArraySize(&obj);
+					for (UINT32 j = 0; i < numElements; j++)
+					{
+						SPtr<IReflectable> childObj = reflectablePtrField->getArrayValue(&obj, j);
+						findResourceDependenciesInternal(*childObj, true, dependencies);
+					}
+				}
+				else
+				{
+					SPtr<IReflectable> childObj = reflectablePtrField->getValue(&obj);
+					findResourceDependenciesInternal(*childObj, true, dependencies);
+				}
+			}
+		}
+
+		rtti->onDeserializationEnded(&obj);
+	}
+}

+ 2 - 1
BansheeUtility/Include/BsRTTIField.h

@@ -89,7 +89,8 @@ namespace BansheeEngine
 		bool isDataBlockType() { return mType == SerializableFT_DataBlock; }
 		bool isDataBlockType() { return mType == SerializableFT_DataBlock; }
 		bool isReflectableType() { return mType == SerializableFT_Reflectable; }
 		bool isReflectableType() { return mType == SerializableFT_Reflectable; }
 		bool isReflectablePtrType() { return mType == SerializableFT_ReflectablePtr; }
 		bool isReflectablePtrType() { return mType == SerializableFT_ReflectablePtr; }
-		
+		bool isArray() const { return mIsVectorType; }
+
 		/**
 		/**
 		 * @brief	Returns flags that were set in the field meta-data.
 		 * @brief	Returns flags that were set in the field meta-data.
 		 */
 		 */

+ 17 - 11
TODO.txt

@@ -1,8 +1,5 @@
 --------- ALL LONG TERM TASKS / FIXES BELONG TO GOOGLE DOCS: ImplementationTODO OR PossibleImprovements ----------
 --------- ALL LONG TERM TASKS / FIXES BELONG TO GOOGLE DOCS: ImplementationTODO OR PossibleImprovements ----------
 
 
- New issues:
-  - Since Mesh refactor when I select/deselect a gizmo the entire render texture flashes white for one frame (might be related to RT refactor instead)
-
 1. Make sure shader create() methods returns a HShader
 1. Make sure shader create() methods returns a HShader
 2. Make sure material uses HShader
 2. Make sure material uses HShader
 3. Make sure material listens for HShader load event (derives from IResourceListener)
 3. Make sure material listens for HShader load event (derives from IResourceListener)
@@ -12,12 +9,26 @@
 
 
 See GDrive/Resources doc for resources refactor
 See GDrive/Resources doc for resources refactor
 
 
+ManagedComponent deserialization IS WRONG
+ - I register the component with ScriptGameObjectManager during deserialization when its ID is wrong
+
+Add a special mode to GameObjectManager that is active during deserialization
+ - Any handle or GameObject deserialized when its active will use a special mapping for resolving/updating IDs
+  - THIS doesn't really work because I might need to resolve a handle before the object is deserialized
+  - But could I add entries to the map from both handle and object regardless of which is resolved first?
+    - YES - This gets rid of the need for post-processing of GameObject, solves my ScriptComponent deserialization issue and allows me to deserialize managed fields on demand
+
+Modify managed serialization so that deserialization/serialization happens per field instead of in deserialize/serialize methods during pre- and post-processing step.
+ - Make sure to fix the GameObjectManager delayed deserialization issue first
+ - When generating SerializableFieldInfo generate mFieldGlobalIdx (index that takes into consideration any base classes)
+   - Then when de/serializing use that index to get field info and call get/setFieldData accordingly in RTTI getter/setter directly
+   - How to use it when deserializing though?
+     - Ensure that ManagedObjectInfo is deserialized first. Since this is an unclear dependency make sure to add asserts so when it fails it is clear why.
+     - Then use that to look up field during runtime
+
 I can get mono errors by checking g_print calls in goutput.c
 I can get mono errors by checking g_print calls in goutput.c
  - Calling thunks incorrectly can cause those weird errors with no real callstack
  - Calling thunks incorrectly can cause those weird errors with no real callstack
 
 
-Mouse wrap doesn't seem to work the first time
-If you release mouse outside the window the handle doesn't get deselected and wrap remains active
-
 Other:
 Other:
 Window resize end callback
 Window resize end callback
 Add cutoff plane when rendering discs for rotation handle.
 Add cutoff plane when rendering discs for rotation handle.
@@ -29,11 +40,6 @@ Add ProjectWindow and HierarchyWindow to C#
  - Make TreeViews a C# element?
  - Make TreeViews a C# element?
 Set up a default layout and save it
 Set up a default layout and save it
 
 
-Test:
- - If cursor wrap works
- - If handles work when dragged outside of scene window
- - If handle is properly released if mouse up is pressed outside
-
 -----------------
 -----------------
 
 
 Need a way to drag and drop items from Scene tree view to Scene view
 Need a way to drag and drop items from Scene tree view to Scene view