ZoeAppClass/Library/PackageCache/com.unity.addressables@1.1.10/Editor/Build/AnalyzeRules/CheckBundleDupeDependencies.cs

176 lines
6.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.AddressableAssets.Build.DataBuilders;
using UnityEditor.AddressableAssets.GUI;
using UnityEditor.AddressableAssets.Settings;
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
using UnityEditor.Build.Pipeline;
using UnityEditor.SceneManagement;
using UnityEngine;
namespace UnityEditor.AddressableAssets.Build.AnalyzeRules
{
class CheckBundleDupeDependencies : BundleRuleBase
{
internal struct CheckDupeResult
{
public AddressableAssetGroup Group;
public List<string> DuplicatedFiles;
public string AssetPath;
public GUID DuplicatedGroupGuid;
}
public override bool CanFix
{
get { return true; }
}
public override string ruleName
{ get { return "Check Duplicate Bundle Dependencies"; } }
[NonSerialized]
internal readonly Dictionary<string, Dictionary<string, List<string>>> m_AllIssues = new Dictionary<string, Dictionary<string, List<string>>>();
[SerializeField]
internal HashSet<GUID> m_ImplicitAssets;
public override List<AnalyzeResult> RefreshAnalysis(AddressableAssetSettings settings)
{
ClearAnalysis();
return CheckForDuplicateDependencies(settings);
}
List<AnalyzeResult> CheckForDuplicateDependencies(AddressableAssetSettings settings)
{
if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
{
Debug.LogError("Cannot run Analyze with unsaved scenes");
m_Results.Add(new AnalyzeResult{resultName = ruleName + "Cannot run Analyze with unsaved scenes"});
return m_Results;
}
CalculateInputDefinitions(settings);
if (m_AllBundleInputDefs.Count > 0)
{
var context = GetBuildContext(settings);
ReturnCode exitCode = RefreshBuild(context);
if (exitCode < ReturnCode.Success)
{
Debug.LogError("Analyze build failed. " + exitCode);
m_Results.Add(new AnalyzeResult{resultName = ruleName + "Analyze build failed. " + exitCode});
return m_Results;
}
var implicitGuids = GetImplicitGuidToFilesMap();
var checkDupeResults = CalculateDuplicates(implicitGuids, context);
BuildImplicitDuplicatedAssetsSet(checkDupeResults);
m_Results = (from issueGroup in m_AllIssues
from bundle in issueGroup.Value
from item in bundle.Value
select new AnalyzeResult {resultName = ruleName + kDelimiter +
issueGroup.Key + kDelimiter +
bundle.Key + kDelimiter +
item, severity = MessageType.Warning}).ToList();
}
if (m_Results.Count == 0)
m_Results.Add(noErrors);
return m_Results;
}
internal IEnumerable<CheckDupeResult> CalculateDuplicates(Dictionary<GUID, List<string>> implicitGuids, AddressableAssetsBuildContext aaContext)
{
//Get all guids that have more than one bundle referencing them
IEnumerable<KeyValuePair<GUID, List<string>>> validGuids =
from dupeGuid in implicitGuids
where dupeGuid.Value.Count > 1
where IsValidPath(AssetDatabase.GUIDToAssetPath(dupeGuid.Key.ToString()))
select dupeGuid;
return
from guidToFile in validGuids
from file in guidToFile.Value
//Get the files that belong to those guids
let fileToBundle = m_ExtractData.WriteData.FileToBundle[file]
//Get the bundles that belong to those files
let bundleToGroup = aaContext.bundleToAssetGroup[fileToBundle]
//Get the asset groups that belong to those bundles
let selectedGroup = aaContext.settings.FindGroup(findGroup => findGroup.Guid == bundleToGroup)
select new CheckDupeResult
{
Group = selectedGroup,
DuplicatedFiles = guidToFile.Value,
AssetPath = AssetDatabase.GUIDToAssetPath(guidToFile.Key.ToString()),
DuplicatedGroupGuid = guidToFile.Key
};
}
internal void BuildImplicitDuplicatedAssetsSet(IEnumerable<CheckDupeResult> checkDupeResults)
{
m_ImplicitAssets = new HashSet<GUID>();
foreach (var checkDupeResult in checkDupeResults)
{
Dictionary<string, List<string>> groupData;
if (!m_AllIssues.TryGetValue(checkDupeResult.Group.Name, out groupData))
{
groupData = new Dictionary<string, List<string>>();
m_AllIssues.Add(checkDupeResult.Group.Name, groupData);
}
foreach (string file in checkDupeResult.DuplicatedFiles)
{
List<string> assets;
if (!groupData.TryGetValue(m_ExtractData.WriteData.FileToBundle[file], out assets))
{
assets = new List<string>();
groupData.Add(m_ExtractData.WriteData.FileToBundle[file], assets);
}
assets.Add(checkDupeResult.AssetPath);
}
m_ImplicitAssets.Add(checkDupeResult.DuplicatedGroupGuid);
}
}
public override void FixIssues(AddressableAssetSettings settings)
{
if (m_ImplicitAssets == null)
CheckForDuplicateDependencies(settings);
if (m_ImplicitAssets.Count == 0)
return;
var group = settings.CreateGroup("Duplicate Asset Isolation", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
foreach (var asset in m_ImplicitAssets)
settings.CreateOrMoveEntry(asset.ToString(), group, false, false);
}
public override void ClearAnalysis()
{
m_AllIssues.Clear();
m_ImplicitAssets = null;
base.ClearAnalysis();
}
}
[InitializeOnLoad]
class RegisterCheckBundleDupeDependencies
{
static RegisterCheckBundleDupeDependencies()
{
AnalyzeWindow.RegisterNewRule<CheckBundleDupeDependencies>();
}
}
}