4 using System.Collections.Generic;
6 using System.Reflection;
7 using SharpYaml.Serialization;
8 using SiliconStudio.Assets.Serializers;
9 using SiliconStudio.Core;
10 using SiliconStudio.Core.Diagnostics;
11 using SiliconStudio.Core.Reflection;
12 using SiliconStudio.Core.VisualStudio;
13 using SiliconStudio.Core.Yaml;
16 namespace SiliconStudio.Assets
24 private static Logger log = GlobalLogger.GetLogger(
"Assets.Registry");
26 private static readonly Dictionary<Type, string> RegisteredDefaultAssetExtension =
new Dictionary<Type, string>();
27 private static readonly Dictionary<Type, IAssetFactory> RegisteredFactories =
new Dictionary<Type, IAssetFactory>();
28 private static readonly Dictionary<Type, AssetDescription> RegisteredDescriptions =
new Dictionary<Type, AssetDescription>();
29 private static readonly Dictionary<Guid, IAssetImporter> RegisteredImportersInternal =
new Dictionary<Guid, IAssetImporter>();
30 private static readonly Dictionary<Type, int> RegisteredFormatVersions =
new Dictionary<Type, int>();
31 private static readonly Dictionary<Type, Type[]> RegisteredFormatVersionUpdaterTypes =
new Dictionary<Type, Type[]>();
32 private static readonly Dictionary<string, List<IAssetImporter>> RegisterImportExtensions =
new Dictionary<string, List<IAssetImporter>>(StringComparer.InvariantCultureIgnoreCase);
33 private static readonly HashSet<string> RegisteredAssetFileExtensions =
new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
34 internal static readonly HashSet<Assembly> RegisteredAssemblies =
new HashSet<Assembly>();
35 internal static readonly HashSet<IYamlSerializableFactory> RegisteredSerializerFactories =
new HashSet<IYamlSerializableFactory>();
36 internal static readonly List<IDataCustomVisitor> RegisteredDataVisitNodes =
new List<IDataCustomVisitor>();
37 private static Func<object, string, string> stringExpander;
47 return supportedPlatforms;
58 if (platforms == null)
throw new ArgumentNullException(
"platforms");
59 if (supportedPlatforms.Count > 0)
throw new InvalidOperationException(
"Cannot register new platforms. RegisterSupportedPlatforms can only be called once");
61 supportedPlatforms.AddRange(platforms);
70 stringExpander = expander;
79 public static string ExpandString(
object context,
string stringToExpand)
81 if (stringExpander != null)
83 return stringExpander(context, stringToExpand);
85 return stringToExpand;
94 return RegisteredAssetFileExtensions.ToArray();
105 lock (RegisteredImportersInternal)
107 return RegisteredImportersInternal.Values;
119 if (extension == null)
return false;
120 return RegisteredAssetFileExtensions.Contains(extension);
130 AssertAssetType(assetType);
132 RegisteredDefaultAssetExtension.TryGetValue(assetType, out extension);
143 AssertAssetType(assetType);
145 RegisteredFormatVersions.TryGetValue(assetType, out version);
156 AssertAssetType(assetType);
158 RegisteredFormatVersionUpdaterTypes.TryGetValue(assetType, out updaters);
167 public static string GetDefaultExtension<T>() where T :
Asset
169 return GetDefaultExtension(typeof(T));
178 return RegisteredFactories.Keys.ToArray();
188 AssertAssetType(assetType);
190 RegisteredDescriptions.TryGetValue(assetType, out description);
200 return RegisteredDescriptions.Keys.ToArray();
210 AssertAssetType(assetType);
212 RegisteredFactories.TryGetValue(assetType, out factory);
217 return (
Asset)Activator.CreateInstance(assetType);
220 return factory.New();
232 if (extension == null)
throw new ArgumentNullException(
"extension");
234 lock (RegisterImportExtensions)
236 return RegisterImportExtensions.ContainsKey(extension);
247 if (extension == null)
throw new ArgumentNullException(
"extension");
249 lock (RegisterImportExtensions)
251 List<IAssetImporter> importers;
252 if (RegisterImportExtensions.TryGetValue(extension, out importers))
254 var newImporters =
new List<IAssetImporter>(importers);
268 lock (RegisteredImportersInternal)
271 if (RegisteredImportersInternal.TryGetValue(importerId, out importer))
286 if (importer == null)
throw new ArgumentNullException(
"importer");
289 lock (RegisteredImportersInternal)
291 if (RegisteredImportersInternal.ContainsKey(importer.
Id))
293 RegisteredImportersInternal[importer.Id] = importer;
297 var extensions = FileUtility.GetFileExtensions(importer.SupportedFileExtensions);
298 lock (RegisterImportExtensions)
300 foreach (var extension
in extensions)
302 List<IAssetImporter> importers;
303 if (!RegisterImportExtensions.TryGetValue(extension, out importers))
305 importers =
new List<IAssetImporter>();
306 RegisterImportExtensions.Add(extension, importers);
308 if (!importers.Contains(importer))
310 importers.Add(importer);
312 importers.Sort( (left, right) => -left.DisplayRank.CompareTo(right.DisplayRank));
325 AssertAssetType(assetType);
326 RegisteredFactories[assetType] = factory;
336 if (description == null)
throw new ArgumentNullException(
"description");
337 AssertAssetType(assetType);
338 RegisteredDescriptions[assetType] = description;
358 if (assembly == null)
throw new ArgumentNullException(
"assembly");
360 if (RegisteredAssemblies.Contains(assembly))
364 RegisteredAssemblies.Add(assembly);
367 foreach (var type
in assembly.GetTypes())
377 RegisteredSerializerFactories.Add(yamlFactory);
381 if (dataCustomVisitor != null)
383 RegisteredDataVisitNodes.Add(dataCustomVisitor);
388 log.Error(
"Unable to instantiate serializer factory [{0}]", ex, type);
394 if (typeof(
IAssetImporter).IsAssignableFrom(type) && type.GetConstructor(
new Type[0]) != null)
398 var importerInstance = Activator.CreateInstance(type) as
IAssetImporter;
401 RegisterImporter(importerInstance);
405 log.Error(
"Unable to instantiate importer [{0}]", ex, type.Name);
411 var assetType = type;
412 if (!typeof(
Asset).IsAssignableFrom(assetType) || !assetType.IsClass)
417 var isSourceCodeAsset = typeof(
SourceCodeAsset).IsAssignableFrom(assetType);
421 if (assetFileExtensionAttribute != null && assetFileExtensionAttribute.FileExtensions != null)
423 var extensions = FileUtility.GetFileExtensions(assetFileExtensionAttribute.FileExtensions);
424 RegisteredDefaultAssetExtension[assetType] = extensions.FirstOrDefault();
425 foreach (var extension
in extensions)
427 RegisteredAssetFileExtensions.Add(extension);
430 if (isSourceCodeAsset)
432 SourceCodeAssetSerializer.RegisterExtension(assetType, extension);
438 if (assetFormatVersion != null)
440 RegisteredFormatVersions.Add(assetType, assetFormatVersion.Version);
441 RegisteredFormatVersionUpdaterTypes.Add(assetType, assetFormatVersion.AssetUpdaterTypes);
446 if (assetFactory != null)
449 if (assetFactory.FactoryTypeName != null)
453 var factoryType = Type.GetType(assetFactory.FactoryTypeName);
454 if (factoryType == null)
456 log.Error(
"Unable to find factory [{0}] for asset [{1}]", assetFactory.FactoryTypeName, assetType);
457 goto labelAssetDescription;
460 var factoryInstance = Activator.CreateInstance(factoryType) as
IAssetFactory;
461 if (factoryInstance == null)
463 log.Error(
"Invalid factory type [{0}], must inherit from IAssetImporter", assetFactory.FactoryTypeName);
464 goto labelAssetDescription;
467 RegisterFactory(assetType, factoryInstance);
474 throw new AssetException(
"Unable to instantiate factory [{0}]".ToFormat(assetFactory.FactoryTypeName), ex);
480 var assetConstructor = assetType.GetConstructor(Type.EmptyTypes);
481 if (assetConstructor != null)
483 RegisterFactory(assetType, null);
486 labelAssetDescription:
490 if (assetDescription != null)
492 RegisterDescription(assetType, assetDescription.GetDescription());
497 private static void AssertAssetType(Type assetType)
499 if (assetType == null)
500 throw new ArgumentNullException(
"assetType");
502 if (!typeof(
Asset).IsAssignableFrom(assetType))
503 throw new ArgumentException(
"Type [{0}] must be assignable to Asset".ToFormat(assetType),
"assetType");
506 static AssetRegistry()
509 var assemblies = AssemblyRegistry.Find(AssemblyCommonCategories.Assets);
510 foreach (var assembly
in assemblies)
512 RegisterAssembly(assembly);
514 AssemblyRegistry.AssemblyRegistered += AssemblyRegistry_AssemblyRegistered;
Attribute to define for a IAssetFactory for a Asset.
static bool IsAssetFileExtension(string extension)
Determines whether the extension is an asset file type.
static IAssetImporter FindImporterById(Guid importerId)
Finds an importer by its id.
Attribute use to tag a class that is implementing a IYamlSerializable or IYamlSerializableFactory and...
static AssetDescription GetDescription(Type assetType)
Gets the description associated to the asset type, if available.
A registry for file extensions, IAssetImporter, IAssetFactory and aliases associated with assets...
static void RegisterDescription(Type assetType, AssetDescription description)
Registers a AssetDescription for the specified asset type.
static int GetFormatVersion(Type assetType)
Gets the current format version of an asset.
static void RegisterImporter(IAssetImporter importer)
Registers a IAssetImporter for the specified asset type.
static Type[] GetDescribedTypes()
Returns an array of asset types that have a description.
Interface to create default instance of an asset type.
Assembly Assembly
Gets the assembly that has been registered.
Base implementation for ILogger.
static void RegisterSupportedPlatforms(List< SolutionPlatform > platforms)
Registers the supported platforms.
static void RegisterFactory(Type assetType, IAssetFactory factory)
Registers a IAssetFactory for the specified asset type.
static string GetDefaultExtension(Type assetType)
Gets the default extension associated with an asset.
Guid Id
Gets an unique identifier to identify the importer. See remarks.
An event occuring when an assembly is registered with AssemblyRegistry.
Common categories that can be used with AssemblyRegistry
A custom visitor used by DataVisitorBase.
static void RegisterStringExpander(Func< object, string, string > expander)
Registers the string expander used by the package references.
SiliconStudio.Core.Reflection.AttributeRegistry AttributeRegistry
static bool IsImporterSupportingExtension(string extension)
Determines whether [is importer supporting extension] [the specified extension].
const string Assets
The assembly is containing assets data.
Imports a raw asset into the asset system.
static Type[] GetInstantiableTypes()
Returns an array of asset types that can be instanced with NewDefaultInstance.
static void RegisterAssembly(Assembly assembly)
Registers the asset assembly. This assembly should provide Asset objects, associated with ICompiler a...
Contains user-friendly names and descriptions of an asset type.
static string[] GetAssetFileExtensions()
Gets the asset file extensions.
static Type[] GetFormatVersionUpdaterTypes(Type assetType)
Gets the current format version of an asset.
static IEnumerable< IAssetImporter > FindImporterByExtension(string extension)
Finds the importer associated with an asset by the extension of the file to import.
static string ExpandString(object context, string stringToExpand)
Expands a string using the registered string expander (RegisterStringExpander)
HashSet< string > Categories
Gets the new categories registered for the specified Assembly
A default implementation for IAttributeRegistry. This implementation allows to retrieve default attri...
Associates a file extension (e.g '.pfxfont') with a particular Asset.
static Asset NewDefaultInstance(Type assetType)
Creates a default instance for an asset type.
Associates user-friendly names and descriptions to an asset type.