Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
AttributeBasedRegistry.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 
4 using System;
5 using System.Collections.Generic;
6 using System.Reflection;
7 
8 using SiliconStudio.Core.Diagnostics;
9 using SiliconStudio.Core.Reflection;
10 
11 namespace SiliconStudio.Assets.Compiler
12 {
13  /// <summary>
14  /// A registry that builds itself based on assembly customs attributes
15  /// </summary>
16  /// <typeparam name="T">The type of the attribute that specifies the compiler to use</typeparam>
17  /// <typeparam name="I">The type of the class implementing the <see cref="IAssetCompiler"/> interface to register</typeparam>
18  public abstract class AttributeBasedRegistry<T, I> : CompilerRegistry<I> where T: CompilerAttribute where I: class, IAssetCompiler
19  {
20  private readonly Logger log = GlobalLogger.GetLogger("AssetsCompiler.AttributeBasedRegistry");
21 
22  private readonly HashSet<Assembly> registeredAssemblies = new HashSet<Assembly>();
23 
24  /// <summary>
25  /// Create an instance of that registry
26  /// </summary>
28  {
29  // Statically find all assemblies related to assets and register them
30  var assemblies = AssemblyRegistry.Find(AssemblyCommonCategories.Assets);
31  foreach (var assembly in assemblies)
32  AnalyseAssembly(assembly);
33 
34  AssemblyRegistry.AssemblyRegistered += AssemblyRegistered;
35  }
36 
37  /// <summary>
38  /// Analyses an assembly and extracted asset compilers.
39  /// </summary>
40  /// <param name="assembly"></param>
41  private void AnalyseAssembly(Assembly assembly)
42  {
43  if (assembly == null) throw new ArgumentNullException("assembly");
44 
45  if (registeredAssemblies.Contains(assembly))
46  return;
47 
48  // Process Asset types.
49  foreach (var type in assembly.GetTypes())
50  {
51  // Only process Asset types
52  if (!typeof(Asset).IsAssignableFrom(type) || !type.IsClass)
53  continue;
54 
55  // Asset compiler
56  var compilerAttribute = type.GetCustomAttribute<T>();
57 
58  if (compilerAttribute == null) // no compiler attribute in this asset
59  continue;
60 
61  try
62  {
63  var compilerType = Type.GetType(compilerAttribute.CompilerTypeName);
64  if (compilerType == null)
65  {
66  log.Error("Unable to find compiler [{0}] for asset [{1}]", compilerAttribute.CompilerTypeName, type);
67  continue;
68  }
69 
70  var compilerInstance = Activator.CreateInstance(compilerType) as I;
71  if (compilerInstance == null)
72  {
73  log.Error("Invalid compiler type [{0}], must inherit from IAssetCompiler", compilerAttribute.CompilerTypeName);
74  continue;
75  }
76 
77  RegisterCompiler(type, compilerInstance);
78  }
79  catch (Exception ex)
80  {
81  log.Error("Unable to instantiate compiler [{0}]", ex, compilerAttribute.CompilerTypeName);
82  }
83  }
84  registeredAssemblies.Add(assembly);
85  }
86 
87  private void AssemblyRegistered(object sender, AssemblyRegisteredEventArgs e)
88  {
89  // Handle delay-loading assemblies
91  AnalyseAssembly(e.Assembly);
92  }
93  }
94 }
Base class for Asset.
Definition: Asset.cs:14
Assembly Assembly
Gets the assembly that has been registered.
Base implementation for ILogger.
Definition: Logger.cs:10
An event occuring when an assembly is registered with AssemblyRegistry.
Common categories that can be used with AssemblyRegistry
const string Assets
The assembly is containing assets data.
HashSet< string > Categories
Gets the new categories registered for the specified Assembly
Main interface for compiling an Asset.
Attribute to define for a IAssetCompiler for a Asset.