using System; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Unity.VisualScripting { public interface IUnit : IGraphElementWithDebugData { new FlowGraph graph { get; } #region Definition bool canDefine { get; } bool isDefined { get; } bool failedToDefine { get; } Exception definitionException { get; } void Define(); void EnsureDefined(); void RemoveUnconnectedInvalidPorts(); #endregion #region Default Values Dictionary defaultValues { get; } #endregion #region Ports IUnitPortCollection controlInputs { get; } IUnitPortCollection controlOutputs { get; } IUnitPortCollection valueInputs { get; } IUnitPortCollection valueOutputs { get; } IUnitPortCollection invalidInputs { get; } IUnitPortCollection invalidOutputs { get; } IEnumerable inputs { get; } IEnumerable outputs { get; } IEnumerable validInputs { get; } IEnumerable validOutputs { get; } IEnumerable ports { get; } IEnumerable invalidPorts { get; } IEnumerable validPorts { get; } void PortsChanged(); event Action onPortsChanged; #endregion #region Connections IConnectionCollection relations { get; } IEnumerable connections { get; } #endregion #region Analysis bool isControlRoot { get; } #endregion #region Widget Vector2 position { get; set; } #endregion } public static class XUnit { public static ValueInput CompatibleValueInput(this IUnit unit, Type outputType) { Ensure.That(nameof(outputType)).IsNotNull(outputType); return unit.valueInputs .Where(valueInput => ConversionUtility.CanConvert(outputType, valueInput.type, false)) .OrderBy((valueInput) => { var exactType = outputType == valueInput.type; var free = !valueInput.hasValidConnection; if (free && exactType) { return 1; } else if (free) { return 2; } else if (exactType) { return 3; } else { return 4; } }).FirstOrDefault(); } public static ValueOutput CompatibleValueOutput(this IUnit unit, Type inputType) { Ensure.That(nameof(inputType)).IsNotNull(inputType); return unit.valueOutputs .Where(valueOutput => ConversionUtility.CanConvert(valueOutput.type, inputType, false)) .OrderBy((valueOutput) => { var exactType = inputType == valueOutput.type; var free = !valueOutput.hasValidConnection; if (free && exactType) { return 1; } else if (free) { return 2; } else if (exactType) { return 3; } else { return 4; } }).FirstOrDefault(); } } }