using System; using System.Collections.Generic; namespace UnityEngine.Rendering { /// <summary> /// Holds the state of a Volume blending update. A global stack is /// available by default in <see cref="VolumeManager"/> but you can also create your own using /// <see cref="VolumeManager.CreateStack"/> if you need to update the manager with specific /// settings and store the results for later use. /// </summary> public sealed class VolumeStack : IDisposable { // Holds the state of _all_ component types you can possibly add on volumes internal readonly Dictionary<Type, VolumeComponent> components = new(); // Holds the default value for every volume parameter for faster per-frame stack reset. internal (VolumeParameter parameter, VolumeParameter defaultValue)[] defaultParameters; internal bool requiresReset = true; internal VolumeStack() { } internal void Reload(List<VolumeComponent> componentDefaultStates) { components.Clear(); requiresReset = true; List<(VolumeParameter parameter, VolumeParameter defaultValue)> defaultParametersList = new(); foreach (var defaultVolumeComponent in componentDefaultStates) { var type = defaultVolumeComponent.GetType(); var component = (VolumeComponent)ScriptableObject.CreateInstance(type); components.Add(type, component); int count = component.parameters.Count; for (int i = 0; i < count; i++) { defaultParametersList.Add(new() { parameter = component.parameters[i], defaultValue = defaultVolumeComponent.parameters[i] }); } } defaultParameters = defaultParametersList.ToArray(); } /// <summary> /// Gets the current state of the <see cref="VolumeComponent"/> of type <typeparamref name="T"/> /// in the stack. /// </summary> /// <typeparam name="T">A type of <see cref="VolumeComponent"/>.</typeparam> /// <returns>The current state of the <see cref="VolumeComponent"/> of type <typeparamref name="T"/> /// in the stack.</returns> public T GetComponent<T>() where T : VolumeComponent { var comp = GetComponent(typeof(T)); return (T)comp; } /// <summary> /// Gets the current state of the <see cref="VolumeComponent"/> of the specified type in the /// stack. /// </summary> /// <param name="type">The type of <see cref="VolumeComponent"/> to look for.</param> /// <returns>The current state of the <see cref="VolumeComponent"/> of the specified type, /// or <c>null</c> if the type is invalid.</returns> public VolumeComponent GetComponent(Type type) { components.TryGetValue(type, out var comp); return comp; } /// <summary> /// Cleans up the content of this stack. Once a <c>VolumeStack</c> is disposed, it souldn't /// be used anymore. /// </summary> public void Dispose() { foreach (var component in components) CoreUtils.Destroy(component.Value); components.Clear(); } } }