WuhuIslandTesting/Library/PackageCache/com.unity.scriptablebuildpipeline@1.21.5/Editor/Utilities/BuildCacheUtility.cs
2025-01-07 02:06:59 +01:00

200 lines
7.2 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.Build.Content;
using UnityEditor.Build.Pipeline.Interfaces;
using UnityEditor.Build.Pipeline.Utilities;
using UnityEditor.Build.Player;
using UnityEditor.Build.Utilities;
using UnityEngine;
internal class AutoBuildCacheUtility : IDisposable
{
public AutoBuildCacheUtility()
{
BuildCacheUtility.ClearCacheHashes();
}
public void Dispose()
{
BuildCacheUtility.ClearCacheHashes();
}
}
internal static class BuildCacheUtility
{
internal static Dictionary<KeyValuePair<GUID, int>, CacheEntry> m_GuidToHash = new Dictionary<KeyValuePair<GUID, int>, CacheEntry>();
static Dictionary<KeyValuePair<string, int>, CacheEntry> m_PathToHash = new Dictionary<KeyValuePair<string, int>, CacheEntry>();
static Dictionary<KeyValuePair<Type, int>, CacheEntry> m_TypeToHash = new Dictionary<KeyValuePair<Type, int>, CacheEntry>();
static Dictionary<ObjectIdentifier, Type[]> m_ObjectToType = new Dictionary<ObjectIdentifier, Type[]>();
static TypeDB m_TypeDB;
internal static HashSet<GUID> m_ExplicitAssets = new HashSet<GUID>();
#if !ENABLE_TYPE_HASHING
static Hash128 m_UnityVersion = HashingMethods.Calculate(Application.unityVersion).ToHash128();
#endif
public static void SetCurrentBuildContent(IBuildContent content)
{
m_ExplicitAssets.Clear();
foreach (GUID asset in content.Assets)
m_ExplicitAssets.Add(asset);
foreach (GUID scene in content.Scenes)
m_ExplicitAssets.Add(scene);
}
public static CacheEntry GetCacheEntry(GUID asset, int version = 1)
{
CacheEntry entry;
KeyValuePair<GUID, int> key = new KeyValuePair<GUID, int>(asset, version);
if (m_GuidToHash.TryGetValue(key, out entry))
return entry;
entry = new CacheEntry { Guid = asset, Version = version };
string path = AssetDatabase.GUIDToAssetPath(asset.ToString());
entry.Type = CacheEntry.EntryType.Asset;
if (path.Equals(CommonStrings.UnityBuiltInExtraPath, StringComparison.OrdinalIgnoreCase) || path.Equals(CommonStrings.UnityDefaultResourcePath, StringComparison.OrdinalIgnoreCase))
entry.Hash = HashingMethods.Calculate(Application.unityVersion, path).ToHash128();
else
{
entry.Hash = AssetDatabase.GetAssetDependencyHash(path);
if (!entry.Hash.isValid && File.Exists(path))
entry.Hash = HashingMethods.CalculateFile(path).ToHash128();
if (path.EndsWith(".unity", StringComparison.OrdinalIgnoreCase))
entry.Hash = HashingMethods.Calculate(entry.Hash, BuildInterfacesWrapper.SceneCallbackVersionHash, PlayerSettings.stripUnusedMeshComponents).ToHash128();
}
if (entry.Hash.isValid)
entry.Hash = HashingMethods.Calculate(entry.Hash, entry.Version).ToHash128();
entry.Inclusion = m_ExplicitAssets.Contains(asset) ? CacheEntry.InclusionType.Explicit : CacheEntry.InclusionType.Implicit;
m_GuidToHash[key] = entry;
return entry;
}
public static CacheEntry GetCacheEntry(string path, int version = 1)
{
CacheEntry entry;
KeyValuePair<string, int> key = new KeyValuePair<string, int>(path, version);
if (m_PathToHash.TryGetValue(key, out entry))
return entry;
var guid = AssetDatabase.AssetPathToGUID(path);
if (!string.IsNullOrEmpty(guid))
return GetCacheEntry(new GUID(guid), version);
entry = new CacheEntry { File = path, Version = version };
entry.Guid = HashingMethods.Calculate("FileHash", entry.File).ToGUID();
if (File.Exists(entry.File))
entry.Hash = HashingMethods.Calculate(HashingMethods.CalculateFile(entry.File), entry.Version).ToHash128();
entry.Type = CacheEntry.EntryType.File;
m_PathToHash[key] = entry;
return entry;
}
public static CacheEntry GetCacheEntry(Type type, int version = 1)
{
CacheEntry entry;
KeyValuePair<Type, int> key = new KeyValuePair<Type, int>(type, version);
if (m_TypeToHash.TryGetValue(key, out entry))
return entry;
entry = new CacheEntry { ScriptType = type.AssemblyQualifiedName, Version = version };
entry.Guid = HashingMethods.Calculate("TypeHash", entry.ScriptType).ToGUID();
#if ENABLE_TYPE_HASHING
entry.Hash = ContentBuildInterface.CalculatePlayerSerializationHashForType(type, m_TypeDB);
#else
entry.Hash = m_TypeDB != null ? m_TypeDB.GetHash128() : m_UnityVersion;
#endif
entry.Type = CacheEntry.EntryType.ScriptType;
m_TypeToHash[key] = entry;
return entry;
}
static Type[] GetCachedTypesForObject(ObjectIdentifier objectId)
{
if (!m_ObjectToType.TryGetValue(objectId, out Type[] types))
{
#if ENABLE_TYPE_HASHING
types = ContentBuildInterface.GetTypesForObject(objectId);
#else
types = ContentBuildInterface.GetTypeForObjects(new[] { objectId });
#endif
m_ObjectToType[objectId] = types;
}
return types;
}
public static Type GetMainTypeForObject(ObjectIdentifier objectId)
{
Type[] types = GetCachedTypesForObject(objectId);
return types[0];
}
public static Type[] GetMainTypeForObjects(IEnumerable<ObjectIdentifier> objectIds)
{
List<Type> results = new List<Type>();
foreach (var objectId in objectIds)
{
Type[] types = GetCachedTypesForObject(objectId);
results.Add(types[0]);
}
return results.ToArray();
}
public static Type[] GetSortedUniqueTypesForObject(ObjectIdentifier objectId)
{
Type[] types = GetCachedTypesForObject(objectId);
Array.Sort(types, (x, y) => x.AssemblyQualifiedName.CompareTo(y.AssemblyQualifiedName));
return types;
}
public static Type[] GetSortedUniqueTypesForObjects(IEnumerable<ObjectIdentifier> objectIds)
{
Type[] types;
HashSet<Type> results = new HashSet<Type>();
foreach (var objectId in objectIds)
{
types = GetCachedTypesForObject(objectId);
results.UnionWith(types);
}
types = results.ToArray();
Array.Sort(types, (x, y) => x.AssemblyQualifiedName.CompareTo(y.AssemblyQualifiedName));
return types;
}
public static void SetTypeForObjects(IEnumerable<ObjectTypes> pairs)
{
foreach (var pair in pairs)
m_ObjectToType[pair.ObjectID] = pair.Types;
}
internal static void ClearCacheHashes()
{
m_GuidToHash.Clear();
m_PathToHash.Clear();
m_TypeToHash.Clear();
m_ObjectToType.Clear();
m_TypeDB = null;
}
public static void SetTypeDB(TypeDB typeDB)
{
if (m_TypeToHash.Count > 0)
throw new InvalidOperationException("Changing Player TypeDB mid build is not supported at this time.");
m_TypeDB = typeDB;
}
public static CacheEntry GetCacheEntry(ObjectIdentifier objectID, int version = 1)
{
if (objectID.guid.Empty())
return GetCacheEntry(objectID.filePath, version);
return GetCacheEntry(objectID.guid, version);
}
}