public static void RegisterSerializationAssembly([NotNull] AssemblySerializers assemblySerializers) { lock (Lock) { // Register it (so that we can get it back if unregistered) if (!AvailableAssemblySerializers.ContainsKey(assemblySerializers.Assembly)) { AvailableAssemblySerializers.Add(assemblySerializers.Assembly, assemblySerializers); } // Check if already loaded if (AssemblySerializers.Contains(assemblySerializers)) { return; } // Update existing SerializerSelector AssemblySerializers.Add(assemblySerializers); } // Run module ctor foreach (var module in assemblySerializers.Modules) { ModuleRuntimeHelpers.RunModuleConstructor(module); } lock (Lock) { RegisterSerializers(assemblySerializers); ++Version; // Invalidate each serializer selector (to force them to rebuild combined list of serializers) foreach (var weakSerializerSelector in SerializerSelectors) { SerializerSelector serializerSelector; if (weakSerializerSelector.TryGetTarget(out serializerSelector)) { serializerSelector.Invalidate(); } } } }
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; }
public void Reload() { CloneReferenceSerializer.References = new List <object>(); var loadedAssembliesSet = new HashSet <Assembly>(assembliesToUnregister); var reloadedScripts = CollectReloadedScriptEntries(loadedAssembliesSet); 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 (ReloadedScriptEntryLive reloadedScript in reloadedScripts) { // Try to create object var objectStart = reloadedScript.YamlEvents.OfType <SharpYaml.Events.MappingStart>().FirstOrDefault(); if (objectStart != null) { // Get type info var objectStartTag = objectStart.Tag; bool alias; var scriptType = YamlSerializer.GetSerializerSettings().TagTypeRegistry.TypeFromTag(objectStartTag, out alias); if (scriptType != null) { reloadedScript.NewScript = (Script)Activator.CreateInstance(scriptType); } } } // 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 script = CloneReferenceSerializer.References[index] as Script; if (script != null) { var reloadedScript = reloadedScripts.Cast <ReloadedScriptEntryLive>().FirstOrDefault(x => x.OriginalScript == script); if (reloadedScript != null) { CloneReferenceSerializer.References[index] = reloadedScript.NewScript; } } } // Third pass: deserialize RestoreReloadedScriptEntries(reloadedScripts); CloneReferenceSerializer.References = null; }