diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/AssetDependencyCache.cs b/Assets/YooAsset/Editor/AssetBundleCollector/AssetDependencyCache.cs
index 7d1020a5..6da69a2d 100644
--- a/Assets/YooAsset/Editor/AssetBundleCollector/AssetDependencyCache.cs
+++ b/Assets/YooAsset/Editor/AssetBundleCollector/AssetDependencyCache.cs
@@ -10,246 +10,23 @@ namespace YooAsset.Editor
{
public class AssetDependencyCache
{
- ///
- /// 资源依赖缓存数据库
- ///
- private class CacheDatabase
- {
- private class CacheInfo
- {
- ///
- /// 此哈希函数会聚合了以下内容:源资源路径、源资源、元文件、目标平台以及导入器版本。
- /// 如果此哈希值发送变化,则说明导入资源可能已更改,因此应重新搜集依赖关系。
- ///
- public string DependHash;
-
- ///
- /// 直接依赖资源的GUID列表
- ///
- public List DependGUIDs = new List();
- }
-
- private string _databaseFilePath;
- private readonly Dictionary _database = new Dictionary(100000);
-
- ///
- /// 创建数据库
- ///
- public void CreateDatabase(string databaseFilePath, bool useCacheDatabase)
- {
- _databaseFilePath = databaseFilePath;
- _database.Clear();
-
- try
- {
- if (useCacheDatabase && File.Exists(databaseFilePath))
- {
- // 解析缓存文件
- using var stream = File.OpenRead(databaseFilePath);
- using var reader = new BinaryReader(stream);
- var count = reader.ReadInt32();
- for (int i = 0; i < count; i++)
- {
- var assetPath = reader.ReadString();
- var cacheInfo = new CacheInfo
- {
- DependHash = reader.ReadString(),
- DependGUIDs = ReadStringList(reader),
- };
- _database.Add(assetPath, cacheInfo);
- }
-
- // 移除无效资源
- List removeList = new List(10000);
- foreach (var cacheInfoPair in _database)
- {
- var assetPath = cacheInfoPair.Key;
- var assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
- if (string.IsNullOrEmpty(assetGUID))
- {
- removeList.Add(assetPath);
- }
- }
- foreach (var assetPath in removeList)
- {
- _database.Remove(assetPath);
- }
- }
- }
- catch (Exception ex)
- {
- ClearCache(true);
- Debug.LogError($"Failed to load cache database : {ex.Message}");
- }
-
- // 查找新增或变动资源
- var allAssetPaths = AssetDatabase.GetAllAssetPaths();
- foreach (var assetPath in allAssetPaths)
- {
- if (_database.TryGetValue(assetPath, out CacheInfo cacheInfo))
- {
- var dependHash = AssetDatabase.GetAssetDependencyHash(assetPath);
- if (dependHash.ToString() != cacheInfo.DependHash)
- {
- _database[assetPath] = CreateCacheInfo(assetPath);
- }
- }
- else
- {
- var newCacheInfo = CreateCacheInfo(assetPath);
- _database.Add(assetPath, newCacheInfo);
- }
- }
- }
-
- ///
- /// 保存缓存文件
- ///
- public void SaveCacheFile()
- {
- if (File.Exists(_databaseFilePath))
- File.Delete(_databaseFilePath);
-
- try
- {
- using var stream = File.Create(_databaseFilePath);
- using var writer = new BinaryWriter(stream);
- writer.Write(_database.Count);
- foreach (var assetPair in _database)
- {
- string assetPath = assetPair.Key;
- var assetInfo = assetPair.Value;
- writer.Write(assetPath);
- writer.Write(assetInfo.DependHash);
- WriteStringList(writer, assetInfo.DependGUIDs);
- }
- writer.Flush();
- }
- catch (Exception ex)
- {
- Debug.LogError($"Failed to save cache database : {ex.Message}");
- }
- }
-
- ///
- /// 清理缓存数据
- ///
- public void ClearCache(bool clearDatabaseFile)
- {
- if (clearDatabaseFile)
- {
- if (File.Exists(_databaseFilePath))
- File.Delete(_databaseFilePath);
- }
-
- _database.Clear();
- }
-
- ///
- /// 获取资源的依赖列表
- ///
- public string[] GetDependencies(string assetPath, bool recursive)
- {
- // 注意:AssetDatabase.GetDependencies()方法返回结果里会踢出丢失文件!
- // 注意:AssetDatabase.GetDependencies()方法返回结果里会包含主资源路径!
-
- // 注意:机制上不允许存在未收录的资源
- if (_database.ContainsKey(assetPath) == false)
- {
- throw new Exception($"Fatal : can not found cache info : {assetPath}");
- }
-
- var result = new HashSet { assetPath };
- CollectDependencies(assetPath, result, recursive);
-
- // 注意:AssetDatabase.GetDependencies保持一致,将主资源添加到依赖列表最前面
- return result.ToArray();
- }
- private void CollectDependencies(string assetPath, HashSet result, bool recursive)
- {
- if (_database.TryGetValue(assetPath, out var cacheInfo) == false)
- {
- throw new Exception($"Fatal : can not found cache info : {assetPath}");
- }
-
- foreach (var dependGUID in cacheInfo.DependGUIDs)
- {
- string dependAssetPath = AssetDatabase.GUIDToAssetPath(dependGUID);
- if (string.IsNullOrEmpty(dependAssetPath))
- continue;
-
- // 如果是文件夹资源
- if (AssetDatabase.IsValidFolder(dependAssetPath))
- continue;
-
- // 如果已经收集过
- if (result.Contains(dependAssetPath))
- continue;
-
- result.Add(dependAssetPath);
-
- // 递归收集依赖
- if (recursive)
- CollectDependencies(dependAssetPath, result, recursive);
- }
- }
-
- private List ReadStringList(BinaryReader reader)
- {
- var count = reader.ReadInt32();
- var values = new List(count);
- for (int i = 0; i < count; i++)
- {
- values.Add(reader.ReadString());
- }
- return values;
- }
- private void WriteStringList(BinaryWriter writer, List values)
- {
- writer.Write(values.Count);
- foreach (var value in values)
- {
- writer.Write(value);
- }
- }
- private CacheInfo CreateCacheInfo(string assetPath)
- {
- var dependHash = AssetDatabase.GetAssetDependencyHash(assetPath);
- var dependAssetPaths = AssetDatabase.GetDependencies(assetPath, false);
- var dependGUIDs = new List();
- foreach (var dependAssetPath in dependAssetPaths)
- {
- string guid = AssetDatabase.AssetPathToGUID(dependAssetPath);
- if (string.IsNullOrEmpty(guid) == false)
- {
- dependGUIDs.Add(guid);
- }
- }
-
- var cacheInfo = new CacheInfo();
- cacheInfo.DependHash = dependHash.ToString();
- cacheInfo.DependGUIDs = dependGUIDs;
- return cacheInfo;
- }
- }
-
- private readonly CacheDatabase _database;
+ private readonly AssetDependencyDatabase _database;
///
/// 初始化资源依赖缓存系统
///
- public AssetDependencyCache(bool useCacheDatabase)
+ public AssetDependencyCache(bool useAssetDependencyDB)
{
- if (useCacheDatabase)
+ if (useAssetDependencyDB)
Debug.Log("Use asset dependency database !");
string databaseFilePath = "Library/AssetDependencyDB";
- _database = new CacheDatabase();
- _database.CreateDatabase(databaseFilePath, useCacheDatabase);
+ _database = new AssetDependencyDatabase();
+ _database.CreateDatabase(useAssetDependencyDB, databaseFilePath);
- if (useCacheDatabase)
+ if (useAssetDependencyDB)
{
- _database.SaveCacheFile();
+ _database.SaveDatabase();
}
}
diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/AssetDependencyDatabase.cs b/Assets/YooAsset/Editor/AssetBundleCollector/AssetDependencyDatabase.cs
new file mode 100644
index 00000000..50aea16c
--- /dev/null
+++ b/Assets/YooAsset/Editor/AssetBundleCollector/AssetDependencyDatabase.cs
@@ -0,0 +1,240 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using UnityEditor;
+using UnityEngine;
+
+namespace YooAsset.Editor
+{
+ ///
+ /// 资源依赖数据库
+ ///
+ public class AssetDependencyDatabase
+ {
+ private const string FILE_VERSION = "1.0";
+
+ private class DependencyInfo
+ {
+ ///
+ /// 此哈希函数会聚合了以下内容:源资源路径、源资源、元文件、目标平台以及导入器版本。
+ /// 如果此哈希值发送变化,则说明导入资源可能已更改,因此应重新搜集依赖关系。
+ ///
+ public string DependHash;
+
+ ///
+ /// 直接依赖资源的GUID列表
+ ///
+ public List DependGUIDs = new List();
+ }
+
+ private string _databaseFilePath;
+ private readonly Dictionary _database = new Dictionary(100000);
+
+ ///
+ /// 创建缓存数据库
+ ///
+ public void CreateDatabase(bool readCacheDatabaseFile, string databaseFilePath)
+ {
+ _databaseFilePath = databaseFilePath;
+ _database.Clear();
+
+ try
+ {
+ if (readCacheDatabaseFile && File.Exists(databaseFilePath))
+ {
+ // 解析缓存文件
+ using var stream = File.OpenRead(databaseFilePath);
+ using var reader = new BinaryReader(stream);
+ string fileVersion = reader.ReadString();
+ if (fileVersion != FILE_VERSION)
+ throw new Exception("The database file version not match !");
+
+ var count = reader.ReadInt32();
+ for (int i = 0; i < count; i++)
+ {
+ var assetPath = reader.ReadString();
+ var cacheInfo = new DependencyInfo
+ {
+ DependHash = reader.ReadString(),
+ DependGUIDs = ReadStringList(reader),
+ };
+ _database.Add(assetPath, cacheInfo);
+ }
+
+ // 移除无效资源
+ List removeList = new List(10000);
+ foreach (var cacheInfoPair in _database)
+ {
+ var assetPath = cacheInfoPair.Key;
+ var assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
+ if (string.IsNullOrEmpty(assetGUID))
+ {
+ removeList.Add(assetPath);
+ }
+ }
+ foreach (var assetPath in removeList)
+ {
+ _database.Remove(assetPath);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ ClearDatabase(true);
+ Debug.LogError($"Failed to load cache database : {ex.Message}");
+ }
+
+ // 查找新增或变动资源
+ var allAssetPaths = AssetDatabase.GetAllAssetPaths();
+ foreach (var assetPath in allAssetPaths)
+ {
+ if (_database.TryGetValue(assetPath, out DependencyInfo cacheInfo))
+ {
+ var dependHash = AssetDatabase.GetAssetDependencyHash(assetPath);
+ if (dependHash.ToString() != cacheInfo.DependHash)
+ {
+ _database[assetPath] = CreateDependencyInfo(assetPath);
+ }
+ }
+ else
+ {
+ var newCacheInfo = CreateDependencyInfo(assetPath);
+ _database.Add(assetPath, newCacheInfo);
+ }
+ }
+ }
+
+ ///
+ /// 保存缓存数据库
+ ///
+ public void SaveDatabase()
+ {
+ if (File.Exists(_databaseFilePath))
+ File.Delete(_databaseFilePath);
+
+ try
+ {
+ using var stream = File.Create(_databaseFilePath);
+ using var writer = new BinaryWriter(stream);
+ writer.Write(FILE_VERSION);
+ writer.Write(_database.Count);
+ foreach (var assetPair in _database)
+ {
+ string assetPath = assetPair.Key;
+ var assetInfo = assetPair.Value;
+ writer.Write(assetPath);
+ writer.Write(assetInfo.DependHash);
+ WriteStringList(writer, assetInfo.DependGUIDs);
+ }
+ writer.Flush();
+ }
+ catch (Exception ex)
+ {
+ Debug.LogError($"Failed to save cache database : {ex.Message}");
+ }
+ }
+
+ ///
+ /// 清理缓存数据库
+ ///
+ public void ClearDatabase(bool deleteDatabaseFile)
+ {
+ if (deleteDatabaseFile)
+ {
+ if (File.Exists(_databaseFilePath))
+ File.Delete(_databaseFilePath);
+ }
+
+ _database.Clear();
+ }
+
+ ///
+ /// 获取资源的依赖列表
+ ///
+ public string[] GetDependencies(string assetPath, bool recursive)
+ {
+ // 注意:AssetDatabase.GetDependencies()方法返回结果里会踢出丢失文件!
+ // 注意:AssetDatabase.GetDependencies()方法返回结果里会包含主资源路径!
+
+ // 注意:机制上不允许存在未收录的资源
+ if (_database.ContainsKey(assetPath) == false)
+ {
+ throw new Exception($"Fatal : can not found cache info : {assetPath}");
+ }
+
+ var result = new HashSet { assetPath };
+ CollectDependencies(assetPath, result, recursive);
+
+ // 注意:AssetDatabase.GetDependencies保持一致,将主资源添加到依赖列表最前面
+ return result.ToArray();
+ }
+ private void CollectDependencies(string assetPath, HashSet result, bool recursive)
+ {
+ if (_database.TryGetValue(assetPath, out var cacheInfo) == false)
+ {
+ throw new Exception($"Fatal : can not found cache info : {assetPath}");
+ }
+
+ foreach (var dependGUID in cacheInfo.DependGUIDs)
+ {
+ string dependAssetPath = AssetDatabase.GUIDToAssetPath(dependGUID);
+ if (string.IsNullOrEmpty(dependAssetPath))
+ continue;
+
+ // 如果是文件夹资源
+ if (AssetDatabase.IsValidFolder(dependAssetPath))
+ continue;
+
+ // 如果已经收集过
+ if (result.Contains(dependAssetPath))
+ continue;
+
+ result.Add(dependAssetPath);
+
+ // 递归收集依赖
+ if (recursive)
+ CollectDependencies(dependAssetPath, result, recursive);
+ }
+ }
+
+ private List ReadStringList(BinaryReader reader)
+ {
+ var count = reader.ReadInt32();
+ var values = new List(count);
+ for (int i = 0; i < count; i++)
+ {
+ values.Add(reader.ReadString());
+ }
+ return values;
+ }
+ private void WriteStringList(BinaryWriter writer, List values)
+ {
+ writer.Write(values.Count);
+ foreach (var value in values)
+ {
+ writer.Write(value);
+ }
+ }
+ private DependencyInfo CreateDependencyInfo(string assetPath)
+ {
+ var dependHash = AssetDatabase.GetAssetDependencyHash(assetPath);
+ var dependAssetPaths = AssetDatabase.GetDependencies(assetPath, false);
+ var dependGUIDs = new List();
+ foreach (var dependAssetPath in dependAssetPaths)
+ {
+ string guid = AssetDatabase.AssetPathToGUID(dependAssetPath);
+ if (string.IsNullOrEmpty(guid) == false)
+ {
+ dependGUIDs.Add(guid);
+ }
+ }
+
+ var cacheInfo = new DependencyInfo();
+ cacheInfo.DependHash = dependHash.ToString();
+ cacheInfo.DependGUIDs = dependGUIDs;
+ return cacheInfo;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Editor/AssetBundleCollector/AssetDependencyDatabase.cs.meta b/Assets/YooAsset/Editor/AssetBundleCollector/AssetDependencyDatabase.cs.meta
new file mode 100644
index 00000000..e48d3471
--- /dev/null
+++ b/Assets/YooAsset/Editor/AssetBundleCollector/AssetDependencyDatabase.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 38f3f2338cca06a42a0f845df9fbb563
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: