Esempio n. 1
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);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Registers the asset assembly. This assembly should provide <see cref="Asset"/> objects, associated with
        /// <see cref="ICompiler"/> 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.CompilerTypeName)
        /// or
        /// Unable to instantiate compiler [{0}].ToFormat(assetCompiler.CompilerTypeName)
        /// 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");
            }

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

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


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

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

                // Asset FileExtensions
                var assetFileExtensionAttribute = assetType.GetCustomAttribute <AssetFileExtensionAttribute>();
                if (assetFileExtensionAttribute != null && assetFileExtensionAttribute.FileExtensions != null)
                {
                    var extensions = FileUtility.GetFileExtensions(assetFileExtensionAttribute.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);
                        }
                    }
                }

                var assetFormatVersion = assetType.GetCustomAttribute <AssetFormatVersionAttribute>();
                if (assetFormatVersion != null)
                {
                    RegisteredFormatVersions.Add(assetType, assetFormatVersion.Version);
                    RegisteredFormatVersionUpdaterTypes.Add(assetType, assetFormatVersion.AssetUpdaterTypes);
                }

                // Asset factory
                var assetFactory = assetType.GetCustomAttribute <AssetFactoryAttribute>();
                if (assetFactory != null)
                {
                    // A null factory name means that the type is not instantiable
                    if (assetFactory.FactoryTypeName != null)
                    {
                        try
                        {
                            var factoryType = Type.GetType(assetFactory.FactoryTypeName);
                            if (factoryType == null)
                            {
                                log.Error("Unable to find factory [{0}] for asset [{1}]", assetFactory.FactoryTypeName, assetType);
                                goto labelAssetDescription;
                            }

                            var factoryInstance = Activator.CreateInstance(factoryType) as IAssetFactory;
                            if (factoryInstance == null)
                            {
                                log.Error("Invalid factory type [{0}], must inherit from IAssetImporter", assetFactory.FactoryTypeName);
                                goto labelAssetDescription;
                            }

                            RegisterFactory(assetType, factoryInstance);
                        }
                        catch (Exception ex)
                        {
                            if (ex is AssetException)
                            {
                                throw;
                            }

                            throw new AssetException("Unable to instantiate factory [{0}]".ToFormat(assetFactory.FactoryTypeName), ex);
                        }
                    }
                }
                else
                {
                    var assetConstructor = assetType.GetConstructor(Type.EmptyTypes);
                    if (assetConstructor != null)
                    {
                        RegisterFactory(assetType, null);
                    }
                }
labelAssetDescription:

                // Asset description
                var assetDescription = assetType.GetCustomAttribute <AssetDescriptionAttribute>();
                if (assetDescription != null)
                {
                    RegisterDescription(assetType, assetDescription.GetDescription());
                }
            }
        }