File size: 4,678 Bytes
18a519f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityObject = UnityEngine.Object;
namespace Unity.VisualScripting
{
public sealed class ValueInput : UnitPort<ValueOutput, IUnitOutputPort, ValueConnection>, IUnitValuePort, IUnitInputPort
{
public ValueInput(string key, Type type) : base(key)
{
Ensure.That(nameof(type)).IsNotNull(type);
this.type = type;
}
public Type type { get; }
public bool hasDefaultValue => unit.defaultValues.ContainsKey(key);
public override IEnumerable<ValueConnection> validConnections => unit?.graph?.valueConnections.WithDestination(this) ?? Enumerable.Empty<ValueConnection>();
public override IEnumerable<InvalidConnection> invalidConnections => unit?.graph?.invalidConnections.WithDestination(this) ?? Enumerable.Empty<InvalidConnection>();
public override IEnumerable<ValueOutput> validConnectedPorts => validConnections.Select(c => c.source);
public override IEnumerable<IUnitOutputPort> invalidConnectedPorts => invalidConnections.Select(c => c.source);
// Use for inspector metadata
[DoNotSerialize]
internal object _defaultValue
{
get
{
return unit.defaultValues[key];
}
set
{
unit.defaultValues[key] = value;
}
}
public bool nullMeansSelf { get; private set; }
public bool allowsNull { get; private set; }
public ValueConnection connection => unit.graph?.valueConnections.SingleOrDefaultWithDestination(this);
public override bool hasValidConnection => connection != null;
public void SetDefaultValue(object value)
{
Ensure.That(nameof(value)).IsOfType(value, type);
if (!SupportsDefaultValue(type))
{
return;
}
if (unit.defaultValues.ContainsKey(key))
{
unit.defaultValues[key] = value;
}
else
{
unit.defaultValues.Add(key, value);
}
}
public override bool CanConnectToValid(ValueOutput port)
{
var source = port;
var destination = this;
return source.type.IsConvertibleTo(destination.type, false);
}
public override void ConnectToValid(ValueOutput port)
{
var source = port;
var destination = this;
destination.Disconnect();
unit.graph.valueConnections.Add(new ValueConnection(source, destination));
}
public override void ConnectToInvalid(IUnitOutputPort port)
{
ConnectInvalid(port, this);
}
public override void DisconnectFromValid(ValueOutput port)
{
var connection = validConnections.SingleOrDefault(c => c.source == port);
if (connection != null)
{
unit.graph.valueConnections.Remove(connection);
}
}
public override void DisconnectFromInvalid(IUnitOutputPort port)
{
DisconnectInvalid(port, this);
}
public ValueInput NullMeansSelf()
{
if (ComponentHolderProtocol.IsComponentHolderType(type))
{
nullMeansSelf = true;
}
return this;
}
public ValueInput AllowsNull()
{
if (type.IsNullable())
{
allowsNull = true;
}
return this;
}
private static readonly HashSet<Type> typesWithDefaultValues = new HashSet<Type>()
{
typeof(Vector2),
typeof(Vector3),
typeof(Vector4),
typeof(Color),
typeof(AnimationCurve),
typeof(Rect),
typeof(Ray),
typeof(Ray2D),
typeof(Type),
#if PACKAGE_INPUT_SYSTEM_EXISTS
typeof(UnityEngine.InputSystem.InputAction),
#endif
};
public static bool SupportsDefaultValue(Type type)
{
return
typesWithDefaultValues.Contains(type) ||
typesWithDefaultValues.Contains(Nullable.GetUnderlyingType(type)) ||
type.IsBasic() ||
typeof(UnityObject).IsAssignableFrom(type);
}
public override IUnitPort CompatiblePort(IUnit unit)
{
if (unit == this.unit) return null;
return unit.CompatibleValueOutput(type);
}
}
}
|