Exemple #1
0
        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();
                    }
                }
            }
        }
Exemple #2
0
        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;
        }