using System; using System.Collections.Generic; using System.Linq; using UnityEditor.AddressableAssets.Settings; using UnityEngine; namespace AutoGroupGenerator { /// /// Base class for output rules that filter or transform group layouts. /// public abstract class OutputRule : ScriptableObject { #region Fields /// /// Template applied to generated group layouts. /// [SerializeField] protected AddressableAssetGroupTemplate m_Template; /// /// Data container providing input, output, and settings. /// protected DataContainer m_DataContainer; /// /// Cached selection of group layouts targeted by this rule. /// protected List m_Selection; #endregion #region Methods private void OnValidate() { if (m_Template == null) { m_Template = AddressableUtil.FindDefaultAddressableGroupTemplate(); } } /// /// Initializes the rule with the shared data container. /// /// The data container to use. public virtual void Initialize(DataContainer dataContainer) { m_DataContainer = dataContainer; } /// /// Selects group layouts that match this rule's criteria. /// public virtual void Select() { m_Selection = m_DataContainer.GroupLayout.Values.Where(DoesMatchSelectionCriteria).ToList(); } /// /// Applies rule-specific refinements to the selected layouts. /// public virtual void Refine() { ApplyTemplate(m_Selection); } /// /// Clears cached state after execution. /// public virtual void UnInit() { m_DataContainer = null; m_Selection = null; } /// /// Determines whether a group layout matches this rule. /// /// The layout to evaluate. /// True if the layout matches. protected abstract bool DoesMatchSelectionCriteria(GroupLayout groupLayout); /// /// Merges multiple group layouts into a single layout. /// /// Group layouts to merge. /// Optional name for the merged layout. protected void Merge(List groupLayouts, string mergedGroupName = null) { if (groupLayouts == null || groupLayouts.Count == 0) { return; } foreach (var groupLayout in groupLayouts) { if (!m_DataContainer.GroupLayout.ContainsKey(groupLayout.Name)) { Debug.LogError($"Cannot find group layout name = {groupLayout.Name}"); return; } } var keysToRemove = new List(); var allNodes = new HashSet(); var allSources = new HashSet(); foreach (var groupLayout in groupLayouts) { keysToRemove.Add(groupLayout.Name); allNodes.UnionWith(groupLayout.Nodes); allSources.UnionWith(groupLayout.Sources); } var hashOfAllSources = SubgraphCommandQueue.CalculateHashForSources(allSources); string groupLayoutName = !string.IsNullOrEmpty(mergedGroupName) ? mergedGroupName : $"Merged_Shared_Assets_{hashOfAllSources}"; var mergedGroupLayout = new GroupLayout { Nodes = allNodes, Sources = allSources, HashOfSources = hashOfAllSources, Name = groupLayoutName, }; foreach (var key in keysToRemove) { m_DataContainer.GroupLayout.Remove(key); } m_DataContainer.GroupLayout.Add(mergedGroupLayout.Name, mergedGroupLayout); Select(); } /// /// Applies the configured template to the provided group layouts. /// /// Layouts to update. protected void ApplyTemplate(List groupLayouts) { AddressableAssetGroupTemplate template = m_Template != null ? m_Template : AddressableUtil.FindDefaultAddressableGroupTemplate(); foreach (var groupLayout in groupLayouts) { groupLayout.TemplateName = template.name; } } /// /// Renames a group layout in the data container. /// /// Layout to rename. /// New name to apply. protected void Rename(GroupLayout groupLayout, string newName) { if (groupLayout == null || string.IsNullOrEmpty(newName)) { return; } var oldName = groupLayout.Name; if (!m_DataContainer.GroupLayout.ContainsKey(oldName)) { Debug.LogError($"Cannot find group layout name = {oldName}"); return; } if (oldName.Equals(newName)) { return; } if (m_DataContainer.GroupLayout.ContainsKey(newName)) { Debug.LogError($"{newName} is not available!"); return; } m_DataContainer.GroupLayout.Remove(oldName); groupLayout.Name = newName; m_DataContainer.GroupLayout.Add(groupLayout.Name, groupLayout); } #endregion } }