using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityEditor.Rendering.Universal
{
///
/// Filter for the list of converters used in batch mode.
///
/// .)
public enum ConverterFilter
{
///
/// Use this to include converters matching the filter.
///
Inclusive,
///
/// Use this to exclude converters matching the filter.
///
Exclusive
}
///
/// The container to run in batch mode.
///
/// .)
public enum ConverterContainerId
{
///
/// Use this for Built-in to URP converter.
///
BuiltInToURP,
///
/// Use this for Built-in to 2D (URP) converter.
///
BuiltInToURP2D,
///
/// Use this to upgrade 2D (URP) assets.
///
UpgradeURP2DAssets,
}
///
/// The converter to run in batch mode.
///
/// .)
public enum ConverterId
{
///
/// Use this for the material converters.
///
Material,
///
/// Use this for the render settings converters.
///
RenderSettings,
///
/// Use this for the animation clip converters.
///
AnimationClip,
///
/// Use this for readonly material converters.
///
ReadonlyMaterial,
///
/// Use this for post processing V2 converters.
///
PPv2,
///
/// Use this for parametric to freeform light converters.
///
ParametricToFreeformLight,
}
///
/// Class for the converter framework.
///
public static class Converters
{
static Type GetContainerType(ConverterContainerId containerName)
{
switch (containerName)
{
case ConverterContainerId.BuiltInToURP:
return typeof(BuiltInToURPConverterContainer);
case ConverterContainerId.BuiltInToURP2D:
return typeof(BuiltInToURP2DConverterContainer);
case ConverterContainerId.UpgradeURP2DAssets:
return typeof(UpgradeURP2DAssetsContainer);
}
return null;
}
static Type GetConverterType(ConverterId converterName)
{
switch (converterName)
{
case ConverterId.Material:
return typeof(UniversalRenderPipelineMaterialUpgrader);
case ConverterId.RenderSettings:
return typeof(RenderSettingsConverter);
case ConverterId.AnimationClip:
return typeof(AnimationClipConverter);
case ConverterId.ReadonlyMaterial:
return typeof(ReadonlyMaterialConverter);
#if PPV2_EXISTS
case ConverterId.PPv2:
return typeof(PPv2Converter);
#endif
case ConverterId.ParametricToFreeformLight:
return typeof(ParametricToFreeformLightUpgrader);
}
return null;
}
///
/// Call this method to run all the converters in a specific container in batch mode.
///
/// The name of the container which will be batched. All Converters in this Container will run if prerequisites are met.
public static void RunInBatchMode(ConverterContainerId containerName)
{
Type typeName = GetContainerType(containerName);
if (typeName != null)
{
RunInBatchMode(typeName);
}
}
///
/// Call this method to run a specific list of converters in a specific container in batch mode.
///
/// The name of the container which will be batched.
/// The list of converters that will be either included or excluded from batching. These converters need to be part of the passed in container for them to run.
/// The enum that decide if the list of converters will be included or excluded when batching.
public static void RunInBatchMode(ConverterContainerId containerName, List converterList, ConverterFilter converterFilter)
{
Type containerType = GetContainerType(containerName);
List converterTypes = new List(converterList.Count);
foreach (ConverterId typeName in converterList)
{
var converterType = GetConverterType(typeName);
if (containerType != null && !converterTypes.Contains(converterType))
{
converterTypes.Add(converterType);
}
}
if (containerType != null && converterTypes.Any())
{
RunInBatchMode(containerType, converterTypes, converterFilter);
}
}
internal static void RunInBatchMode(Type containerName, List converterList, ConverterFilter converterFilter)
{
Debug.Log($"Converter Batch Mode: {containerName}");
var container = (RenderPipelineConverterContainer)Activator.CreateInstance(containerName);
List converters = GetConvertersInContainer(container);
List convertersToBatch = new List(converters.Count);
// This is just a temp to deal with the Include and Exclude enum
List tempConvertersToBatch = new List(converters.Count);
if (converterFilter == ConverterFilter.Inclusive)
{
foreach (RenderPipelineConverter converter in converters)
{
if (converterList.Contains(converter.GetType()))
{
tempConvertersToBatch.Add(converter);
}
}
}
else if (converterFilter == ConverterFilter.Exclusive)
{
tempConvertersToBatch = converters;
foreach (RenderPipelineConverter converter in converters)
{
if (converterList.Contains(converter.GetType()))
{
tempConvertersToBatch.Remove(converter);
}
}
}
convertersToBatch = tempConvertersToBatch;
BatchConverters(convertersToBatch);
}
///
/// The method that will be run when converting the assets in batch mode.
///
/// The name of the container which will be batched.
internal static void RunInBatchMode(Type containerName)
{
List converters = new List();
var containers = TypeCache.GetTypesDerivedFrom();
foreach (var containerType in containers)
{
if (containerType == containerName)
{
var container = (RenderPipelineConverterContainer)Activator.CreateInstance(containerType);
converters = GetConvertersInContainer(container);
}
}
BatchConverters(converters);
}
internal static void BatchConverters(List converters)
{
// This need to be sorted by Priority property
converters = converters.OrderBy(o => o.priority).ToList();
foreach (RenderPipelineConverter converter in converters)
{
List converterItemInfos = new List();
var initCtx = new InitializeConverterContext { items = converterItemInfos };
initCtx.isBatchMode = true;
converter.OnInitialize(initCtx, () => { });
converter.OnPreRun();
for (int i = 0; i < initCtx.items.Count; i++)
{
var item = new ConverterItemInfo()
{
index = i,
descriptor = initCtx.items[i],
};
var ctx = new RunItemContext(item);
ctx.isBatchMode = true;
converter.OnRun(ref ctx);
string converterStatus = ctx.didFail ? $"Fail\nInfo: {ctx.info}" : "Pass";
Debug.Log($"Name: {ctx.item.descriptor.name}\nConverter Status: {converterStatus}");
}
converter.OnPostRun();
AssetDatabase.SaveAssets();
}
}
internal static List GetConvertersInContainer(RenderPipelineConverterContainer container)
{
List listOfConverters = new List();
var converterList = TypeCache.GetTypesDerivedFrom();
for (int i = 0; i < converterList.Count; ++i)
{
// Iterate over the converters that are used by the current container
RenderPipelineConverter conv = (RenderPipelineConverter)Activator.CreateInstance(converterList[i]);
if (conv.container == container.GetType())
{
listOfConverters.Add(conv);
}
}
return listOfConverters;
}
}
}