using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEditor.Rendering.Analytics; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UIElements; namespace UnityEditor.Rendering.Universal { // Status for each row item to say in which state they are in. // This will make sure they are showing the correct icon [Serializable] enum Status { Pending, Warning, Error, Success } // This is the serialized class that stores the state of each item in the list of items to convert [Serializable] class ConverterItemState { public ConverterItemDescriptor descriptor; public bool isActive; // Message that will be displayed on the icon if warning or failed. public string message; // Status of the converted item, Pending, Warning, Error or Success public Status status; internal bool hasConverted = false; } // Each converter uses the active bool // Each converter has a list of active items/assets // We do this so that we can use the binding system of the UI Elements [Serializable] class ConverterState { public bool isActive; public bool isLoading; // to name public bool isInitialized; public List items = new List(); public int pending; public int warnings; public int errors; public int success; public override string ToString() { return $"Warnings: {warnings} - Errors: {errors} - Ok: {success} - Total: {items?.Count ?? 0}"; } public int selectedItemsCount { get { int count = 0; foreach (ConverterItemState itemState in items) { if (itemState.isActive) { count++; } } return count; } } } class ConverterInfo { public IRenderPipelineConverter converter; public ConverterState state; public ConverterInfo(IRenderPipelineConverter converter, ConverterState state) { this.converter = converter; this.state = state; } public Type type => converter.GetType(); } [Serializable] [EditorWindowTitle(title = "Render Pipeline Converters")] internal class RenderPipelineConvertersEditor : EditorWindow, IHasCustomMenu { public VisualTreeAsset converterEditorAsset; public VisualTreeAsset converterItem; public VisualTreeAsset converterWidgetMainAsset; ScrollView m_ScrollView; RenderPipelineConverterVisualElement m_ConverterSelectedVE; Button m_ConvertButton; Button m_InitButton; Button m_ContainerHelpButton; List m_CoreConvertersList = new (); List m_VEList = new (); internal static List CategorizeConverters() { var elements = new List(); var manager = RenderPipelineConverterManager.instance; foreach (var converter in manager.renderPipelineConverters) { elements.Add(new ConverterInfo(converter, manager.GetConverterState(converter))); } return elements; } List m_ContainerChoices = new List(); List m_Containers = new List(); int m_ContainerChoiceIndex = 0; RenderPipelineConverterContainer currentContainer => m_Containers[m_ContainerChoiceIndex]; [MenuItem("Window/Rendering/Render Pipeline Converter", false, 50)] public static void ShowWindow() { RenderPipelineConvertersEditor wnd = GetWindow(); wnd.titleContent = new GUIContent("Render Pipeline Converter"); DontSaveToLayout(wnd); wnd.minSize = new Vector2(650f, 400f); wnd.Show(); } internal static void DontSaveToLayout(EditorWindow wnd) { // Making sure that the window is not saved in layouts. Assembly assembly = typeof(EditorWindow).Assembly; var editorWindowType = typeof(EditorWindow); var hostViewType = assembly.GetType("UnityEditor.HostView"); var containerWindowType = assembly.GetType("UnityEditor.ContainerWindow"); var parentViewField = editorWindowType.GetField("m_Parent", BindingFlags.Instance | BindingFlags.NonPublic); var parentViewValue = parentViewField.GetValue(wnd); // window should not be saved to layout var containerWindowProperty = hostViewType.GetProperty("window", BindingFlags.Instance | BindingFlags.Public); var parentContainerWindowValue = containerWindowProperty.GetValue(parentViewValue); var dontSaveToLayoutField = containerWindowType.GetField("m_DontSaveToLayout", BindingFlags.Instance | BindingFlags.NonPublic); dontSaveToLayoutField.SetValue(parentContainerWindowValue, true); } void OnEnable() { GraphicsToolLifetimeAnalytic.WindowOpened(); } private void OnDisable() { GraphicsToolLifetimeAnalytic.WindowClosed(); } void InitIfNeeded() { if (m_CoreConvertersList.Count > 0) return; foreach (var containerType in TypeCache.GetTypesDerivedFrom()) { var container = (RenderPipelineConverterContainer)Activator.CreateInstance(containerType); m_Containers.Add(container); } // this need to be sorted by Priority property m_Containers = m_Containers .OrderBy(o => o.priority).ToList(); foreach (var container in m_Containers) { m_ContainerChoices.Add(container.name); } m_CoreConvertersList = CategorizeConverters(); } public void CreateGUI() { InitIfNeeded(); rootVisualElement.Clear(); converterEditorAsset.CloneTree(rootVisualElement); rootVisualElement.Q("conversionsDropDown").choices = m_ContainerChoices; rootVisualElement.Q("conversionsDropDown").index = m_ContainerChoiceIndex; // Getting the scrollview where the converters should be added m_ScrollView = rootVisualElement.Q("convertersScrollView"); m_ConvertButton = rootVisualElement.Q