Browse Source

WIP: UndoRedo refactor
- SerializedObject and SerializedDiff updated so they work with native-wrapped objects

BearishSun 6 years ago
parent
commit
a2b29a2971

+ 9 - 3
Source/EditorManaged/Utility/GameObjectUndo.cs

@@ -53,11 +53,13 @@ namespace bs.Editor
                 if (obj.IsDestroyed)
                 if (obj.IsDestroyed)
                     return;
                     return;
 
 
-                SerializedDiff oldToNew = SerializedDiff.Create(orgState, obj);
-                if (oldToNew.IsEmpty)
+                SerializedObject newState = SerializedObject.Create(obj);
+
+                SerializedDiff oldToNew = SerializedDiff.Create(orgState, newState);
+                if (oldToNew == null || oldToNew.IsEmpty)
                     return;
                     return;
 
 
-                SerializedDiff newToOld = SerializedDiff.Create(obj, orgState);
+                SerializedDiff newToOld = SerializedDiff.Create(newState, orgState);
                 UndoRedo.Global.RegisterCommand(new RecordComponentUndo(obj, path, oldToNew, newToOld));
                 UndoRedo.Global.RegisterCommand(new RecordComponentUndo(obj, path, oldToNew, newToOld));
             }
             }
         }
         }
@@ -279,6 +281,8 @@ namespace bs.Editor
         private SceneObjectDiff newToOld;
         private SceneObjectDiff newToOld;
         private SceneObjectDiff oldToNew;
         private SceneObjectDiff oldToNew;
 
 
+        private RecordSceneObjectHeaderUndo() { }
+
         /// <summary>
         /// <summary>
         /// Creates the new scene object undo command.
         /// Creates the new scene object undo command.
         /// </summary>
         /// </summary>
@@ -378,6 +382,8 @@ namespace bs.Editor
         private SerializedDiff newToOld;
         private SerializedDiff newToOld;
         private SerializedDiff oldToNew;
         private SerializedDiff oldToNew;
 
 
+        private RecordComponentUndo() { }
+
         /// <summary>
         /// <summary>
         /// Creates the new component undo command.
         /// Creates the new component undo command.
         /// </summary>
         /// </summary>

+ 1 - 1
Source/EditorManaged/Utility/SerializedObject.cs

@@ -28,7 +28,7 @@ namespace bs.Editor
         /// </summary>
         /// </summary>
         /// <param name="obj">Component to serialize.</param>
         /// <param name="obj">Component to serialize.</param>
         /// <returns>Object containing serialized data.</returns>
         /// <returns>Object containing serialized data.</returns>
-        public static SerializedObject Create(ManagedComponent obj)
+        public static SerializedObject Create(Component obj)
         {
         {
             if (obj == null)
             if (obj == null)
                 return null;
                 return null;

+ 1 - 1
Source/EditorScript/BsScriptGizmoManager.cpp

@@ -89,7 +89,7 @@ namespace bs
 				else
 				else
 				{
 				{
 					ScriptGameObjectManager& sgoManager = ScriptGameObjectManager::instance();
 					ScriptGameObjectManager& sgoManager = ScriptGameObjectManager::instance();
-					ScriptComponentBase* scriptComponent = sgoManager.getBuiltinScriptComponent(component, false);
+					ScriptComponentBase* scriptComponent = sgoManager.getBuiltinScriptComponent(component);
 
 
 					if (scriptComponent)
 					if (scriptComponent)
 					{
 					{

+ 1 - 2
Source/EditorScript/Wrappers/BsScriptEditorSettings.cpp

@@ -278,7 +278,6 @@ namespace bs
 		settings->setString(nativeName, nativeValue);
 		settings->setString(nativeName, nativeValue);
 	}
 	}
 
 
-
 	void ScriptEditorSettings::internal_SetObject(MonoString* name, MonoObject* value)
 	void ScriptEditorSettings::internal_SetObject(MonoString* name, MonoObject* value)
 	{
 	{
 		String nativeName = MonoUtil::monoToString(name);
 		String nativeName = MonoUtil::monoToString(name);
@@ -286,7 +285,7 @@ namespace bs
 		SPtr<IReflectable> nativeValue;
 		SPtr<IReflectable> nativeValue;
 		if(value != nullptr)
 		if(value != nullptr)
 		{
 		{
-			nativeValue = ScriptAssemblyManager::getReflectableFromManagedObject(value);
+			nativeValue = ScriptAssemblyManager::instance().getReflectableFromManagedObject(value);
 
 
 			if(!nativeValue)
 			if(!nativeValue)
 				return;
 				return;

+ 1 - 1
Source/EditorScript/Wrappers/BsScriptProjectSettings.cpp

@@ -92,7 +92,7 @@ namespace bs
 		SPtr<IReflectable> nativeValue;
 		SPtr<IReflectable> nativeValue;
 		if(value != nullptr)
 		if(value != nullptr)
 		{
 		{
-			nativeValue = ScriptAssemblyManager::getReflectableFromManagedObject(value);
+			nativeValue = ScriptAssemblyManager::instance().getReflectableFromManagedObject(value);
 
 
 			if(!nativeValue)
 			if(!nativeValue)
 				return;
 				return;

+ 50 - 15
Source/EditorScript/Wrappers/BsScriptSerializedDiff.cpp

@@ -6,10 +6,16 @@
 #include "Serialization/BsManagedSerializableObject.h"
 #include "Serialization/BsManagedSerializableObject.h"
 #include "Wrappers/BsScriptSerializedObject.h"
 #include "Wrappers/BsScriptSerializedObject.h"
 #include "Serialization/BsManagedSerializableDiff.h"
 #include "Serialization/BsManagedSerializableDiff.h"
+#include "Serialization/BsBinaryDiff.h"
+#include "Reflection/BsRTTIType.h"
+#include "Serialization/BsSerializedObject.h"
+#include "Serialization/BsScriptAssemblyManager.h"
+#include "Utility/BsUtility.h"
+#include "Serialization/BsBinaryDiff.h"
 
 
 namespace bs
 namespace bs
 {
 {
-	ScriptSerializedDiff::ScriptSerializedDiff(MonoObject* instance, const SPtr<ManagedSerializableDiff>& obj)
+	ScriptSerializedDiff::ScriptSerializedDiff(MonoObject* instance, const SPtr<IReflectable>& obj)
 		: ScriptObject(instance), mSerializedDiff(obj)
 		: ScriptObject(instance), mSerializedDiff(obj)
 	{
 	{
 
 
@@ -24,21 +30,36 @@ namespace bs
 
 
 	MonoObject* ScriptSerializedDiff::internal_CreateDiff(ScriptSerializedObject* oldObj, ScriptSerializedObject* newObj)
 	MonoObject* ScriptSerializedDiff::internal_CreateDiff(ScriptSerializedObject* oldObj, ScriptSerializedObject* newObj)
 	{
 	{
-		SPtr<ManagedSerializableObject> oldSerializedObject = oldObj->getInternal();
-		SPtr<ManagedSerializableObject> newSerializedObject = newObj->getInternal();
+		SPtr<IReflectable> oldSerializedObject = oldObj->getInternal();
+		SPtr<IReflectable> newSerializedObject = newObj->getInternal();
 
 
 		if (oldSerializedObject == nullptr || newSerializedObject == nullptr)
 		if (oldSerializedObject == nullptr || newSerializedObject == nullptr)
 			return nullptr;
 			return nullptr;
 
 
-		oldSerializedObject->serialize();
-		newSerializedObject->serialize();
+		auto oldManagedSerializedObject = rtti_cast<ManagedSerializableObject>(oldSerializedObject);
+		auto newManagedSerializedObject = rtti_cast<ManagedSerializableObject>(newSerializedObject);
 
 
-		SPtr<ManagedSerializableDiff> diff = ManagedSerializableDiff::create(oldSerializedObject, newSerializedObject);
+		auto oldNativeSerializedObj = rtti_cast<SerializedObject>(oldSerializedObject);
+		auto newNativeSerializedObj = rtti_cast<SerializedObject>(newSerializedObject);
 
 
-		MonoObject* instance = metaData.scriptClass->createInstance();
-		new (bs_alloc<ScriptSerializedDiff>()) ScriptSerializedDiff(instance, diff);
+		SPtr<IReflectable> diff;
+		if(oldManagedSerializedObject != nullptr && newManagedSerializedObject != nullptr)
+			diff = ManagedSerializableDiff::create(oldManagedSerializedObject, newManagedSerializedObject);
+		else if(oldNativeSerializedObj != nullptr && newNativeSerializedObj != nullptr)
+		{
+			BinaryDiff diffHandler;
+			diff = diffHandler.generateDiff(oldNativeSerializedObj, newNativeSerializedObj);
+		}
 
 
-		return instance;
+		if(diff)
+		{
+			MonoObject* instance = metaData.scriptClass->createInstance();
+			new (bs_alloc<ScriptSerializedDiff>()) ScriptSerializedDiff(instance, diff);
+
+			return instance;
+		}
+
+		return nullptr;
 	}
 	}
 
 
 	void ScriptSerializedDiff::internal_ApplyDiff(ScriptSerializedDiff* thisPtr, MonoObject* obj)
 	void ScriptSerializedDiff::internal_ApplyDiff(ScriptSerializedDiff* thisPtr, MonoObject* obj)
@@ -46,15 +67,29 @@ namespace bs
 		if(thisPtr->mSerializedDiff == nullptr)
 		if(thisPtr->mSerializedDiff == nullptr)
 			return;
 			return;
 
 
-		SPtr<ManagedSerializableObject> serializedObject = ManagedSerializableObject::createFromExisting(obj);
-		if (serializedObject == nullptr)
-			return;
+		SPtr<ManagedSerializableDiff> managedDiff = rtti_cast<ManagedSerializableDiff>(thisPtr->mSerializedDiff);
+		if(managedDiff != nullptr)
+		{
+			SPtr<ManagedSerializableObject> serializedObject = ManagedSerializableObject::createFromExisting(obj);
+			if (!serializedObject)
+				return;
+
+			managedDiff->apply(serializedObject);
+		}
+		else
+		{
+			SPtr<IReflectable> nativeValue = ScriptAssemblyManager::instance().getReflectableFromManagedObject(obj);
+			if (!nativeValue)
+				return;
 
 
-		thisPtr->mSerializedDiff->apply(serializedObject);
+			IDiff& diffHandler = nativeValue->getRTTI()->getDiffHandler();
+			CoreSerializationContext serzContext;
+			diffHandler.applyDiff(nativeValue, rtti_cast<SerializedObject>(thisPtr->mSerializedDiff), &serzContext);
+		}
 	}
 	}
 
 
 	bool ScriptSerializedDiff::internal_IsEmpty(ScriptSerializedDiff* thisPtr)
 	bool ScriptSerializedDiff::internal_IsEmpty(ScriptSerializedDiff* thisPtr)
 	{
 	{
-		return thisPtr->mSerializedDiff != nullptr;
+		return thisPtr->mSerializedDiff == nullptr;
 	}
 	}
-}
+}

+ 2 - 2
Source/EditorScript/Wrappers/BsScriptSerializedDiff.h

@@ -20,9 +20,9 @@ namespace bs
 		SCRIPT_OBJ(EDITOR_ASSEMBLY, EDITOR_NS, "SerializedDiff")
 		SCRIPT_OBJ(EDITOR_ASSEMBLY, EDITOR_NS, "SerializedDiff")
 
 
 	private:
 	private:
-		ScriptSerializedDiff(MonoObject* instance, const SPtr<ManagedSerializableDiff>& obj);
+		ScriptSerializedDiff(MonoObject* instance, const SPtr<IReflectable>& obj);
 
 
-		SPtr<ManagedSerializableDiff> mSerializedDiff;
+		SPtr<IReflectable> mSerializedDiff;
 
 
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/* 								CLR HOOKS						   		*/

+ 54 - 15
Source/EditorScript/Wrappers/BsScriptSerializedObject.cpp

@@ -10,10 +10,12 @@
 #include "Serialization/BsManagedSerializableObject.h"
 #include "Serialization/BsManagedSerializableObject.h"
 #include "Serialization/BsScriptAssemblyManager.h"
 #include "Serialization/BsScriptAssemblyManager.h"
 #include "Reflection/BsRTTIType.h"
 #include "Reflection/BsRTTIType.h"
+#include "BsScriptGameObjectManager.h"
+#include "Serialization/BsSerializedObject.h"
 
 
 namespace bs
 namespace bs
 {
 {
-	ScriptSerializedObject::ScriptSerializedObject(MonoObject* instance, const SPtr<ManagedSerializableObject>& obj)
+	ScriptSerializedObject::ScriptSerializedObject(MonoObject* instance, const SPtr<IReflectable>& obj)
 		: ScriptObject(instance), mSerializedObject(obj)
 		: ScriptObject(instance), mSerializedObject(obj)
 	{
 	{
 
 
@@ -27,18 +29,28 @@ namespace bs
 		metaData.scriptClass->addInternalCall("Internal_Deserialize", (void*)&ScriptSerializedObject::internal_Deserialize);
 		metaData.scriptClass->addInternalCall("Internal_Deserialize", (void*)&ScriptSerializedObject::internal_Deserialize);
 	}
 	}
 
 
-	MonoObject* ScriptSerializedObject::internal_CreateComponent(ScriptManagedComponent* componentPtr)
+	MonoObject* ScriptSerializedObject::internal_CreateComponent(ScriptComponentBase* componentPtr)
 	{
 	{
-		HManagedComponent component = static_object_cast<ManagedComponent>(componentPtr->getHandle());
+		HComponent component = componentPtr->getComponent();
 		if (component.isDestroyed())
 		if (component.isDestroyed())
 			return nullptr;
 			return nullptr;
 
 
-		MonoObject* managedInstance = component->getManagedInstance();
-		SPtr<ManagedSerializableObject> serializedObject = ManagedSerializableObject::createFromExisting(managedInstance);
-		if (serializedObject == nullptr)
-			return nullptr;
+		SPtr<IReflectable> serializedObject;
+		if (rtti_is_of_type<ManagedComponent>(component.get()))
+		{
+			ManagedComponent* managedComponent = static_cast<ManagedComponent*>(component.get());
+			MonoObject* managedInstance = managedComponent->getManagedInstance();
+
+			SPtr<ManagedSerializableObject> managedSerializedObject = ManagedSerializableObject::createFromExisting(managedInstance);
+			if (managedSerializedObject == nullptr)
+				return nullptr;
+
+			managedSerializedObject->serialize();
+			serializedObject = managedSerializedObject;
+		}
+		else
+			serializedObject = SerializedObject::create(*component.get());
 
 
-		serializedObject->serialize();
 
 
 		MonoObject* instance = metaData.scriptClass->createInstance();
 		MonoObject* instance = metaData.scriptClass->createInstance();
 		new (bs_alloc<ScriptSerializedObject>()) ScriptSerializedObject(instance, serializedObject);
 		new (bs_alloc<ScriptSerializedObject>()) ScriptSerializedObject(instance, serializedObject);
@@ -70,24 +82,51 @@ namespace bs
 		if (obj == nullptr)
 		if (obj == nullptr)
 			return nullptr;
 			return nullptr;
 
 
-		SPtr<ManagedSerializableObject> serializedObject = ManagedSerializableObject::createFromExisting(obj);
-		if (serializedObject == nullptr)
+		SPtr<IReflectable> nativeValue = ScriptAssemblyManager::instance().getReflectableFromManagedObject(obj);
+		if (!nativeValue)
 			return nullptr;
 			return nullptr;
 
 
-		serializedObject->serialize();
+		if(!rtti_is_of_type<ManagedSerializableObject>(nativeValue))
+			nativeValue = SerializedObject::create(*nativeValue);
 
 
 		MonoObject* instance = metaData.scriptClass->createInstance();
 		MonoObject* instance = metaData.scriptClass->createInstance();
-		new (bs_alloc<ScriptSerializedObject>()) ScriptSerializedObject(instance, serializedObject);
+		new (bs_alloc<ScriptSerializedObject>()) ScriptSerializedObject(instance, nativeValue);
 
 
 		return instance;
 		return instance;
 	}
 	}
 
 
 	MonoObject* ScriptSerializedObject::internal_Deserialize(ScriptSerializedObject* thisPtr)
 	MonoObject* ScriptSerializedObject::internal_Deserialize(ScriptSerializedObject* thisPtr)
 	{
 	{
-		SPtr<ManagedSerializableObject> serializedObject = thisPtr->mSerializedObject;
+		SPtr<IReflectable> serializedObject = thisPtr->mSerializedObject;
 		if (serializedObject == nullptr)
 		if (serializedObject == nullptr)
 			return nullptr;
 			return nullptr;
 
 
-		return serializedObject->deserialize();
+		if(auto managedSerializableObject = rtti_cast<ManagedSerializableObject>(serializedObject))
+		{
+			if (!managedSerializableObject)
+				return nullptr;
+
+			return managedSerializableObject->deserialize();
+		}
+		else
+		{
+			if(auto nativeSerializedObject = rtti_cast<SerializedObject>(serializedObject))
+			{
+				SPtr<IReflectable> obj = nativeSerializedObject->decode();
+
+				UINT32 rttiId = obj->getRTTI()->getRTTIId();
+				const ReflectableTypeInfo* reflTypeInfo = ScriptAssemblyManager::instance().getReflectableTypeInfo(rttiId);
+				if (reflTypeInfo == nullptr)
+				{
+					LOGERR(StringUtil::format("Mapping between a reflectable object and a managed type is missing "
+						"for type \"{0}\"", rttiId))
+						return nullptr;
+				}
+
+				return reflTypeInfo->createCallback(obj);
+			}
+		}
+
+		return nullptr;
 	}
 	}
-}
+}

+ 4 - 4
Source/EditorScript/Wrappers/BsScriptSerializedObject.h

@@ -18,17 +18,17 @@ namespace bs
 		SCRIPT_OBJ(EDITOR_ASSEMBLY, EDITOR_NS, "SerializedObject")
 		SCRIPT_OBJ(EDITOR_ASSEMBLY, EDITOR_NS, "SerializedObject")
 
 
 		/** Returns the serialized object wrapped by this object. */
 		/** Returns the serialized object wrapped by this object. */
-		SPtr<ManagedSerializableObject> getInternal() const { return mSerializedObject; }
+		SPtr<IReflectable> getInternal() const { return mSerializedObject; }
 
 
 	private:
 	private:
-		ScriptSerializedObject(MonoObject* instance, const SPtr<ManagedSerializableObject>& obj);
+		ScriptSerializedObject(MonoObject* instance, const SPtr<IReflectable>& obj);
 
 
-		SPtr<ManagedSerializableObject> mSerializedObject;
+		SPtr<IReflectable> mSerializedObject;
 
 
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
 		/************************************************************************/
-		static MonoObject* internal_CreateComponent(ScriptManagedComponent* componentPtr);
+		static MonoObject* internal_CreateComponent(ScriptComponentBase* componentPtr);
 		static MonoObject* internal_CreateResource(ScriptManagedResource* resourcePtr);
 		static MonoObject* internal_CreateResource(ScriptManagedResource* resourcePtr);
 		static MonoObject* internal_CreateGeneric(MonoObject* obj);
 		static MonoObject* internal_CreateGeneric(MonoObject* obj);
 		static MonoObject* internal_Deserialize(ScriptSerializedObject* thisPtr);
 		static MonoObject* internal_Deserialize(ScriptSerializedObject* thisPtr);

+ 1 - 1
Source/bsf

@@ -1 +1 @@
-Subproject commit 86cd6355fd77e97a94f52bb4fd1269301b75159b
+Subproject commit 464761a164a47cb9bfdb5e559516e7df882a3211