Ejemplo n.º 1
0
 /// <summary>
 /// Gets a type from its <see cref="DataContractAttribute.Alias"/> or <see cref="DataAliasAttribute.Name"/>.
 /// </summary>
 /// <param name="alias"></param>
 /// <returns></returns>
 public static Type GetTypeFromAlias(string alias)
 {
     // TODO: At some point we might want to reorganize AssemblyRegistry and DataSerializerFactory
     // I am not sure the list of assemblies matches between those two (some assemblies are probably not registered in AssemblyRegistry),
     // so the semantic of GetTypeFromAlias (which include all assemblies) might be different than GetType.
     return(DataSerializerFactory.GetTypeFromAlias(alias));
 }
Ejemplo n.º 2
0
        private static void UnloadAssemblies(ILogger log, AssemblyContainer assemblyContainer, List <ReloadedAssembly> loadedAssemblies)
        {
            for (int index = loadedAssemblies.Count - 1; index >= 0; index--)
            {
                var loadedAssembly = loadedAssemblies[index];
                var assembly       = loadedAssembly.PackageLoadedAssembly.Assembly;

                // Already unloaded or never loaded?
                if (assembly == null)
                {
                    continue;
                }

                log?.Info($"Unloading assembly {assembly}");

                // 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);

                loadedAssembly.PackageLoadedAssembly.Assembly = null;
            }
        }
Ejemplo n.º 3
0
        private static void LoadAssemblies(ILogger log, AssemblyContainer assemblyContainer, List <ReloadedAssembly> loadedAssemblies, bool newVersion, bool firstTime)
        {
            foreach (var loadedAssembly in loadedAssemblies)
            {
                loadedAssembly.PackageLoadedAssembly.Path = newVersion ? loadedAssembly.NewAssemblyPath : loadedAssembly.OldAssemblyPath;
                Assembly assembly = null;
                try
                {
                    // If first time, load assembly
                    if (firstTime)
                    {
                        loadedAssembly.NewAssembly = assemblyContainer.LoadAssemblyFromPath(loadedAssembly.PackageLoadedAssembly.Path);
                    }

                    // Load assembly
                    assembly = newVersion
                        ? loadedAssembly.NewAssembly
                        : loadedAssembly.OriginalAssembly;

                    log?.Info($"Loading assembly {assembly}");

                    loadedAssembly.PackageLoadedAssembly.Assembly = assembly;

                    // Unregisters assemblies that have been registered in Package.Load => Package.LoadAssemblyReferencesForPackage
                    AssemblyRegistry.Register(assembly, AssemblyCommonCategories.Assets);

                    DataSerializerFactory.RegisterSerializationAssembly(assembly);
                }
                catch (Exception e)
                {
                    log?.Error($"Error loading assembly {assembly?.ToString() ?? Path.GetFileNameWithoutExtension(loadedAssembly.PackageLoadedAssembly.Path)}: ", e);
                }
            }
        }
Ejemplo n.º 4
0
        internal static void Initialize()
        {
            var assemblySerializers = new AssemblySerializers(typeof(StrategySerializerFactory).GetTypeInfo().Assembly);

            // Register data contract aliases

            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Xenko_EngineSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.Strategy_GameSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Xenko_PhysicsSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Xenko_ParticlesSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Xenko_SpriteStudio_RuntimeSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Xenko_NativeSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Xenko_UISerializerFactory).GetTypeInfo().Module);

            {
                var assemblySerializersProfile = new AssemblySerializersPerProfile();
                assemblySerializers.Profiles["Default"] = assemblySerializersProfile;
            }
            {
                var assemblySerializersProfile = new AssemblySerializersPerProfile();
                assemblySerializers.Profiles["Content"] = assemblySerializersProfile;
            }
            {
                var assemblySerializersProfile = new AssemblySerializersPerProfile();
                assemblySerializers.Profiles["Hash"] = assemblySerializersProfile;
            }
            {
                var assemblySerializersProfile = new AssemblySerializersPerProfile();
                assemblySerializers.Profiles["Clone"] = assemblySerializersProfile;
            }

            DataSerializerFactory.RegisterSerializationAssembly(assemblySerializers);
            AssemblyRegistry.Register(typeof(StrategySerializerFactory).GetTypeInfo().Assembly, AssemblyCommonCategories.Engine);
        }
Ejemplo n.º 5
0
        internal static void Initialize()
        {
            var assemblySerializers = new AssemblySerializers(typeof(Strategy_GameSerializerFactory).GetTypeInfo().Assembly);

            // Register data contract aliases

            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Xenko_EngineSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Core_MathematicsSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_CoreSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Xenko_PhysicsSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Xenko_ParticlesSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Xenko_SpriteStudio_RuntimeSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Xenko_NativeSerializerFactory).GetTypeInfo().Module);
            assemblySerializers.Modules.Add(typeof(SiliconStudio.DataSerializers.SiliconStudio_Xenko_UISerializerFactory).GetTypeInfo().Module);

            {
                var assemblySerializersProfile = new AssemblySerializersPerProfile();
                assemblySerializers.Profiles["Default"] = assemblySerializersProfile;

                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0x8ecbed72, 0x29961d9f, 0x7617bcde, 0x48ddcbbf), typeof(Strategy.BasicCameraController), typeof(SiliconStudio.DataSerializers.Strategy_BasicCameraControllerSerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0xda9eedc9, 0x763b3754, 0x1aba0f49, 0xfd437b97), typeof(Strategy.Believe), typeof(SiliconStudio.DataSerializers.Strategy_BelieveSerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0x65a63635, 0x905b96ce, 0x5fa716d9, 0x67302976), typeof(Strategy.City), typeof(SiliconStudio.DataSerializers.Strategy_CitySerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0xa6f677d0, 0x0f6a25c4, 0x56c1dbd7, 0x70d216a3), typeof(System.Collections.Generic.Dictionary <System.Int32, System.Int32>), typeof(SiliconStudio.Core.Serialization.Serializers.DictionarySerializer <System.Int32, System.Int32>)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0xdc943164, 0x20bcb78a, 0xf70ca33c, 0xf1fd3d6a), typeof(Strategy.City_Classification), typeof(SiliconStudio.DataSerializers.Strategy_City_ClassificationSerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0xa93b8fcb, 0x9809c426, 0x3a89a217, 0x4b079f7c), typeof(Strategy.Country), typeof(SiliconStudio.DataSerializers.Strategy_CountrySerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0x3e3ca2b8, 0x17007a32, 0xa8a3b32f, 0x26e7f933), typeof(System.Collections.Generic.List <System.Int32>), typeof(SiliconStudio.Core.Serialization.Serializers.ListSerializer <System.Int32>)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0xeeced12e, 0xe7cf9dbb, 0x418d7fb1, 0xb4736226), typeof(System.Collections.Generic.Dictionary <Strategy.Population, System.Int32>), typeof(SiliconStudio.Core.Serialization.Serializers.DictionarySerializer <Strategy.Population, System.Int32>)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0x6f744978, 0xf28745fb, 0x96b3d247, 0x06f11b9a), typeof(Strategy.Population), typeof(SiliconStudio.DataSerializers.Strategy_PopulationSerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0x1e34102a, 0x1db28d8e, 0xad398cdc, 0x67d931a3), typeof(Strategy.Government), typeof(SiliconStudio.DataSerializers.Strategy_GovernmentSerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0xeb366091, 0x8f13daa9, 0x2af6fed2, 0x2b70cd7b), typeof(System.Collections.Generic.List <Strategy.Government_Staff_Person>), typeof(SiliconStudio.Core.Serialization.Serializers.ListSerializer <Strategy.Government_Staff_Person>)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0x0f93cb0b, 0xd9c95143, 0x88fe7784, 0x38de8233), typeof(Strategy.Government_Staff_Person), typeof(SiliconStudio.DataSerializers.Strategy_Government_Staff_PersonSerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0x1834c528, 0x4428c4d7, 0x80fbc09a, 0xb103d274), typeof(Strategy.Religion), typeof(SiliconStudio.DataSerializers.Strategy_ReligionSerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0xec16c101, 0x148a775a, 0x4ab58eb2, 0x4c6bfa4d), typeof(Strategy.country_reign_form), typeof(SiliconStudio.DataSerializers.Strategy_country_reign_formSerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0xe72963d9, 0x84002115, 0x9cf6d4cd, 0x3c378fd3), typeof(Strategy.Ethnicity), typeof(SiliconStudio.DataSerializers.Strategy_EthnicitySerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0x1dfc486b, 0xd61bfe58, 0x4e0d571a, 0x2a4deabf), typeof(Strategy.GameManager), typeof(SiliconStudio.DataSerializers.Strategy_GameManagerSerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0x736e9489, 0x057acd73, 0xf1f06ac1, 0x04cee503), typeof(System.Collections.Generic.Dictionary <System.Int32, Strategy.Population>), typeof(SiliconStudio.Core.Serialization.Serializers.DictionarySerializer <System.Int32, Strategy.Population>)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0x386b93ec, 0xb58c77bd, 0x7393c4df, 0xc5d84cf2), typeof(System.Collections.Generic.Dictionary <System.Int32, Strategy.Country>), typeof(SiliconStudio.Core.Serialization.Serializers.DictionarySerializer <System.Int32, Strategy.Country>)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0xdf6c3af2, 0x24e8bdaa, 0xa6f91ebf, 0x67389c06), typeof(System.Collections.Generic.Dictionary <System.Int32, Strategy.Believe>), typeof(SiliconStudio.Core.Serialization.Serializers.DictionarySerializer <System.Int32, Strategy.Believe>)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0x764a2b01, 0x498771de, 0xf8b11b3b, 0x4b0c00ff), typeof(System.Collections.Generic.Dictionary <System.Int32, Strategy.State>), typeof(SiliconStudio.Core.Serialization.Serializers.DictionarySerializer <System.Int32, Strategy.State>)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0xfb71cc71, 0xc716d0b7, 0x72b5948e, 0xb3c53064), typeof(Strategy.State), typeof(SiliconStudio.DataSerializers.Strategy_StateSerializer)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0xfb6b8fed, 0x28034bf3, 0x2c6d2465, 0xe27ec6fb), typeof(System.Collections.Generic.Dictionary <System.Int32, Strategy.Province>), typeof(SiliconStudio.Core.Serialization.Serializers.DictionarySerializer <System.Int32, Strategy.Province>)));
                assemblySerializersProfile.Add(new AssemblySerializerEntry(new SiliconStudio.Core.Storage.ObjectId(0x79983ce7, 0xa418e807, 0xd9b616f3, 0x6c9e7a2c), typeof(Strategy.Province), typeof(SiliconStudio.DataSerializers.Strategy_ProvinceSerializer)));
            }
            {
                var assemblySerializersProfile = new AssemblySerializersPerProfile();
                assemblySerializers.Profiles["Content"] = assemblySerializersProfile;
            }
            {
                var assemblySerializersProfile = new AssemblySerializersPerProfile();
                assemblySerializers.Profiles["Hash"] = assemblySerializersProfile;
            }
            {
                var assemblySerializersProfile = new AssemblySerializersPerProfile();
                assemblySerializers.Profiles["Clone"] = assemblySerializersProfile;
            }

            DataSerializerFactory.RegisterSerializationAssembly(assemblySerializers);
            AssemblyRegistry.Register(typeof(Strategy_GameSerializerFactory).GetTypeInfo().Assembly, AssemblyCommonCategories.Engine);
        }
        public void RegisterAssembly(Assembly assembly, IAttributeRegistry attributeRegistry)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException(nameof(assembly));
            }
            if (attributeRegistry == null)
            {
                throw new ArgumentNullException(nameof(attributeRegistry));
            }

            // Add automatically the assembly for lookup
            if (!lookupAssemblies.Contains(assembly))
            {
                lookupAssemblies.Add(assembly);

                // Register all tags automatically.
                var assemblySerializers = DataSerializerFactory.GetAssemblySerializers(assembly);
                if (assemblySerializers != null)
                {
                    foreach (var dataContractAlias in assemblySerializers.DataContractAliases)
                    {
                        RegisterTagMapping(dataContractAlias.Name, dataContractAlias.Type, dataContractAlias.IsAlias);
                    }
                }
                else
                {
                    Log.Warning($"Assembly [{assembly}] has not been processed by assembly processor with --serialization flags. [DataContract] aliases won't be available.");
                }
                // Automatically register YamlSerializableFactory
                var assemblyScanTypes = AssemblyRegistry.GetScanTypes(assembly);
                if (assemblyScanTypes != null)
                {
                    List <Type> types;

                    // Register serializer factories
                    if (assemblyScanTypes.Types.TryGetValue(typeof(IYamlSerializableFactory), out types))
                    {
                        foreach (var type in types)
                        {
                            if (typeof(IYamlSerializableFactory).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null)
                            {
                                try
                                {
                                    SerializableFactories.Add((IYamlSerializableFactory)Activator.CreateInstance(type));
                                }
                                catch
                                {
                                    // Registrying an assembly should not fail, so we are silently discarding a factory if
                                    // we are not able to load it.
                                }
                            }
                        }
                    }
                }
            }
        }
        public void NondataContractObject_ReturnsXmlSerializer()
        {
            //Arrange
            var factory = new DataSerializerFactory();

            //Act
            var serializer = factory.GetSerializer<XmlTestClass>();

            //Assert
            Assert.IsNotNull(serializer as XmlSerializer<XmlTestClass>, "failed to select XmlSerializer for non data contract");
        }
Ejemplo n.º 8
0
        public override UpdatableMember ResolveIndexer(string indexerName)
        {
            // Note: we currently only support component with data contract aliases
            var dotIndex = indexerName.LastIndexOf('.');

            // TODO: Temporary hack to get static field of the requested type/property name
            // Need to have access to DataContract name<=>type mapping in the runtime (only accessible in SiliconStudio.Core.Design now)
            var typeName = (dotIndex == -1) ? indexerName : indexerName.Substring(0, dotIndex);
            var type     = DataSerializerFactory.GetTypeFromAlias(typeName);

            if (type == null)
            {
                throw new InvalidOperationException($"Can't find a type with alias {typeName}; did you properly set a DataContractAttribute with this alias?");
            }

            return(new EntityComponentPropertyAccessor(type));
        }
Ejemplo n.º 9
0
        public void Serialize(ContentSerializerContext context, SerializationStream stream, T obj)
        {
            // Get serializer
            // Note: Currently registered serializer is the content reference one
            // However, we would like to serialize the actual type here
            if (dataSerializer == null)
            {
                var dataSerializerType = DataSerializerFactory.GetSerializer("Default", typeof(T)).SerializerType;
                if (dataSerializerType == null)
                {
                    throw new InvalidOperationException($"Could not find a serializer for type {typeof(T)}");
                }
                dataSerializer = (DataSerializer <T>)Activator.CreateInstance(dataSerializerType);
                dataSerializer.Initialize(stream.Context.SerializerSelector);
            }

            // Serialize object
            stream.SerializeExtended(ref obj, context.Mode, dataSerializer);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Compiles a list of update operations into a <see cref="CompiledUpdate"/>, for use with <see cref="Run"/>.
        /// </summary>
        /// <param name="rootObjectType">The type of the root object.</param>
        /// <param name="animationPaths">The different paths and source offsets to use when <see cref="Run"/> is applied.</param>
        /// <returns>A <see cref="CompiledUpdate"/> object that can be used for <see cref="Run"/>.</returns>
        public static CompiledUpdate Compile(Type rootObjectType, List <UpdateMemberInfo> animationPaths)
        {
            var currentPath          = string.Empty;
            var temporaryObjectsList = new List <object>();

            var state = new ComputeUpdateOperationState();

            state.UpdateOperations = new List <UpdateOperation>();
            state.StackPath        = new List <AnimationBuilderStackEntry>
            {
                new AnimationBuilderStackEntry(rootObjectType, 0, 0, -1),
            };

            foreach (var animationPath in animationPaths)
            {
                var commonPathParts = 1;

                // Detect how much of the path is unmodified (note: we start from 1 because root always stay there)
                for (int index = 1; index < state.StackPath.Count; index++)
                {
                    var pathPart = state.StackPath[index];

                    // Check if next path part is the same (first check length then content)
                    if (((animationPath.Name.Length == pathPart.EndIndex) ||
                         (animationPath.Name.Length > pathPart.EndIndex && (animationPath.Name[pathPart.EndIndex] == PathDelimiter || animationPath.Name[pathPart.EndIndex] == PathIndexerOpen))) &&
                        string.Compare(animationPath.Name, pathPart.StartIndex, currentPath, pathPart.StartIndex, pathPart.EndIndex - pathPart.StartIndex, StringComparison.Ordinal) == 0)
                    {
                        commonPathParts++;
                        continue;
                    }

                    break;
                }

                PopObjects(ref state, commonPathParts);

                // Parse the new path parts
                state.ParseElementStart = state.StackPath.Last().EndIndex;

                // Compute offset from start of current object
                state.NewOffset = state.StackPath.Last().ObjectStartOffset;

                while (state.ParseElementStart < animationPath.Name.Length)
                {
                    var containerType = state.StackPath.Last().Type;

                    // We have only two cases for now: array or property/field name
                    bool isIndexerAccess = animationPath.Name[state.ParseElementStart] == PathIndexerOpen;
                    if (isIndexerAccess)
                    {
                        // Parse until end of indexer
                        state.ParseElementEnd = animationPath.Name.IndexOf(PathIndexerClose, state.ParseElementStart + 1);
                        if (state.ParseElementEnd == -1)
                        {
                            throw new InvalidOperationException("Property path parse error: could not find indexer end ']'");
                        }

                        // Include the indexer close
                        state.ParseElementEnd++;

                        // Parse integer
                        // TODO: Avoid substring?
                        var indexerString = animationPath.Name.Substring(state.ParseElementStart + 1, state.ParseElementEnd - state.ParseElementStart - 2);

                        // T[], IList<T>, etc...
                        // Try to resolve using custom resolver
                        UpdatableMember updatableMember = null;
                        var             parentType      = containerType;
                        while (parentType != null)
                        {
                            UpdateMemberResolver resolver;
                            if (MemberResolvers.TryGetValue(parentType, out resolver))
                            {
                                updatableMember = resolver.ResolveIndexer(indexerString);
                                if (updatableMember != null)
                                {
                                    break;
                                }
                            }

                            parentType = parentType.GetTypeInfo().BaseType;
                        }

                        // Try interfaces
                        if (updatableMember == null)
                        {
                            foreach (var implementedInterface in containerType.GetTypeInfo().ImplementedInterfaces)
                            {
                                UpdateMemberResolver resolver;
                                if (MemberResolvers.TryGetValue(implementedInterface, out resolver))
                                {
                                    updatableMember = resolver.ResolveIndexer(indexerString);
                                    if (updatableMember != null)
                                    {
                                        break;
                                    }
                                }
                            }
                        }

                        if (updatableMember == null)
                        {
                            throw new InvalidOperationException(string.Format("Property path parse error: could not find binding info for index {0} in type {1}", indexerString, containerType));
                        }

                        ProcessMember(ref state, animationPath, updatableMember, temporaryObjectsList);
                    }
                    else
                    {
                        // Note: first character might be a . delimiter, if so, skip it
                        var propertyStart = state.ParseElementStart;
                        if (animationPath.Name[propertyStart] == PathDelimiter)
                        {
                            propertyStart++;
                        }

                        // Check if it started with a parenthesis (to perform a cast operation)
                        if (animationPath.Name[propertyStart] == PathCastOpen)
                        {
                            // Parse until end of cast operation
                            state.ParseElementEnd = animationPath.Name.IndexOf(PathCastClose, ++propertyStart);
                            if (state.ParseElementEnd == -1)
                            {
                                throw new InvalidOperationException("Property path parse error: could not find cast operation ending ')'");
                            }

                            var typeName = animationPath.Name.Substring(propertyStart, state.ParseElementEnd - propertyStart);

                            // Include the indexer close
                            state.ParseElementEnd++;

                            // Try to resolve using alias first, then full assembly registry using assembly qualified name
                            var type = DataSerializerFactory.GetTypeFromAlias(typeName) ?? AssemblyRegistry.GetType(typeName);
                            if (type == null)
                            {
                                throw new InvalidOperationException($"Could not resolve type {typeName}");
                            }

                            // Push entry with new type
                            // TODO: Should we actually perform an early castclass and skip if type is incorrect?
                            state.StackPath.Add(new AnimationBuilderStackEntry(type, state.ParseElementStart, state.ParseElementEnd, -1)
                            {
                                ObjectStartOffset = state.NewOffset,
                            });
                        }
                        else
                        {
                            UpdatableMember updatableMember;

                            // Parse until end next group (or end)
                            state.ParseElementEnd = animationPath.Name.IndexOfAny(PathGroupDelimiters, state.ParseElementStart + 1);
                            if (state.ParseElementEnd == -1)
                            {
                                state.ParseElementEnd = animationPath.Name.Length;
                            }

                            // TODO: Avoid substring?
                            var propertyName = animationPath.Name.Substring(propertyStart, state.ParseElementEnd - propertyStart);
                            if (!UpdateKeys.TryGetValue(new UpdateKey(containerType, propertyName), out updatableMember))
                            {
                                // Try to resolve using custom resolver
                                var parentType = containerType;
                                while (parentType != null)
                                {
                                    UpdateMemberResolver resolver;
                                    if (MemberResolvers.TryGetValue(parentType, out resolver))
                                    {
                                        updatableMember = resolver.ResolveProperty(propertyName);
                                        if (updatableMember != null)
                                        {
                                            break;
                                        }
                                    }

                                    parentType = parentType.GetTypeInfo().BaseType;
                                }

                                if (updatableMember == null)
                                {
                                    throw new InvalidOperationException(string.Format("Property path parse error: could not find binding info for member {0} in type {1}", propertyName, containerType));
                                }
                            }

                            // Process member
                            ProcessMember(ref state, animationPath, updatableMember, temporaryObjectsList);
                        }
                    }

                    state.ParseElementStart = state.ParseElementEnd;
                }

                currentPath = animationPath.Name;
            }

            // Totally pop the stack (we might still have stuff to copy back into properties
            PopObjects(ref state, 0);

            return(new CompiledUpdate
            {
                TemporaryObjects = temporaryObjectsList.ToArray(),
                UpdateOperations = state.UpdateOperations.ToArray(),
            });
        }
        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;
        }
Ejemplo n.º 12
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;
        }
Ejemplo n.º 13
0
        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;
        }