using System; using System.Collections.Generic; using UnityEditor.AddressableAssets.Settings; using UnityEditor.Build.Pipeline.Interfaces; using UnityEngine; using UnityEngine.AddressableAssets.Initialization; using UnityEngine.AddressableAssets.ResourceLocators; namespace UnityEditor.AddressableAssets.Build.DataBuilders { /// <summary> /// Interface for any Addressables specific context objects to be used in the Scriptable Build Pipeline context store /// </summary> public interface IAddressableAssetsBuildContext : IContextObject { } /// <summary> /// Simple context object for passing data through SBP, between different sections of Addressables code. /// </summary> public class AddressableAssetsBuildContext : IAddressableAssetsBuildContext { private AddressableAssetSettings m_Settings; /// <summary> /// The settings object to use. /// </summary> [Obsolete("Use Settings property instead.")] public AddressableAssetSettings settings; /// <summary> /// The settings object to use. /// </summary> public AddressableAssetSettings Settings { get { if (m_Settings == null && !string.IsNullOrEmpty(m_SettingsAssetPath)) m_Settings = AssetDatabase.LoadAssetAtPath<AddressableAssetSettings>(m_SettingsAssetPath); return m_Settings; } set { m_Settings = value; string guid; if (m_Settings != null && AssetDatabase.TryGetGUIDAndLocalFileIdentifier(m_Settings, out guid, out long localId)) m_SettingsAssetPath = AssetDatabase.GUIDToAssetPath(guid); else m_SettingsAssetPath = null; } } private string m_SettingsAssetPath; /// <summary> /// The time the build started /// </summary> public DateTime buildStartTime; /// <summary> /// The current runtime data being built. /// </summary> public ResourceManagerRuntimeData runtimeData; /// <summary> /// The list of catalog locations. /// </summary> public List<ContentCatalogDataEntry> locations; /// <summary> /// Mapping of bundles to asset groups. /// </summary> public Dictionary<string, string> bundleToAssetGroup; /// <summary> /// Mapping of asset group to bundles. /// </summary> public Dictionary<AddressableAssetGroup, List<string>> assetGroupToBundles; /// <summary> /// Set of provider types needed in this build. /// </summary> public HashSet<Type> providerTypes; /// <summary> /// The list of all AddressableAssetEntry objects. /// </summary> public List<AddressableAssetEntry> assetEntries; /// <summary> /// Mapping of AssetBundle to the direct dependencies. /// </summary> public Dictionary<string, List<string>> bundleToImmediateBundleDependencies; /// <summary> /// A mapping of AssetBundle to the full dependency tree, flattened into a single list. /// </summary> public Dictionary<string, List<string>> bundleToExpandedBundleDependencies; /// <summary> /// A mapping of Asset GUID's to resulting ContentCatalogDataEntry entries. /// </summary> internal Dictionary<GUID, List<ContentCatalogDataEntry>> GuidToCatalogLocation = null; private Dictionary<string, List<ContentCatalogDataEntry>> m_PrimaryKeyToDependers = null; internal Dictionary<string, List<ContentCatalogDataEntry>> PrimaryKeyToDependerLocations { get { if (m_PrimaryKeyToDependers != null) return m_PrimaryKeyToDependers; if (locations == null || locations.Count == 0) { Debug.LogError("Attempting to get Entries dependent on key, but currently no locations"); return new Dictionary<string, List<ContentCatalogDataEntry>>(0); } m_PrimaryKeyToDependers = new Dictionary<string, List<ContentCatalogDataEntry>>(locations.Count); foreach (ContentCatalogDataEntry location in locations) { for (int i = 0; i < location.Dependencies.Count; ++i) { string dependencyKey = location.Dependencies[i] as string; if (string.IsNullOrEmpty(dependencyKey)) continue; if (!m_PrimaryKeyToDependers.TryGetValue(dependencyKey, out var dependers)) { dependers = new List<ContentCatalogDataEntry>(); m_PrimaryKeyToDependers.Add(dependencyKey, dependers); } dependers.Add(location); } } return m_PrimaryKeyToDependers; } } private Dictionary<string, ContentCatalogDataEntry> m_PrimaryKeyToLocation = null; internal Dictionary<string, ContentCatalogDataEntry> PrimaryKeyToLocation { get { if (m_PrimaryKeyToLocation != null) return m_PrimaryKeyToLocation; if (locations == null || locations.Count == 0) { Debug.LogError("Attempting to get Primary key to entries dependent on key, but currently no locations"); return new Dictionary<string, ContentCatalogDataEntry>(); } m_PrimaryKeyToLocation = new Dictionary<string, ContentCatalogDataEntry>(); foreach (var loc in locations) { if (loc != null && loc.Keys[0] != null && loc.Keys[0] is string && !m_PrimaryKeyToLocation.ContainsKey((string)loc.Keys[0])) m_PrimaryKeyToLocation[(string)loc.Keys[0]] = loc; } return m_PrimaryKeyToLocation; } } } }