using System; using System.Collections.Generic; namespace Unity.VisualScripting { /// /// Branches flow by switching over an enum. /// [UnitCategory("Control")] [UnitTitle("Switch On Enum")] [UnitShortTitle("Switch")] [UnitSubtitle("On Enum")] [UnitOrder(3)] [TypeIcon(typeof(IBranchUnit))] public sealed class SwitchOnEnum : Unit, IBranchUnit { [DoNotSerialize] public Dictionary branches { get; private set; } [Serialize] [Inspectable, UnitHeaderInspectable] [TypeFilter(Enums = true, Classes = false, Interfaces = false, Structs = false, Primitives = false)] public Type enumType { get; set; } /// /// The entry point for the switch. /// [DoNotSerialize] [PortLabelHidden] public ControlInput enter { get; private set; } /// /// The enum value on which to switch. /// [DoNotSerialize] [PortLabelHidden] public ValueInput @enum { get; private set; } public override bool canDefine => enumType != null && enumType.IsEnum; protected override void Definition() { branches = new Dictionary(); enter = ControlInput(nameof(enter), Enter); @enum = ValueInput(enumType, nameof(@enum)); Requirement(@enum, enter); foreach (var valueByName in EnumUtility.ValuesByNames(enumType)) { var enumName = valueByName.Key; var enumValue = valueByName.Value; // Just like in C#, duplicate switch labels for the same underlying value is prohibited if (!branches.ContainsKey(enumValue)) { var branch = ControlOutput("%" + enumName); branches.Add(enumValue, branch); Succession(enter, branch); } } } public ControlOutput Enter(Flow flow) { var @enum = (Enum)flow.GetValue(this.@enum, enumType); if (branches.ContainsKey(@enum)) { return branches[@enum]; } else { return null; } } } }