A game about forced loneliness, made by TACStudios
1namespace Unity.VisualScripting 2{ 3 /// <summary> 4 /// Sets the value of a field or property via reflection. 5 /// </summary> 6 public sealed class SetMember : MemberUnit 7 { 8 public SetMember() : base() { } 9 10 public SetMember(Member member) : base(member) { } 11 12 /// <summary> 13 /// Whether the target should be output to allow for chaining. 14 /// </summary> 15 [Serialize] 16 [InspectableIf(nameof(supportsChaining))] 17 public bool chainable { get; set; } 18 19 [DoNotSerialize] 20 public bool supportsChaining => member.requiresTarget; 21 22 [DoNotSerialize] 23 [MemberFilter(Fields = true, Properties = true, ReadOnly = false)] 24 public Member setter 25 { 26 get => member; 27 set => member = value; 28 } 29 30 [DoNotSerialize] 31 [PortLabelHidden] 32 public ControlInput assign { get; private set; } 33 34 [DoNotSerialize] 35 [PortLabel("Value")] 36 [PortLabelHidden] 37 public ValueInput input { get; private set; } 38 39 [DoNotSerialize] 40 [PortLabel("Value")] 41 [PortLabelHidden] 42 public ValueOutput output { get; private set; } 43 44 /// <summary> 45 /// The target object used when setting the value. 46 /// </summary> 47 [DoNotSerialize] 48 [PortLabel("Target")] 49 [PortLabelHidden] 50 public ValueOutput targetOutput { get; private set; } 51 52 [DoNotSerialize] 53 [PortLabelHidden] 54 public ControlOutput assigned { get; private set; } 55 56 protected override void Definition() 57 { 58 base.Definition(); 59 60 assign = ControlInput(nameof(assign), Assign); 61 assigned = ControlOutput(nameof(assigned)); 62 Succession(assign, assigned); 63 64 if (supportsChaining && chainable) 65 { 66 targetOutput = ValueOutput(member.targetType, nameof(targetOutput)); 67 Assignment(assign, targetOutput); 68 } 69 70 output = ValueOutput(member.type, nameof(output)); 71 Assignment(assign, output); 72 73 if (member.requiresTarget) 74 { 75 Requirement(target, assign); 76 } 77 78 input = ValueInput(member.type, nameof(input)); 79 Requirement(input, assign); 80 81 if (member.allowsNull) 82 { 83 input.AllowsNull(); 84 } 85 86 input.SetDefaultValue(member.type.PseudoDefault()); 87 } 88 89 protected override bool IsMemberValid(Member member) 90 { 91 return member.isAccessor && member.isSettable; 92 } 93 94 private object GetAndChainTarget(Flow flow) 95 { 96 if (member.requiresTarget) 97 { 98 var target = flow.GetValue(this.target, member.targetType); 99 100 if (supportsChaining && chainable) 101 { 102 flow.SetValue(targetOutput, target); 103 } 104 105 return target; 106 } 107 108 return null; 109 } 110 111 private ControlOutput Assign(Flow flow) 112 { 113 var target = GetAndChainTarget(flow); 114 115 var value = flow.GetConvertedValue(input); 116 117 flow.SetValue(output, member.Set(target, value)); 118 119 return assigned; 120 } 121 122 #region Analytics 123 124 public override AnalyticsIdentifier GetAnalyticsIdentifier() 125 { 126 var aid = new AnalyticsIdentifier 127 { 128 Identifier = $"{member.targetType.FullName}.{member.name}(Set)", 129 Namespace = member.targetType.Namespace, 130 }; 131 aid.Hashcode = aid.Identifier.GetHashCode(); 132 return aid; 133 } 134 135 #endregion 136 } 137}