Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
AssetResolver.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 using System;
4 using System.Collections.Generic;
5 
6 using SiliconStudio.Core.IO;
7 
8 namespace SiliconStudio.Assets.Analysis
9 {
10  /// <summary>
11  /// Helper to find available new asset locations and identifiers.
12  /// </summary>
13  public sealed class AssetResolver
14  {
15  /// <summary>
16  /// Delegate to test if the specified location is already used.
17  /// </summary>
18  /// <param name="location">The location to try to use.</param>
19  /// <returns><c>true</c> if the specified location is already used, <c>false</c> otherwise.</returns>
20  public delegate bool ContainsAssetWithLocationDelegate(UFile location);
21 
22  /// <summary>
23  /// Delegate to test if an asset id is already used.
24  /// </summary>
25  /// <param name="guid">The unique identifier.</param>
26  /// <returns><c>true</c> if an asset id is already used, <c>false</c> otherwise.</returns>
27  public delegate bool ContainsAssetWithIdDelegate(Guid guid);
28 
29  private readonly HashSet<Guid> existingIds;
30  private readonly HashSet<string> existingLocations;
31 
32  private readonly ContainsAssetWithLocationDelegate containsLocation;
33 
34  private readonly ContainsAssetWithIdDelegate containsId;
35 
36  /// <summary>
37  /// Initializes a new instance of the <see cref="AssetResolver"/> class.
38  /// </summary>
39  public AssetResolver() : this(null, null)
40  {
41  }
42 
43  /// <summary>
44  /// Initializes a new instance of the <see cref="AssetResolver" /> class.
45  /// </summary>
46  /// <param name="containsAssetWithLocation">The delegate used to check if an asset location is already used.</param>
47  /// <param name="containsAssetWithId">The delegate used to check if an asset identifier is already used.</param>
48  public AssetResolver(ContainsAssetWithLocationDelegate containsAssetWithLocation, ContainsAssetWithIdDelegate containsAssetWithId)
49  {
50  existingIds = new HashSet<Guid>();
51  existingLocations = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
52  ContainsAssetWithLocation = containsAssetWithLocation;
53  ContainsAssetWithId = containsAssetWithId;
54  containsLocation = DefaultContainsLocation;
55  containsId = DefaultContainsId;
56  }
57 
58  /// <summary>
59  /// Gets the locations already used.
60  /// </summary>
61  /// <value>The locations.</value>
62  public HashSet<string> ExistingLocations
63  {
64  get
65  {
66  return existingLocations;
67  }
68  }
69 
70  /// <summary>
71  /// Gets the asset ids already used.
72  /// </summary>
73  /// <value>The existing ids.</value>
74  public HashSet<Guid> ExistingIds
75  {
76  get
77  {
78  return existingIds;
79  }
80  }
81 
82  /// <summary>
83  /// Gets or sets a value indicating whether to always generate a new id on <see cref="RegisterId"/>.
84  /// </summary>
85  /// <value><c>true</c> if [force new identifier]; otherwise, <c>false</c>.</value>
86  public bool AlwaysCreateNewId { get; set; }
87 
88  /// <summary>
89  /// Gets or sets a delegate to test if a location is already used.
90  /// </summary>
91  /// <value>A delegate to test if a location is already used.</value>
92  public ContainsAssetWithLocationDelegate ContainsAssetWithLocation { get; set; }
93 
94  /// <summary>
95  /// Gets or sets a delegate to test if an asset id is already used.
96  /// </summary>
97  /// <value>A delegate to test if an asset id is already used.</value>
98  public ContainsAssetWithIdDelegate ContainsAssetWithId { get; set; }
99 
100  /// <summary>
101  /// Finds a name available for a new asset. This method will try to create a name based on an existing name and will append
102  /// "_" + (number++) on every try. The new location found is added to the known existing locations.
103  /// </summary>
104  /// <param name="location">The location.</param>
105  /// <param name="newLocation">The new location.</param>
106  /// <returns><c>true</c> if there is a new location, <c>false</c> otherwise.</returns>
107  public bool RegisterLocation(UFile location, out UFile newLocation)
108  {
109  var result = FindAvailableLocation(location, containsLocation, out newLocation);
110  ExistingLocations.Add(newLocation ?? location);
111  return result;
112  }
113 
114  /// <summary>
115  /// Registers an asset identifier for usage.
116  /// </summary>
117  /// <param name="assetId">The asset identifier.</param>
118  /// <param name="newGuid">The new unique identifier if an asset has already been registered with the same id.</param>
119  /// <returns><c>true</c> if the asset id is already in used. <paramref name="newGuid" /> contains a new guid, <c>false</c> otherwise.</returns>
120  public bool RegisterId(Guid assetId, out Guid newGuid)
121  {
122  newGuid = assetId;
123  var result = AlwaysCreateNewId || containsId(assetId);
124  if (result)
125  {
126  newGuid = Guid.NewGuid();
127  }
128  ExistingIds.Add(newGuid);
129  return result;
130  }
131 
132  /// <summary>
133  /// Creates a new <see cref="AssetResolver" /> using an existing package to check the existence of asset locations and ids.
134  /// </summary>
135  /// <param name="package">The package.</param>
136  /// <returns>A new AssetResolver.</returns>
137  /// <exception cref="System.ArgumentNullException">package</exception>
138  public static AssetResolver FromPackage(Package package)
139  {
140  if (package == null) throw new ArgumentNullException("package");
141 
142  var packagesForLocation = package.FindDependencies(true);
143  var packagesForIds = package.Session != null ? package.Session.Packages : packagesForLocation;
144 
145  return new AssetResolver(packagesForLocation.ContainsAsset, packagesForIds.ContainsAsset);
146  }
147 
148  /// <summary>
149  /// Creates a new <see cref="AssetResolver"/> using an existing package to check the existence of asset locations and ids.
150  /// </summary>
151  /// <param name="packages">The packages.</param>
152  /// <returns>A new AssetResolver.</returns>
153  /// <exception cref="System.ArgumentNullException">package</exception>
154  public static AssetResolver FromPackage(IList<Package> packages)
155  {
156  if (packages == null) throw new ArgumentNullException("packages");
157  return new AssetResolver(packages.ContainsAsset, packages.ContainsAsset);
158  }
159 
160  /// <summary>
161  /// Default delegate for location.
162  /// </summary>
163  private bool DefaultContainsLocation(UFile location)
164  {
165  if (ExistingLocations.Contains(location))
166  {
167  return true;
168  }
169  if (ContainsAssetWithLocation != null)
170  {
171  return ContainsAssetWithLocation(location);
172  }
173  return false;
174  }
175 
176  /// <summary>
177  /// Default delegate for ids.
178  /// </summary>
179  private bool DefaultContainsId(Guid guid)
180  {
181  if (ExistingIds.Contains(guid))
182  {
183  return true;
184  }
185  if (ContainsAssetWithId != null)
186  {
187  return ContainsAssetWithId(guid);
188  }
189  return false;
190  }
191 
192  /// <summary>
193  /// Finds a name available for a new asset. This method will try to create a name based on an existing name and will append
194  /// "_" + (number++) on every try.
195  /// </summary>
196  /// <param name="location">The path of the original asset.</param>
197  /// <param name="containsAssetWithLocation">The try location.</param>
198  /// <param name="newLocation">A new asset location that has the guaranty to be available when adding the assets to a package..</param>
199  /// <returns><c>true</c> if this is a new location, false otherwise.</returns>
200  /// <exception cref="System.ArgumentNullException">localNames</exception>
201  private static bool FindAvailableLocation(UFile location, ContainsAssetWithLocationDelegate containsAssetWithLocation, out UFile newLocation)
202  {
203  if (location == null) throw new ArgumentNullException("location");
204  if (containsAssetWithLocation == null) throw new ArgumentNullException("containsAssetWithLocation");
205 
206  var pathStr = location.FullPath;
207  int i = 1;
208  string newPath = pathStr;
209  while (containsAssetWithLocation(newPath))
210  {
211  newPath = pathStr + "_" + i;
212  i++;
213  }
214 
215  newLocation = newPath;
216  return i > 1;
217  }
218  }
219 }
bool RegisterLocation(UFile location, out UFile newLocation)
Finds a name available for a new asset. This method will try to create a name based on an existing na...
static AssetResolver FromPackage(Package package)
Creates a new AssetResolver using an existing package to check the existence of asset locations and i...
Helper to find available new asset locations and identifiers.
AssetResolver()
Initializes a new instance of the AssetResolver class.
bool RegisterId(Guid assetId, out Guid newGuid)
Registers an asset identifier for usage.
AssetResolver(ContainsAssetWithLocationDelegate containsAssetWithLocation, ContainsAssetWithIdDelegate containsAssetWithId)
Initializes a new instance of the AssetResolver class.
A package managing assets.
Definition: Package.cs:28
static AssetResolver FromPackage(IList< Package > packages)
Creates a new AssetResolver using an existing package to check the existence of asset locations and i...
Defines a normalized file path. See UPath for details. This class cannot be inherited.
Definition: UFile.cs:13