using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Reflection; using System.Linq; namespace UnityEngine.Experimental.Rendering { [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public sealed class VolumeComponentMenu : Attribute { public readonly string menu; // TODO: Add support for component icons public VolumeComponentMenu(string menu) { this.menu = menu; } } [Serializable] public class VolumeComponent : ScriptableObject { // Used to control the state of this override - handy to quickly turn a volume override // on & off in the editor public bool active = true; internal ReadOnlyCollection parameters { get; private set; } protected virtual void OnEnable() { // Automatically grab all fields of type VolumeParameter for this instance parameters = this.GetType() .GetFields(BindingFlags.Public | BindingFlags.Instance) .Where(t => t.FieldType.IsSubclassOf(typeof(VolumeParameter))) .OrderBy(t => t.MetadataToken) // Guaranteed order .Select(t => (VolumeParameter)t.GetValue(this)) .ToList() .AsReadOnly(); } protected virtual void OnDisable() { } public void SetAllOverridesTo(bool state) { SetAllOverridesTo(parameters, state); } void SetAllOverridesTo(IEnumerable enumerable, bool state) { foreach (var prop in enumerable) { prop.overrideState = state; var t = prop.GetType(); if (VolumeParameter.IsObjectParameter(t)) { // This method won't be called a lot but this is sub-optimal, fix me var innerParams = (ReadOnlyCollection) t.GetProperty("parameters", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue(prop, null); if (innerParams != null) SetAllOverridesTo(innerParams, state); } } } // Custom hashing function used to compare the state of settings (it's not meant to be // unique but to be a quick way to check if two setting sets have the same state or not). // Hash collision rate should be pretty low. public override int GetHashCode() { unchecked { //return parameters.Aggregate(17, (i, p) => i * 23 + p.GetHash()); int hash = 17; foreach (var p in parameters) hash = hash * 23 + p.GetHashCode(); return hash; } } } }