Skip to content

Commit 50551b7

Browse files
committed
Add all switches enabled node.
1 parent 73d5600 commit 50551b7

File tree

7 files changed

+249
-0
lines changed

7 files changed

+249
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Visual Pinball Engine
2+
// Copyright (C) 2022 freezy and VPE Team
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
// ReSharper disable UnusedType.Global
18+
19+
using System.Text.RegularExpressions;
20+
using Unity.VisualScripting;
21+
22+
namespace VisualPinball.Unity.VisualScripting.Editor
23+
{
24+
[Descriptor(typeof(AllSwitchesEnabledEventUnit))]
25+
public class AllSwitchesEnabledEventUnitDescriptor : MultiUnitDescriptor<AllSwitchesEnabledEventUnit>
26+
{
27+
public AllSwitchesEnabledEventUnitDescriptor(AllSwitchesEnabledEventUnit target) : base(target) { }
28+
protected override string ItemLabel(int id) => $"Switch ID {id}";
29+
protected override string ItemDescription(int id) => $"Switch ID {id} to look for enabled status.";
30+
protected override string DefinedSummary() => "This node triggers an event when the last switch in the list gets enabled.";
31+
protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.SwitchEvent);
32+
}
33+
34+
public abstract class MultiUnitDescriptor<TUnit> : UnitDescriptor<TUnit> where TUnit : class, IUnit
35+
{
36+
protected abstract string ItemLabel(int id);
37+
protected abstract string ItemDescription(int id);
38+
39+
protected MultiUnitDescriptor(TUnit target) : base(target)
40+
{
41+
}
42+
43+
protected override void DefinedPort(IUnitPort port, UnitPortDescription desc)
44+
{
45+
base.DefinedPort(port, desc);
46+
var match = new Regex("^(item)([0-9]+)$").Match(port.key);
47+
if (match.Success) {
48+
var id = int.Parse(match.Groups[2].Value) + 1;
49+
desc.label = ItemLabel(id);
50+
desc.summary = ItemDescription(id);
51+
}
52+
}
53+
}
54+
}

Editor/Descriptors/MultiUnitDescriptor.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Visual Pinball Engine
2+
// Copyright (C) 2022 freezy and VPE Team
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
using System;
18+
using System.Collections.Generic;
19+
using System.Linq;
20+
using Unity.VisualScripting;
21+
22+
namespace VisualPinball.Unity.VisualScripting.Editor
23+
{
24+
[Widget(typeof(AllSwitchesEnabledEventUnit))]
25+
public sealed class AllSwitchesEnabledEventUnitWidget : GleMultiUnitWidget<AllSwitchesEnabledEventUnit>
26+
{
27+
public AllSwitchesEnabledEventUnitWidget(FlowCanvas canvas, AllSwitchesEnabledEventUnit unit) : base(canvas, unit)
28+
{
29+
}
30+
protected override IEnumerable<string> IdSuggestions(IGamelogicEngine gle) => gle.RequestedSwitches.Select(sw => sw.Id);
31+
}
32+
33+
public abstract class GleMultiUnitWidget<TUnit> : GleUnitWidget<TUnit> where TUnit : Unit, IGleUnit, IMultiInputUnit
34+
{
35+
protected abstract IEnumerable<string> IdSuggestions(IGamelogicEngine gle);
36+
37+
private readonly List<Func<Metadata, VariableNameInspector>> _idInspectorConstructorList;
38+
39+
protected GleMultiUnitWidget(FlowCanvas canvas, TUnit unit) : base(canvas, unit)
40+
{
41+
_idInspectorConstructorList = new List<Func<Metadata, VariableNameInspector>>();
42+
}
43+
44+
public override Inspector GetPortInspector(IUnitPort port, Metadata meta)
45+
{
46+
if (_idInspectorConstructorList.Count() < unit.inputCount) {
47+
for (var index = 0; index < unit.inputCount - _idInspectorConstructorList.Count(); index++) {
48+
_idInspectorConstructorList.Add(m => new VariableNameInspector(m, GetNameSuggestions));
49+
}
50+
}
51+
52+
for (var index = 0; index < unit.inputCount; index++) {
53+
if (unit.multiInputs[index] == port) {
54+
var idInspector = new VariableNameInspector(meta, GetNameSuggestions);
55+
InspectorProvider.instance.Renew(ref idInspector, meta, _idInspectorConstructorList[index]);
56+
57+
return idInspector;
58+
}
59+
}
60+
61+
return base.GetPortInspector(port, meta);
62+
}
63+
64+
private IEnumerable<string> GetNameSuggestions()
65+
{
66+
return !GleAvailable ? new List<string>() : IdSuggestions(Gle).ToList();
67+
}
68+
}
69+
}

Editor/Widgets/GleMultiUnitWidget.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Nodes/GleUnit.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,21 @@ public abstract class GleEventUnit<TArgs> : EventUnit<TArgs>, IGleUnit
2424
[DoNotSerialize]
2525
public List<string> Errors { get; } = new();
2626

27+
[DoNotSerialize]
28+
protected IGamelogicEngine Gle;
29+
2730
[DoNotSerialize]
2831
protected VisualScriptingGamelogicEngine VsGle;
2932

33+
protected bool AssertGle(Flow flow)
34+
{
35+
if (!Gle.IsUnityNull()) {
36+
return true;
37+
}
38+
Gle = flow.stack.gameObject.GetComponentInParent<IGamelogicEngine>();
39+
return Gle != null;
40+
}
41+
3042
protected bool AssertVsGle(Flow flow)
3143
{
3244
if (!VsGle.IsUnityNull()) {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Visual Pinball Engine
2+
// Copyright (C) 2022 freezy and VPE Team
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
using System.Collections.Generic;
18+
using System.Collections.ObjectModel;
19+
using Unity.VisualScripting;
20+
using UnityEngine;
21+
22+
namespace VisualPinball.Unity.VisualScripting
23+
{
24+
[UnitTitle("On All Switches Enabled")]
25+
[UnitSurtitle("Gamelogic Engine")]
26+
[UnitCategory("Events\\Visual Pinball")]
27+
public class AllSwitchesEnabledEventUnit : GleEventUnit<SwitchEventArgs2>, IMultiInputUnit
28+
{
29+
[SerializeAs(nameof(inputCount))]
30+
private int _itemCount = 1;
31+
32+
[DoNotSerialize]
33+
[Inspectable, UnitHeaderInspectable("Switch IDs")]
34+
public int inputCount
35+
{
36+
get => _itemCount;
37+
set => _itemCount = Mathf.Clamp(value, 1, 10);
38+
}
39+
40+
[DoNotSerialize]
41+
public ReadOnlyCollection<ValueInput> multiInputs { get; private set; }
42+
43+
[DoNotSerialize]
44+
protected override bool register => true;
45+
46+
public override EventHook GetHook(GraphReference reference) => new EventHook(VisualScriptingEventNames.SwitchEvent);
47+
48+
protected override void Definition()
49+
{
50+
base.Definition();
51+
52+
var list = new List<ValueInput>();
53+
for (var i = 0; i < inputCount; i++) {
54+
var item = ValueInput($"item{i}", string.Empty);
55+
list.Add(item);
56+
}
57+
58+
multiInputs = new ReadOnlyCollection<ValueInput>(list);
59+
}
60+
61+
protected override bool ShouldTrigger(Flow flow, SwitchEventArgs2 args)
62+
{
63+
if (!AssertGle(flow)) {
64+
Debug.LogError("Cannot find GLE.");
65+
return false;
66+
}
67+
68+
var validSwitch = false;
69+
foreach(var item in multiInputs) {
70+
var swId = flow.GetValue<string>(item);
71+
if (swId == args.Id) {
72+
validSwitch = true;
73+
}
74+
if (!Gle.GetSwitch(swId)) {
75+
return false;
76+
}
77+
}
78+
return validSwitch;
79+
}
80+
}
81+
}

Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)