Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
AssetAnalysis.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 using System.Linq;
6 
7 using SiliconStudio.Assets.Diagnostics;
8 using SiliconStudio.Core.Diagnostics;
9 using SiliconStudio.Core.IO;
10 using SiliconStudio.Core.Serialization;
11 
12 namespace SiliconStudio.Assets.Analysis
13 {
14  /// <summary>
15  /// Analysis for <see cref="AssetItem"/>.
16  /// </summary>
17  public sealed class AssetAnalysis
18  {
20  {
21  if (items == null) throw new ArgumentNullException("items");
22  if (parameters == null) throw new ArgumentNullException("parameters");
23 
24  var result = new LoggerResult();
25  Run(items, result, parameters);
26  return result;
27  }
28 
29  public static void Run(IEnumerable<AssetItem> items, ILogger log, AssetAnalysisParameters parameters)
30  {
31  if (items == null) throw new ArgumentNullException("items");
32  if (log == null) throw new ArgumentNullException("log");
33  if (parameters == null) throw new ArgumentNullException("parameters");
34 
35  foreach (var assetItem in items)
36  {
37  Run(assetItem, log, parameters);
38  }
39  }
40 
42  {
43  var parameters = new AssetAnalysisParameters() { IsProcessingAssetReferences = true, IsLoggingAssetNotFoundAsError = true};
44  var result = new LoggerResult();
45  Run(items, result, parameters);
46  return result;
47  }
48 
49  public static void Run(AssetItem assetItem, ILogger log, AssetAnalysisParameters parameters)
50  {
51  if (assetItem == null) throw new ArgumentNullException("assetItem");
52  if (log == null) throw new ArgumentNullException("log");
53  if (parameters == null) throw new ArgumentNullException("parameters");
54 
55  if (assetItem.Package == null)
56  {
57  throw new InvalidOperationException("AssetItem must belong to an existing package");
58  }
59 
60  var package = assetItem.Package;
61 
62  // Check that there is no duplicate in assets
63  if (package.Session != null)
64  {
65  var packages = package.FindDependencies();
66 
67  foreach (var otherPackage in packages)
68  {
69  var existingAsset = otherPackage.Assets.Find(assetItem.Id);
70 
71  if (existingAsset != null)
72  {
73  log.Error("Assets [{0}] with id [{1}] from Package [{2}] is already loaded from package [{3}]", existingAsset.FullPath, existingAsset.Id, package.FullPath, existingAsset.Package.FullPath);
74  }
75  else
76  {
77  existingAsset = otherPackage.Assets.Find(assetItem.Location);
78  if (existingAsset != null)
79  {
80  log.Error("Assets [{0}] with location [{1}] from Package [{2}] is already loaded from package [{3}]", existingAsset.FullPath, existingAsset.Location, package.FullPath, existingAsset.Package.FullPath);
81  }
82  }
83  }
84  }
85 
86  var assetReferences = AssetReferenceAnalysis.Visit(assetItem.Asset);
87 
88  if (package.Session != null && parameters.IsProcessingAssetReferences)
89  {
90  UpdateAssetReferences(assetItem, assetReferences, log, parameters);
91  }
92  // Update paths for asset items
93 
94  if (parameters.IsProcessingUPaths)
95  {
96  // Find where this asset item was previously stored (in a different package for example)
97  CommonAnalysis.UpdatePaths(assetItem, assetReferences.Where(link => link.Reference is UPath), parameters);
98  }
99  }
100 
101  internal static void UpdateAssetReferences(AssetItem assetItem, IEnumerable<AssetReferenceLink> assetReferences, ILogger log, AssetAnalysisParameters parameters)
102  {
103  var package = assetItem.Package;
104  var session = package.Session;
105 
106  // Update reference
107  foreach (var assetReferenceLink in assetReferences.Where(link => link.Reference is IContentReference))
108  {
109  var contentReference = (IContentReference)assetReferenceLink.Reference;
110  // If the content reference is an asset base that is in fact a root import, just skip it
111  if ((contentReference is AssetBase) && ((AssetBase)contentReference).IsRootImport)
112  {
113  continue;
114  }
115 
116  // Update Asset references (AssetReference, AssetBase, ContentReference)
117  var id = contentReference.Id;
118  var newItemReference = session.FindAsset(id);
119 
120  // If asset was not found by id try to find by its location
121  if (newItemReference == null)
122  {
123  newItemReference = session.FindAsset(contentReference.Location);
124  if (newItemReference != null)
125  {
126  // If asset was found by its location, just emit a warning
127  log.Warning(package, contentReference, AssetMessageCode.AssetReferenceChanged, contentReference, newItemReference.Id);
128  }
129  }
130 
131  // If asset was not found, display an error or a warning
132  if (newItemReference == null)
133  {
134  if (parameters.IsLoggingAssetNotFoundAsError)
135  {
136  log.Error(package, contentReference, AssetMessageCode.AssetNotFound, contentReference);
137  }
138  else
139  {
140  log.Warning(package, contentReference, AssetMessageCode.AssetNotFound, contentReference);
141  }
142  continue;
143  }
144 
145  // Only update location that are actually different
146  var newLocationWithoutExtension = newItemReference.Location;
147  if (newLocationWithoutExtension != contentReference.Location || newItemReference.Id != contentReference.Id)
148  {
149  assetReferenceLink.UpdateReference(newItemReference.Id, newLocationWithoutExtension);
150  assetItem.IsDirty = true;
151  }
152  }
153  }
154  }
155 }
static LoggerResult Run(IEnumerable< AssetItem > items, AssetAnalysisParameters parameters)
SiliconStudio.Core.Diagnostics.LoggerResult LoggerResult
A logger that stores messages locally useful for internal log scenarios.
Definition: LoggerResult.cs:14
An asset item part of a Package accessible through Package.Assets.
Definition: AssetBase.cs:16
An asset item part of a Package accessible through SiliconStudio.Assets.Package.Assets.
Definition: AssetItem.cs:17
Package Package
Gets the package where this asset is stored.
Definition: AssetItem.cs:97
static void Run(IEnumerable< AssetItem > items, ILogger log, AssetAnalysisParameters parameters)
static LoggerResult FixAssetReferences(IEnumerable< AssetItem > items)
Base class that describes a uniform path and provides method to manipulate them. Concrete class are U...
Definition: UPath.cs:21
static void Run(AssetItem assetItem, ILogger log, AssetAnalysisParameters parameters)
An interface that provides a reference to an asset.
Interface for logging.
Definition: ILogger.cs:8