public static void Reload(Game game, AssemblyContainer assemblyContainer, List<Assembly> assembliesToUnregister, List<Assembly> assembliesToRegister) { List<Entity> entities = new List<Entity>(); if (game != null) entities.AddRange(game.SceneSystem.SceneInstance); CloneReferenceSerializer.References = new List<object>(); var loadedAssembliesSet = new HashSet<Assembly>(assembliesToUnregister); var reloadedComponents = new List<ReloadedComponentEntryLive>(); var componentsToReload = AssemblyReloader.CollectComponentsToReload(entities, loadedAssembliesSet); foreach (var componentToReload in componentsToReload) { var parsingEvents = SerializeComponent(componentToReload.Component); // TODO: Serialize Scene script too (async?) -- doesn't seem necessary even for complex cases // (i.e. referencing assets, entities and/or scripts) but still a ref counting check might be good reloadedComponents.Add(new ReloadedComponentEntryLive(componentToReload, parsingEvents)); } foreach (var assembly in assembliesToUnregister) { // Unregisters assemblies that have been registered in Package.Load => Package.LoadAssemblyReferencesForPackage AssemblyRegistry.Unregister(assembly); // Unload binary serialization DataSerializerFactory.UnregisterSerializationAssembly(assembly); // Unload assembly assemblyContainer.UnloadAssembly(assembly); } foreach (var assembly in assembliesToRegister) { ModuleRuntimeHelpers.RunModuleConstructor(assembly.ManifestModule); // Unregisters assemblies that have been registered in Package.Load => Package.LoadAssemblyReferencesForPackage AssemblyRegistry.Register(assembly, AssemblyCommonCategories.Assets); DataSerializerFactory.RegisterSerializationAssembly(assembly); } // First pass of deserialization: recreate the scripts foreach (ReloadedComponentEntryLive reloadedScript in reloadedComponents) { // Try to create object var objectStart = reloadedScript.YamlEvents.OfType<MappingStart>().FirstOrDefault(); if (objectStart != null) { // Get type info var objectStartTag = objectStart.Tag; bool alias; var componentType = YamlSerializer.GetSerializerSettings().TagTypeRegistry.TypeFromTag(objectStartTag, out alias); if (componentType != null) { reloadedScript.NewComponent = (EntityComponent)Activator.CreateInstance(componentType); } } } // Second pass: update script references in live objects // As a result, any script references processed by Yaml serializer will point to updated objects (script reference cycle will work!) for (int index = 0; index < CloneReferenceSerializer.References.Count; index++) { var component = CloneReferenceSerializer.References[index] as EntityComponent; if (component != null) { var reloadedComponent = reloadedComponents.FirstOrDefault(x => x.OriginalComponent == component); if (reloadedComponent != null) { CloneReferenceSerializer.References[index] = reloadedComponent.NewComponent; } } } // Third pass: deserialize reloadedComponents.ForEach(x => ReplaceComponent(game, x)); CloneReferenceSerializer.References = null; }
public static void Reload(Game game, AssemblyContainer assemblyContainer, List<Assembly> assembliesToUnregister, List<Assembly> assembliesToRegister) { List<Entity> entities = new List<Entity>(); if (game != null) entities.AddRange(game.SceneSystem.SceneInstance); CloneReferenceSerializer.References = new List<object>(); var loadedAssembliesSet = new HashSet<Assembly>(assembliesToUnregister); var reloadedComponents = new List<ReloadedComponentEntryLive>(); throw new NotImplementedException("Need to reimplement this to use IUnloadable"); foreach (var assembly in assembliesToUnregister) { // Unregisters assemblies that have been registered in Package.Load => Package.LoadAssemblyReferencesForPackage AssemblyRegistry.Unregister(assembly); // Unload binary serialization DataSerializerFactory.UnregisterSerializationAssembly(assembly); // Unload assembly assemblyContainer.UnloadAssembly(assembly); } foreach (var assembly in assembliesToRegister) { ModuleRuntimeHelpers.RunModuleConstructor(assembly.ManifestModule); // Unregisters assemblies that have been registered in Package.Load => Package.LoadAssemblyReferencesForPackage AssemblyRegistry.Register(assembly, AssemblyCommonCategories.Assets); DataSerializerFactory.RegisterSerializationAssembly(assembly); } // First pass of deserialization: recreate the scripts foreach (ReloadedComponentEntryLive reloadedScript in reloadedComponents) { // Try to create object var objectStart = reloadedScript.YamlEvents.OfType<MappingStart>().FirstOrDefault(); if (objectStart != null) { // Get type info var objectStartTag = objectStart.Tag; bool alias; var componentType = AssetYamlSerializer.Default.GetSerializerSettings().TagTypeRegistry.TypeFromTag(objectStartTag, out alias); if (componentType != null) { reloadedScript.NewComponent = (EntityComponent)Activator.CreateInstance(componentType); } } } // Second pass: update script references in live objects // As a result, any script references processed by Yaml serializer will point to updated objects (script reference cycle will work!) for (int index = 0; index < CloneReferenceSerializer.References.Count; index++) { var component = CloneReferenceSerializer.References[index] as EntityComponent; if (component != null) { var reloadedComponent = reloadedComponents.FirstOrDefault(x => x.OriginalComponent == component); if (reloadedComponent != null) { CloneReferenceSerializer.References[index] = reloadedComponent.NewComponent; } } } // Third pass: deserialize reloadedComponents.ForEach(x => ReplaceComponent(game, x)); CloneReferenceSerializer.References = null; }