Skip to content

Commit c7fbafb

Browse files
jsm174freezy
authored andcommitted
unit: rework LampSequenceUnit to use mappings
1 parent 2fb3e3a commit c7fbafb

File tree

2 files changed

+153
-47
lines changed

2 files changed

+153
-47
lines changed

Runtime/Nodes/Lamps/LampSequenceUnit.cs

+129-45
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,44 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616

17+
using System;
1718
using System.Collections.Generic;
1819
using System.Collections.ObjectModel;
20+
using System.Linq;
1921
using Unity.VisualScripting;
2022
using UnityEngine;
23+
using VisualPinball.Engine.Game.Engines;
24+
using Color = VisualPinball.Engine.Math.Color;
2125

2226
namespace VisualPinball.Unity.VisualScripting
2327
{
28+
public struct LightComponentMapping
29+
{
30+
public LightComponent lightComponent;
31+
public string id;
32+
33+
public bool IsValid() => !lightComponent.IsUnityNull();
34+
}
35+
2436
[UnitTitle("Lamp Sequence")]
2537
[UnitSurtitle("Gamelogic Engine")]
2638
[UnitCategory("Visual Pinball")]
2739
public class LampSequenceUnit : GleUnit, IMultiInputUnit
2840
{
41+
[Serialize, Inspectable, UnitHeaderInspectable("Value")]
42+
public LampDataType ValueDataType { get; set; }
43+
44+
[Serialize, Inspectable, UnitHeaderInspectable("Non Step Value")]
45+
public LampDataType NonStepValueDataType { get; set; }
46+
47+
[DoNotSerialize]
48+
[Inspectable, UnitHeaderInspectable("Lamp IDs")]
49+
public int inputCount
50+
{
51+
get => _inputCount;
52+
set => _inputCount = Mathf.Clamp(value, 1, 10);
53+
}
54+
2955
[DoNotSerialize]
3056
[PortLabelHidden]
3157
public ControlInput InputTrigger;
@@ -38,55 +64,66 @@ public class LampSequenceUnit : GleUnit, IMultiInputUnit
3864
private int _inputCount = 1;
3965

4066
[DoNotSerialize]
41-
[Inspectable, UnitHeaderInspectable("Lamp IDs")]
42-
public int inputCount
43-
{
44-
get => _inputCount;
45-
set => _inputCount = Mathf.Clamp(value, 1, 10);
46-
}
67+
public ReadOnlyCollection<ValueInput> multiInputs { get; private set; }
4768

4869
[DoNotSerialize]
49-
public ReadOnlyCollection<ValueInput> multiInputs { get; private set; }
70+
[PortLabel("Step")]
71+
public ValueInput Step;
5072

5173
[DoNotSerialize]
52-
[PortLabel("Value")]
5374
public ValueInput Value { get; private set; }
5475

5576
[DoNotSerialize]
56-
[PortLabel("Step")]
57-
public ValueInput Step;
77+
public ValueInput NonStepValue { get; private set; }
78+
79+
[DoNotSerialize]
80+
private readonly Dictionary<string, float> _intensityMultipliers = new();
5881

82+
private List<LightComponentMapping> _lightComponentCache = new();
5983
private int _currentIndex;
60-
private List<LightComponent> _lightComponentCache = null;
6184

6285
protected override void Definition()
6386
{
6487
InputTrigger = ControlInput(nameof(InputTrigger), Process);
6588
OutputTrigger = ControlOutput(nameof(OutputTrigger));
6689

67-
var _multiInputs = new List<ValueInput>();
68-
69-
multiInputs = _multiInputs.AsReadOnly();
90+
var mi = new List<ValueInput>();
91+
multiInputs = mi.AsReadOnly();
7092

7193
for (var i = 0; i < inputCount; i++) {
7294
var input = ValueInput(i.ToString(), string.Empty);
73-
_multiInputs.Add(input);
74-
95+
mi.Add(input);
7596
Requirement(input, InputTrigger);
7697
}
7798

78-
Value = ValueInput(nameof(Value), 0f);
7999
Step = ValueInput(nameof(Step), 1);
80100

101+
Value = ValueDataType switch
102+
{
103+
LampDataType.OnOff => ValueInput(nameof(Value), false),
104+
LampDataType.Status => ValueInput(nameof(Value), LampStatus.Off),
105+
LampDataType.Intensity => ValueInput(nameof(Value), 0f),
106+
LampDataType.Color => ValueInput(nameof(Value), UnityEngine.Color.white),
107+
_ => throw new ArgumentOutOfRangeException()
108+
};
109+
110+
NonStepValue = NonStepValueDataType switch
111+
{
112+
LampDataType.OnOff => ValueInput(nameof(NonStepValue), false),
113+
LampDataType.Status => ValueInput(nameof(NonStepValue), LampStatus.Off),
114+
LampDataType.Intensity => ValueInput(nameof(NonStepValue), 0f),
115+
LampDataType.Color => ValueInput(nameof(NonStepValue), UnityEngine.Color.white),
116+
_ => throw new ArgumentOutOfRangeException()
117+
};
118+
81119
Succession(InputTrigger, OutputTrigger);
82120

83-
_lightComponentCache = null;
121+
_lightComponentCache.Clear();
84122
}
85123

86124
private ControlOutput Process(Flow flow)
87125
{
88-
if (!AssertGle(flow))
89-
{
126+
if (!AssertGle(flow)) {
90127
Debug.LogError("Cannot find GLE.");
91128
return OutputTrigger;
92129
}
@@ -96,52 +133,99 @@ private ControlOutput Process(Flow flow)
96133
return OutputTrigger;
97134
}
98135

99-
var value = flow.GetValue<float>(Value);
100-
var stepRaw = flow.GetValue<int>(Step);
101-
102-
if (_lightComponentCache != null) {
103-
foreach (var component in _lightComponentCache) {
104-
if (component.IsUnityNull()) {
105-
_lightComponentCache = null;
106-
break;
107-
}
136+
foreach (var mapping in _lightComponentCache) {
137+
if (!mapping.IsValid()) {
138+
_lightComponentCache.Clear();
139+
break;
108140
}
109141
}
110142

111-
if (_lightComponentCache == null) {
112-
_lightComponentCache = new List<LightComponent>();
113-
143+
if (_lightComponentCache.Count == 0) {
114144
foreach (var input in multiInputs) {
115145
var lampId = flow.GetValue<string>(input);
116-
_lightComponentCache.AddRange(Flatten(Player.LampDevice(lampId)));
146+
147+
var mapping = Player.LampMapping.FirstOrDefault(l => l.Id == lampId);
148+
if (mapping != null) {
149+
UpdateLightComponentCache(mapping.Device, lampId);
150+
}
151+
else {
152+
Debug.LogError($"Unknown lamp ID {lampId}.");
153+
_lightComponentCache.Clear();
154+
155+
break;
156+
}
117157
}
118158
}
119159

160+
var stepRaw = flow.GetValue<int>(Step);
161+
162+
LampDataType dataType;
163+
ValueInput value;
164+
120165
for (var index = 0; index < _lightComponentCache.Count; index++) {
121-
;
166+
if (index >= _currentIndex * stepRaw && index < (_currentIndex + 1) * stepRaw) {
167+
dataType = ValueDataType;
168+
value = Value;
169+
}
170+
else {
171+
dataType = NonStepValueDataType;
172+
value = NonStepValue;
173+
}
174+
175+
var lampApi = Player.Lamp(_lightComponentCache[index].lightComponent);
176+
177+
switch (dataType) {
178+
case LampDataType.OnOff:
179+
lampApi.OnLamp(flow.GetValue<bool>(value) ? LampStatus.On : LampStatus.Off);
180+
break;
181+
case LampDataType.Status:
182+
lampApi.OnLamp(flow.GetValue<LampStatus>(value));
183+
break;
184+
case LampDataType.Intensity:
185+
lampApi.OnLamp(flow.GetValue<float>(value) * GetIntensityMultiplier(_lightComponentCache[index].id));
186+
break;
187+
case LampDataType.Color:
188+
lampApi.OnLamp(flow.GetValue<UnityEngine.Color>(value));
189+
break;
190+
default:
191+
throw new ArgumentOutOfRangeException();
192+
}
122193
}
123194

124195
if (++_currentIndex >= _lightComponentCache.Count / stepRaw) {
125196
_currentIndex = 0;
126197
}
127-
198+
128199
return OutputTrigger;
129200
}
130201

131-
private List<LightComponent> Flatten(List<ILampDeviceComponent> lampDeviceList)
202+
private float GetIntensityMultiplier(string id)
132203
{
133-
List<LightComponent> lights = new List<LightComponent>();
204+
if (_intensityMultipliers.ContainsKey(id)) {
205+
return _intensityMultipliers[id];
206+
}
134207

135-
foreach (ILampDeviceComponent device in lampDeviceList) {
136-
if (device is LightComponent) {
137-
lights.Add(device as LightComponent);
138-
}
139-
else if (device is LightGroupComponent) {
140-
lights.AddRange(Flatten(((LightGroupComponent)device).Lights));
141-
}
208+
var mapping = Player.LampMapping.FirstOrDefault(l => l.Id == id);
209+
if (mapping == null) {
210+
Debug.LogError($"Unknown lamp ID {id}.");
211+
_intensityMultipliers[id] = 1;
212+
return 1;
142213
}
143214

144-
return lights;
215+
_intensityMultipliers[id] = mapping.Type == LampType.Rgb ? 255 : 1;
216+
return _intensityMultipliers[id];
217+
}
218+
219+
private void UpdateLightComponentCache(ILampDeviceComponent device, string id)
220+
{
221+
if (device is LightComponent) {
222+
_lightComponentCache.Add(new LightComponentMapping { lightComponent = device as LightComponent, id = id });
223+
}
224+
else if (device is LightGroupComponent) {
225+
foreach (var light in (device as LightGroupComponent).Lights) {
226+
UpdateLightComponentCache(light, id);
227+
}
228+
}
145229
}
146230
}
147231
}

Runtime/Nodes/Lamps/SwitchLampUnit.cs

+24-2
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
using System;
1818
using System.Collections.Generic;
1919
using System.Collections.ObjectModel;
20+
using System.Linq;
2021
using Unity.VisualScripting;
2122
using UnityEngine;
2223
using VisualPinball.Engine.Game.Engines;
24+
using Color = VisualPinball.Engine.Math.Color;
2325

2426
namespace VisualPinball.Unity.VisualScripting
2527
{
@@ -54,6 +56,9 @@ public int inputCount
5456
[SerializeAs(nameof(inputCount))]
5557
private int _inputCount = 1;
5658

59+
[DoNotSerialize]
60+
public ReadOnlyCollection<ValueInput> multiInputs { get; private set; }
61+
5762
[DoNotSerialize]
5863
[PortLabel("Source Value")]
5964
public ValueInput SourceValue { get; private set; }
@@ -65,7 +70,7 @@ public int inputCount
6570
public ValueInput NonMatch { get; private set; }
6671

6772
[DoNotSerialize]
68-
public ReadOnlyCollection<ValueInput> multiInputs { get; private set; }
73+
private readonly Dictionary<string, float> _intensityMultipliers = new();
6974

7075
private Dictionary<int, LampIdValue> _lampIdValueCache = new Dictionary<int, LampIdValue>();
7176

@@ -140,7 +145,7 @@ private ControlOutput Process(Flow flow)
140145
Player.SetLamp(lampIdValue.id, flow.GetValue<LampStatus>(value));
141146
break;
142147
case LampDataType.Intensity:
143-
Player.SetLamp(lampIdValue.id, flow.GetValue<float>(value));
148+
Player.SetLamp(lampIdValue.id, flow.GetValue<float>(value) * GetIntensityMultiplier(lampIdValue.id));
144149
break;
145150
case LampDataType.Color:
146151
Player.SetLamp(lampIdValue.id, flow.GetValue<UnityEngine.Color>(value).ToEngineColor());
@@ -152,5 +157,22 @@ private ControlOutput Process(Flow flow)
152157

153158
return OutputTrigger;
154159
}
160+
161+
private float GetIntensityMultiplier(string id)
162+
{
163+
if (_intensityMultipliers.ContainsKey(id)) {
164+
return _intensityMultipliers[id];
165+
}
166+
167+
var mapping = Player.LampMapping.FirstOrDefault(l => l.Id == id);
168+
if (mapping == null) {
169+
Debug.LogError($"Unknown lamp ID {id}.");
170+
_intensityMultipliers[id] = 1;
171+
return 1;
172+
}
173+
174+
_intensityMultipliers[id] = mapping.Type == LampType.Rgb ? 255 : 1;
175+
return _intensityMultipliers[id];
176+
}
155177
}
156178
}

0 commit comments

Comments
 (0)