Beispiel #1
0
        private static void RegisterAssetAssembly(Assembly assembly)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException(nameof(assembly));
            }

            lock (RegistryLock)
            {
                if (RegisteredAssetAssemblies.Contains(assembly))
                {
                    return;
                }

                RegisteredAssetAssemblies.Add(assembly);

                // Process Asset types.
                foreach (var type in assembly.GetTypes())
                {
                    object instance = null;

                    // Register serializer factories
                    if (!type.IsAbstract && typeof(IYamlSerializableFactory).IsAssignableFrom(type) &&
                        type.GetCustomAttribute <YamlSerializerFactoryAttribute>() != null && type.GetConstructor(Type.EmptyTypes) != null)
                    {
                        try
                        {
                            instance = Activator.CreateInstance(type);
                            RegisteredSerializerFactories.Add((IYamlSerializableFactory)instance);
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"Unable to instantiate serializer factory [{type}]", ex);
                        }
                    }
                    // Custom visitors
                    if (!type.IsAbstract && typeof(IDataCustomVisitor).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null)
                    {
                        try
                        {
                            if (instance == null)
                            {
                                instance = Activator.CreateInstance(type);
                            }
                            RegisteredDataVisitNodes.Add((IDataCustomVisitor)instance);
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"Unable to instantiate custom visitor [{type}]", ex);
                        }
                    }
                    // Asset importer
                    if (!type.IsAbstract && typeof(IAssetImporter).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null)
                    {
                        try
                        {
                            if (instance == null)
                            {
                                instance = Activator.CreateInstance(type);
                            }
                            // Register the importer instance
                            RegisterImporter((IAssetImporter)instance);
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"Unable to instantiate importer [{type.Name}]", ex);
                        }
                    }

                    // Register asset factory
                    if (!type.IsAbstract && typeof(IAssetFactory <Asset>).IsAssignableFrom(type) && !type.IsGenericTypeDefinition &&
                        type.GetConstructor(Type.EmptyTypes) != null)
                    {
                        if (instance == null)
                        {
                            instance = Activator.CreateInstance(type);
                        }
                        RegisteredAssetFactories.Add(type.Name, (IAssetFactory <Asset>)instance);
                    }

                    if (typeof(PackageSessionAnalysisBase).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null)
                    {
                        RegisteredPackageSessionAnalysisTypes.Add(type);
                    }

                    // Package upgraders
                    var packageUpgraderAttribute = type.GetCustomAttribute <PackageUpgraderAttribute>();
                    if (packageUpgraderAttribute != null)
                    {
                        try
                        {
                            var packageUpgrader = (PackageUpgrader)Activator.CreateInstance(type);
                            packageUpgrader.Attribute = packageUpgraderAttribute;
                            RegisteredPackageUpgraders[packageUpgraderAttribute.PackageName] = packageUpgrader;
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"Unable to instantiate package upgrader [{type.Name}]", ex);
                        }
                    }

                    // Asset types
                    var assetType = type;
                    if (typeof(Asset).IsAssignableFrom(assetType) || assetType == typeof(Package))
                    {
                        // Store in a list all asset types loaded
                        if (assetType.IsPublic && !assetType.IsAbstract)
                        {
                            AssetTypes.Add(assetType);
                        }

                        // Asset FileExtensions
                        var assetDescriptionAttribute = assetType.GetCustomAttribute <AssetDescriptionAttribute>();
                        if (assetDescriptionAttribute != null)
                        {
                            if (assetDescriptionAttribute.FileExtensions != null)
                            {
                                var extensions = FileUtility.GetFileExtensions(assetDescriptionAttribute.FileExtensions);
                                RegisteredDefaultAssetExtension[assetType] = extensions.FirstOrDefault();
                                foreach (var extension in extensions)
                                {
                                    if (!RegisteredAssetFileExtensions.ContainsKey(extension))
                                    {
                                        RegisteredAssetFileExtensions.Add(extension, assetType);
                                    }
                                }
                            }

                            if (assetDescriptionAttribute.AlwaysMarkAsRoot)
                            {
                                lock (AlwaysMarkAsRootAssetTypes)
                                {
                                    AlwaysMarkAsRootAssetTypes.Add(assetType);
                                }
                            }
                        }

                        // Content type associated to assets
                        var assetContentType = assetType.GetCustomAttribute <AssetContentTypeAttribute>();
                        if (assetContentType != null)
                        {
                            List <Type> assetTypes;
                            if (!ContentToAssetTypes.TryGetValue(assetContentType.ContentType, out assetTypes))
                            {
                                assetTypes = new List <Type>();
                                ContentToAssetTypes[assetContentType.ContentType] = assetTypes;
                            }
                            assetTypes.Add(assetType);
                            AssetToContentTypes.Add(assetType, assetContentType.ContentType);
                        }

                        // Asset format version (process name by name)
                        var assetFormatVersions = assetType.GetCustomAttributes <AssetFormatVersionAttribute>();
                        foreach (var assetFormatVersion in assetFormatVersions)
                        {
                            var formatVersion = assetFormatVersion.Version;
                            var minVersion    = assetFormatVersion.MinUpgradableVersion;
                            SortedList <string, PackageVersion> formatVersions;
                            if (!RegisteredFormatVersions.TryGetValue(assetType, out formatVersions))
                            {
                                RegisteredFormatVersions.Add(assetType, formatVersions = new SortedList <string, PackageVersion>());
                            }
                            formatVersions.Add(assetFormatVersion.Name, formatVersion);

                            // Asset upgraders (only those matching current name)
                            var assetUpgraders = assetType.GetCustomAttributes <AssetUpgraderAttribute>().Where(x => x.Name == assetFormatVersion.Name);
                            AssetUpgraderCollection upgraderCollection = null;
                            foreach (var upgrader in assetUpgraders)
                            {
                                if (upgraderCollection == null)
                                {
                                    upgraderCollection = new AssetUpgraderCollection(assetType, formatVersion);
                                }

                                upgraderCollection.RegisterUpgrader(upgrader.AssetUpgraderType, upgrader.StartVersion, upgrader.TargetVersion);
                            }
                            if (upgraderCollection != null)
                            {
                                upgraderCollection.Validate(minVersion);
                                RegisteredAssetUpgraders.Add(new KeyValuePair <Type, string>(assetType, assetFormatVersion.Name), upgraderCollection);
                            }
                        }

                        // Part reference types for asset composites
                        if (typeof(AssetComposite).IsAssignableFrom(assetType))
                        {
                            var attributes = assetType.GetCustomAttributes(typeof(AssetPartReferenceAttribute), true).Cast <AssetPartReferenceAttribute>().ToList();
                            foreach (var attribute in attributes)
                            {
                                HashSet <AssetPartReferenceAttribute> relatedPartTypes;
                                if (!RegisteredAssetCompositePartTypes.TryGetValue(attribute.ReferenceableType, out relatedPartTypes))
                                {
                                    relatedPartTypes = new HashSet <AssetPartReferenceAttribute>();
                                    RegisteredAssetCompositePartTypes.Add(attribute.ReferenceableType, relatedPartTypes);
                                }
                                attributes.ForEach(x => relatedPartTypes.Add(x));
                            }
                        }
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Registers the asset assembly. This assembly should provide <see cref="Asset"/> objects, associated with
        /// <see cref="IAssetCompiler"/> and optionaly a <see cref="IAssetImporter"/>.
        /// </summary>
        /// <param name="assembly">The assembly.</param>
        /// <exception cref="System.ArgumentNullException">assembly</exception>
        /// <exception cref="AssetException">
        /// Invalid compiler type [{0}], must inherit from IAssetImporter.ToFormat(assetCompiler.TypeName)
        /// or
        /// Unable to instantiate compiler [{0}].ToFormat(assetCompiler.TypeName)
        /// or
        /// Invalid importer type [{0}], must inherit from IAssetImporter.ToFormat(assetImporter.ImpoterTypeName)
        /// or
        /// Unable to instantiate importer [{0}].ToFormat(assetImporter.ImpoterTypeName)
        /// </exception>
        public static void RegisterAssembly(Assembly assembly)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException("assembly");
            }

            lock (RegistryLock)
            {
                if (RegisteredAssemblies.Contains(assembly))
                {
                    return;
                }
                RegisteredAssemblies.Add(assembly);

                // Process Asset types.
                foreach (var type in assembly.GetTypes())
                {
                    // Register serializer factories
                    if (type.GetCustomAttribute <YamlSerializerFactoryAttribute>() != null)
                    {
                        if (typeof(IYamlSerializableFactory).IsAssignableFrom(type))
                        {
                            try
                            {
                                var yamlFactory = (IYamlSerializableFactory)Activator.CreateInstance(type);
                                RegisteredSerializerFactories.Add(yamlFactory);

                                // TODO: Handle IDataCustomVisitor on its own instead of relying on the coupling with IYamlSerializableFactory
                                var dataCustomVisitor = yamlFactory as IDataCustomVisitor;
                                if (dataCustomVisitor != null)
                                {
                                    RegisteredDataVisitNodes.Add(dataCustomVisitor);
                                }
                            }
                            catch (Exception ex)
                            {
                                Log.Error("Unable to instantiate serializer factory [{0}]", ex, type);
                            }
                        }
                    }

                    if (type.GetCustomAttribute <DiffNodeBuilderAttribute>() != null)
                    {
                        if (typeof(IDataCustomVisitor).IsAssignableFrom(type))
                        {
                            try
                            {
                                var dataCustomVisitor = (IDataCustomVisitor)Activator.CreateInstance(type);
                                RegisteredDataVisitNodeBuilders.Add(dataCustomVisitor);
                            }
                            catch (Exception ex)
                            {
                                Log.Error("Unable to instantiate diff converter [{0}]", ex, type);
                            }
                        }
                    }

                    // Asset importer
                    if (typeof(IAssetImporter).IsAssignableFrom(type) && type.GetConstructor(new Type[0]) != null)
                    {
                        try
                        {
                            var importerInstance = Activator.CreateInstance(type) as IAssetImporter;

                            // Register the importer instance
                            RegisterImporter(importerInstance);
                        }
                        catch (Exception ex)
                        {
                            Log.Error("Unable to instantiate importer [{0}]", ex, type.Name);
                        }
                    }

                    if (typeof(PackageSessionAnalysisBase).IsAssignableFrom(type) && type.GetConstructor(new Type[0]) != null)
                    {
                        RegisteredPackageSessionAnalysisTypes.Add(type);
                    }

                    {
                        var packageUpgraderAttribute = type.GetCustomAttribute <PackageUpgraderAttribute>();
                        if (packageUpgraderAttribute != null)
                        {
                            try
                            {
                                var packageUpgrader = (PackageUpgrader)Activator.CreateInstance(type);
                                packageUpgrader.Attribute = packageUpgraderAttribute;
                                RegisteredPackageUpgraders[packageUpgraderAttribute.PackageName] = packageUpgrader;
                            }
                            catch (Exception ex)
                            {
                                Log.Error("Unable to instantiate package upgrader [{0}]", ex, type.Name);
                            }
                        }
                    }

                    // Only process Asset types
                    var assetType = type;
                    if (!typeof(Asset).IsAssignableFrom(assetType) || !assetType.IsClass)
                    {
                        continue;
                    }

                    // Store in a list all asset types loaded
                    if (assetType.IsPublic && !assetType.IsAbstract)
                    {
                        AssetTypes.Add(assetType);
                    }

                    // Asset FileExtensions
                    var assetDescriptionAttribute = assetType.GetCustomAttribute <AssetDescriptionAttribute>();
                    if (assetDescriptionAttribute != null)
                    {
                        if (assetDescriptionAttribute.FileExtensions != null)
                        {
                            var extensions = FileUtility.GetFileExtensions(assetDescriptionAttribute.FileExtensions);
                            RegisteredDefaultAssetExtension[assetType] = extensions.FirstOrDefault();
                            foreach (var extension in extensions)
                            {
                                if (!RegisteredAssetFileExtensions.ContainsKey(extension))
                                {
                                    RegisteredAssetFileExtensions.Add(extension, assetType);
                                }
                            }
                        }
                        if (!assetDescriptionAttribute.AllowUserCreation)
                        {
                            RegisteredInternalAssetTypes.Add(assetType);
                        }

                        if (assetDescriptionAttribute.AlwaysMarkAsRoot)
                        {
                            lock (AlwaysMarkAsRootAssetTypes)
                            {
                                AlwaysMarkAsRootAssetTypes.Add(assetType);
                            }
                        }
                    }

                    // Asset format version (process name by name)
                    var assetFormatVersions = assetType.GetCustomAttributes <AssetFormatVersionAttribute>();
                    foreach (var assetFormatVersion in assetFormatVersions)
                    {
                        var formatVersion = assetFormatVersion.Version;
                        var minVersion    = assetFormatVersion.MinUpgradableVersion;
                        SortedList <string, PackageVersion> formatVersions;
                        if (!RegisteredFormatVersions.TryGetValue(assetType, out formatVersions))
                        {
                            RegisteredFormatVersions.Add(assetType, formatVersions = new SortedList <string, PackageVersion>());
                        }
                        formatVersions.Add(assetFormatVersion.Name, formatVersion);

                        // Asset upgraders (only those matching current name)
                        var assetUpgraders = assetType.GetCustomAttributes <AssetUpgraderAttribute>().Where(x => x.Name == assetFormatVersion.Name);
                        AssetUpgraderCollection upgraderCollection = null;
                        foreach (var upgrader in assetUpgraders)
                        {
                            if (upgraderCollection == null)
                            {
                                upgraderCollection = new AssetUpgraderCollection(assetType, formatVersion);
                            }

                            upgraderCollection.RegisterUpgrader(upgrader.AssetUpgraderType, upgrader.StartVersion, upgrader.TargetVersion);
                        }
                        if (upgraderCollection != null)
                        {
                            upgraderCollection.Validate(minVersion);
                            RegisteredAssetUpgraders.Add(new KeyValuePair <Type, string>(assetType, assetFormatVersion.Name), upgraderCollection);
                        }
                    }

                    // Asset factory
                    var assetFactory = assetType.GetCustomAttribute <ObjectFactoryAttribute>();
                    if (assetFactory != null)
                    {
                        try
                        {
                            ObjectFactory.RegisterFactory(assetType);
                        }
                        catch (Exception ex)
                        {
                            Log.Error("Unable to instantiate factory [{0}] for asset [{1}]", ex, assetFactory.FactoryTypeName, assetType);
                        }
                    }
                    else
                    {
                        var assetConstructor = assetType.GetConstructor(Type.EmptyTypes);
                        if (assetConstructor != null)
                        {
                            // Register the asset even if it has no factory (default using empty constructor)
                            ObjectFactory.RegisterFactory(assetType, null);
                        }
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Registers the asset assembly. This assembly should provide <see cref="Asset"/> objects, associated with
        /// <see cref="IAssetCompiler"/> and optionaly a <see cref="IAssetImporter"/>.
        /// </summary>
        /// <param name="assembly">The assembly.</param>
        /// <exception cref="System.ArgumentNullException">assembly</exception>
        /// <exception cref="AssetException">
        /// Invalid compiler type [{0}], must inherit from IAssetImporter.ToFormat(assetCompiler.TypeName)
        /// or
        /// Unable to instantiate compiler [{0}].ToFormat(assetCompiler.TypeName)
        /// or
        /// Invalid importer type [{0}], must inherit from IAssetImporter.ToFormat(assetImporter.ImpoterTypeName)
        /// or
        /// Unable to instantiate importer [{0}].ToFormat(assetImporter.ImpoterTypeName)
        /// </exception>
        public static void RegisterAssembly(Assembly assembly)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException("assembly");
            }

            lock (RegisteredAssemblies)
            {
                if (RegisteredAssemblies.Contains(assembly))
                {
                    return;
                }
                RegisteredAssemblies.Add(assembly);
            }

            // Process Asset types.
            foreach (var type in assembly.GetTypes())
            {
                // Register serializer factories
                if (type.GetCustomAttribute <YamlSerializerFactoryAttribute>() != null)
                {
                    if (typeof(IYamlSerializableFactory).IsAssignableFrom(type))
                    {
                        try
                        {
                            var yamlFactory = (IYamlSerializableFactory)Activator.CreateInstance(type);
                            lock (RegisteredSerializerFactories)
                            {
                                RegisteredSerializerFactories.Add(yamlFactory);
                            }
                            // TODO: Handle IDataCustomVisitor on its own instead of relying on the coupling with IYamlSerializableFactory
                            var dataCustomVisitor = yamlFactory as IDataCustomVisitor;
                            if (dataCustomVisitor != null)
                            {
                                lock (RegisteredDataVisitNodes)
                                {
                                    RegisteredDataVisitNodes.Add(dataCustomVisitor);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("Unable to instantiate serializer factory [{0}]", ex, type);
                        }
                    }
                }

                if (type.GetCustomAttribute <DiffNodeBuilderAttribute>() != null)
                {
                    if (typeof(IDataCustomVisitor).IsAssignableFrom(type))
                    {
                        try
                        {
                            var dataCustomVisitor = (IDataCustomVisitor)Activator.CreateInstance(type);
                            lock (RegisteredDataVisitNodeBuilders)
                            {
                                RegisteredDataVisitNodeBuilders.Add(dataCustomVisitor);
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("Unable to instantiate diff converter [{0}]", ex, type);
                        }
                    }
                }

                // Asset importer
                if (typeof(IAssetImporter).IsAssignableFrom(type) && type.GetConstructor(new Type[0]) != null)
                {
                    try
                    {
                        var importerInstance = Activator.CreateInstance(type) as IAssetImporter;

                        // Register the importer instance
                        RegisterImporter(importerInstance);
                    }
                    catch (Exception ex)
                    {
                        Log.Error("Unable to instantiate importer [{0}]", ex, type.Name);
                    }
                }

                if (typeof(PackageSessionAnalysisBase).IsAssignableFrom(type) && type.GetConstructor(new Type[0]) != null)
                {
                    RegisteredPackageSessionAnalysisTypes.Add(type);
                }

                {
                    var packageUpgraderAttribute = type.GetCustomAttribute <PackageUpgraderAttribute>();
                    if (packageUpgraderAttribute != null)
                    {
                        try
                        {
                            var packageUpgrader = (PackageUpgrader)Activator.CreateInstance(type);
                            packageUpgrader.Attribute = packageUpgraderAttribute;
                            RegisteredPackageUpgraders[packageUpgraderAttribute.PackageName] = packageUpgrader;
                        }
                        catch (Exception ex)
                        {
                            Log.Error("Unable to instantiate package upgrader [{0}]", ex, type.Name);
                        }
                    }
                }

                // Only process Asset types
                var assetType = type;
                if (!typeof(Asset).IsAssignableFrom(assetType) || !assetType.IsClass)
                {
                    continue;
                }

                // Store in a list all asset types loaded
                if (assetType.IsPublic && !assetType.IsAbstract)
                {
                    AssetTypes.Add(assetType);
                }

                var isSourceCodeAsset = typeof(SourceCodeAsset).IsAssignableFrom(assetType);

                // Asset FileExtensions
                var assetDescriptionAttribute = assetType.GetCustomAttribute <AssetDescriptionAttribute>();
                if (assetDescriptionAttribute != null)
                {
                    if (assetDescriptionAttribute.FileExtensions != null)
                    {
                        var extensions = FileUtility.GetFileExtensions(assetDescriptionAttribute.FileExtensions);
                        RegisteredDefaultAssetExtension[assetType] = extensions.FirstOrDefault();
                        foreach (var extension in extensions)
                        {
                            RegisteredAssetFileExtensions.Add(extension);

                            // If the asset is a pure sourcecode asset, then register the serializer
                            if (isSourceCodeAsset)
                            {
                                SourceCodeAssetSerializer.RegisterExtension(assetType, extension);
                            }
                        }
                    }
                    if (!assetDescriptionAttribute.AllowUserCreation)
                    {
                        RegisteredInternalAssetTypes.Add(assetType);
                    }
                }

                // Asset format version
                var assetFormatVersion = assetType.GetCustomAttribute <AssetFormatVersionAttribute>();
                int formatVersion      = assetFormatVersion != null ? assetFormatVersion.Version : 0;
                int minVersion         = assetFormatVersion != null ? assetFormatVersion.MinUpgradableVersion : 0;
                RegisteredFormatVersions.Add(assetType, Tuple.Create(minVersion, formatVersion));

                // Asset upgraders
                var assetUpgraders = assetType.GetCustomAttributes <AssetUpgraderAttribute>();
                AssetUpgraderCollection upgraderCollection = null;
                foreach (var upgrader in assetUpgraders)
                {
                    if (upgraderCollection == null)
                    {
                        upgraderCollection = new AssetUpgraderCollection(assetType, formatVersion);
                    }

                    upgraderCollection.RegisterUpgrader(upgrader.AssetUpgraderType, upgrader.StartMinVersion, upgrader.StartMaxVersion, upgrader.TargetVersion);
                }
                if (upgraderCollection != null)
                {
                    upgraderCollection.Validate(minVersion);
                    RegisteredAssetUpgraders.Add(assetType, upgraderCollection);
                }

                // Asset factory
                var assetFactory = assetType.GetCustomAttribute <ObjectFactoryAttribute>();
                if (assetFactory != null)
                {
                    try
                    {
                        ObjectFactory.RegisterFactory(assetType);
                    }
                    catch (Exception ex)
                    {
                        Log.Error("Unable to instantiate factory [{0}] for asset [{1}]", ex, assetFactory.FactoryTypeName, assetType);
                    }
                }
                else
                {
                    var assetConstructor = assetType.GetConstructor(Type.EmptyTypes);
                    if (assetConstructor != null)
                    {
                        // Register the asset even if it has no factory (default using empty constructor)
                        ObjectFactory.RegisterFactory(assetType, null);
                    }
                }

                // Asset description
                var thumbnailCompilerAttribute = assetType.GetCustomAttribute <ThumbnailCompilerAttribute>();
                if (thumbnailCompilerAttribute != null)
                {
                    RegisterDynamicThumbnail(assetType, thumbnailCompilerAttribute.DynamicThumbnails);
                }
            }
        }