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
}
}