File size: 3,775 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 | namespace Unity.VisualScripting
{
/// <summary>
/// Sets the value of a field or property via reflection.
/// </summary>
public sealed class SetMember : MemberUnit
{
public SetMember() : base() { }
public SetMember(Member member) : base(member) { }
/// <summary>
/// Whether the target should be output to allow for chaining.
/// </summary>
[Serialize]
[InspectableIf(nameof(supportsChaining))]
public bool chainable { get; set; }
[DoNotSerialize]
public bool supportsChaining => member.requiresTarget;
[DoNotSerialize]
[MemberFilter(Fields = true, Properties = true, ReadOnly = false)]
public Member setter
{
get => member;
set => member = value;
}
[DoNotSerialize]
[PortLabelHidden]
public ControlInput assign { get; private set; }
[DoNotSerialize]
[PortLabel("Value")]
[PortLabelHidden]
public ValueInput input { get; private set; }
[DoNotSerialize]
[PortLabel("Value")]
[PortLabelHidden]
public ValueOutput output { get; private set; }
/// <summary>
/// The target object used when setting the value.
/// </summary>
[DoNotSerialize]
[PortLabel("Target")]
[PortLabelHidden]
public ValueOutput targetOutput { get; private set; }
[DoNotSerialize]
[PortLabelHidden]
public ControlOutput assigned { get; private set; }
protected override void Definition()
{
base.Definition();
assign = ControlInput(nameof(assign), Assign);
assigned = ControlOutput(nameof(assigned));
Succession(assign, assigned);
if (supportsChaining && chainable)
{
targetOutput = ValueOutput(member.targetType, nameof(targetOutput));
Assignment(assign, targetOutput);
}
output = ValueOutput(member.type, nameof(output));
Assignment(assign, output);
if (member.requiresTarget)
{
Requirement(target, assign);
}
input = ValueInput(member.type, nameof(input));
Requirement(input, assign);
if (member.allowsNull)
{
input.AllowsNull();
}
input.SetDefaultValue(member.type.PseudoDefault());
}
protected override bool IsMemberValid(Member member)
{
return member.isAccessor && member.isSettable;
}
private object GetAndChainTarget(Flow flow)
{
if (member.requiresTarget)
{
var target = flow.GetValue(this.target, member.targetType);
if (supportsChaining && chainable)
{
flow.SetValue(targetOutput, target);
}
return target;
}
return null;
}
private ControlOutput Assign(Flow flow)
{
var target = GetAndChainTarget(flow);
var value = flow.GetConvertedValue(input);
flow.SetValue(output, member.Set(target, value));
return assigned;
}
#region Analytics
public override AnalyticsIdentifier GetAnalyticsIdentifier()
{
var aid = new AnalyticsIdentifier
{
Identifier = $"{member.targetType.FullName}.{member.name}(Set)",
Namespace = member.targetType.Namespace,
};
aid.Hashcode = aid.Identifier.GetHashCode();
return aid;
}
#endregion
}
}
|