//********************************** Banshee Engine (www.banshee3d.com) **************************************************// //**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************// #include "Wrappers/BsScriptSerializedDiff.h" #include "BsScriptMeta.h" #include "BsMonoClass.h" #include "Serialization/BsManagedSerializableObject.h" #include "Wrappers/BsScriptSerializedObject.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 { ScriptSerializedDiff::ScriptSerializedDiff(MonoObject* instance, const SPtr& obj) : ScriptObject(instance), mSerializedDiff(obj) { } void ScriptSerializedDiff::initRuntimeData() { metaData.scriptClass->addInternalCall("Internal_CreateDiff", (void*)&ScriptSerializedDiff::internal_CreateDiff); metaData.scriptClass->addInternalCall("Internal_ApplyDiff", (void*)&ScriptSerializedDiff::internal_ApplyDiff); metaData.scriptClass->addInternalCall("Internal_IsEmpty", (void*)&ScriptSerializedDiff::internal_IsEmpty); } MonoObject* ScriptSerializedDiff::internal_CreateDiff(ScriptSerializedObject* oldObj, ScriptSerializedObject* newObj) { SPtr oldSerializedObject = oldObj->getInternal(); SPtr newSerializedObject = newObj->getInternal(); if (oldSerializedObject == nullptr || newSerializedObject == nullptr) return nullptr; auto oldManagedSerializedObject = rtti_cast(oldSerializedObject); auto newManagedSerializedObject = rtti_cast(newSerializedObject); auto oldNativeSerializedObj = rtti_cast(oldSerializedObject); auto newNativeSerializedObj = rtti_cast(newSerializedObject); SPtr diff; if(oldManagedSerializedObject != nullptr && newManagedSerializedObject != nullptr) diff = ManagedSerializableDiff::create(oldManagedSerializedObject, newManagedSerializedObject); else if(oldNativeSerializedObj != nullptr && newNativeSerializedObj != nullptr) { BinaryDiff diffHandler; diff = diffHandler.generateDiff(oldNativeSerializedObj, newNativeSerializedObj); } if(diff) { MonoObject* instance = metaData.scriptClass->createInstance(); new (bs_alloc()) ScriptSerializedDiff(instance, diff); return instance; } return nullptr; } void ScriptSerializedDiff::internal_ApplyDiff(ScriptSerializedDiff* thisPtr, MonoObject* obj) { if(thisPtr->mSerializedDiff == nullptr) return; SPtr managedDiff = rtti_cast(thisPtr->mSerializedDiff); if(managedDiff != nullptr) { SPtr serializedObject = ManagedSerializableObject::createFromExisting(obj); if (!serializedObject) return; managedDiff->apply(serializedObject); } else { SPtr nativeValue = ScriptAssemblyManager::instance().getReflectableFromManagedObject(obj); if (!nativeValue) return; IDiff& diffHandler = nativeValue->getRTTI()->getDiffHandler(); CoreSerializationContext serzContext; diffHandler.applyDiff(nativeValue, rtti_cast(thisPtr->mSerializedDiff), &serzContext); } } bool ScriptSerializedDiff::internal_IsEmpty(ScriptSerializedDiff* thisPtr) { return thisPtr->mSerializedDiff == nullptr; } }