using System;
using System.Collections.Generic;
using System.Reflection;
using NUnit.Framework;
using UnityEngine;
namespace UnityEditor.Rendering.Converter
{
class RenderPipelineConverterManager : ScriptableSingleton<RenderPipelineConverterManager>
, ISerializationCallbackReceiver
{
[field:SerializeField]
public List<ConverterState> converterStates { get; private set; } = new();
public RenderPipelineConverterManager()
{
ReloadConverters();
}
private void ReloadConverters()
{
using(UnityEngine.Pool.HashSetPool<Type>.Get(out var availableConverterTypes))
{
foreach (var converterType in TypeCache.GetTypesDerivedFrom<IRenderPipelineConverter>())
{
if (converterType.IsAbstract || converterType.IsInterface)
continue;
var obsoleteAtt = converterType.GetCustomAttribute<ObsoleteAttribute>();
if (obsoleteAtt != null && obsoleteAtt.IsError == false)
{
// Skip obsolete converters that are soft deprecated
continue;
}
availableConverterTypes.Add(converterType);
var serializedConverter = converterStates.Find(i => i.converter.GetType() == converterType);
if (serializedConverter != null)
continue;
var renderPipelineConverter = Activator.CreateInstance(converterType) as IRenderPipelineConverter;
// Create a new ConvertState which holds the active state of the converter
var converterState = new ConverterState
{
isSelected = false,
isInitialized = false,
items = new List<ConverterItemState>(),
converter = renderPipelineConverter
};
converterStates.Add(converterState);
}
foreach(var converter in converterStates)
{
if (!availableConverterTypes.Contains(converter.converter.GetType()))
{
Debug.Log($"Removing converter state {converter.converter.GetType()} as it is no longer available or deprecated.");
converterStates.Remove(converter);
}
}
}
}
internal void Reset()
{
converterStates.Clear();
ReloadConverters();
}
public void OnBeforeSerialize()
{
// TODO: As the converters have data stored inside during initialization we need to clear the states
// Once we keep the items to be classes and converters can inherit them to store any kind of data this can be removed
foreach (var state in converterStates)
state.Clear();
}
public void OnAfterDeserialize()
{
// Something null, remove it
for (int i = converterStates.Count - 1; i >= 0; i--)
{
if (converterStates[i] == null || converterStates[i].converter == null)
{
converterStates.RemoveAt(i);
}
}
}
}
}