static AssetCloner() { ClonerSelector = new SerializerSelector(); ClonerSelector.RegisterProfile("Default"); ClonerSelector.RegisterProfile("Asset"); ClonerSelector.RegisterProfile("AssetClone"); ClonerSelector.ReuseReferences = true; }
/// <summary> /// Clones the specified object, taking special care of <see cref="Entity"/>, <see cref="EntityComponent"/> and external assets. /// User can optionally provides list of cloned objects (list of data reference objects that should be cloned) /// and mapped objects (list of data reference objects that should be ducplicated using the given instance). /// </summary> /// <typeparam name="T"></typeparam> /// <param name="clonedObjects">The cloned objects.</param> /// <param name="mappedObjects">The mapped objects.</param> /// <param name="entity">The entity.</param> /// <returns></returns> private static T Clone <T>(HashSet <object> clonedObjects, TryGetValueFunction <object, object> mappedObjects, T entity) where T : class { if (cloneSerializerSelector == null) { cloneSerializerSelector = new SerializerSelector(); cloneSerializerSelector.ReuseReferences = true; cloneSerializerSelector .RegisterProfile("Default") .RegisterProfile("Clone") .RegisterSerializer(new EntitySerializer()) .RegisterSerializer(new CloneSerializer <string>()) .RegisterSerializer(new CloneSerializer <Effect>()) .RegisterSerializer(new CloneSerializer <Mesh>()) .RegisterSerializer(new CloneSerializer <Model>()) .RegisterSerializer(new CloneSerializer <AnimationClip>()); } // Initialize CloneContext lock (cloneContext) { try { cloneContext.EntitySerializerSelector = cloneSerializerSelector; cloneContext.ClonedObjects = clonedObjects; cloneContext.MappedObjects = mappedObjects; // Serialize var memoryStream = cloneContext.MemoryStream; var writer = new BinarySerializationWriter(memoryStream); writer.Context.SerializerSelector = cloneSerializerSelector; writer.Context.Set(CloneContextProperty, cloneContext); writer.SerializeExtended(entity, ArchiveMode.Serialize, null); // Deserialization reuses this list and expect it to be empty at the beginning. cloneContext.SerializedObjects.Clear(); // Deserialize T result = null; memoryStream.Seek(0, SeekOrigin.Begin); var reader = new BinarySerializationReader(memoryStream); reader.Context.SerializerSelector = cloneSerializerSelector; reader.Context.Set(CloneContextProperty, cloneContext); reader.SerializeExtended(ref result, ArchiveMode.Deserialize, null); return(result); } finally { cloneContext.Cleanup(); } } }