#if UNITY_EDITOR using System; using System.Collections.Generic; using UnityEditor; namespace UnityEngine.Rendering.Universal { [Serializable] internal class Provider2DSources : IProvider2DSources where T : Provider2D where U : Provider2DSource { //Editor [SerializeField] int m_SelectedHashCode; [SerializeReference] SelectionSource m_SelectedSource; [SerializeReference] IProvider2DCache m_Provider2DCache; List m_Sources = new List(); List m_AdditionalSources = new List(); private static int GetSelectedSourceIndexFromId(Provider2DSources provider2DSources) { int hashCode = provider2DSources.m_SelectedHashCode; for (int i = 0; i < provider2DSources.m_Sources.Count; i++) { int sourceHashCode = provider2DSources.m_Sources[i].GetHashCode(); if (hashCode == sourceHashCode) { return i; } } return -1; } static void DeconflictNames(List selectionSources) { Dictionary> selectionSourcesByName = new Dictionary>(); // Add all the names to the dictionary foreach (var selection in selectionSources) { string name = selection.GetSourceName()?.text?.Trim(); ; List sourceList; if(selectionSourcesByName.ContainsKey(name)) { sourceList = selectionSourcesByName[name]; } else { sourceList = new List(); selectionSourcesByName.Add(name, sourceList); } sourceList.Add(selection); } // Look for any repeats foreach(var sourceList in selectionSourcesByName.Values) { // If there is more than one source with the same name renumber it if(sourceList.Count > 1) { for(int i=0;i 0) sourceList[i].m_MenuName.text = sourceList[i].m_MenuName.text + " (" + i + ")"; } } } } static void AddAddtionalSources(Provider2DSources provider2DSources) { List additionalSources = provider2DSources.m_AdditionalSources; if (additionalSources != null) { foreach (SelectionSource additionalSource in additionalSources) { provider2DSources.m_Sources.Add(additionalSource); } } } // This must be called. public static int RefreshSources(IProvider2DSources sources, GameObject gameObj, int providerType) { Provider2DSources provider2DSources = sources as Provider2DSources; Debug.Assert(provider2DSources != null); provider2DSources.m_Sources.Clear(); if (provider2DSources.m_Provider2DCache == null) provider2DSources.m_Provider2DCache = new Provider2DCache(); provider2DSources.m_Provider2DCache.UpdateCache(gameObj); // Combine additional sources with ones from the cache. foreach (var kvp in provider2DSources.m_Provider2DCache.Cache) { if (kvp.m_Key.m_Component != null) { U source = (U)Activator.CreateInstance(typeof(U)); source.Initialize(kvp.m_Value.m_Provider, kvp.m_Key.m_Component, providerType); provider2DSources.m_Sources.Add(source); } } AddAddtionalSources(provider2DSources); DeconflictNames(provider2DSources.m_Sources); // This has to be done because unfortunately the dropdown which supports GUIContent lacks the robustness to handle duplicate names. provider2DSources.m_Sources.Sort((a, b) => b.m_MenuPriority.CompareTo(a.m_MenuPriority)); // Set the current source index return GetSelectedSourceIndexFromId(provider2DSources); } public static void UpdateSelectionFromIndex(IProvider2DSources sources, int index) { Provider2DSources provider2DSources = sources as Provider2DSources; Debug.Assert(provider2DSources != null); if (index >= 0) { provider2DSources.m_SelectedSource = provider2DSources.m_Sources[index]; provider2DSources.m_SelectedHashCode = provider2DSources.m_Sources[index].GetHashCode(); } else { provider2DSources.m_SelectedSource = null; provider2DSources.m_SelectedHashCode = 0; } } public GUIContent[] GetSourceNames() { GUIContent[] content = new GUIContent[m_Sources.Count]; for(int i = 0; i < content.Length; i++) { content[i] = m_Sources[i].GetSourceName(); } return content; } public List GetAdditionalSources() { return m_AdditionalSources; } public int selectedHashCode { get { return m_SelectedHashCode; } set { m_SelectedHashCode = value; } } static public void SetAdditionalSources(SerializedProperty property, List additionalSources) { Provider2DSources sources = property.boxedValue as Provider2DSources; if (sources.m_Sources != null) { sources.m_AdditionalSources.Clear(); foreach (var additionalSource in additionalSources) sources.m_AdditionalSources.Add(additionalSource); } property.boxedValue = sources; property.serializedObject.ApplyModifiedProperties(); } static public void SetSourceType(SerializedProperty property) { property.serializedObject.Update(); Provider2DSources sources = property.boxedValue as Provider2DSources; if (sources.m_SelectedSource != null) sources.m_SelectedSource.SetSourceType(property.serializedObject); property.serializedObject.ApplyModifiedProperties(); } public static void DrawSelectedSourceUI(SerializedProperty property) { property.serializedObject.Update(); Provider2DSources sources = property.boxedValue as Provider2DSources; if (sources.m_SelectedSource != null) sources.m_SelectedSource.DrawUI(property, property.serializedObject, property.serializedObject.targetObjects); property.serializedObject.ApplyModifiedProperties(); } } } #endif