From 633b1ee209d370f28f297790cb72b7fd6d4f7388 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Wed, 26 Jan 2022 18:15:21 -0500 Subject: [PATCH 01/54] units: add get switch unit --- Editor/Descriptors/GetSwitchUnitDescriptor.cs | 53 +++++++++++++++++ .../GetSwitchUnitDescriptor.cs.meta | 11 ++++ Editor/Widgets/GetSwitchUnitWidget.cs | 59 +++++++++++++++++++ Editor/Widgets/GetSwitchUnitWidget.cs.meta | 11 ++++ Editor/Widgets/SwitchEventUnitWidget.cs | 2 +- Runtime/Nodes/Switches/GetSwitchUnit.cs | 52 ++++++++++++++++ Runtime/Nodes/Switches/GetSwitchUnit.cs.meta | 11 ++++ 7 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 Editor/Descriptors/GetSwitchUnitDescriptor.cs create mode 100644 Editor/Descriptors/GetSwitchUnitDescriptor.cs.meta create mode 100644 Editor/Widgets/GetSwitchUnitWidget.cs create mode 100644 Editor/Widgets/GetSwitchUnitWidget.cs.meta create mode 100644 Runtime/Nodes/Switches/GetSwitchUnit.cs create mode 100644 Runtime/Nodes/Switches/GetSwitchUnit.cs.meta diff --git a/Editor/Descriptors/GetSwitchUnitDescriptor.cs b/Editor/Descriptors/GetSwitchUnitDescriptor.cs new file mode 100644 index 0000000..e50b8d8 --- /dev/null +++ b/Editor/Descriptors/GetSwitchUnitDescriptor.cs @@ -0,0 +1,53 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; +using VisualPinball.Unity.Editor; +using IconSize = VisualPinball.Unity.Editor.IconSize; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(GetSwitchUnit))] + public class GetSwitchUnitDescriptor : UnitDescriptor + { + public GetSwitchUnitDescriptor(GetSwitchUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node retrieves the current status of the switch."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Switch(false, IconSize.Large, IconColor.Orange)); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(GetSwitchUnit.Id): + desc.summary = "The ID of the switch for which to get current status."; + break; + case nameof(GetSwitchUnit.IsEnabled): + desc.summary = "Whether the switch is enabled."; + break; + } + } + } +} diff --git a/Editor/Descriptors/GetSwitchUnitDescriptor.cs.meta b/Editor/Descriptors/GetSwitchUnitDescriptor.cs.meta new file mode 100644 index 0000000..bf2658d --- /dev/null +++ b/Editor/Descriptors/GetSwitchUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f4ba0e998e0174672a7439dd7e7d4398 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/GetSwitchUnitWidget.cs b/Editor/Widgets/GetSwitchUnitWidget.cs new file mode 100644 index 0000000..cdcb18b --- /dev/null +++ b/Editor/Widgets/GetSwitchUnitWidget.cs @@ -0,0 +1,59 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(GetSwitchUnit))] + public sealed class GetSwitchUnitWidget : GleUnitWidget + { + public GetSwitchUnitWidget(FlowCanvas canvas, GetSwitchUnit unit) : base(canvas, unit) + { + _switchIdInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + } + + protected override NodeColorMix baseColor => NodeColorMix.TealReadable; + + private VariableNameInspector _switchIdInspector; + private readonly Func _switchIdInspectorConstructor; + + public override Inspector GetPortInspector(IUnitPort port, Metadata meta) + { + if (port == unit.Id) { + InspectorProvider.instance.Renew(ref _switchIdInspector, meta, _switchIdInspectorConstructor); + + return _switchIdInspector; + } + + return base.GetPortInspector(port, meta); + } + + private IEnumerable GetNameSuggestions() + { + if (!GameObjectAvailable) { + return new List(); + } + var gle = Gle; + return gle == null ? new List() : gle.AvailableSwitches.Select(sw => sw.Id).ToList(); + } + } +} diff --git a/Editor/Widgets/GetSwitchUnitWidget.cs.meta b/Editor/Widgets/GetSwitchUnitWidget.cs.meta new file mode 100644 index 0000000..d09f2bb --- /dev/null +++ b/Editor/Widgets/GetSwitchUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7d886023af764b62b6ca54f024a1e0a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/SwitchEventUnitWidget.cs b/Editor/Widgets/SwitchEventUnitWidget.cs index d4d98c4..6c3bce6 100644 --- a/Editor/Widgets/SwitchEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEventUnitWidget.cs @@ -51,7 +51,7 @@ private IEnumerable GetNameSuggestions() return new List(); } var gle = Gle; - return gle == null ? new List() : gle.AvailableSwitches.Select(lamp => lamp.Id).ToList(); + return gle == null ? new List() : gle.AvailableSwitches.Select(sw => sw.Id).ToList(); } } } diff --git a/Runtime/Nodes/Switches/GetSwitchUnit.cs b/Runtime/Nodes/Switches/GetSwitchUnit.cs new file mode 100644 index 0000000..e80720b --- /dev/null +++ b/Runtime/Nodes/Switches/GetSwitchUnit.cs @@ -0,0 +1,52 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Get Switch Value")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Visual Pinball")] + public class GetSwitchUnit : GleUnit + { + [DoNotSerialize] + [PortLabel("Switch ID")] + public ValueInput Id { get; private set; } + + [DoNotSerialize] + [PortLabel("Is Enabled")] + public ValueOutput IsEnabled { get; private set; } + + protected override void Definition() + { + Id = ValueInput(nameof(Id), string.Empty); + + IsEnabled = ValueOutput(nameof(IsEnabled), GetEnabled); + } + + private bool GetEnabled(Flow flow) + { + if (!AssertGle(flow)) { + Debug.LogError("Cannot find GLE."); + return false; + } + + return Gle.GetSwitch(flow.GetValue(Id)); + } + } +} diff --git a/Runtime/Nodes/Switches/GetSwitchUnit.cs.meta b/Runtime/Nodes/Switches/GetSwitchUnit.cs.meta new file mode 100644 index 0000000..5d17946 --- /dev/null +++ b/Runtime/Nodes/Switches/GetSwitchUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fcc0ca29871c04d7fa61243e08eab438 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From ee779700c1620b8af7cbcbd14c1f2c2dce2f056e Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Fri, 28 Jan 2022 07:48:30 -0500 Subject: [PATCH 02/54] events: Added SwitchEnabled event --- .../SwitchEnabledEventUnitDescriptor.cs | 48 ++++++++++++++++ .../SwitchEnabledEventUnitDescriptor.cs.meta | 11 ++++ .../Widgets/SwitchEnabledEventUnitWidget.cs | 57 +++++++++++++++++++ .../SwitchEnabledEventUnitWidget.cs.meta | 11 ++++ .../Gamelogic/VisualScriptingEventNames.cs | 1 + .../VisualScriptingGamelogicBridge.cs | 8 ++- .../VisualScriptingGamelogicEngine.cs | 11 +++- .../Nodes/Switches/SwitchEnabledEventUnit.cs | 51 +++++++++++++++++ .../Switches/SwitchEnabledEventUnit.cs.meta | 11 ++++ 9 files changed, 206 insertions(+), 3 deletions(-) create mode 100644 Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs create mode 100644 Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs.meta create mode 100644 Editor/Widgets/SwitchEnabledEventUnitWidget.cs create mode 100644 Editor/Widgets/SwitchEnabledEventUnitWidget.cs.meta create mode 100644 Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs create mode 100644 Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs.meta diff --git a/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs b/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs new file mode 100644 index 0000000..6686e37 --- /dev/null +++ b/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs @@ -0,0 +1,48 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(SwitchEnabledEventUnit))] + public class SwitchEnabledEventUnitDescriptor : UnitDescriptor + { + public SwitchEnabledEventUnitDescriptor(SwitchEnabledEventUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node triggers an event when a switch with a given ID is enabled."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.SwitchEvent); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(SwitchEnabledEventUnit.Id): + desc.summary = "The ID of the switch that was enabled."; + break; + } + } + } +} diff --git a/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs.meta b/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs.meta new file mode 100644 index 0000000..7998fd4 --- /dev/null +++ b/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32e28bb31bbaf4ddeac7824d4428df1f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs new file mode 100644 index 0000000..3149a96 --- /dev/null +++ b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs @@ -0,0 +1,57 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(SwitchEnabledEventUnit))] + public sealed class SwitchEnabledEventUnitWidget : GleUnitWidget + { + private VariableNameInspector _switchIdInspector; + private readonly Func _switchIdInspectorConstructor; + + public SwitchEnabledEventUnitWidget(FlowCanvas canvas, SwitchEnabledEventUnit unit) : base(canvas, unit) + { + _switchIdInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + } + + public override Inspector GetPortInspector(IUnitPort port, Metadata meta) + { + if (port == unit.Id) { + InspectorProvider.instance.Renew(ref _switchIdInspector, meta, _switchIdInspectorConstructor); + + return _switchIdInspector; + } + + return base.GetPortInspector(port, meta); + } + + private IEnumerable GetNameSuggestions() + { + if (!GameObjectAvailable) { + return new List(); + } + var gle = Gle; + return gle == null ? new List() : gle.AvailableSwitches.Select(sw => sw.Id).ToList(); + } + } +} diff --git a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs.meta b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs.meta new file mode 100644 index 0000000..a932460 --- /dev/null +++ b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d1a289dc9bb6e4020b64677e18de4f43 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Gamelogic/VisualScriptingEventNames.cs b/Runtime/Gamelogic/VisualScriptingEventNames.cs index 8805ddd..24737c7 100644 --- a/Runtime/Gamelogic/VisualScriptingEventNames.cs +++ b/Runtime/Gamelogic/VisualScriptingEventNames.cs @@ -21,6 +21,7 @@ public static class VisualScriptingEventNames public const string GleStartedEvent = "GleStartedEvent"; public const string LampEvent = "LampEvent"; public const string SwitchEvent = "SwitchEvent"; + public const string SwitchEnabledEvent = "SwitchEnabledEvent"; public const string CoilEvent = "CoilEvent"; } } diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicBridge.cs b/Runtime/Gamelogic/VisualScriptingGamelogicBridge.cs index 3add681..3439d77 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicBridge.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicBridge.cs @@ -76,7 +76,13 @@ private void OnStarted(object sender, EventArgs e) private static void OnSwitchChanged(object sender, SwitchEventArgs2 e) { - EventBus.Trigger(VisualScriptingEventNames.SwitchEvent, new SwitchEventArgs2(e.Id, e.IsEnabled)); + var args = new SwitchEventArgs2(e.Id, e.IsEnabled); + + EventBus.Trigger(VisualScriptingEventNames.SwitchEvent, args); + + if (e.IsEnabled) { + EventBus.Trigger(VisualScriptingEventNames.SwitchEnabledEvent, args); + } } private static void OnCoilChanged(object sender, CoilEventArgs e) diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index 8403214..11a764d 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -66,8 +66,15 @@ public void OnInit(Player player, TableApi tableApi, BallManager ballManager) public void Switch(string id, bool isClosed) { - OnSwitchChanged?.Invoke(this, new SwitchEventArgs2(id, isClosed)); - EventBus.Trigger(VisualScriptingEventNames.SwitchEvent, new SwitchEventArgs2(id, isClosed)); + var args = new SwitchEventArgs2(id, isClosed); + + OnSwitchChanged?.Invoke(this, args); + + EventBus.Trigger(VisualScriptingEventNames.SwitchEvent, args); + + if (isClosed) { + EventBus.Trigger(VisualScriptingEventNames.SwitchEnabledEvent, args); + } } public void SetCoil(string id, bool isEnabled) diff --git a/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs new file mode 100644 index 0000000..045745f --- /dev/null +++ b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs @@ -0,0 +1,51 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("On Switch Enabled")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Events\\Visual Pinball")] + public class SwitchEnabledEventUnit : GleEventUnit + { + [DoNotSerialize] + [PortLabel("Switch ID")] + public ValueInput Id { get; private set; } + + [DoNotSerialize] + protected override bool register => true; + + // Adding an EventHook with the name of the event to the list of visual scripting events. + public override EventHook GetHook(GraphReference reference) + { + return new EventHook(VisualScriptingEventNames.SwitchEnabledEvent); + } + + protected override void Definition() + { + base.Definition(); + + Id = ValueInput(nameof(Id), string.Empty); + } + + protected override bool ShouldTrigger(Flow flow, SwitchEventArgs2 args) + { + return flow.GetValue(Id) == args.Id; + } + } +} diff --git a/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs.meta b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs.meta new file mode 100644 index 0000000..378e7a9 --- /dev/null +++ b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a896594a52944a3e8f0c3f69e85d254 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From e40761b4073be471e76cd018c1ed473cf27c0bc4 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Fri, 28 Jan 2022 08:00:02 -0500 Subject: [PATCH 03/54] cosmetics: lamp to switch update --- Editor/Widgets/SwitchEventUnitWidget.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Editor/Widgets/SwitchEventUnitWidget.cs b/Editor/Widgets/SwitchEventUnitWidget.cs index 6c3bce6..538e8da 100644 --- a/Editor/Widgets/SwitchEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEventUnitWidget.cs @@ -26,7 +26,7 @@ namespace VisualPinball.Unity.VisualScripting.Editor [Widget(typeof(SwitchEventUnit))] public sealed class SwitchEventUnitWidget : GleUnitWidget { - private VariableNameInspector _lampIdInspector; + private VariableNameInspector _switchIdInspector; private readonly Func _switchIdInspectorConstructor; public SwitchEventUnitWidget(FlowCanvas canvas, SwitchEventUnit unit) : base(canvas, unit) @@ -37,9 +37,9 @@ public SwitchEventUnitWidget(FlowCanvas canvas, SwitchEventUnit unit) : base(can public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { if (port == unit.Id) { - InspectorProvider.instance.Renew(ref _lampIdInspector, meta, _switchIdInspectorConstructor); + InspectorProvider.instance.Renew(ref _switchIdInspector, meta, _switchIdInspectorConstructor); - return _lampIdInspector; + return _switchIdInspector; } return base.GetPortInspector(port, meta); From e270438907c5b2b441b61b5e72485813ed61b6cf Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 30 Jan 2022 00:37:38 +0100 Subject: [PATCH 04/54] refactor: Don't use separate event for enabled switch event. --- Runtime/Gamelogic/VisualScriptingEventNames.cs | 1 - Runtime/Gamelogic/VisualScriptingGamelogicBridge.cs | 4 ---- Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs | 5 +---- Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs | 8 ++------ 4 files changed, 3 insertions(+), 15 deletions(-) diff --git a/Runtime/Gamelogic/VisualScriptingEventNames.cs b/Runtime/Gamelogic/VisualScriptingEventNames.cs index 24737c7..8805ddd 100644 --- a/Runtime/Gamelogic/VisualScriptingEventNames.cs +++ b/Runtime/Gamelogic/VisualScriptingEventNames.cs @@ -21,7 +21,6 @@ public static class VisualScriptingEventNames public const string GleStartedEvent = "GleStartedEvent"; public const string LampEvent = "LampEvent"; public const string SwitchEvent = "SwitchEvent"; - public const string SwitchEnabledEvent = "SwitchEnabledEvent"; public const string CoilEvent = "CoilEvent"; } } diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicBridge.cs b/Runtime/Gamelogic/VisualScriptingGamelogicBridge.cs index 3439d77..41f4ebd 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicBridge.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicBridge.cs @@ -79,10 +79,6 @@ private static void OnSwitchChanged(object sender, SwitchEventArgs2 e) var args = new SwitchEventArgs2(e.Id, e.IsEnabled); EventBus.Trigger(VisualScriptingEventNames.SwitchEvent, args); - - if (e.IsEnabled) { - EventBus.Trigger(VisualScriptingEventNames.SwitchEnabledEvent, args); - } } private static void OnCoilChanged(object sender, CoilEventArgs e) diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index 11a764d..2c33512 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -61,6 +61,7 @@ public void OnInit(Player player, TableApi tableApi, BallManager ballManager) _player = player; BallManager = ballManager; + OnStarted?.Invoke(this, EventArgs.Empty); EventBus.Trigger(VisualScriptingEventNames.GleStartedEvent, EventArgs.Empty); } @@ -71,10 +72,6 @@ public void Switch(string id, bool isClosed) OnSwitchChanged?.Invoke(this, args); EventBus.Trigger(VisualScriptingEventNames.SwitchEvent, args); - - if (isClosed) { - EventBus.Trigger(VisualScriptingEventNames.SwitchEnabledEvent, args); - } } public void SetCoil(string id, bool isEnabled) diff --git a/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs index 045745f..32aac43 100644 --- a/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs +++ b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs @@ -31,21 +31,17 @@ public class SwitchEnabledEventUnit : GleEventUnit protected override bool register => true; // Adding an EventHook with the name of the event to the list of visual scripting events. - public override EventHook GetHook(GraphReference reference) - { - return new EventHook(VisualScriptingEventNames.SwitchEnabledEvent); - } + public override EventHook GetHook(GraphReference reference) => new EventHook(VisualScriptingEventNames.SwitchEvent); protected override void Definition() { base.Definition(); - Id = ValueInput(nameof(Id), string.Empty); } protected override bool ShouldTrigger(Flow flow, SwitchEventArgs2 args) { - return flow.GetValue(Id) == args.Id; + return flow.GetValue(Id) == args.Id && args.IsEnabled; } } } From 27003b1d2aea25f464f7a0e9b63a0cadcf27c9b8 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Sun, 30 Jan 2022 19:12:24 -0500 Subject: [PATCH 05/54] switches: update SwitchEnabledEvent to accept multiple ids (OR). update GetSwitch to accept multiple ids (AND) --- Editor/Descriptors/GetSwitchUnitDescriptor.cs | 4 +-- .../SwitchEnabledEventUnitDescriptor.cs | 6 ++-- Editor/Widgets/GetSwitchUnitWidget.cs | 22 +++++++++---- .../Widgets/SwitchEnabledEventUnitWidget.cs | 20 ++++++++---- Runtime/Nodes/Switches/GetSwitchUnit.cs | 30 ++++++++++++++--- .../Nodes/Switches/SwitchEnabledEventUnit.cs | 32 ++++++++++++++++--- 6 files changed, 88 insertions(+), 26 deletions(-) diff --git a/Editor/Descriptors/GetSwitchUnitDescriptor.cs b/Editor/Descriptors/GetSwitchUnitDescriptor.cs index e50b8d8..01e59a8 100644 --- a/Editor/Descriptors/GetSwitchUnitDescriptor.cs +++ b/Editor/Descriptors/GetSwitchUnitDescriptor.cs @@ -41,8 +41,8 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(GetSwitchUnit.Id): - desc.summary = "The ID of the switch for which to get current status."; + case nameof(GetSwitchUnit.Ids): + desc.summary = "The IDs of the switches for which to get the current status."; break; case nameof(GetSwitchUnit.IsEnabled): desc.summary = "Whether the switch is enabled."; diff --git a/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs b/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs index 6686e37..8b1fea0 100644 --- a/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs +++ b/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs @@ -29,7 +29,7 @@ public SwitchEnabledEventUnitDescriptor(SwitchEnabledEventUnit target) : base(ta protected override string DefinedSummary() { - return "This node triggers an event when a switch with a given ID is enabled."; + return "This node triggers an event when a switch in the list of given ID is enabled."; } protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.SwitchEvent); @@ -39,8 +39,8 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(SwitchEnabledEventUnit.Id): - desc.summary = "The ID of the switch that was enabled."; + case nameof(SwitchEnabledEventUnit.Ids): + desc.summary = "The IDs of the switches for which to look for enabled status."; break; } } diff --git a/Editor/Widgets/GetSwitchUnitWidget.cs b/Editor/Widgets/GetSwitchUnitWidget.cs index cdcb18b..5b1b662 100644 --- a/Editor/Widgets/GetSwitchUnitWidget.cs +++ b/Editor/Widgets/GetSwitchUnitWidget.cs @@ -26,22 +26,30 @@ namespace VisualPinball.Unity.VisualScripting.Editor [Widget(typeof(GetSwitchUnit))] public sealed class GetSwitchUnitWidget : GleUnitWidget { + private readonly List> _switchIdInspectorConstructorList; + public GetSwitchUnitWidget(FlowCanvas canvas, GetSwitchUnit unit) : base(canvas, unit) { - _switchIdInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + _switchIdInspectorConstructorList = new List>(); } protected override NodeColorMix baseColor => NodeColorMix.TealReadable; - private VariableNameInspector _switchIdInspector; - private readonly Func _switchIdInspectorConstructor; - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (port == unit.Id) { - InspectorProvider.instance.Renew(ref _switchIdInspector, meta, _switchIdInspectorConstructor); + if (_switchIdInspectorConstructorList.Count() < unit.idCount) { + for (var index = 0; index < unit.idCount - _switchIdInspectorConstructorList.Count(); index++) { + _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.idCount; index++) { + if (unit.Ids[index] == port) { + VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); - return _switchIdInspector; + return switchIdInspector; + } } return base.GetPortInspector(port, meta); diff --git a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs index 3149a96..0c1abef 100644 --- a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs @@ -26,20 +26,28 @@ namespace VisualPinball.Unity.VisualScripting.Editor [Widget(typeof(SwitchEnabledEventUnit))] public sealed class SwitchEnabledEventUnitWidget : GleUnitWidget { - private VariableNameInspector _switchIdInspector; - private readonly Func _switchIdInspectorConstructor; + private readonly List> _switchIdInspectorConstructorList; public SwitchEnabledEventUnitWidget(FlowCanvas canvas, SwitchEnabledEventUnit unit) : base(canvas, unit) { - _switchIdInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + _switchIdInspectorConstructorList = new List>(); } public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (port == unit.Id) { - InspectorProvider.instance.Renew(ref _switchIdInspector, meta, _switchIdInspectorConstructor); + if (_switchIdInspectorConstructorList.Count() < unit.idCount) { + for (var index = 0; index < unit.idCount - _switchIdInspectorConstructorList.Count(); index++) { + _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.idCount; index++) { + if (unit.Ids[index] == port) { + VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); - return _switchIdInspector; + return switchIdInspector; + } } return base.GetPortInspector(port, meta); diff --git a/Runtime/Nodes/Switches/GetSwitchUnit.cs b/Runtime/Nodes/Switches/GetSwitchUnit.cs index e80720b..ab8c841 100644 --- a/Runtime/Nodes/Switches/GetSwitchUnit.cs +++ b/Runtime/Nodes/Switches/GetSwitchUnit.cs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; @@ -24,9 +25,19 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Visual Pinball")] public class GetSwitchUnit : GleUnit { + [SerializeAs(nameof(idCount))] + private int _idCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Switch IDs")] + public int idCount + { + get => _idCount; + set => _idCount = Mathf.Clamp(value, 1, 10); + } + [DoNotSerialize] - [PortLabel("Switch ID")] - public ValueInput Id { get; private set; } + public List Ids { get; private set; } [DoNotSerialize] [PortLabel("Is Enabled")] @@ -34,7 +45,12 @@ public class GetSwitchUnit : GleUnit protected override void Definition() { - Id = ValueInput(nameof(Id), string.Empty); + Ids = new List(); + + for (var i = 0; i < idCount; i++) { + var id = ValueInput("Switch ID " + (i + 1), string.Empty); + Ids.Add(id); + } IsEnabled = ValueOutput(nameof(IsEnabled), GetEnabled); } @@ -46,7 +62,13 @@ private bool GetEnabled(Flow flow) return false; } - return Gle.GetSwitch(flow.GetValue(Id)); + foreach (var id in Ids) { + if (!Gle.GetSwitch(flow.GetValue(id))) { + return false; + } + } + + return true; } } } diff --git a/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs index 32aac43..2b371dc 100644 --- a/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs +++ b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs @@ -14,7 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System.Collections.Generic; using Unity.VisualScripting; +using UnityEngine; namespace VisualPinball.Unity.VisualScripting { @@ -23,9 +25,19 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Events\\Visual Pinball")] public class SwitchEnabledEventUnit : GleEventUnit { + [SerializeAs(nameof(idCount))] + private int _idCount = 1; + [DoNotSerialize] - [PortLabel("Switch ID")] - public ValueInput Id { get; private set; } + [Inspectable, UnitHeaderInspectable("Switch IDs")] + public int idCount + { + get => _idCount; + set => _idCount = Mathf.Clamp(value, 1, 10); + } + + [DoNotSerialize] + public List Ids { get; private set; } [DoNotSerialize] protected override bool register => true; @@ -36,12 +48,24 @@ public class SwitchEnabledEventUnit : GleEventUnit protected override void Definition() { base.Definition(); - Id = ValueInput(nameof(Id), string.Empty); + + Ids = new List(); + + for (var i = 0; i < idCount; i++) { + var id = ValueInput("Switch ID " + (i + 1), string.Empty); + Ids.Add(id); + } } protected override bool ShouldTrigger(Flow flow, SwitchEventArgs2 args) { - return flow.GetValue(Id) == args.Id && args.IsEnabled; + foreach(var id in Ids) { + if (flow.GetValue(id) == args.Id && args.IsEnabled) { + return true; + } + } + + return false; } } } From d77583d94f40f473a88c053e615d7e86c50bda7b Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Mon, 31 Jan 2022 07:40:20 -0500 Subject: [PATCH 06/54] coils: update pulse coil unit to take multiple coils --- Editor/Descriptors/PulseCoilUnitDescriptor.cs | 6 +-- Editor/Widgets/PulseCoilUnitWidget.cs | 21 +++++++--- Runtime/Nodes/Coils/PulseCoilUnit.cs | 38 ++++++++++++++----- 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/Editor/Descriptors/PulseCoilUnitDescriptor.cs b/Editor/Descriptors/PulseCoilUnitDescriptor.cs index 522dcea..86c5443 100644 --- a/Editor/Descriptors/PulseCoilUnitDescriptor.cs +++ b/Editor/Descriptors/PulseCoilUnitDescriptor.cs @@ -44,11 +44,11 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(PulseCoilUnit.Id): - desc.summary = "The ID of the coil to be pulsed."; + case nameof(PulseCoilUnit.Ids): + desc.summary = "The IDs of the coils to be pulsed."; break; case nameof(PulseCoilUnit.PulseDuration): - desc.summary = "The time in milliseconds until the coil is disabled again."; + desc.summary = "The time in milliseconds until the coils are disabled again."; break; } } diff --git a/Editor/Widgets/PulseCoilUnitWidget.cs b/Editor/Widgets/PulseCoilUnitWidget.cs index 7120ca0..6e33904 100644 --- a/Editor/Widgets/PulseCoilUnitWidget.cs +++ b/Editor/Widgets/PulseCoilUnitWidget.cs @@ -26,19 +26,28 @@ namespace VisualPinball.Unity.VisualScripting.Editor [Widget(typeof(PulseCoilUnit))] public sealed class PulseCoilUnitWidget : GleUnitWidget { - private VariableNameInspector _coilIdInspector; - private readonly Func _setCoilInspectorConstructor; + private readonly List> _coilIdInspectorConstructorList; public PulseCoilUnitWidget(FlowCanvas canvas, PulseCoilUnit unit) : base(canvas, unit) { - _setCoilInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + _coilIdInspectorConstructorList = new List>(); } public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (port == unit.Id) { - InspectorProvider.instance.Renew(ref _coilIdInspector, meta, _setCoilInspectorConstructor); - return _coilIdInspector; + if (_coilIdInspectorConstructorList.Count() < unit.idCount) { + for (var index = 0; index < unit.idCount - _coilIdInspectorConstructorList.Count(); index++) { + _coilIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.idCount; index++) { + if (unit.Ids[index] == port) { + VariableNameInspector coilIdInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref coilIdInspector, meta, _coilIdInspectorConstructorList[index]); + + return coilIdInspector; + } } return base.GetPortInspector(port, meta); diff --git a/Runtime/Nodes/Coils/PulseCoilUnit.cs b/Runtime/Nodes/Coils/PulseCoilUnit.cs index 137ac17..d842b68 100644 --- a/Runtime/Nodes/Coils/PulseCoilUnit.cs +++ b/Runtime/Nodes/Coils/PulseCoilUnit.cs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; @@ -32,9 +33,19 @@ public class PulseCoilUnit : GleUnit [PortLabelHidden] public ControlOutput OutputTrigger; + [SerializeAs(nameof(idCount))] + private int _idCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Coil IDs")] + public int idCount + { + get => _idCount; + set => _idCount = Mathf.Clamp(value, 1, 10); + } + [DoNotSerialize] - [PortLabel("Coil ID")] - public ValueInput Id { get; private set; } + public List Ids { get; private set; } [DoNotSerialize] [PortLabel("Duration (ms)")] @@ -45,10 +56,17 @@ protected override void Definition() InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - Id = ValueInput(nameof(Id), string.Empty); + Ids = new List(); + + for (var i = 0; i < idCount; i++) { + var id = ValueInput("Coil ID " + (i + 1), string.Empty); + Ids.Add(id); + + Requirement(id, InputTrigger); + } + PulseDuration = ValueInput(nameof(PulseDuration), 80); - Requirement(Id, InputTrigger); Succession(InputTrigger, OutputTrigger); } @@ -60,15 +78,17 @@ private ControlOutput Process(Flow flow) } if (!AssertPlayer(flow)) { - Debug.LogError("Cannot find GLE."); + Debug.LogError("Cannot find Player."); return OutputTrigger; } - var id = flow.GetValue(Id); - var pulseDuration = flow.GetValue(PulseDuration); + foreach (var id in Ids) { + var idValue = flow.GetValue(id); + var pulseDuration = flow.GetValue(PulseDuration); - Gle.SetCoil(id, true); - Player.ScheduleAction(pulseDuration, () => Gle.SetCoil(id, false)); + Gle.SetCoil(idValue, true); + Player.ScheduleAction(pulseDuration, () => Gle.SetCoil(idValue, false)); + } return OutputTrigger; } From 002f62cbacabbe014eff56cb8955507f76a99c78 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Mon, 31 Jan 2022 07:50:56 -0500 Subject: [PATCH 07/54] scripting: update set coil unit to accept multiple coils --- Editor/Descriptors/SetCoilUnitDescriptor.cs | 8 ++--- Editor/Widgets/SetCoilUnitWidget.cs | 21 +++++++++---- Runtime/Nodes/Coils/PulseCoilUnit.cs | 3 +- Runtime/Nodes/Coils/SetCoilUnit.cs | 33 +++++++++++++++++---- 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/Editor/Descriptors/SetCoilUnitDescriptor.cs b/Editor/Descriptors/SetCoilUnitDescriptor.cs index 8d628cc..24222aa 100644 --- a/Editor/Descriptors/SetCoilUnitDescriptor.cs +++ b/Editor/Descriptors/SetCoilUnitDescriptor.cs @@ -30,7 +30,7 @@ public SetCoilUnitDescriptor(SetCoilUnit target) : base(target) protected override string DefinedSummary() { - return "This node assigns a given value to a coil defined by its ID."; + return "This node assigns a given value to coils defined by their IDs."; } protected override EditorTexture DefinedIcon() @@ -44,11 +44,11 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(SetCoilUnit.Id): - desc.summary = "The ID of the coil to be set."; + case nameof(SetCoilUnit.Ids): + desc.summary = "The IDs of the coils to be set."; break; case nameof(SetCoilUnit.IsEnabled): - desc.summary = "The value to assign to the coil."; + desc.summary = "The value to assign to the coils."; break; } } diff --git a/Editor/Widgets/SetCoilUnitWidget.cs b/Editor/Widgets/SetCoilUnitWidget.cs index 7c59c14..788dcc4 100644 --- a/Editor/Widgets/SetCoilUnitWidget.cs +++ b/Editor/Widgets/SetCoilUnitWidget.cs @@ -26,19 +26,28 @@ namespace VisualPinball.Unity.VisualScripting.Editor [Widget(typeof(SetCoilUnit))] public sealed class SetCoilUnitWidget : GleUnitWidget { - private VariableNameInspector _coilIdInspector; - private readonly Func _setCoilInspectorConstructor; + private readonly List> _coilIdInspectorConstructorList; public SetCoilUnitWidget(FlowCanvas canvas, SetCoilUnit unit) : base(canvas, unit) { - _setCoilInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + _coilIdInspectorConstructorList = new List>(); } public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (port == unit.Id) { - InspectorProvider.instance.Renew(ref _coilIdInspector, meta, _setCoilInspectorConstructor); - return _coilIdInspector; + if (_coilIdInspectorConstructorList.Count() < unit.idCount) { + for (var index = 0; index < unit.idCount - _coilIdInspectorConstructorList.Count(); index++) { + _coilIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.idCount; index++) { + if (unit.Ids[index] == port) { + VariableNameInspector coilIdInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref coilIdInspector, meta, _coilIdInspectorConstructorList[index]); + + return coilIdInspector; + } } return base.GetPortInspector(port, meta); diff --git a/Runtime/Nodes/Coils/PulseCoilUnit.cs b/Runtime/Nodes/Coils/PulseCoilUnit.cs index d842b68..db8a3ce 100644 --- a/Runtime/Nodes/Coils/PulseCoilUnit.cs +++ b/Runtime/Nodes/Coils/PulseCoilUnit.cs @@ -82,9 +82,10 @@ private ControlOutput Process(Flow flow) return OutputTrigger; } + var pulseDuration = flow.GetValue(PulseDuration); + foreach (var id in Ids) { var idValue = flow.GetValue(id); - var pulseDuration = flow.GetValue(PulseDuration); Gle.SetCoil(idValue, true); Player.ScheduleAction(pulseDuration, () => Gle.SetCoil(idValue, false)); diff --git a/Runtime/Nodes/Coils/SetCoilUnit.cs b/Runtime/Nodes/Coils/SetCoilUnit.cs index 69eee0b..4ebef76 100644 --- a/Runtime/Nodes/Coils/SetCoilUnit.cs +++ b/Runtime/Nodes/Coils/SetCoilUnit.cs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; @@ -32,9 +33,19 @@ public class SetCoilUnit : GleUnit [PortLabelHidden] public ControlOutput OutputTrigger; + [SerializeAs(nameof(idCount))] + private int _idCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Coil IDs")] + public int idCount + { + get => _idCount; + set => _idCount = Mathf.Clamp(value, 1, 10); + } + [DoNotSerialize] - [PortLabel("Coil ID")] - public ValueInput Id { get; private set; } + public List Ids { get; private set; } [DoNotSerialize] [PortLabel("Value")] @@ -45,10 +56,17 @@ protected override void Definition() InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - Id = ValueInput(nameof(Id), string.Empty); + Ids = new List(); + + for (var i = 0; i < idCount; i++) { + var id = ValueInput("Coil ID " + (i + 1), string.Empty); + Ids.Add(id); + + Requirement(id, InputTrigger); + } + IsEnabled = ValueInput(nameof(IsEnabled), false); - Requirement(Id, InputTrigger); Succession(InputTrigger, OutputTrigger); } @@ -59,10 +77,13 @@ private ControlOutput Process(Flow flow) return OutputTrigger; } - var id = flow.GetValue(Id); var isEnabled = flow.GetValue(IsEnabled); - Gle.SetCoil(id, isEnabled); + foreach (var id in Ids) { + var idValue = flow.GetValue(id); + + Gle.SetCoil(idValue, isEnabled); + } return OutputTrigger; } From 6c6e37a8b67c488d030be0223a18d422393e7368 Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 1 Feb 2022 00:23:19 +0100 Subject: [PATCH 08/54] Add groundwork for player states. --- .../Gamelogic/VisualScriptingEventNames.cs | 2 + .../VisualScriptingGamelogicEngine.cs | 48 +++++++ .../Gamelogic/VisualScriptingPlayerState.cs | 121 ++++++++++++++++++ .../VisualScriptingPlayerState.cs.meta | 11 ++ .../VisualScriptingPlayerStateDefinition.cs | 56 ++++++++ ...sualScriptingPlayerStateDefinition.cs.meta | 11 ++ .../VisualScriptingPlayerStateProperty.cs | 57 +++++++++ ...VisualScriptingPlayerStateProperty.cs.meta | 11 ++ Runtime/Nodes/CreateBallUnit.cs | 2 +- Runtime/Nodes/GleUnit.cs | 42 +++++- Runtime/Nodes/PlayerState.meta | 8 ++ .../PlayerStateAddToIntegerUnit.cs | 71 ++++++++++ .../PlayerStateAddToIntegerUnit.cs.meta | 11 ++ .../PlayerState/PlayerStateCreateUnit.cs | 62 +++++++++ .../PlayerState/PlayerStateCreateUnit.cs.meta | 11 ++ 15 files changed, 520 insertions(+), 4 deletions(-) create mode 100644 Runtime/Gamelogic/VisualScriptingPlayerState.cs create mode 100644 Runtime/Gamelogic/VisualScriptingPlayerState.cs.meta create mode 100644 Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs create mode 100644 Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs.meta create mode 100644 Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs create mode 100644 Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs.meta create mode 100644 Runtime/Nodes/PlayerState.meta create mode 100644 Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs create mode 100644 Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs.meta create mode 100644 Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs create mode 100644 Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs.meta diff --git a/Runtime/Gamelogic/VisualScriptingEventNames.cs b/Runtime/Gamelogic/VisualScriptingEventNames.cs index 8805ddd..1d24c5d 100644 --- a/Runtime/Gamelogic/VisualScriptingEventNames.cs +++ b/Runtime/Gamelogic/VisualScriptingEventNames.cs @@ -22,5 +22,7 @@ public static class VisualScriptingEventNames public const string LampEvent = "LampEvent"; public const string SwitchEvent = "SwitchEvent"; public const string CoilEvent = "CoilEvent"; + public const string CurrentPlayerChanged = "CurrentPlayerChanged"; + public const string CurrentPlayerStateChanged = "CurrentPlayerStateChanged"; } } diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index 2c33512..07634fd 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -17,6 +17,7 @@ // ReSharper disable InconsistentNaming using System; +using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; using UnityEngine; @@ -30,6 +31,8 @@ public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine { public string Name => "Visual Scripting Gamelogic Engine"; + public List PlayerStateDefinition; + [Tooltip("The switches that are exposed in the Visual Scripting nodes.")] public VisualScriptingSwitch[] Switches; public VisualScriptingCoil[] Coils; @@ -56,6 +59,51 @@ public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine [NonSerialized] public BallManager BallManager; [NonSerialized] private Player _player; + [NonSerialized] private int _currentPlayer; + [NonSerialized] private readonly Dictionary _playerStates = new (); + + public VisualScriptingPlayerState CurrentPlayerState { + get { + if (!_playerStates.ContainsKey(_currentPlayer)) { + throw new InvalidOperationException("Must create a player state before accessing it!"); + } + return _playerStates[_currentPlayer]; + } + } + + public int CurrentPlayer { + get => _currentPlayer; + set { + if (!_playerStates.ContainsKey(value)) { + Debug.LogError($"Cannot change to non-existing player {value}."); + return; + } + var previousPlayer = _currentPlayer; + _currentPlayer = value; + if (previousPlayer != _currentPlayer) { + EventBus.Trigger(VisualScriptingEventNames.CurrentPlayerChanged, EventArgs.Empty); + } + } + } + + public void CreatePlayerState(int playerId) + { + if (_playerStates.ContainsKey(playerId)) { + Debug.LogWarning($"Tried to create new player state for existing state {playerId}, skipping."); + return; + } + var playerState = new VisualScriptingPlayerState(playerId); + foreach (var propertyDefinition in PlayerStateDefinition) { + playerState.AddProperty(propertyDefinition.Instantiate()); + } + _playerStates[playerId] = playerState; + + // switch to this state if current state is invalid + if (!_playerStates.ContainsKey(_currentPlayer)) { + CurrentPlayer = playerId; + } + } + public void OnInit(Player player, TableApi tableApi, BallManager ballManager) { _player = player; diff --git a/Runtime/Gamelogic/VisualScriptingPlayerState.cs b/Runtime/Gamelogic/VisualScriptingPlayerState.cs new file mode 100644 index 0000000..653100a --- /dev/null +++ b/Runtime/Gamelogic/VisualScriptingPlayerState.cs @@ -0,0 +1,121 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting +{ + public class VisualScriptingPlayerState + { + public readonly int Id; + + private readonly Dictionary _properties = new(); + + public VisualScriptingPlayerState(int id) + { + Id = id; + } + + public void AddProperty(VisualScriptingPlayerStateProperty property) + { + _properties[property.Name] = property; + } + + public T Get(string propertyName) where T : class + { + if (!_properties.ContainsKey(propertyName)) { + throw new ArgumentException($"No such property name ({propertyName}).", nameof(propertyName)); + } + if (_properties[propertyName].Type != typeof(T)) { + throw new InvalidOperationException($"Property \"{propertyName}\" is of type {_properties[propertyName].Type}, but you asked for a {typeof(T)}."); + } + + return _properties[propertyName].Get(); + } + + public void Set(string propertyName, T value) where T : class + { + if (!_properties.ContainsKey(propertyName)) { + throw new ArgumentException($"No such property name ({propertyName}).", nameof(propertyName)); + } + if (_properties[propertyName].Type != value.GetType()) { + throw new ArgumentException($"Property \"{propertyName}\" is of type {_properties[propertyName].Type}, but you provided a {value.GetType()}.", nameof(value)); + } + + var currentValue = _properties[propertyName].Get(); + _properties[propertyName].Set(value); + + if (currentValue != value) { + EventBus.Trigger(VisualScriptingEventNames.CurrentPlayerStateChanged, new PlayerStateChangedArgs(propertyName)); + } + } + + internal bool Has(string propertyName) => _properties.ContainsKey(propertyName) && typeof(T) == _properties[propertyName].Type; + } + + public class Integer + { + private readonly int _value; + public Integer(int value) + { + _value = value; + } + public static Integer operator +(Integer lhs, Integer rhs) => new(lhs._value + rhs._value); + public static Integer operator -(Integer lhs, Integer rhs) => new(lhs._value - rhs._value); + public static Integer operator *(Integer lhs, Integer rhs) => new(lhs._value * rhs._value); + public static Integer operator /(Integer lhs, Integer rhs) => new(lhs._value / rhs._value); + public static implicit operator int(Integer num) => num._value; + public static implicit operator Integer(int num) => new(num); + } + + public class Float + { + private readonly float _value; + public Float(float value) + { + _value = value; + } + public static Float operator +(Float lhs, Float rhs) => new(lhs._value + rhs._value); + public static Float operator -(Float lhs, Float rhs) => new(lhs._value - rhs._value); + public static Float operator *(Float lhs, Float rhs) => new(lhs._value * rhs._value); + public static Float operator /(Float lhs, Float rhs) => new(lhs._value / rhs._value); + public static implicit operator float(Float num) => num._value; + public static implicit operator Float(float num) => new(num); + } + + public class Bool + { + private readonly bool _value; + public Bool(bool value) + { + _value = value; + } + public static implicit operator bool(Bool num) => num._value; + public static implicit operator Bool(bool num) => new(num); + } + + public readonly struct PlayerStateChangedArgs + { + public readonly string PropertyName; + + public PlayerStateChangedArgs(string propertyName) + { + PropertyName = propertyName; + } + } +} diff --git a/Runtime/Gamelogic/VisualScriptingPlayerState.cs.meta b/Runtime/Gamelogic/VisualScriptingPlayerState.cs.meta new file mode 100644 index 0000000..1ceee59 --- /dev/null +++ b/Runtime/Gamelogic/VisualScriptingPlayerState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e05e8d3a73ef6114f99ebdd2464d255e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs b/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs new file mode 100644 index 0000000..6b7992d --- /dev/null +++ b/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs @@ -0,0 +1,56 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable InconsistentNaming + +using System; + +namespace VisualPinball.Unity.VisualScripting +{ + + [Serializable] + public class VisualScriptingPlayerStatePropertyDefinition + { + public string Name; + public VisualScriptingPropertyType Type; + + public string StringDefaultValue; + public int IntegerDefaultValue; + public float FloatDefaultValue; + public bool BooleanDefaultValue; + + public VisualScriptingPlayerStateProperty Instantiate() + { + switch (Type) { + case VisualScriptingPropertyType.String: + return new VisualScriptingPlayerStateProperty(Name, StringDefaultValue); + case VisualScriptingPropertyType.Integer: + return new VisualScriptingPlayerStateProperty(Name, IntegerDefaultValue); + case VisualScriptingPropertyType.Float: + return new VisualScriptingPlayerStateProperty(Name, FloatDefaultValue); + case VisualScriptingPropertyType.Boolean: + return new VisualScriptingPlayerStateProperty(Name, BooleanDefaultValue); + default: + throw new ArgumentOutOfRangeException(); + } + } + } + + public enum VisualScriptingPropertyType + { + String, Integer, Float, Boolean + } +} diff --git a/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs.meta b/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs.meta new file mode 100644 index 0000000..d034587 --- /dev/null +++ b/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 589c55ec2c5c1c8468847784fe7b54bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs b/Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs new file mode 100644 index 0000000..d50ba1c --- /dev/null +++ b/Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs @@ -0,0 +1,57 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; + +namespace VisualPinball.Unity.VisualScripting +{ + public class VisualScriptingPlayerStateProperty + { + public string Name; + public Type Type; + private object _value; + + public VisualScriptingPlayerStateProperty(string name, string initialValue) : this(name, typeof(string), initialValue) + { + } + public VisualScriptingPlayerStateProperty(string name, int initialValue) : this(name, typeof(Integer),new Integer(initialValue)) + { + } + public VisualScriptingPlayerStateProperty(string name, float initialValue) : this(name, typeof(Float), new Float(initialValue)) + { + } + public VisualScriptingPlayerStateProperty(string name, bool initialValue) : this(name, typeof(Bool), new Bool(initialValue)) + { + } + + private VisualScriptingPlayerStateProperty(string name, Type type, object initialValue) + { + Name = name; + Type = type; + _value = initialValue; + } + + public T Get() where T : class + { + return _value as T; + } + + public void Set(T value) + { + _value = value; + } + } +} diff --git a/Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs.meta b/Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs.meta new file mode 100644 index 0000000..fedc5b7 --- /dev/null +++ b/Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e3022795485dd6248a3fec806ab1656f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/CreateBallUnit.cs b/Runtime/Nodes/CreateBallUnit.cs index 97d751d..7ad5cc1 100644 --- a/Runtime/Nodes/CreateBallUnit.cs +++ b/Runtime/Nodes/CreateBallUnit.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity.VisualScripting { [UnitTitle("Create Ball")] - [UnitCategory("Events\\Visual Pinball")] + [UnitCategory("Visual Pinball")] public class CreateBallUnit : GleUnit { [DoNotSerialize] diff --git a/Runtime/Nodes/GleUnit.cs b/Runtime/Nodes/GleUnit.cs index 07eb387..71ca947 100644 --- a/Runtime/Nodes/GleUnit.cs +++ b/Runtime/Nodes/GleUnit.cs @@ -23,6 +23,30 @@ public abstract class GleEventUnit : EventUnit, IGleUnit { [DoNotSerialize] public List Errors { get; } = new(); + + [DoNotSerialize] + protected IGamelogicEngine Gle; + + [DoNotSerialize] + protected Player Player; + + protected bool AssertGle(Flow flow) + { + if (!Gle.IsUnityNull()) { + return true; + } + Gle = flow.stack.gameObject.GetComponentInParent(); + return Gle != null; + } + + protected bool AssertPlayer(Flow flow) + { + if (!Player.IsUnityNull()) { + return true; + } + Player = flow.stack.gameObject.GetComponentInParent(); + return Player != null; + } } public abstract class GleUnit : Unit, IGleUnit @@ -33,21 +57,33 @@ public abstract class GleUnit : Unit, IGleUnit [DoNotSerialize] protected IGamelogicEngine Gle; + [DoNotSerialize] + protected VisualScriptingGamelogicEngine VsGle; + [DoNotSerialize] protected Player Player; - + protected bool AssertGle(Flow flow) { - if (!UnityObjectUtility.IsUnityNull(Gle)) { + if (!Gle.IsUnityNull()) { return true; } Gle = flow.stack.gameObject.GetComponentInParent(); return Gle != null; } + protected bool AssertVsGle(Flow flow) + { + if (!VsGle.IsUnityNull()) { + return true; + } + VsGle = flow.stack.gameObject.GetComponentInParent(); + return VsGle != null; + } + protected bool AssertPlayer(Flow flow) { - if (!UnityObjectUtility.IsUnityNull(Player)) { + if (!Player.IsUnityNull()) { return true; } Player = flow.stack.gameObject.GetComponentInParent(); diff --git a/Runtime/Nodes/PlayerState.meta b/Runtime/Nodes/PlayerState.meta new file mode 100644 index 0000000..4918ac4 --- /dev/null +++ b/Runtime/Nodes/PlayerState.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6d6c8897d98d2ac45b5beb287485da78 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs b/Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs new file mode 100644 index 0000000..ce42954 --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs @@ -0,0 +1,71 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Player State: Add to property (integer)")] + [UnitSurtitle("Player State")] + [UnitCategory("Visual Pinball/State")] + public class PlayerStateAddToIntegerUnit : GleUnit + { + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + + [DoNotSerialize] + [PortLabel("Property Name")] + public ValueInput PropertyName { get; private set; } + + [DoNotSerialize] + [PortLabel("Value to Add")] + public ValueInput ValueToAdd { get; private set; } + + protected override void Definition() + { + PropertyName = ValueInput(nameof(PropertyName), string.Empty); + ValueToAdd = ValueInput(nameof(ValueToAdd), 0); + + InputTrigger = ControlInput(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + Requirement(PropertyName, InputTrigger); + Requirement(ValueToAdd, InputTrigger); + Succession(InputTrigger, OutputTrigger); + } + + private ControlOutput Process(Flow flow) + { + if (!AssertVsGle(flow)) { + Debug.LogError("Cannot find GLE."); + return OutputTrigger; + } + + var propertyName = flow.GetValue(PropertyName); + var valueToAdd = flow.GetValue(ValueToAdd); + VsGle.CurrentPlayerState.Set(propertyName, VsGle.CurrentPlayerState.Get(propertyName) + valueToAdd); + + return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs.meta new file mode 100644 index 0000000..5a7dbca --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7bd0fd9284dd5740892c3947893406e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs b/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs new file mode 100644 index 0000000..b642b47 --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs @@ -0,0 +1,62 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Create Player State")] + [UnitSurtitle("Player State")] + [UnitCategory("Visual Pinball/State")] + public class PlayerStateCreateUnit : GleUnit + { + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + + [DoNotSerialize] + [PortLabel("Player ID")] + public ValueInput PlayerId { get; private set; } + + protected override void Definition() + { + PlayerId = ValueInput(nameof(PlayerId), 0); + + InputTrigger = ControlInput(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + Requirement(PlayerId, InputTrigger); + Succession(InputTrigger, OutputTrigger); + } + + private ControlOutput Process(Flow flow) + { + if (!AssertVsGle(flow)) { + Debug.LogError("Cannot find GLE."); + return OutputTrigger; + } + + VsGle.CreatePlayerState(flow.GetValue(PlayerId)); + + return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs.meta new file mode 100644 index 0000000..d8edede --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f58bc7f875f7f7446ae915edfeeb9203 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 31dbe36341f855c8fb0c27374b3a7fc1e64f08d9 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 2 Feb 2022 00:55:27 +0100 Subject: [PATCH 09/54] Add set player state unit that allows selecting the variable. --- Editor/Inspectors/GleInspector.cs | 48 +++++++++++++ Editor/Inspectors/GleInspector.cs.meta | 11 +++ ...gPlayerStatePropertyDefinitionInspector.cs | 72 +++++++++++++++++++ ...erStatePropertyDefinitionInspector.cs.meta | 11 +++ ...tingPlayerStateDefinitionPropertyDrawer.cs | 26 +++++++ ...layerStateDefinitionPropertyDrawer.cs.meta | 11 +++ Editor/Widgets/GleUnitWidget.cs | 2 + Editor/Widgets/PlayerStateSetUnitWidget.cs | 59 +++++++++++++++ .../Widgets/PlayerStateSetUnitWidget.cs.meta | 11 +++ .../VisualScriptingGamelogicEngine.cs | 20 +++++- .../VisualScriptingPlayerStateDefinition.cs | 4 ++ .../Nodes/PlayerState/PlayerStateSetUnit.cs | 66 +++++++++++++++++ .../PlayerState/PlayerStateSetUnit.cs.meta | 11 +++ 13 files changed, 351 insertions(+), 1 deletion(-) create mode 100644 Editor/Inspectors/GleInspector.cs create mode 100644 Editor/Inspectors/GleInspector.cs.meta create mode 100644 Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs create mode 100644 Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs.meta create mode 100644 Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs create mode 100644 Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs.meta create mode 100644 Editor/Widgets/PlayerStateSetUnitWidget.cs create mode 100644 Editor/Widgets/PlayerStateSetUnitWidget.cs.meta create mode 100644 Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs create mode 100644 Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs.meta diff --git a/Editor/Inspectors/GleInspector.cs b/Editor/Inspectors/GleInspector.cs new file mode 100644 index 0000000..17548fd --- /dev/null +++ b/Editor/Inspectors/GleInspector.cs @@ -0,0 +1,48 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.VisualScripting; +using VisualPinball.Unity; +using VisualPinball.Unity.VisualScripting; + +public abstract class GleInspector : Inspector +{ + protected GleInspector(Metadata metadata) : base(metadata) { } + + private const string NoGleError = "Unable to find Gamelogic Engine in scene."; + + protected VisualScriptingGamelogicEngine Gle { + get { + if (_gle != null) { + return _gle; + } + var tableComponent = TableSelector.Instance.SelectedOrFirstTable; + if (tableComponent != null) { + _gle = tableComponent.GetComponentInChildren(); + } + if (_gle == null && ErrorMessage == null) { + ErrorMessage = NoGleError; + + } else if (_gle != null && ErrorMessage == NoGleError) { + ErrorMessage = null; + } + return _gle; + } + } + protected string ErrorMessage; + + private VisualScriptingGamelogicEngine _gle; +} diff --git a/Editor/Inspectors/GleInspector.cs.meta b/Editor/Inspectors/GleInspector.cs.meta new file mode 100644 index 0000000..7dac231 --- /dev/null +++ b/Editor/Inspectors/GleInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fcd362b6a8f17ea438744161a4e990ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs b/Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs new file mode 100644 index 0000000..3cae486 --- /dev/null +++ b/Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs @@ -0,0 +1,72 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Linq; +using Unity.VisualScripting; +using UnityEditor; +using UnityEngine; +using VisualPinball.Unity.VisualScripting; + +[Inspector(typeof(VisualScriptingPlayerStatePropertyDefinition))] +public class VisualScriptingPlayerStatePropertyDefinitionInspector : GleInspector +{ + public VisualScriptingPlayerStatePropertyDefinitionInspector(Metadata metadata) : base(metadata) { } + + protected override void OnGUI(Rect position, GUIContent label) + { + // can't get this from the flow + var gle = Gle; + if (gle != null) { + var propDefinitions = gle.PlayerStateDefinition; + + if (propDefinitions.Count == 0) { + ErrorMessage = "No properties defined."; + + } else { + var propNames = propDefinitions.Select(d => d.Name).ToArray(); + var currentPropDef = metadata.value as VisualScriptingPlayerStatePropertyDefinition; + var playerPropDef = propDefinitions.FirstOrDefault(p => p.Id == currentPropDef!.Id); + var currentIndex = playerPropDef != null ? propDefinitions.IndexOf(playerPropDef) : 0; + + var newIndex = EditorGUI.Popup(position, currentIndex, propNames); + if (EndBlock(metadata)) + { + metadata.RecordUndo(); + metadata.value = propDefinitions[newIndex]; + } + } + } + + + if (ErrorMessage != null) { + position.height -= EditorGUIUtility.standardVerticalSpacing; + EditorGUI.HelpBox(position, ErrorMessage, MessageType.Error); + } + } + + public override float GetAdaptiveWidth() => LudiqGUIUtility.currentInspectorWidth; + + protected override float GetHeight(float width, GUIContent label) + { + if (ErrorMessage != null) { + var height = LudiqGUIUtility.GetHelpBoxHeight(ErrorMessage, MessageType.Error, width); + height += EditorGUIUtility.standardVerticalSpacing; + return height; + } + + return EditorGUIUtility.singleLineHeight; + } +} diff --git a/Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs.meta b/Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs.meta new file mode 100644 index 0000000..5463cd5 --- /dev/null +++ b/Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1750d8491ca391b4a87decd7488aabac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs b/Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs new file mode 100644 index 0000000..2fdfd2d --- /dev/null +++ b/Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs @@ -0,0 +1,26 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// using UnityEditor; +// +// namespace VisualPinball.Unity.VisualScripting.Editor +// { +// [CustomPropertyDrawer(typeof(VisualScriptingCoil))] +// public class VisualScriptingPlayerStateDefinitionPropertyDrawer : PropertyDrawer +// { +// } +// } + diff --git a/Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs.meta b/Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs.meta new file mode 100644 index 0000000..0def5d3 --- /dev/null +++ b/Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0571cab62bbde71458ff1f10ea832889 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/GleUnitWidget.cs b/Editor/Widgets/GleUnitWidget.cs index 0cac6e6..14fb916 100644 --- a/Editor/Widgets/GleUnitWidget.cs +++ b/Editor/Widgets/GleUnitWidget.cs @@ -23,7 +23,9 @@ public abstract class GleUnitWidget : UnitWidget where TUnit : Uni protected override NodeColorMix baseColor => GleAvailable ? NodeColorMix.TealReadable : new NodeColorMix { red = 1f, green = 0f, blue = 0f }; protected bool GameObjectAvailable => reference != null && reference.gameObject != null; protected IGamelogicEngine Gle => reference.gameObject.GetComponentInParent(); + protected VisualScriptingGamelogicEngine VsGle => reference.gameObject.GetComponentInParent(); private bool GleAvailable => GameObjectAvailable && Gle != null; + private bool VsGleAvailable => GameObjectAvailable && VsGle != null; protected GleUnitWidget(FlowCanvas canvas, TUnit unit) : base(canvas, unit) { diff --git a/Editor/Widgets/PlayerStateSetUnitWidget.cs b/Editor/Widgets/PlayerStateSetUnitWidget.cs new file mode 100644 index 0000000..c240d2a --- /dev/null +++ b/Editor/Widgets/PlayerStateSetUnitWidget.cs @@ -0,0 +1,59 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(PlayerStateSetUnit))] + public sealed class PlayerStateSetUnitWidget : GleUnitWidget + { + public PlayerStateSetUnitWidget(FlowCanvas canvas, PlayerStateSetUnit unit) : base(canvas, unit) + { + _propertyNameInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + } + + protected override NodeColorMix baseColor => NodeColorMix.TealReadable; + + private VariableNameInspector _propertyNameInspector; + private readonly Func _propertyNameInspectorConstructor; + + public override Inspector GetPortInspector(IUnitPort port, Metadata meta) + { + // if (port == unit.PropertyName) { + // InspectorProvider.instance.Renew(ref _propertyNameInspector, meta, _propertyNameInspectorConstructor); + // + // return _propertyNameInspector; + // } + + return base.GetPortInspector(port, meta); + } + + private IEnumerable GetNameSuggestions() + { + if (!GameObjectAvailable) { + return new List(); + } + var gle = VsGle; + return gle == null ? new List() : gle.PlayerStateDefinition.Select(prop => prop.Name).ToList(); + } + } +} diff --git a/Editor/Widgets/PlayerStateSetUnitWidget.cs.meta b/Editor/Widgets/PlayerStateSetUnitWidget.cs.meta new file mode 100644 index 0000000..6079123 --- /dev/null +++ b/Editor/Widgets/PlayerStateSetUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 966947ac781c5e4489a4dad0c7d0d7e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index 07634fd..eb7931e 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -27,7 +27,7 @@ namespace VisualPinball.Unity.VisualScripting { [DisallowMultipleComponent] [AddComponentMenu("Visual Pinball/Gamelogic Engine/Visual Scripting Game Logic")] - public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine + public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine, ISerializationCallbackReceiver { public string Name => "Visual Scripting Gamelogic Engine"; @@ -151,5 +151,23 @@ public bool GetCoil(string id) { return _player.CoilStatuses.ContainsKey(id) && _player.CoilStatuses[id]; } + + + public void OnBeforeSerialize() + { + #if UNITY_EDITOR + + var ids = new HashSet(); + foreach (var def in PlayerStateDefinition) { + if (!def.HasId || ids.Contains(def.Id)) { + def.GenerateId(); + } + ids.Add(def.Id); + } + #endif + } + public void OnAfterDeserialize() + { + } } } diff --git a/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs b/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs index 6b7992d..5007415 100644 --- a/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs +++ b/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs @@ -24,6 +24,7 @@ namespace VisualPinball.Unity.VisualScripting [Serializable] public class VisualScriptingPlayerStatePropertyDefinition { + public string Id; public string Name; public VisualScriptingPropertyType Type; @@ -47,6 +48,9 @@ public VisualScriptingPlayerStateProperty Instantiate() throw new ArgumentOutOfRangeException(); } } + + public bool HasId => !string.IsNullOrEmpty(Id); + public void GenerateId() => Id = Guid.NewGuid().ToString()[..13]; } public enum VisualScriptingPropertyType diff --git a/Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs b/Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs new file mode 100644 index 0000000..ecdbde1 --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs @@ -0,0 +1,66 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Set Player State Value")] + [UnitSurtitle("Player State")] + [UnitCategory("Visual Pinball/State")] + public class PlayerStateSetUnit : GleUnit + { + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + + [Serialize, Inspectable, UnitHeaderInspectable] + public VisualScriptingPlayerStatePropertyDefinition Property { get; set; } + + [DoNotSerialize] + [PortLabel("Value")] + public ValueInput Value { get; private set; } + + protected override void Definition() + { + Value = ValueInput(nameof(Value), null); + + InputTrigger = ControlInput(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + Requirement(Value, InputTrigger); + Succession(InputTrigger, OutputTrigger); + } + + private ControlOutput Process(Flow flow) + { + if (!AssertVsGle(flow)) { + Debug.LogError("Cannot find GLE."); + return OutputTrigger; + } + + var val = flow.GetValue(Value); + + Debug.Log($"Prop = {Property?.Name}, val = {val}"); + return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs.meta new file mode 100644 index 0000000..06bc4cb --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0e3abb86612c26e46879ed1c11dd18c9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 102fb7855a9cfa76d05a653e46e32e33656e20b7 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 2 Feb 2022 01:08:21 +0100 Subject: [PATCH 10/54] state: Make player variables types work (somewhat). --- ...s => PlayerVariableDefinitionInspector.cs} | 38 +++++----- .../PlayerVariableDefinitionInspector.cs.meta | 2 +- .../PlayerVariableDefinitionPropertyDrawer.cs | 71 +++++++++++++++++++ ...rVariableDefinitionPropertyDrawer.cs.meta} | 2 +- ...tingPlayerStateDefinitionPropertyDrawer.cs | 26 ------- Editor/Widgets/GleUnitWidget.cs | 2 +- Editor/Widgets/PlayerStateSetUnitWidget.cs | 60 ++++++++-------- ...ScriptingPlayerState.cs => PlayerState.cs} | 48 ++++++------- ...Definition.cs.meta => PlayerState.cs.meta} | 2 +- ...ayerStateProperty.cs => PlayerVariable.cs} | 14 ++-- .../Gamelogic/PlayerVariable.cs.meta | 2 +- ...inition.cs => PlayerVariableDefinition.cs} | 24 +++---- .../PlayerVariableDefinition.cs.meta | 11 +++ .../VisualScriptingGamelogicEngine.cs | 12 ++-- ...VisualScriptingPlayerStateProperty.cs.meta | 11 --- .../PlayerStateAddToIntegerUnit.cs | 71 ------------------- .../PlayerStateAddToIntegerUnit.cs.meta | 11 --- .../PlayerState/PlayerStateSetUnit.cs.meta | 11 --- ...ateSetUnit.cs => PlayerVariableSetUnit.cs} | 50 +++++++++---- .../PlayerState/PlayerVariableSetUnit.cs.meta | 11 +++ 20 files changed, 233 insertions(+), 246 deletions(-) rename Editor/Inspectors/{VisualScriptingPlayerStatePropertyDefinitionInspector.cs => PlayerVariableDefinitionInspector.cs} (58%) rename Runtime/Gamelogic/VisualScriptingPlayerState.cs.meta => Editor/Inspectors/PlayerVariableDefinitionInspector.cs.meta (83%) create mode 100644 Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs rename Editor/{Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs.meta => PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs.meta} (83%) delete mode 100644 Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs rename Runtime/Gamelogic/{VisualScriptingPlayerState.cs => PlayerState.cs} (58%) rename Runtime/Gamelogic/{VisualScriptingPlayerStateDefinition.cs.meta => PlayerState.cs.meta} (83%) rename Runtime/Gamelogic/{VisualScriptingPlayerStateProperty.cs => PlayerVariable.cs} (60%) rename Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs.meta => Runtime/Gamelogic/PlayerVariable.cs.meta (83%) rename Runtime/Gamelogic/{VisualScriptingPlayerStateDefinition.cs => PlayerVariableDefinition.cs} (62%) create mode 100644 Runtime/Gamelogic/PlayerVariableDefinition.cs.meta delete mode 100644 Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs.meta delete mode 100644 Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs delete mode 100644 Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs.meta delete mode 100644 Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs.meta rename Runtime/Nodes/PlayerState/{PlayerStateSetUnit.cs => PlayerVariableSetUnit.cs} (52%) create mode 100644 Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs.meta diff --git a/Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs b/Editor/Inspectors/PlayerVariableDefinitionInspector.cs similarity index 58% rename from Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs rename to Editor/Inspectors/PlayerVariableDefinitionInspector.cs index 3cae486..f5b8111 100644 --- a/Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs +++ b/Editor/Inspectors/PlayerVariableDefinitionInspector.cs @@ -14,43 +14,45 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; using UnityEditor; using UnityEngine; using VisualPinball.Unity.VisualScripting; -[Inspector(typeof(VisualScriptingPlayerStatePropertyDefinition))] -public class VisualScriptingPlayerStatePropertyDefinitionInspector : GleInspector +[Inspector(typeof(PlayerVariableDefinition))] +public class PlayerVariableDefinitionInspector : GleInspector { - public VisualScriptingPlayerStatePropertyDefinitionInspector(Metadata metadata) : base(metadata) { } + public PlayerVariableDefinitionInspector(Metadata metadata) : base(metadata) { } protected override void OnGUI(Rect position, GUIContent label) { // can't get this from the flow var gle = Gle; if (gle != null) { - var propDefinitions = gle.PlayerStateDefinition; - - if (propDefinitions.Count == 0) { - ErrorMessage = "No properties defined."; + var varDefinitions = gle.PlayerVariableDefinitions; + if (varDefinitions == null || varDefinitions.Count(p => !string.IsNullOrEmpty(p.Name)) == 0) { + ErrorMessage = "No variables defined."; } else { - var propNames = propDefinitions.Select(d => d.Name).ToArray(); - var currentPropDef = metadata.value as VisualScriptingPlayerStatePropertyDefinition; - var playerPropDef = propDefinitions.FirstOrDefault(p => p.Id == currentPropDef!.Id); - var currentIndex = playerPropDef != null ? propDefinitions.IndexOf(playerPropDef) : 0; - - var newIndex = EditorGUI.Popup(position, currentIndex, propNames); - if (EndBlock(metadata)) - { - metadata.RecordUndo(); - metadata.value = propDefinitions[newIndex]; + var varNames = new List { "None" } + .Concat(varDefinitions.Select(d => d.Name)) + .ToArray(); + var currentVarDef = metadata.value as PlayerVariableDefinition; + var currentIndex = 0; + if (currentVarDef != null) { + var playerVarDef = varDefinitions.FirstOrDefault(p => p.Id == currentVarDef!.Id); + currentIndex = playerVarDef != null ? varDefinitions.IndexOf(playerVarDef) + 1 : 0; } + + var newIndex = EditorGUI.Popup(position, currentIndex, varNames); + metadata.RecordUndo(); + metadata.value = newIndex == 0 ? null : varDefinitions[newIndex - 1]; + ErrorMessage = null; } } - if (ErrorMessage != null) { position.height -= EditorGUIUtility.standardVerticalSpacing; EditorGUI.HelpBox(position, ErrorMessage, MessageType.Error); diff --git a/Runtime/Gamelogic/VisualScriptingPlayerState.cs.meta b/Editor/Inspectors/PlayerVariableDefinitionInspector.cs.meta similarity index 83% rename from Runtime/Gamelogic/VisualScriptingPlayerState.cs.meta rename to Editor/Inspectors/PlayerVariableDefinitionInspector.cs.meta index 1ceee59..ffc5085 100644 --- a/Runtime/Gamelogic/VisualScriptingPlayerState.cs.meta +++ b/Editor/Inspectors/PlayerVariableDefinitionInspector.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e05e8d3a73ef6114f99ebdd2464d255e +guid: f63d46325fcab7b43935ee0cee57ee0a MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs b/Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs new file mode 100644 index 0000000..cba49a2 --- /dev/null +++ b/Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs @@ -0,0 +1,71 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [CustomPropertyDrawer(typeof(PlayerVariableDefinition))] + public class PlayerVariableDefinitionPropertyDrawer : PropertyDrawer + { + private const float Padding = 2f; + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return 3 * (EditorGUIUtility.singleLineHeight + Padding); + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + EditorGUI.BeginProperty(position, label, property); + + var nameProperty = property.FindPropertyRelative(nameof(PlayerVariableDefinition.Name)); + var typeProperty = property.FindPropertyRelative(nameof(PlayerVariableDefinition.Type)); + var typeIndex = typeProperty.enumValueIndex; + + SerializedProperty valueProp; + switch (typeIndex) { + case (int)VariableType.String: + valueProp = property.FindPropertyRelative(nameof(PlayerVariableDefinition.StringDefaultValue)); + break; + case (int)VariableType.Integer: + valueProp = property.FindPropertyRelative(nameof(PlayerVariableDefinition.IntegerDefaultValue)); + break; + case (int)VariableType.Float: + valueProp = property.FindPropertyRelative(nameof(PlayerVariableDefinition.FloatDefaultValue)); + break; + case (int)VariableType.Boolean: + valueProp = property.FindPropertyRelative(nameof(PlayerVariableDefinition.BooleanDefaultValue)); + break; + default: + throw new ArgumentException($"Undefined type index {typeIndex}."); + } + + position.height = EditorGUIUtility.singleLineHeight; + + EditorGUI.PropertyField(position, nameProperty, new GUIContent("Name:")); + position.y += EditorGUIUtility.singleLineHeight + Padding; + EditorGUI.PropertyField(position, typeProperty, new GUIContent("Type:")); + position.y += EditorGUIUtility.singleLineHeight + Padding; + EditorGUI.PropertyField(position, valueProp, new GUIContent("Initial Value:")); + + EditorGUI.EndProperty(); + } + } +} + diff --git a/Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs.meta b/Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs.meta similarity index 83% rename from Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs.meta rename to Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs.meta index 5463cd5..5577ee2 100644 --- a/Editor/Inspectors/VisualScriptingPlayerStatePropertyDefinitionInspector.cs.meta +++ b/Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1750d8491ca391b4a87decd7488aabac +guid: 195abac7c9631244da60e2b9cd38680a MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs b/Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs deleted file mode 100644 index 2fdfd2d..0000000 --- a/Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// using UnityEditor; -// -// namespace VisualPinball.Unity.VisualScripting.Editor -// { -// [CustomPropertyDrawer(typeof(VisualScriptingCoil))] -// public class VisualScriptingPlayerStateDefinitionPropertyDrawer : PropertyDrawer -// { -// } -// } - diff --git a/Editor/Widgets/GleUnitWidget.cs b/Editor/Widgets/GleUnitWidget.cs index 14fb916..bef15ca 100644 --- a/Editor/Widgets/GleUnitWidget.cs +++ b/Editor/Widgets/GleUnitWidget.cs @@ -20,7 +20,7 @@ namespace VisualPinball.Unity.VisualScripting.Editor { public abstract class GleUnitWidget : UnitWidget where TUnit : Unit, IGleUnit { - protected override NodeColorMix baseColor => GleAvailable ? NodeColorMix.TealReadable : new NodeColorMix { red = 1f, green = 0f, blue = 0f }; + protected override NodeColorMix baseColor => GleAvailable ? new NodeColorMix(NodeColor.Orange) : new NodeColorMix { red = 1f, green = 0f, blue = 0f }; protected bool GameObjectAvailable => reference != null && reference.gameObject != null; protected IGamelogicEngine Gle => reference.gameObject.GetComponentInParent(); protected VisualScriptingGamelogicEngine VsGle => reference.gameObject.GetComponentInParent(); diff --git a/Editor/Widgets/PlayerStateSetUnitWidget.cs b/Editor/Widgets/PlayerStateSetUnitWidget.cs index c240d2a..91103da 100644 --- a/Editor/Widgets/PlayerStateSetUnitWidget.cs +++ b/Editor/Widgets/PlayerStateSetUnitWidget.cs @@ -16,44 +16,44 @@ // ReSharper disable UnusedType.Global -using System; -using System.Collections.Generic; -using System.Linq; using Unity.VisualScripting; namespace VisualPinball.Unity.VisualScripting.Editor { - [Widget(typeof(PlayerStateSetUnit))] - public sealed class PlayerStateSetUnitWidget : GleUnitWidget + [Widget(typeof(PlayerVariableSetUnit))] + public sealed class PlayerStateSetUnitWidget : GleUnitWidget { - public PlayerStateSetUnitWidget(FlowCanvas canvas, PlayerStateSetUnit unit) : base(canvas, unit) + public PlayerStateSetUnitWidget(FlowCanvas canvas, PlayerVariableSetUnit unit) : base(canvas, unit) { - _propertyNameInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + //_intInspectorConstructor = meta => new IntInspector(meta); } - protected override NodeColorMix baseColor => NodeColorMix.TealReadable; + // private IntInspector _intInspector; + // + // private readonly Func _intInspectorConstructor; + + // public override Inspector GetPortInspector(IUnitPort port, Metadata meta) + // { + // if (port != unit.Value) { + // return base.GetPortInspector(port, meta); + // } + // + // switch (unit.Property.Type) { + // case VisualScriptingPropertyType.String: + // break; + // case VisualScriptingPropertyType.Integer: + // InspectorProvider.instance.Renew(ref _intInspector, meta, _intInspectorConstructor); + // return _intInspector; + // case VisualScriptingPropertyType.Float: + // break; + // case VisualScriptingPropertyType.Boolean: + // break; + // default: + // throw new ArgumentOutOfRangeException(); + // } + // + // return base.GetPortInspector(port, meta); + // } - private VariableNameInspector _propertyNameInspector; - private readonly Func _propertyNameInspectorConstructor; - - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - // if (port == unit.PropertyName) { - // InspectorProvider.instance.Renew(ref _propertyNameInspector, meta, _propertyNameInspectorConstructor); - // - // return _propertyNameInspector; - // } - - return base.GetPortInspector(port, meta); - } - - private IEnumerable GetNameSuggestions() - { - if (!GameObjectAvailable) { - return new List(); - } - var gle = VsGle; - return gle == null ? new List() : gle.PlayerStateDefinition.Select(prop => prop.Name).ToList(); - } } } diff --git a/Runtime/Gamelogic/VisualScriptingPlayerState.cs b/Runtime/Gamelogic/PlayerState.cs similarity index 58% rename from Runtime/Gamelogic/VisualScriptingPlayerState.cs rename to Runtime/Gamelogic/PlayerState.cs index 653100a..e39a32f 100644 --- a/Runtime/Gamelogic/VisualScriptingPlayerState.cs +++ b/Runtime/Gamelogic/PlayerState.cs @@ -20,52 +20,50 @@ namespace VisualPinball.Unity.VisualScripting { - public class VisualScriptingPlayerState + public class PlayerState { public readonly int Id; - private readonly Dictionary _properties = new(); + private readonly Dictionary _variables = new(); - public VisualScriptingPlayerState(int id) + public PlayerState(int id) { Id = id; } - public void AddProperty(VisualScriptingPlayerStateProperty property) + public void AddProperty(PlayerVariable variable) { - _properties[property.Name] = property; + _variables[variable.Id] = variable; } - public T Get(string propertyName) where T : class + public T Get(string variableId) where T : class { - if (!_properties.ContainsKey(propertyName)) { - throw new ArgumentException($"No such property name ({propertyName}).", nameof(propertyName)); + if (!_variables.ContainsKey(variableId)) { + throw new ArgumentException($"No such variable ID ({variableId}).", nameof(variableId)); } - if (_properties[propertyName].Type != typeof(T)) { - throw new InvalidOperationException($"Property \"{propertyName}\" is of type {_properties[propertyName].Type}, but you asked for a {typeof(T)}."); + if (_variables[variableId].Type != typeof(T)) { + throw new InvalidOperationException($"Variable \"{variableId}\" is of type {_variables[variableId].Type}, but you asked for a {typeof(T)}."); } - return _properties[propertyName].Get(); + return _variables[variableId].Get(); } - public void Set(string propertyName, T value) where T : class + public void Set(string variableId, T value) where T : class { - if (!_properties.ContainsKey(propertyName)) { - throw new ArgumentException($"No such property name ({propertyName}).", nameof(propertyName)); + if (!_variables.ContainsKey(variableId)) { + throw new ArgumentException($"No such variable ID ({variableId}).", nameof(variableId)); } - if (_properties[propertyName].Type != value.GetType()) { - throw new ArgumentException($"Property \"{propertyName}\" is of type {_properties[propertyName].Type}, but you provided a {value.GetType()}.", nameof(value)); + if (_variables[variableId].Type != value.GetType()) { + throw new ArgumentException($"Variable \"{variableId}\" is of type {_variables[variableId].Type}, but you provided a {value.GetType()}.", nameof(value)); } - var currentValue = _properties[propertyName].Get(); - _properties[propertyName].Set(value); + var currentValue = _variables[variableId].Get(); + _variables[variableId].Set(value); if (currentValue != value) { - EventBus.Trigger(VisualScriptingEventNames.CurrentPlayerStateChanged, new PlayerStateChangedArgs(propertyName)); + EventBus.Trigger(VisualScriptingEventNames.CurrentPlayerStateChanged, new PlayerVariableChangedArgs(variableId)); } } - - internal bool Has(string propertyName) => _properties.ContainsKey(propertyName) && typeof(T) == _properties[propertyName].Type; } public class Integer @@ -109,13 +107,13 @@ public Bool(bool value) public static implicit operator Bool(bool num) => new(num); } - public readonly struct PlayerStateChangedArgs + public readonly struct PlayerVariableChangedArgs { - public readonly string PropertyName; + public readonly string VariableId; - public PlayerStateChangedArgs(string propertyName) + public PlayerVariableChangedArgs(string variableId) { - PropertyName = propertyName; + VariableId = variableId; } } } diff --git a/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs.meta b/Runtime/Gamelogic/PlayerState.cs.meta similarity index 83% rename from Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs.meta rename to Runtime/Gamelogic/PlayerState.cs.meta index d034587..edc18e1 100644 --- a/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs.meta +++ b/Runtime/Gamelogic/PlayerState.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 589c55ec2c5c1c8468847784fe7b54bb +guid: 0fab504153838564799572c83cc37bd2 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs b/Runtime/Gamelogic/PlayerVariable.cs similarity index 60% rename from Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs rename to Runtime/Gamelogic/PlayerVariable.cs index d50ba1c..fab4429 100644 --- a/Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs +++ b/Runtime/Gamelogic/PlayerVariable.cs @@ -18,27 +18,29 @@ namespace VisualPinball.Unity.VisualScripting { - public class VisualScriptingPlayerStateProperty + public class PlayerVariable { + public string Id; public string Name; public Type Type; private object _value; - public VisualScriptingPlayerStateProperty(string name, string initialValue) : this(name, typeof(string), initialValue) + public PlayerVariable(string id, string name, string initialValue) : this(id, name, typeof(string), initialValue) { } - public VisualScriptingPlayerStateProperty(string name, int initialValue) : this(name, typeof(Integer),new Integer(initialValue)) + public PlayerVariable(string id, string name, int initialValue) : this(id, name, typeof(Integer),new Integer(initialValue)) { } - public VisualScriptingPlayerStateProperty(string name, float initialValue) : this(name, typeof(Float), new Float(initialValue)) + public PlayerVariable(string id, string name, float initialValue) : this(id, name, typeof(Float), new Float(initialValue)) { } - public VisualScriptingPlayerStateProperty(string name, bool initialValue) : this(name, typeof(Bool), new Bool(initialValue)) + public PlayerVariable(string id, string name, bool initialValue) : this(id, name, typeof(Bool), new Bool(initialValue)) { } - private VisualScriptingPlayerStateProperty(string name, Type type, object initialValue) + private PlayerVariable(string id, string name, Type type, object initialValue) { + Id = id; Name = name; Type = type; _value = initialValue; diff --git a/Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs.meta b/Runtime/Gamelogic/PlayerVariable.cs.meta similarity index 83% rename from Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs.meta rename to Runtime/Gamelogic/PlayerVariable.cs.meta index 0def5d3..a80b05d 100644 --- a/Editor/PropertyDrawers/VisualScriptingPlayerStateDefinitionPropertyDrawer.cs.meta +++ b/Runtime/Gamelogic/PlayerVariable.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0571cab62bbde71458ff1f10ea832889 +guid: 1c93ce3b96af4be4d958aca3af6fb268 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs b/Runtime/Gamelogic/PlayerVariableDefinition.cs similarity index 62% rename from Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs rename to Runtime/Gamelogic/PlayerVariableDefinition.cs index 5007415..a9738f6 100644 --- a/Runtime/Gamelogic/VisualScriptingPlayerStateDefinition.cs +++ b/Runtime/Gamelogic/PlayerVariableDefinition.cs @@ -22,28 +22,28 @@ namespace VisualPinball.Unity.VisualScripting { [Serializable] - public class VisualScriptingPlayerStatePropertyDefinition + public class PlayerVariableDefinition { public string Id; public string Name; - public VisualScriptingPropertyType Type; + public VariableType Type; public string StringDefaultValue; public int IntegerDefaultValue; public float FloatDefaultValue; public bool BooleanDefaultValue; - public VisualScriptingPlayerStateProperty Instantiate() + public PlayerVariable Instantiate() { switch (Type) { - case VisualScriptingPropertyType.String: - return new VisualScriptingPlayerStateProperty(Name, StringDefaultValue); - case VisualScriptingPropertyType.Integer: - return new VisualScriptingPlayerStateProperty(Name, IntegerDefaultValue); - case VisualScriptingPropertyType.Float: - return new VisualScriptingPlayerStateProperty(Name, FloatDefaultValue); - case VisualScriptingPropertyType.Boolean: - return new VisualScriptingPlayerStateProperty(Name, BooleanDefaultValue); + case VariableType.String: + return new PlayerVariable(Id, Name, StringDefaultValue); + case VariableType.Integer: + return new PlayerVariable(Id, Name, IntegerDefaultValue); + case VariableType.Float: + return new PlayerVariable(Id, Name, FloatDefaultValue); + case VariableType.Boolean: + return new PlayerVariable(Id, Name, BooleanDefaultValue); default: throw new ArgumentOutOfRangeException(); } @@ -53,7 +53,7 @@ public VisualScriptingPlayerStateProperty Instantiate() public void GenerateId() => Id = Guid.NewGuid().ToString()[..13]; } - public enum VisualScriptingPropertyType + public enum VariableType { String, Integer, Float, Boolean } diff --git a/Runtime/Gamelogic/PlayerVariableDefinition.cs.meta b/Runtime/Gamelogic/PlayerVariableDefinition.cs.meta new file mode 100644 index 0000000..8c01e1c --- /dev/null +++ b/Runtime/Gamelogic/PlayerVariableDefinition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef351adb3f965a04aa317b8e25e85df9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index eb7931e..9a6d966 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -31,7 +31,7 @@ public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine, I { public string Name => "Visual Scripting Gamelogic Engine"; - public List PlayerStateDefinition; + public List PlayerVariableDefinitions; [Tooltip("The switches that are exposed in the Visual Scripting nodes.")] public VisualScriptingSwitch[] Switches; @@ -60,9 +60,9 @@ public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine, I [NonSerialized] private Player _player; [NonSerialized] private int _currentPlayer; - [NonSerialized] private readonly Dictionary _playerStates = new (); + [NonSerialized] private readonly Dictionary _playerStates = new (); - public VisualScriptingPlayerState CurrentPlayerState { + public PlayerState CurrentPlayerState { get { if (!_playerStates.ContainsKey(_currentPlayer)) { throw new InvalidOperationException("Must create a player state before accessing it!"); @@ -92,8 +92,8 @@ public void CreatePlayerState(int playerId) Debug.LogWarning($"Tried to create new player state for existing state {playerId}, skipping."); return; } - var playerState = new VisualScriptingPlayerState(playerId); - foreach (var propertyDefinition in PlayerStateDefinition) { + var playerState = new PlayerState(playerId); + foreach (var propertyDefinition in PlayerVariableDefinitions) { playerState.AddProperty(propertyDefinition.Instantiate()); } _playerStates[playerId] = playerState; @@ -158,7 +158,7 @@ public void OnBeforeSerialize() #if UNITY_EDITOR var ids = new HashSet(); - foreach (var def in PlayerStateDefinition) { + foreach (var def in PlayerVariableDefinitions) { if (!def.HasId || ids.Contains(def.Id)) { def.GenerateId(); } diff --git a/Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs.meta b/Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs.meta deleted file mode 100644 index fedc5b7..0000000 --- a/Runtime/Gamelogic/VisualScriptingPlayerStateProperty.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e3022795485dd6248a3fec806ab1656f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs b/Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs deleted file mode 100644 index ce42954..0000000 --- a/Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using Unity.VisualScripting; -using UnityEngine; - -namespace VisualPinball.Unity.VisualScripting -{ - [UnitTitle("Player State: Add to property (integer)")] - [UnitSurtitle("Player State")] - [UnitCategory("Visual Pinball/State")] - public class PlayerStateAddToIntegerUnit : GleUnit - { - [DoNotSerialize] - [PortLabelHidden] - public ControlInput InputTrigger; - - [DoNotSerialize] - [PortLabelHidden] - public ControlOutput OutputTrigger; - - [DoNotSerialize] - [PortLabel("Property Name")] - public ValueInput PropertyName { get; private set; } - - [DoNotSerialize] - [PortLabel("Value to Add")] - public ValueInput ValueToAdd { get; private set; } - - protected override void Definition() - { - PropertyName = ValueInput(nameof(PropertyName), string.Empty); - ValueToAdd = ValueInput(nameof(ValueToAdd), 0); - - InputTrigger = ControlInput(nameof(InputTrigger), Process); - OutputTrigger = ControlOutput(nameof(OutputTrigger)); - - Requirement(PropertyName, InputTrigger); - Requirement(ValueToAdd, InputTrigger); - Succession(InputTrigger, OutputTrigger); - } - - private ControlOutput Process(Flow flow) - { - if (!AssertVsGle(flow)) { - Debug.LogError("Cannot find GLE."); - return OutputTrigger; - } - - var propertyName = flow.GetValue(PropertyName); - var valueToAdd = flow.GetValue(ValueToAdd); - VsGle.CurrentPlayerState.Set(propertyName, VsGle.CurrentPlayerState.Get(propertyName) + valueToAdd); - - return OutputTrigger; - } - } -} diff --git a/Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs.meta deleted file mode 100644 index 5a7dbca..0000000 --- a/Runtime/Nodes/PlayerState/PlayerStateAddToIntegerUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f7bd0fd9284dd5740892c3947893406e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs.meta deleted file mode 100644 index 06bc4cb..0000000 --- a/Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0e3abb86612c26e46879ed1c11dd18c9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs b/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs similarity index 52% rename from Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs rename to Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs index ecdbde1..a75f0c1 100644 --- a/Runtime/Nodes/PlayerState/PlayerStateSetUnit.cs +++ b/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs @@ -14,40 +14,48 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; using Unity.VisualScripting; using UnityEngine; namespace VisualPinball.Unity.VisualScripting { - [UnitTitle("Set Player State Value")] + [UnitTitle("Set Player Variable")] [UnitSurtitle("Player State")] [UnitCategory("Visual Pinball/State")] - public class PlayerStateSetUnit : GleUnit + public class PlayerVariableSetUnit : GleUnit { - [DoNotSerialize] - [PortLabelHidden] + [DoNotSerialize, PortLabelHidden] public ControlInput InputTrigger; - [DoNotSerialize] - [PortLabelHidden] + [DoNotSerialize, PortLabelHidden] public ControlOutput OutputTrigger; [Serialize, Inspectable, UnitHeaderInspectable] - public VisualScriptingPlayerStatePropertyDefinition Property { get; set; } + public PlayerVariableDefinition Variable { get; set; } - [DoNotSerialize] - [PortLabel("Value")] + [DoNotSerialize, PortLabel("Value"), Inspectable] public ValueInput Value { get; private set; } protected override void Definition() { - Value = ValueInput(nameof(Value), null); - InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - Requirement(Value, InputTrigger); Succession(InputTrigger, OutputTrigger); + + if (Variable == null) { + return; + } + + Value = Variable.Type switch { + VariableType.String => ValueInput(nameof(Value), string.Empty), + VariableType.Integer => ValueInput(nameof(Value), 0), + VariableType.Float => ValueInput(nameof(Value), 0f), + VariableType.Boolean => ValueInput(nameof(Value), false), + _ => throw new ArgumentOutOfRangeException() + }; + Requirement(Value, InputTrigger); } private ControlOutput Process(Flow flow) @@ -57,9 +65,23 @@ private ControlOutput Process(Flow flow) return OutputTrigger; } - var val = flow.GetValue(Value); + switch (Variable.Type) { + case VariableType.String: + VsGle.CurrentPlayerState.Set(Variable.Id, flow.GetValue(Value)); + break; + case VariableType.Integer: + VsGle.CurrentPlayerState.Set(Variable.Id, new Integer(flow.GetValue(Value))); + break; + case VariableType.Float: + VsGle.CurrentPlayerState.Set(Variable.Id, new Float(flow.GetValue(Value))); + break; + case VariableType.Boolean: + VsGle.CurrentPlayerState.Set(Variable.Id, new Bool(flow.GetValue(Value))); + break; + default: + throw new ArgumentOutOfRangeException(); + } - Debug.Log($"Prop = {Property?.Name}, val = {val}"); return OutputTrigger; } } diff --git a/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs.meta new file mode 100644 index 0000000..19a96ed --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aace145fc931b28408479d7b651a603d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From d944f58fb973d5bb7fb09e7ccaed4e5522d0f0cf Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 3 Feb 2022 00:06:48 +0100 Subject: [PATCH 11/54] More player state units. --- .../PlayerStateChangeUnitDescriptor.cs | 48 ++++++++++ .../PlayerStateChangeUnitDescriptor.cs.meta} | 2 +- .../PlayerStateCreateUnitDescriptor.cs | 54 +++++++++++ .../PlayerStateCreateUnitDescriptor.cs.meta | 11 +++ Editor/Inspectors/GleInspector.cs | 43 +++++---- .../PlayerVariableDefinitionInspector.cs | 79 ++++++++-------- ...VisualScriptingGamelogicEngineInspector.cs | 92 +++++++++++++++++++ ...lScriptingGamelogicEngineInspector.cs.meta | 11 +++ Editor/Widgets/GetLampUnitWidget.cs | 2 - Editor/Widgets/GetSwitchUnitWidget.cs | 2 - Editor/Widgets/GleUnitWidget.cs | 11 ++- Editor/Widgets/LampEventUnitWidget.cs | 2 - Editor/Widgets/PlayerStateChangeUnitWidget.cs | 30 ++++++ .../PlayerStateChangeUnitWidget.cs.meta | 11 +++ Editor/Widgets/PlayerStateCreateUnitWidget.cs | 30 ++++++ .../PlayerStateCreateUnitWidget.cs.meta | 11 +++ Editor/Widgets/PlayerStateSetUnitWidget.cs | 59 ------------ .../PlayerVariableChangedEventUnitWidget.cs | 30 ++++++ ...ayerVariableChangedEventUnitWidget.cs.meta | 11 +++ Editor/Widgets/PlayerVariableGetUnitWidget.cs | 30 ++++++ .../PlayerVariableGetUnitWidget.cs.meta | 11 +++ .../PlayerVariableIncreaseUnitWidget.cs | 30 ++++++ .../PlayerVariableIncreaseUnitWidget.cs.meta | 11 +++ Editor/Widgets/PlayerVariableSetUnitWidget.cs | 30 ++++++ .../PlayerVariableSetUnitWidget.cs.meta | 11 +++ Runtime/Gamelogic/PlayerState.cs | 30 +++++- Runtime/Gamelogic/PlayerVariable.cs | 2 +- .../Gamelogic/VisualScriptingEventNames.cs | 2 +- .../VisualScriptingGamelogicEngine.cs | 14 +-- Runtime/Nodes/GleUnit.cs | 22 +---- .../PlayerState/PlayerStateChangeUnit.cs | 62 +++++++++++++ .../PlayerState/PlayerStateChangeUnit.cs.meta | 11 +++ .../PlayerState/PlayerStateCreateUnit.cs | 36 ++++++-- .../PlayerVariableChangedEventUnit.cs | 82 +++++++++++++++++ .../PlayerVariableChangedEventUnit.cs.meta | 11 +++ .../PlayerState/PlayerVariableGetUnit.cs | 80 ++++++++++++++++ .../PlayerState/PlayerVariableGetUnit.cs.meta | 11 +++ .../PlayerState/PlayerVariableIncreaseUnit.cs | 82 +++++++++++++++++ .../PlayerVariableIncreaseUnit.cs.meta | 11 +++ .../PlayerState/PlayerVariableSetUnit.cs | 3 +- 40 files changed, 960 insertions(+), 161 deletions(-) create mode 100644 Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs rename Editor/{Widgets/PlayerStateSetUnitWidget.cs.meta => Descriptors/PlayerStateChangeUnitDescriptor.cs.meta} (83%) create mode 100644 Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs create mode 100644 Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs.meta create mode 100644 Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs create mode 100644 Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs.meta create mode 100644 Editor/Widgets/PlayerStateChangeUnitWidget.cs create mode 100644 Editor/Widgets/PlayerStateChangeUnitWidget.cs.meta create mode 100644 Editor/Widgets/PlayerStateCreateUnitWidget.cs create mode 100644 Editor/Widgets/PlayerStateCreateUnitWidget.cs.meta delete mode 100644 Editor/Widgets/PlayerStateSetUnitWidget.cs create mode 100644 Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs create mode 100644 Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs.meta create mode 100644 Editor/Widgets/PlayerVariableGetUnitWidget.cs create mode 100644 Editor/Widgets/PlayerVariableGetUnitWidget.cs.meta create mode 100644 Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs create mode 100644 Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs.meta create mode 100644 Editor/Widgets/PlayerVariableSetUnitWidget.cs create mode 100644 Editor/Widgets/PlayerVariableSetUnitWidget.cs.meta create mode 100644 Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs create mode 100644 Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs.meta create mode 100644 Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs create mode 100644 Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs.meta create mode 100644 Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs create mode 100644 Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs.meta create mode 100644 Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs create mode 100644 Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs.meta diff --git a/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs b/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs new file mode 100644 index 0000000..90aad7a --- /dev/null +++ b/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs @@ -0,0 +1,48 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(PlayerStateChangeUnit))] + public class PlayerStateChangeUnitDescriptor : UnitDescriptor + { + public PlayerStateChangeUnitDescriptor(PlayerStateChangeUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node changes the current player state with another one."; + } + + //protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.BallRoller(IconSize.Large, IconColor.Orange)); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(PlayerStateChangeUnit.PlayerId): + desc.summary = "The player ID of the desired state"; + break; + } + } + } +} diff --git a/Editor/Widgets/PlayerStateSetUnitWidget.cs.meta b/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs.meta similarity index 83% rename from Editor/Widgets/PlayerStateSetUnitWidget.cs.meta rename to Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs.meta index 6079123..75e43b6 100644 --- a/Editor/Widgets/PlayerStateSetUnitWidget.cs.meta +++ b/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 966947ac781c5e4489a4dad0c7d0d7e6 +guid: 949972332a27ccc47a095d67b5a5a278 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs b/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs new file mode 100644 index 0000000..eb50ef3 --- /dev/null +++ b/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs @@ -0,0 +1,54 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(PlayerStateCreateUnit))] + public class PlayerStateCreateUnitDescriptor : UnitDescriptor + { + public PlayerStateCreateUnitDescriptor(PlayerStateCreateUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node creates a new player state."; + } + + //protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.BallRoller(IconSize.Large, IconColor.Orange)); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(PlayerStateCreateUnit.PlayerId): + desc.summary = "The player ID of the new state"; + break; + // case nameof(PlayerStateCreateUnit.AutoIncrement): + // desc.summary = "If set, the new player ID will be the currently largest ID, plus one."; + // break; + case nameof(PlayerStateCreateUnit.SetAsActive): + desc.summary = "If set, the new state will be the current state. Otherwise, it will only be the current state if there is no state set."; + break; + } + } + } +} diff --git a/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs.meta b/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs.meta new file mode 100644 index 0000000..d9095d8 --- /dev/null +++ b/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b366a38d0f35b5449719e64ced1938b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Inspectors/GleInspector.cs b/Editor/Inspectors/GleInspector.cs index 17548fd..b3145f6 100644 --- a/Editor/Inspectors/GleInspector.cs +++ b/Editor/Inspectors/GleInspector.cs @@ -18,31 +18,34 @@ using VisualPinball.Unity; using VisualPinball.Unity.VisualScripting; -public abstract class GleInspector : Inspector +namespace VisualPinball.Unity.VisualScripting.Editor { - protected GleInspector(Metadata metadata) : base(metadata) { } + public abstract class GleInspector : Inspector + { + protected GleInspector(Metadata metadata) : base(metadata) { } - private const string NoGleError = "Unable to find Gamelogic Engine in scene."; + private const string NoGleError = "Unable to find Gamelogic Engine in scene."; - protected VisualScriptingGamelogicEngine Gle { - get { - if (_gle != null) { - return _gle; - } - var tableComponent = TableSelector.Instance.SelectedOrFirstTable; - if (tableComponent != null) { - _gle = tableComponent.GetComponentInChildren(); - } - if (_gle == null && ErrorMessage == null) { - ErrorMessage = NoGleError; + protected VisualScriptingGamelogicEngine Gle { + get { + if (_gle != null) { + return _gle; + } + var tableComponent = TableSelector.Instance.SelectedOrFirstTable; + if (tableComponent != null) { + _gle = tableComponent.GetComponentInChildren(); + } + if (_gle == null && ErrorMessage == null) { + ErrorMessage = NoGleError; - } else if (_gle != null && ErrorMessage == NoGleError) { - ErrorMessage = null; + } else if (_gle != null && ErrorMessage == NoGleError) { + ErrorMessage = null; + } + return _gle; } - return _gle; } - } - protected string ErrorMessage; + protected string ErrorMessage; - private VisualScriptingGamelogicEngine _gle; + private VisualScriptingGamelogicEngine _gle; + } } diff --git a/Editor/Inspectors/PlayerVariableDefinitionInspector.cs b/Editor/Inspectors/PlayerVariableDefinitionInspector.cs index f5b8111..8d309b9 100644 --- a/Editor/Inspectors/PlayerVariableDefinitionInspector.cs +++ b/Editor/Inspectors/PlayerVariableDefinitionInspector.cs @@ -19,56 +19,59 @@ using Unity.VisualScripting; using UnityEditor; using UnityEngine; -using VisualPinball.Unity.VisualScripting; -[Inspector(typeof(PlayerVariableDefinition))] -public class PlayerVariableDefinitionInspector : GleInspector +namespace VisualPinball.Unity.VisualScripting.Editor { - public PlayerVariableDefinitionInspector(Metadata metadata) : base(metadata) { } - protected override void OnGUI(Rect position, GUIContent label) + [Inspector(typeof(PlayerVariableDefinition))] + public class PlayerVariableDefinitionInspector : GleInspector { - // can't get this from the flow - var gle = Gle; - if (gle != null) { - var varDefinitions = gle.PlayerVariableDefinitions; - if (varDefinitions == null || varDefinitions.Count(p => !string.IsNullOrEmpty(p.Name)) == 0) { - ErrorMessage = "No variables defined."; + public PlayerVariableDefinitionInspector(Metadata metadata) : base(metadata) { } - } else { - var varNames = new List { "None" } - .Concat(varDefinitions.Select(d => d.Name)) - .ToArray(); - var currentVarDef = metadata.value as PlayerVariableDefinition; - var currentIndex = 0; - if (currentVarDef != null) { - var playerVarDef = varDefinitions.FirstOrDefault(p => p.Id == currentVarDef!.Id); - currentIndex = playerVarDef != null ? varDefinitions.IndexOf(playerVarDef) + 1 : 0; + protected override void OnGUI(Rect position, GUIContent label) + { + // can't get this from the flow + var gle = Gle; + if (gle != null) { + var varDefinitions = gle.PlayerVariableDefinitions; + if (varDefinitions == null || varDefinitions.Count(p => !string.IsNullOrEmpty(p.Name)) == 0) { + ErrorMessage = "No variables defined."; + + } else { + var varNames = new List { "None" } + .Concat(varDefinitions.Select(d => d.Name)) + .ToArray(); + var currentVarDef = metadata.value as PlayerVariableDefinition; + var currentIndex = 0; + if (currentVarDef != null) { + var playerVarDef = varDefinitions.FirstOrDefault(p => p.Id == currentVarDef!.Id); + currentIndex = playerVarDef != null ? varDefinitions.IndexOf(playerVarDef) + 1 : 0; + } + + var newIndex = EditorGUI.Popup(position, currentIndex, varNames); + metadata.RecordUndo(); + metadata.value = newIndex == 0 ? null : varDefinitions[newIndex - 1]; + ErrorMessage = null; } + } - var newIndex = EditorGUI.Popup(position, currentIndex, varNames); - metadata.RecordUndo(); - metadata.value = newIndex == 0 ? null : varDefinitions[newIndex - 1]; - ErrorMessage = null; + if (ErrorMessage != null) { + position.height -= EditorGUIUtility.standardVerticalSpacing; + EditorGUI.HelpBox(position, ErrorMessage, MessageType.Error); } } - if (ErrorMessage != null) { - position.height -= EditorGUIUtility.standardVerticalSpacing; - EditorGUI.HelpBox(position, ErrorMessage, MessageType.Error); - } - } + public override float GetAdaptiveWidth() => LudiqGUIUtility.currentInspectorWidth; - public override float GetAdaptiveWidth() => LudiqGUIUtility.currentInspectorWidth; + protected override float GetHeight(float width, GUIContent label) + { + if (ErrorMessage != null) { + var height = LudiqGUIUtility.GetHelpBoxHeight(ErrorMessage, MessageType.Error, width); + height += EditorGUIUtility.standardVerticalSpacing; + return height; + } - protected override float GetHeight(float width, GUIContent label) - { - if (ErrorMessage != null) { - var height = LudiqGUIUtility.GetHelpBoxHeight(ErrorMessage, MessageType.Error, width); - height += EditorGUIUtility.standardVerticalSpacing; - return height; + return EditorGUIUtility.singleLineHeight; } - - return EditorGUIUtility.singleLineHeight; } } diff --git a/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs b/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs new file mode 100644 index 0000000..e3f5d70 --- /dev/null +++ b/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs @@ -0,0 +1,92 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable AssignmentInConditionalExpression + +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; +using VisualPinball.Unity.Editor; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [CustomEditor(typeof(VisualScriptingGamelogicEngine))] + public class VisualScriptingGamelogicEngineInspector : BaseEditor + { + private VisualScriptingGamelogicEngine _gle; + private SerializedProperty _switchesProperty; + private SerializedProperty _soilsProperty; + private SerializedProperty _lampsProperty; + private SerializedProperty _playerVariableDefinitionsProperty; + + private readonly Dictionary _playerVarFoldout = new(); + + private void OnEnable() + { + _gle = target as VisualScriptingGamelogicEngine; + + _switchesProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.Switches)); + _soilsProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.Coils)); + _lampsProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.Lamps)); + + _playerVariableDefinitionsProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.PlayerVariableDefinitions)); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.PropertyField(_switchesProperty); + EditorGUILayout.PropertyField(_soilsProperty); + EditorGUILayout.PropertyField(_lampsProperty); + + EditorGUILayout.PropertyField(_playerVariableDefinitionsProperty); + + serializedObject.ApplyModifiedProperties(); + + // what follows is runtime data + if (!Application.isPlaying) { + return; + } + if (_gle.PlayerStates.Count == 0) { + EditorGUILayout.HelpBox("No player states created.", MessageType.Info); + return; + } + + EditorGUILayout.TextField("Player States", new GUIStyle(EditorStyles.boldLabel)); + foreach (var playerId in _gle.PlayerStates.Keys) { + if (!_playerVarFoldout.ContainsKey(playerId)) { + _playerVarFoldout[playerId] = true; + } + if (_playerVarFoldout[playerId] = EditorGUILayout.BeginFoldoutHeaderGroup(_playerVarFoldout[playerId], $"Player {playerId}")) { + EditorGUI.indentLevel++; + + var playerState = _gle.PlayerStates[playerId]; + if (_gle.CurrentPlayerState == playerState) { + EditorGUILayout.HelpBox("Current Player", MessageType.Info); + } + + foreach (var varDef in _gle.PlayerVariableDefinitions) { + EditorGUILayout.LabelField(varDef.Name, playerState.Get(varDef.Id).ToString()); + } + + EditorGUI.indentLevel--; + } + EditorGUILayout.EndFoldoutHeaderGroup(); + } + } + } +} diff --git a/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs.meta b/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs.meta new file mode 100644 index 0000000..aca104f --- /dev/null +++ b/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e81903d0a4e88c4ca26c9f902f6d247 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/GetLampUnitWidget.cs b/Editor/Widgets/GetLampUnitWidget.cs index 4a99b9f..4929af3 100644 --- a/Editor/Widgets/GetLampUnitWidget.cs +++ b/Editor/Widgets/GetLampUnitWidget.cs @@ -31,8 +31,6 @@ public GetLampUnitWidget(FlowCanvas canvas, GetLampUnit unit) : base(canvas, uni _lampIdInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); } - protected override NodeColorMix baseColor => NodeColorMix.TealReadable; - private VariableNameInspector _lampIdInspector; private readonly Func _lampIdInspectorConstructor; diff --git a/Editor/Widgets/GetSwitchUnitWidget.cs b/Editor/Widgets/GetSwitchUnitWidget.cs index 5b1b662..19090d0 100644 --- a/Editor/Widgets/GetSwitchUnitWidget.cs +++ b/Editor/Widgets/GetSwitchUnitWidget.cs @@ -33,8 +33,6 @@ public GetSwitchUnitWidget(FlowCanvas canvas, GetSwitchUnit unit) : base(canvas, _switchIdInspectorConstructorList = new List>(); } - protected override NodeColorMix baseColor => NodeColorMix.TealReadable; - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { if (_switchIdInspectorConstructorList.Count() < unit.idCount) { diff --git a/Editor/Widgets/GleUnitWidget.cs b/Editor/Widgets/GleUnitWidget.cs index bef15ca..3e82515 100644 --- a/Editor/Widgets/GleUnitWidget.cs +++ b/Editor/Widgets/GleUnitWidget.cs @@ -18,9 +18,18 @@ namespace VisualPinball.Unity.VisualScripting.Editor { + public static class GleUnitWidget + { + public static readonly NodeColorMix Color = new() { + red = 0.92549019607843137254901960784314f, + green = 0.51764705882352941176470588235294f, + blue = 0.23921568627450980392156862745098f + }; + } + public abstract class GleUnitWidget : UnitWidget where TUnit : Unit, IGleUnit { - protected override NodeColorMix baseColor => GleAvailable ? new NodeColorMix(NodeColor.Orange) : new NodeColorMix { red = 1f, green = 0f, blue = 0f }; + protected override NodeColorMix baseColor => GleAvailable ? GleUnitWidget.Color : NodeColor.Red; protected bool GameObjectAvailable => reference != null && reference.gameObject != null; protected IGamelogicEngine Gle => reference.gameObject.GetComponentInParent(); protected VisualScriptingGamelogicEngine VsGle => reference.gameObject.GetComponentInParent(); diff --git a/Editor/Widgets/LampEventUnitWidget.cs b/Editor/Widgets/LampEventUnitWidget.cs index fdba3f5..09aa9f3 100644 --- a/Editor/Widgets/LampEventUnitWidget.cs +++ b/Editor/Widgets/LampEventUnitWidget.cs @@ -31,8 +31,6 @@ public LampEventUnitWidget(FlowCanvas canvas, LampEventUnit unit) : base(canvas, _lampIdInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); } - protected override NodeColorMix baseColor => NodeColorMix.TealReadable; - private VariableNameInspector _lampIdInspector; private readonly Func _lampIdInspectorConstructor; diff --git a/Editor/Widgets/PlayerStateChangeUnitWidget.cs b/Editor/Widgets/PlayerStateChangeUnitWidget.cs new file mode 100644 index 0000000..5aef645 --- /dev/null +++ b/Editor/Widgets/PlayerStateChangeUnitWidget.cs @@ -0,0 +1,30 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(PlayerStateChangeUnit))] + public sealed class PlayerStateChangeUnitWidget : GleUnitWidget + { + public PlayerStateChangeUnitWidget(FlowCanvas canvas, PlayerStateChangeUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/PlayerStateChangeUnitWidget.cs.meta b/Editor/Widgets/PlayerStateChangeUnitWidget.cs.meta new file mode 100644 index 0000000..f6a00c7 --- /dev/null +++ b/Editor/Widgets/PlayerStateChangeUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 016523a0c515dde429e154cca811d244 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/PlayerStateCreateUnitWidget.cs b/Editor/Widgets/PlayerStateCreateUnitWidget.cs new file mode 100644 index 0000000..3692564 --- /dev/null +++ b/Editor/Widgets/PlayerStateCreateUnitWidget.cs @@ -0,0 +1,30 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(PlayerStateCreateUnit))] + public sealed class PlayerStateCreateUnitWidget : GleUnitWidget + { + public PlayerStateCreateUnitWidget(FlowCanvas canvas, PlayerStateCreateUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/PlayerStateCreateUnitWidget.cs.meta b/Editor/Widgets/PlayerStateCreateUnitWidget.cs.meta new file mode 100644 index 0000000..f78a25d --- /dev/null +++ b/Editor/Widgets/PlayerStateCreateUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c279332e7dd3fe4eaa8c0e801e20fbb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/PlayerStateSetUnitWidget.cs b/Editor/Widgets/PlayerStateSetUnitWidget.cs deleted file mode 100644 index 91103da..0000000 --- a/Editor/Widgets/PlayerStateSetUnitWidget.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable UnusedType.Global - -using Unity.VisualScripting; - -namespace VisualPinball.Unity.VisualScripting.Editor -{ - [Widget(typeof(PlayerVariableSetUnit))] - public sealed class PlayerStateSetUnitWidget : GleUnitWidget - { - public PlayerStateSetUnitWidget(FlowCanvas canvas, PlayerVariableSetUnit unit) : base(canvas, unit) - { - //_intInspectorConstructor = meta => new IntInspector(meta); - } - - // private IntInspector _intInspector; - // - // private readonly Func _intInspectorConstructor; - - // public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - // { - // if (port != unit.Value) { - // return base.GetPortInspector(port, meta); - // } - // - // switch (unit.Property.Type) { - // case VisualScriptingPropertyType.String: - // break; - // case VisualScriptingPropertyType.Integer: - // InspectorProvider.instance.Renew(ref _intInspector, meta, _intInspectorConstructor); - // return _intInspector; - // case VisualScriptingPropertyType.Float: - // break; - // case VisualScriptingPropertyType.Boolean: - // break; - // default: - // throw new ArgumentOutOfRangeException(); - // } - // - // return base.GetPortInspector(port, meta); - // } - - } -} diff --git a/Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs b/Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs new file mode 100644 index 0000000..ba53a03 --- /dev/null +++ b/Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs @@ -0,0 +1,30 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(PlayerVariableChangedEventUnit))] + public sealed class PlayerVariableChangedEventWidget : GleUnitWidget + { + public PlayerVariableChangedEventWidget(FlowCanvas canvas, PlayerVariableChangedEventUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs.meta b/Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs.meta new file mode 100644 index 0000000..a5ee2dd --- /dev/null +++ b/Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 11be2ce60cdd75e47ae00cafec44e9e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/PlayerVariableGetUnitWidget.cs b/Editor/Widgets/PlayerVariableGetUnitWidget.cs new file mode 100644 index 0000000..e5ceb06 --- /dev/null +++ b/Editor/Widgets/PlayerVariableGetUnitWidget.cs @@ -0,0 +1,30 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(PlayerVariableGetUnit))] + public sealed class PlayerVariableGetUnitWidget : GleUnitWidget + { + public PlayerVariableGetUnitWidget(FlowCanvas canvas, PlayerVariableGetUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/PlayerVariableGetUnitWidget.cs.meta b/Editor/Widgets/PlayerVariableGetUnitWidget.cs.meta new file mode 100644 index 0000000..4e91c11 --- /dev/null +++ b/Editor/Widgets/PlayerVariableGetUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aaa28a6744387e348aa7f551a0dd486f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs b/Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs new file mode 100644 index 0000000..e5ae2d3 --- /dev/null +++ b/Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs @@ -0,0 +1,30 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(PlayerVariableIncreaseUnit))] + public sealed class PlayerVariableIncreaseUnitWidget : GleUnitWidget + { + public PlayerVariableIncreaseUnitWidget(FlowCanvas canvas, PlayerVariableIncreaseUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs.meta b/Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs.meta new file mode 100644 index 0000000..6081ba9 --- /dev/null +++ b/Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d28add77ca0342943be979b6ffb6e1d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/PlayerVariableSetUnitWidget.cs b/Editor/Widgets/PlayerVariableSetUnitWidget.cs new file mode 100644 index 0000000..bd03e2d --- /dev/null +++ b/Editor/Widgets/PlayerVariableSetUnitWidget.cs @@ -0,0 +1,30 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(PlayerVariableSetUnit))] + public sealed class PlayerVariableSetUnitWidget : GleUnitWidget + { + public PlayerVariableSetUnitWidget(FlowCanvas canvas, PlayerVariableSetUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/PlayerVariableSetUnitWidget.cs.meta b/Editor/Widgets/PlayerVariableSetUnitWidget.cs.meta new file mode 100644 index 0000000..c7d0222 --- /dev/null +++ b/Editor/Widgets/PlayerVariableSetUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b861c66352e21fe4693886e41e3aebdc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Gamelogic/PlayerState.cs b/Runtime/Gamelogic/PlayerState.cs index e39a32f..7d7e4ef 100644 --- a/Runtime/Gamelogic/PlayerState.cs +++ b/Runtime/Gamelogic/PlayerState.cs @@ -48,6 +48,28 @@ public T Get(string variableId) where T : class return _variables[variableId].Get(); } + public object Get(string variableId) + { + if (!_variables.ContainsKey(variableId)) { + throw new ArgumentException($"No such variable ID ({variableId}).", nameof(variableId)); + } + + if (_variables[variableId].Type == typeof(string)) { + return Get(variableId); + } + if (_variables[variableId].Type == typeof(Integer)) { + return Get(variableId); + } + if (_variables[variableId].Type == typeof(Float)) { + return Get(variableId); + } + if (_variables[variableId].Type == typeof(Bool)) { + return Get(variableId); + } + + throw new InvalidOperationException($"Unknown type of variable {_variables[variableId].Name}."); + } + public void Set(string variableId, T value) where T : class { if (!_variables.ContainsKey(variableId)) { @@ -61,7 +83,10 @@ public void Set(string variableId, T value) where T : class _variables[variableId].Set(value); if (currentValue != value) { - EventBus.Trigger(VisualScriptingEventNames.CurrentPlayerStateChanged, new PlayerVariableChangedArgs(variableId)); + EventBus.Trigger( + VisualScriptingEventNames.PlayerVariableChanged, + new PlayerVariableChangedArgs(variableId) + ); } } } @@ -79,6 +104,7 @@ public Integer(int value) public static Integer operator /(Integer lhs, Integer rhs) => new(lhs._value / rhs._value); public static implicit operator int(Integer num) => num._value; public static implicit operator Integer(int num) => new(num); + public override string ToString() => _value.ToString(); } public class Float @@ -94,6 +120,7 @@ public Float(float value) public static Float operator /(Float lhs, Float rhs) => new(lhs._value / rhs._value); public static implicit operator float(Float num) => num._value; public static implicit operator Float(float num) => new(num); + public override string ToString() => _value.ToString(); } public class Bool @@ -105,6 +132,7 @@ public Bool(bool value) } public static implicit operator bool(Bool num) => num._value; public static implicit operator Bool(bool num) => new(num); + public override string ToString() => _value.ToString(); } public readonly struct PlayerVariableChangedArgs diff --git a/Runtime/Gamelogic/PlayerVariable.cs b/Runtime/Gamelogic/PlayerVariable.cs index fab4429..fc929c9 100644 --- a/Runtime/Gamelogic/PlayerVariable.cs +++ b/Runtime/Gamelogic/PlayerVariable.cs @@ -22,7 +22,7 @@ public class PlayerVariable { public string Id; public string Name; - public Type Type; + public Type Type; // always *object* type (string, Integer, Float, Bool) private object _value; public PlayerVariable(string id, string name, string initialValue) : this(id, name, typeof(string), initialValue) diff --git a/Runtime/Gamelogic/VisualScriptingEventNames.cs b/Runtime/Gamelogic/VisualScriptingEventNames.cs index 1d24c5d..6569641 100644 --- a/Runtime/Gamelogic/VisualScriptingEventNames.cs +++ b/Runtime/Gamelogic/VisualScriptingEventNames.cs @@ -23,6 +23,6 @@ public static class VisualScriptingEventNames public const string SwitchEvent = "SwitchEvent"; public const string CoilEvent = "CoilEvent"; public const string CurrentPlayerChanged = "CurrentPlayerChanged"; - public const string CurrentPlayerStateChanged = "CurrentPlayerStateChanged"; + public const string PlayerVariableChanged = "PlayerVariableChanged"; } } diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index 9a6d966..b61785d 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -60,21 +60,21 @@ public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine, I [NonSerialized] private Player _player; [NonSerialized] private int _currentPlayer; - [NonSerialized] private readonly Dictionary _playerStates = new (); + [NonSerialized] public readonly Dictionary PlayerStates = new (); public PlayerState CurrentPlayerState { get { - if (!_playerStates.ContainsKey(_currentPlayer)) { + if (!PlayerStates.ContainsKey(_currentPlayer)) { throw new InvalidOperationException("Must create a player state before accessing it!"); } - return _playerStates[_currentPlayer]; + return PlayerStates[_currentPlayer]; } } public int CurrentPlayer { get => _currentPlayer; set { - if (!_playerStates.ContainsKey(value)) { + if (!PlayerStates.ContainsKey(value)) { Debug.LogError($"Cannot change to non-existing player {value}."); return; } @@ -88,7 +88,7 @@ public int CurrentPlayer { public void CreatePlayerState(int playerId) { - if (_playerStates.ContainsKey(playerId)) { + if (PlayerStates.ContainsKey(playerId)) { Debug.LogWarning($"Tried to create new player state for existing state {playerId}, skipping."); return; } @@ -96,10 +96,10 @@ public void CreatePlayerState(int playerId) foreach (var propertyDefinition in PlayerVariableDefinitions) { playerState.AddProperty(propertyDefinition.Instantiate()); } - _playerStates[playerId] = playerState; + PlayerStates[playerId] = playerState; // switch to this state if current state is invalid - if (!_playerStates.ContainsKey(_currentPlayer)) { + if (!PlayerStates.ContainsKey(_currentPlayer)) { CurrentPlayer = playerId; } } diff --git a/Runtime/Nodes/GleUnit.cs b/Runtime/Nodes/GleUnit.cs index 71ca947..1c84975 100644 --- a/Runtime/Nodes/GleUnit.cs +++ b/Runtime/Nodes/GleUnit.cs @@ -25,27 +25,15 @@ public abstract class GleEventUnit : EventUnit, IGleUnit public List Errors { get; } = new(); [DoNotSerialize] - protected IGamelogicEngine Gle; - - [DoNotSerialize] - protected Player Player; - - protected bool AssertGle(Flow flow) - { - if (!Gle.IsUnityNull()) { - return true; - } - Gle = flow.stack.gameObject.GetComponentInParent(); - return Gle != null; - } + protected VisualScriptingGamelogicEngine VsGle; - protected bool AssertPlayer(Flow flow) + protected bool AssertVsGle(Flow flow) { - if (!Player.IsUnityNull()) { + if (!VsGle.IsUnityNull()) { return true; } - Player = flow.stack.gameObject.GetComponentInParent(); - return Player != null; + VsGle = flow.stack.gameObject.GetComponentInParent(); + return VsGle != null; } } diff --git a/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs b/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs new file mode 100644 index 0000000..121bd67 --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs @@ -0,0 +1,62 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Change Player State")] + [UnitSurtitle("Player State")] + [UnitCategory("Visual Pinball/State")] + public class PlayerStateChangeUnit : GleUnit + { + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + + [DoNotSerialize] + [PortLabel("Player ID")] + public ValueInput PlayerId { get; private set; } + + protected override void Definition() + { + PlayerId = ValueInput(nameof(PlayerId), 0); + + InputTrigger = ControlInput(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + Requirement(PlayerId, InputTrigger); + Succession(InputTrigger, OutputTrigger); + } + + private ControlOutput Process(Flow flow) + { + if (!AssertVsGle(flow)) { + throw new InvalidOperationException("Cannot retrieve GLE from unit."); + } + + VsGle.CurrentPlayer = flow.GetValue(PlayerId); + + return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs.meta new file mode 100644 index 0000000..c6f9b8c --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3de30daf34bec214eb96ac39398fbc19 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs b/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs index b642b47..13135e6 100644 --- a/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs +++ b/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs @@ -14,8 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; +using System.Linq; using Unity.VisualScripting; -using UnityEngine; namespace VisualPinball.Unity.VisualScripting { @@ -24,6 +25,9 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Visual Pinball/State")] public class PlayerStateCreateUnit : GleUnit { + [Serialize, Inspectable, UnitHeaderInspectable("Auto-increment")] + public bool AutoIncrement { get; set; } + [DoNotSerialize] [PortLabelHidden] public ControlInput InputTrigger; @@ -36,25 +40,43 @@ public class PlayerStateCreateUnit : GleUnit [PortLabel("Player ID")] public ValueInput PlayerId { get; private set; } + [DoNotSerialize] + [PortLabel("Set as Active")] + public ValueInput SetAsActive { get; set; } + protected override void Definition() { - PlayerId = ValueInput(nameof(PlayerId), 0); - InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - Requirement(PlayerId, InputTrigger); + if (!AutoIncrement) { + PlayerId = ValueInput(nameof(PlayerId), 0); + Requirement(PlayerId, InputTrigger); + } + + SetAsActive = ValueInput(nameof(SetAsActive), false); + Succession(InputTrigger, OutputTrigger); } private ControlOutput Process(Flow flow) { if (!AssertVsGle(flow)) { - Debug.LogError("Cannot find GLE."); - return OutputTrigger; + throw new InvalidOperationException("Cannot retrieve GLE from unit."); } - VsGle.CreatePlayerState(flow.GetValue(PlayerId)); + // determine new player id + var newPlayerId = AutoIncrement && VsGle.PlayerStates.Count > 0 + ? VsGle.PlayerStates.Keys.Max() + 1 + : VsGle.PlayerStates.Count == 0 ? 0 : flow.GetValue(PlayerId); + + // create new state + VsGle.CreatePlayerState(newPlayerId); + + // set as active + if (flow.GetValue(SetAsActive)) { + VsGle.CurrentPlayer = newPlayerId; + } return OutputTrigger; } diff --git a/Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs b/Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs new file mode 100644 index 0000000..3245974 --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs @@ -0,0 +1,82 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("On Player Variable Changed")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Events\\Visual Pinball")] + public class PlayerVariableChangedEventUnit : GleEventUnit + { + [Serialize, Inspectable, UnitHeaderInspectable] + public PlayerVariableDefinition Variable { get; set; } + + [DoNotSerialize, PortLabel("Value"), Inspectable] + public ValueOutput Value { get; private set; } + + public override EventHook GetHook(GraphReference reference) => new EventHook(VisualScriptingEventNames.PlayerVariableChanged); + protected override bool register => true; + + protected override void Definition() + { + base.Definition(); + + if (Variable == null) { + return; + } + + Value = Variable.Type switch { + VariableType.String => ValueOutput(nameof(Value)), + VariableType.Integer => ValueOutput(nameof(Value)), + VariableType.Float => ValueOutput(nameof(Value)), + VariableType.Boolean => ValueOutput(nameof(Value)), + _ => throw new ArgumentOutOfRangeException() + }; + } + + protected override bool ShouldTrigger(Flow flow, PlayerVariableChangedArgs args) + { + return Variable.Id == args.VariableId; + } + + protected override void AssignArguments(Flow flow, PlayerVariableChangedArgs args) + { + if (!AssertVsGle(flow)) { + throw new InvalidOperationException("Cannot retrieve GLE from unit."); + } + + switch (Variable.Type) { + case VariableType.String: + flow.SetValue(Value, VsGle.CurrentPlayerState.Get(Variable.Id)); + break; + case VariableType.Integer: + flow.SetValue(Value, (int)VsGle.CurrentPlayerState.Get(Variable.Id)); + break; + case VariableType.Float: + flow.SetValue(Value, (float)VsGle.CurrentPlayerState.Get(Variable.Id)); + break; + case VariableType.Boolean: + flow.SetValue(Value, (bool)VsGle.CurrentPlayerState.Get(Variable.Id)); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } +} diff --git a/Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs.meta new file mode 100644 index 0000000..37ce21e --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39808e80b0493814f9242f200797dbaa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs b/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs new file mode 100644 index 0000000..1a08f38 --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs @@ -0,0 +1,80 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Get Player Variable")] + [UnitSurtitle("Player State")] + [UnitCategory("Visual Pinball/State")] + public class PlayerVariableGetUnit : GleUnit + { + [Serialize, Inspectable, UnitHeaderInspectable] + public PlayerVariableDefinition Variable { get; set; } + + [DoNotSerialize, PortLabel("Value"), Inspectable] + public ValueOutput Value { get; private set; } + + protected override void Definition() + { + if (Variable == null) { + return; + } + + Value = Variable.Type switch { + VariableType.String => ValueOutput(nameof(Value), GetString), + VariableType.Integer => ValueOutput(nameof(Value), GetInt), + VariableType.Float => ValueOutput(nameof(Value), GetFloat), + VariableType.Boolean => ValueOutput(nameof(Value), GetBool), + _ => throw new ArgumentOutOfRangeException() + }; + } + + private string GetString(Flow flow) + { + if (!AssertVsGle(flow)) { + throw new InvalidOperationException("Cannot retrieve GLE from unit."); + } + return VsGle.CurrentPlayerState.Get(Variable.Id); + } + + private bool GetBool(Flow flow) + { + if (!AssertVsGle(flow)) { + throw new InvalidOperationException("Cannot retrieve GLE from unit."); + } + return (bool)VsGle.CurrentPlayerState.Get(Variable.Id); + } + + private float GetFloat(Flow flow) + { + if (!AssertVsGle(flow)) { + throw new InvalidOperationException("Cannot retrieve GLE from unit."); + } + return (float)VsGle.CurrentPlayerState.Get(Variable.Id); + } + + private int GetInt(Flow flow) + { + if (!AssertVsGle(flow)) { + throw new InvalidOperationException("Cannot retrieve GLE from unit."); + } + return (int)VsGle.CurrentPlayerState.Get(Variable.Id); + } + } +} diff --git a/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs.meta new file mode 100644 index 0000000..f959b14 --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8f895af4882d9146b7ef2373b6722f4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs b/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs new file mode 100644 index 0000000..2a98ac0 --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs @@ -0,0 +1,82 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Increase Player Variable")] + [UnitSurtitle("Player State")] + [UnitCategory("Visual Pinball/State")] + public class PlayerVariableIncreaseUnit : GleUnit + { + [DoNotSerialize, PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize, PortLabelHidden] + public ControlOutput OutputTrigger; + + [Serialize, Inspectable, UnitHeaderInspectable] + public PlayerVariableDefinition Variable { get; set; } + + [DoNotSerialize, PortLabel("Value"), Inspectable] + public ValueInput Value { get; private set; } + + protected override void Definition() + { + InputTrigger = ControlInput(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + Succession(InputTrigger, OutputTrigger); + + if (Variable == null) { + return; + } + + Value = Variable.Type switch { + VariableType.Integer => ValueInput(nameof(Value), 0), + VariableType.Float => ValueInput(nameof(Value), 0f), + _ => throw new ArgumentOutOfRangeException($"Type must be integer or float.") + }; + Requirement(Value, InputTrigger); + } + + private ControlOutput Process(Flow flow) + { + if (!AssertVsGle(flow)) { + throw new InvalidOperationException("Cannot retrieve GLE from unit."); + } + + switch (Variable.Type) { + case VariableType.Integer: { + var current = (int)VsGle.CurrentPlayerState.Get(Variable.Id); + VsGle.CurrentPlayerState.Set(Variable.Id, new Integer(current + flow.GetValue(Value))); + break; + } + case VariableType.Float: { + var current = (float)VsGle.CurrentPlayerState.Get(Variable.Id); + VsGle.CurrentPlayerState.Set(Variable.Id, new Float(current + flow.GetValue(Value))); + break; + } + default: + throw new ArgumentOutOfRangeException($"Type must be integer or float."); + } + + return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs.meta new file mode 100644 index 0000000..b6c028a --- /dev/null +++ b/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 195f5e217e66d2b428c7a6ab84c46170 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs b/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs index a75f0c1..7ee8956 100644 --- a/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs +++ b/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs @@ -61,8 +61,7 @@ protected override void Definition() private ControlOutput Process(Flow flow) { if (!AssertVsGle(flow)) { - Debug.LogError("Cannot find GLE."); - return OutputTrigger; + throw new InvalidOperationException("Cannot retrieve GLE from unit."); } switch (Variable.Type) { From 79ce9d4fa465c22a1fb4385864b4aabbb8267220 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 3 Feb 2022 21:15:57 +0100 Subject: [PATCH 12/54] Assign icons to player state nodes. --- .../Descriptors/CreateBallUnitDescriptor.cs | 2 + .../PlayerStateChangeUnitDescriptor.cs | 2 +- .../PlayerStateCreateUnitDescriptor.cs | 2 +- ...layerVariableChangedEventUnitDescriptor.cs | 48 +++++++++++++++++++ ...VariableChangedEventUnitDescriptor.cs.meta | 11 +++++ .../PlayerVariableGetUnitDescriptor.cs | 48 +++++++++++++++++++ .../PlayerVariableGetUnitDescriptor.cs.meta | 11 +++++ .../PlayerVariableIncreaseUnitDescriptor.cs | 48 +++++++++++++++++++ ...ayerVariableIncreaseUnitDescriptor.cs.meta | 11 +++++ .../PlayerVariableSetUnitDescriptor.cs | 48 +++++++++++++++++++ .../PlayerVariableSetUnitDescriptor.cs.meta | 11 +++++ .../PlayerState/PlayerStateChangeUnit.cs | 2 +- .../PlayerState/PlayerStateCreateUnit.cs | 2 +- .../PlayerState/PlayerVariableGetUnit.cs | 2 +- .../PlayerState/PlayerVariableIncreaseUnit.cs | 2 +- .../PlayerState/PlayerVariableSetUnit.cs | 2 +- 16 files changed, 245 insertions(+), 7 deletions(-) create mode 100644 Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs create mode 100644 Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs.meta create mode 100644 Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs create mode 100644 Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs.meta create mode 100644 Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs create mode 100644 Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs.meta create mode 100644 Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs create mode 100644 Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs.meta diff --git a/Editor/Descriptors/CreateBallUnitDescriptor.cs b/Editor/Descriptors/CreateBallUnitDescriptor.cs index 8965ab5..4082b2c 100644 --- a/Editor/Descriptors/CreateBallUnitDescriptor.cs +++ b/Editor/Descriptors/CreateBallUnitDescriptor.cs @@ -34,6 +34,8 @@ protected override string DefinedSummary() return "This node spawns a new ball at a given position."; } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.BallRoller(IconSize.Large, IconColor.Orange)); protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) diff --git a/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs b/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs index 90aad7a..854d77f 100644 --- a/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs +++ b/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs @@ -32,7 +32,7 @@ protected override string DefinedSummary() return "This node changes the current player state with another one."; } - //protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.BallRoller(IconSize.Large, IconColor.Orange)); + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.PlayerVariable); protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { diff --git a/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs b/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs index eb50ef3..af6af33 100644 --- a/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs +++ b/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs @@ -32,7 +32,7 @@ protected override string DefinedSummary() return "This node creates a new player state."; } - //protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.BallRoller(IconSize.Large, IconColor.Orange)); + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.PlayerVariable); protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { diff --git a/Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs b/Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs new file mode 100644 index 0000000..9dca17c --- /dev/null +++ b/Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs @@ -0,0 +1,48 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(PlayerVariableChangedEventUnit))] + public class PlayerVariableChangedEventUnitDescriptor : UnitDescriptor + { + public PlayerVariableChangedEventUnitDescriptor(PlayerVariableChangedEventUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This event is emitted when a given player variable changes."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.PlayerVariableEvent); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(PlayerVariableChangedEventUnit.Value): + desc.summary = "The new value of the player variable."; + break; + } + } + } +} diff --git a/Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs.meta b/Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs.meta new file mode 100644 index 0000000..8a1c2fd --- /dev/null +++ b/Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de72c7ac3063cd441b99bd23bcf888b3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs b/Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs new file mode 100644 index 0000000..1abbf18 --- /dev/null +++ b/Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs @@ -0,0 +1,48 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(PlayerVariableGetUnit))] + public class PlayerVariableGetUnitDescriptor : UnitDescriptor + { + public PlayerVariableGetUnitDescriptor(PlayerVariableGetUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node retrieves the value of a given player variable."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.PlayerVariable); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(PlayerVariableGetUnit.Value): + desc.summary = "The current value of the player variable."; + break; + } + } + } +} diff --git a/Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs.meta b/Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs.meta new file mode 100644 index 0000000..8f9415b --- /dev/null +++ b/Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ed485d92e288194ca29b002871f1f64 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs b/Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs new file mode 100644 index 0000000..12aed3f --- /dev/null +++ b/Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs @@ -0,0 +1,48 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(PlayerVariableIncreaseUnit))] + public class PlayerVariableIncreaseUnitDescriptor : UnitDescriptor + { + public PlayerVariableIncreaseUnitDescriptor(PlayerVariableIncreaseUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node increases the value of a given player variable.\n\nTo decrease, use a negative value."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.PlayerVariable); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(PlayerVariableIncreaseUnit.Value): + desc.summary = "The value to add to the existing value."; + break; + } + } + } +} diff --git a/Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs.meta b/Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs.meta new file mode 100644 index 0000000..7e1de12 --- /dev/null +++ b/Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b1aaf9160ebe664f9cc575b3241f019 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs b/Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs new file mode 100644 index 0000000..14115bb --- /dev/null +++ b/Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs @@ -0,0 +1,48 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(PlayerVariableSetUnit))] + public class PlayerVariableSetUnitDescriptor : UnitDescriptor + { + public PlayerVariableSetUnitDescriptor(PlayerVariableSetUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node sets the value of a given player variable."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.PlayerVariable); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(PlayerVariableSetUnit.Value): + desc.summary = "The new value of the player variable."; + break; + } + } + } +} diff --git a/Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs.meta b/Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs.meta new file mode 100644 index 0000000..2798f1d --- /dev/null +++ b/Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db96b5cf4ac82424586ae9517b22c503 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs b/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs index 121bd67..2a4881a 100644 --- a/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs +++ b/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity.VisualScripting { [UnitTitle("Change Player State")] [UnitSurtitle("Player State")] - [UnitCategory("Visual Pinball/State")] + [UnitCategory("Visual Pinball/Variables")] public class PlayerStateChangeUnit : GleUnit { [DoNotSerialize] diff --git a/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs b/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs index 13135e6..c7f7ad7 100644 --- a/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs +++ b/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity.VisualScripting { [UnitTitle("Create Player State")] [UnitSurtitle("Player State")] - [UnitCategory("Visual Pinball/State")] + [UnitCategory("Visual Pinball/Variables")] public class PlayerStateCreateUnit : GleUnit { [Serialize, Inspectable, UnitHeaderInspectable("Auto-increment")] diff --git a/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs b/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs index 1a08f38..784ab76 100644 --- a/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs +++ b/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity.VisualScripting { [UnitTitle("Get Player Variable")] [UnitSurtitle("Player State")] - [UnitCategory("Visual Pinball/State")] + [UnitCategory("Visual Pinball/Variables")] public class PlayerVariableGetUnit : GleUnit { [Serialize, Inspectable, UnitHeaderInspectable] diff --git a/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs b/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs index 2a98ac0..076ccd1 100644 --- a/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs +++ b/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity.VisualScripting { [UnitTitle("Increase Player Variable")] [UnitSurtitle("Player State")] - [UnitCategory("Visual Pinball/State")] + [UnitCategory("Visual Pinball/Variables")] public class PlayerVariableIncreaseUnit : GleUnit { [DoNotSerialize, PortLabelHidden] diff --git a/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs b/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs index 7ee8956..7057bc7 100644 --- a/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs +++ b/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity.VisualScripting { [UnitTitle("Set Player Variable")] [UnitSurtitle("Player State")] - [UnitCategory("Visual Pinball/State")] + [UnitCategory("Visual Pinball/Variables")] public class PlayerVariableSetUnit : GleUnit { [DoNotSerialize, PortLabelHidden] From c3a7176ebbebfbfe8c7fa85c4ae336d5e81a79cb Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 3 Feb 2022 22:29:23 +0100 Subject: [PATCH 13/54] Add table state. --- ... => VariableChangedEventUnitDescriptor.cs} | 27 ++++++++++ ...ariableChangedEventUnitDescriptor.cs.meta} | 2 +- ...riptor.cs => VariableGetUnitDescriptor.cs} | 26 ++++++++++ ...meta => VariableGetUnitDescriptor.cs.meta} | 2 +- ...r.cs => VariableIncreaseUnitDescriptor.cs} | 26 ++++++++++ ...=> VariableIncreaseUnitDescriptor.cs.meta} | 2 +- ...riptor.cs => VariableSetUnitDescriptor.cs} | 26 ++++++++++ ...meta => VariableSetUnitDescriptor.cs.meta} | 2 +- .../PlayerVariableDefinitionInspector.cs.meta | 11 ---- ...ctor.cs => VariableDefinitionInspector.cs} | 40 ++++++++++++--- .../VariableDefinitionInspector.cs.meta | 11 ++++ ...VisualScriptingGamelogicEngineInspector.cs | 30 +++++++---- ...erVariableDefinitionPropertyDrawer.cs.meta | 11 ---- ...cs => VariableDefinitionPropertyDrawer.cs} | 23 ++++++--- .../VariableDefinitionPropertyDrawer.cs.meta | 11 ++++ Editor/Widgets/CreateBallUnitWidget.cs | 33 ++++++++++++ Editor/Widgets/CreateBallUnitWidget.cs.meta | 11 ++++ ...ayerVariableChangedEventUnitWidget.cs.meta | 11 ---- .../PlayerVariableGetUnitWidget.cs.meta | 11 ---- .../PlayerVariableIncreaseUnitWidget.cs.meta | 11 ---- .../PlayerVariableSetUnitWidget.cs.meta | 11 ---- ...t.cs => VariableChangedEventUnitWidget.cs} | 8 +++ .../VariableChangedEventUnitWidget.cs.meta | 11 ++++ ...UnitWidget.cs => VariableGetUnitWidget.cs} | 8 +++ Editor/Widgets/VariableGetUnitWidget.cs.meta | 11 ++++ ...idget.cs => VariableIncreaseUnitWidget.cs} | 8 +++ .../VariableIncreaseUnitWidget.cs.meta | 11 ++++ ...UnitWidget.cs => VariableSetUnitWidget.cs} | 8 +++ Editor/Widgets/VariableSetUnitWidget.cs.meta | 11 ++++ Runtime/Gamelogic/PlayerState.cs.meta | 11 ---- Runtime/Gamelogic/PlayerVariable.cs.meta | 11 ---- .../PlayerVariableDefinition.cs.meta | 11 ---- .../Gamelogic/{PlayerState.cs => State.cs} | 32 +++++++++--- Runtime/Gamelogic/State.cs.meta | 11 ++++ .../{PlayerVariable.cs => StateVariable.cs} | 12 ++--- Runtime/Gamelogic/StateVariable.cs.meta | 11 ++++ ...bleDefinition.cs => VariableDefinition.cs} | 20 +++++--- Runtime/Gamelogic/VariableDefinition.cs.meta | 11 ++++ .../Gamelogic/VisualScriptingEventNames.cs | 1 + .../VisualScriptingGamelogicEngine.cs | 16 ++++++ .../PlayerVariableChangedEventUnit.cs.meta | 11 ---- .../PlayerState/PlayerVariableGetUnit.cs.meta | 11 ---- .../PlayerVariableIncreaseUnit.cs.meta | 11 ---- .../PlayerState/PlayerVariableSetUnit.cs.meta | 11 ---- ...entUnit.cs => VariableChangedEventUnit.cs} | 50 ++++++++++++++----- .../VariableChangedEventUnit.cs.meta | 11 ++++ ...rVariableGetUnit.cs => VariableGetUnit.cs} | 35 ++++++++++--- .../Nodes/PlayerState/VariableGetUnit.cs.meta | 11 ++++ ...ncreaseUnit.cs => VariableIncreaseUnit.cs} | 42 ++++++++++++---- .../PlayerState/VariableIncreaseUnit.cs.meta | 11 ++++ ...rVariableSetUnit.cs => VariableSetUnit.cs} | 43 ++++++++++++---- .../Nodes/PlayerState/VariableSetUnit.cs.meta | 11 ++++ 52 files changed, 587 insertions(+), 232 deletions(-) rename Editor/Descriptors/{PlayerVariableChangedEventUnitDescriptor.cs => VariableChangedEventUnitDescriptor.cs} (65%) rename Editor/Descriptors/{PlayerVariableIncreaseUnitDescriptor.cs.meta => VariableChangedEventUnitDescriptor.cs.meta} (83%) rename Editor/Descriptors/{PlayerVariableGetUnitDescriptor.cs => VariableGetUnitDescriptor.cs} (66%) rename Editor/Descriptors/{PlayerVariableChangedEventUnitDescriptor.cs.meta => VariableGetUnitDescriptor.cs.meta} (83%) rename Editor/Descriptors/{PlayerVariableIncreaseUnitDescriptor.cs => VariableIncreaseUnitDescriptor.cs} (65%) rename Editor/Descriptors/{PlayerVariableSetUnitDescriptor.cs.meta => VariableIncreaseUnitDescriptor.cs.meta} (83%) rename Editor/Descriptors/{PlayerVariableSetUnitDescriptor.cs => VariableSetUnitDescriptor.cs} (66%) rename Editor/Descriptors/{PlayerVariableGetUnitDescriptor.cs.meta => VariableSetUnitDescriptor.cs.meta} (83%) delete mode 100644 Editor/Inspectors/PlayerVariableDefinitionInspector.cs.meta rename Editor/Inspectors/{PlayerVariableDefinitionInspector.cs => VariableDefinitionInspector.cs} (62%) create mode 100644 Editor/Inspectors/VariableDefinitionInspector.cs.meta delete mode 100644 Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs.meta rename Editor/PropertyDrawers/{PlayerVariableDefinitionPropertyDrawer.cs => VariableDefinitionPropertyDrawer.cs} (68%) create mode 100644 Editor/PropertyDrawers/VariableDefinitionPropertyDrawer.cs.meta create mode 100644 Editor/Widgets/CreateBallUnitWidget.cs create mode 100644 Editor/Widgets/CreateBallUnitWidget.cs.meta delete mode 100644 Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs.meta delete mode 100644 Editor/Widgets/PlayerVariableGetUnitWidget.cs.meta delete mode 100644 Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs.meta delete mode 100644 Editor/Widgets/PlayerVariableSetUnitWidget.cs.meta rename Editor/Widgets/{PlayerVariableChangedEventUnitWidget.cs => VariableChangedEventUnitWidget.cs} (78%) create mode 100644 Editor/Widgets/VariableChangedEventUnitWidget.cs.meta rename Editor/Widgets/{PlayerVariableGetUnitWidget.cs => VariableGetUnitWidget.cs} (79%) create mode 100644 Editor/Widgets/VariableGetUnitWidget.cs.meta rename Editor/Widgets/{PlayerVariableIncreaseUnitWidget.cs => VariableIncreaseUnitWidget.cs} (78%) create mode 100644 Editor/Widgets/VariableIncreaseUnitWidget.cs.meta rename Editor/Widgets/{PlayerVariableSetUnitWidget.cs => VariableSetUnitWidget.cs} (79%) create mode 100644 Editor/Widgets/VariableSetUnitWidget.cs.meta delete mode 100644 Runtime/Gamelogic/PlayerState.cs.meta delete mode 100644 Runtime/Gamelogic/PlayerVariable.cs.meta delete mode 100644 Runtime/Gamelogic/PlayerVariableDefinition.cs.meta rename Runtime/Gamelogic/{PlayerState.cs => State.cs} (82%) create mode 100644 Runtime/Gamelogic/State.cs.meta rename Runtime/Gamelogic/{PlayerVariable.cs => StateVariable.cs} (64%) create mode 100644 Runtime/Gamelogic/StateVariable.cs.meta rename Runtime/Gamelogic/{PlayerVariableDefinition.cs => VariableDefinition.cs} (72%) create mode 100644 Runtime/Gamelogic/VariableDefinition.cs.meta delete mode 100644 Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs.meta delete mode 100644 Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs.meta delete mode 100644 Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs.meta delete mode 100644 Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs.meta rename Runtime/Nodes/PlayerState/{PlayerVariableChangedEventUnit.cs => VariableChangedEventUnit.cs} (51%) create mode 100644 Runtime/Nodes/PlayerState/VariableChangedEventUnit.cs.meta rename Runtime/Nodes/PlayerState/{PlayerVariableGetUnit.cs => VariableGetUnit.cs} (64%) create mode 100644 Runtime/Nodes/PlayerState/VariableGetUnit.cs.meta rename Runtime/Nodes/PlayerState/{PlayerVariableIncreaseUnit.cs => VariableIncreaseUnit.cs} (62%) create mode 100644 Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs.meta rename Runtime/Nodes/PlayerState/{PlayerVariableSetUnit.cs => VariableSetUnit.cs} (64%) create mode 100644 Runtime/Nodes/PlayerState/VariableSetUnit.cs.meta diff --git a/Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs b/Editor/Descriptors/VariableChangedEventUnitDescriptor.cs similarity index 65% rename from Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs rename to Editor/Descriptors/VariableChangedEventUnitDescriptor.cs index 9dca17c..4ce193d 100644 --- a/Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs +++ b/Editor/Descriptors/VariableChangedEventUnitDescriptor.cs @@ -45,4 +45,31 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) } } } + + + [Descriptor(typeof(TableVariableChangedEventUnit))] + public class TableVariableChangedEventUnitDescriptor : UnitDescriptor + { + public TableVariableChangedEventUnitDescriptor(TableVariableChangedEventUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This event is emitted when a given table variable changes."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.TableVariableEvent); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(TableVariableChangedEventUnit.Value): + desc.summary = "The new value of the table variable."; + break; + } + } + } } diff --git a/Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs.meta b/Editor/Descriptors/VariableChangedEventUnitDescriptor.cs.meta similarity index 83% rename from Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs.meta rename to Editor/Descriptors/VariableChangedEventUnitDescriptor.cs.meta index 7e1de12..9a99081 100644 --- a/Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs.meta +++ b/Editor/Descriptors/VariableChangedEventUnitDescriptor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0b1aaf9160ebe664f9cc575b3241f019 +guid: 9eadacb1f3a28324cbbf12296ca1f057 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs b/Editor/Descriptors/VariableGetUnitDescriptor.cs similarity index 66% rename from Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs rename to Editor/Descriptors/VariableGetUnitDescriptor.cs index 1abbf18..60f02db 100644 --- a/Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs +++ b/Editor/Descriptors/VariableGetUnitDescriptor.cs @@ -45,4 +45,30 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) } } } + + [Descriptor(typeof(TableVariableGetUnit))] + public class TableVariableGetUnitDescriptor : UnitDescriptor + { + public TableVariableGetUnitDescriptor(TableVariableGetUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node retrieves the value of a given table variable."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.TableVariable); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(TableVariableGetUnit.Value): + desc.summary = "The current value of the table variable."; + break; + } + } + } } diff --git a/Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs.meta b/Editor/Descriptors/VariableGetUnitDescriptor.cs.meta similarity index 83% rename from Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs.meta rename to Editor/Descriptors/VariableGetUnitDescriptor.cs.meta index 8a1c2fd..79233ec 100644 --- a/Editor/Descriptors/PlayerVariableChangedEventUnitDescriptor.cs.meta +++ b/Editor/Descriptors/VariableGetUnitDescriptor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: de72c7ac3063cd441b99bd23bcf888b3 +guid: 9a2cd70bf3bbec240b902074eece32e4 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs b/Editor/Descriptors/VariableIncreaseUnitDescriptor.cs similarity index 65% rename from Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs rename to Editor/Descriptors/VariableIncreaseUnitDescriptor.cs index 12aed3f..1643525 100644 --- a/Editor/Descriptors/PlayerVariableIncreaseUnitDescriptor.cs +++ b/Editor/Descriptors/VariableIncreaseUnitDescriptor.cs @@ -45,4 +45,30 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) } } } + + [Descriptor(typeof(TableVariableIncreaseUnit))] + public class TableVariableIncreaseUnitDescriptor : UnitDescriptor + { + public TableVariableIncreaseUnitDescriptor(TableVariableIncreaseUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node increases the value of a given table variable.\n\nTo decrease, use a negative value."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.TableVariable); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(TableVariableIncreaseUnit.Value): + desc.summary = "The value to add to the existing value."; + break; + } + } + } } diff --git a/Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs.meta b/Editor/Descriptors/VariableIncreaseUnitDescriptor.cs.meta similarity index 83% rename from Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs.meta rename to Editor/Descriptors/VariableIncreaseUnitDescriptor.cs.meta index 2798f1d..3681797 100644 --- a/Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs.meta +++ b/Editor/Descriptors/VariableIncreaseUnitDescriptor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: db96b5cf4ac82424586ae9517b22c503 +guid: 5dba1ea52bfa9724bb0e65ab8e0d5bae MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs b/Editor/Descriptors/VariableSetUnitDescriptor.cs similarity index 66% rename from Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs rename to Editor/Descriptors/VariableSetUnitDescriptor.cs index 14115bb..07b4365 100644 --- a/Editor/Descriptors/PlayerVariableSetUnitDescriptor.cs +++ b/Editor/Descriptors/VariableSetUnitDescriptor.cs @@ -45,4 +45,30 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) } } } + + [Descriptor(typeof(TableVariableSetUnit))] + public class TableVariableSetUnitDescriptor : UnitDescriptor + { + public TableVariableSetUnitDescriptor(TableVariableSetUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node sets the value of a given table variable."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.TableVariable); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(TableVariableSetUnit.Value): + desc.summary = "The new value of the table variable."; + break; + } + } + } } diff --git a/Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs.meta b/Editor/Descriptors/VariableSetUnitDescriptor.cs.meta similarity index 83% rename from Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs.meta rename to Editor/Descriptors/VariableSetUnitDescriptor.cs.meta index 8f9415b..4e9a54f 100644 --- a/Editor/Descriptors/PlayerVariableGetUnitDescriptor.cs.meta +++ b/Editor/Descriptors/VariableSetUnitDescriptor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 8ed485d92e288194ca29b002871f1f64 +guid: efddfac3f198bd441b263ca2dc1f17a3 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Inspectors/PlayerVariableDefinitionInspector.cs.meta b/Editor/Inspectors/PlayerVariableDefinitionInspector.cs.meta deleted file mode 100644 index ffc5085..0000000 --- a/Editor/Inspectors/PlayerVariableDefinitionInspector.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f63d46325fcab7b43935ee0cee57ee0a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Inspectors/PlayerVariableDefinitionInspector.cs b/Editor/Inspectors/VariableDefinitionInspector.cs similarity index 62% rename from Editor/Inspectors/PlayerVariableDefinitionInspector.cs rename to Editor/Inspectors/VariableDefinitionInspector.cs index 8d309b9..f8ee145 100644 --- a/Editor/Inspectors/PlayerVariableDefinitionInspector.cs +++ b/Editor/Inspectors/VariableDefinitionInspector.cs @@ -22,18 +22,44 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Inspector(typeof(PlayerVariableDefinition))] - public class PlayerVariableDefinitionInspector : GleInspector + public class PlayerVariableDefinitionInspector : VariableDefinitionInspector + { + public PlayerVariableDefinitionInspector(Metadata metadata) : base(metadata) + { + } + + protected override List VariableDefinition(VisualScriptingGamelogicEngine gle) + { + return gle.PlayerVariableDefinitions.Select(s => s as VariableDefinition).ToList(); + } + } + + [Inspector(typeof(TableVariableDefinition))] + public class TableVariableDefinitionInspector : VariableDefinitionInspector { - public PlayerVariableDefinitionInspector(Metadata metadata) : base(metadata) { } + public TableVariableDefinitionInspector(Metadata metadata) : base(metadata) + { + } + + protected override List VariableDefinition(VisualScriptingGamelogicEngine gle) + { + return gle.TableVariableDefinitions.Select(s => s as VariableDefinition).ToList(); + } + } + + public abstract class VariableDefinitionInspector : GleInspector + { + protected abstract List VariableDefinition(VisualScriptingGamelogicEngine gle); + + public VariableDefinitionInspector(Metadata metadata) : base(metadata) { } protected override void OnGUI(Rect position, GUIContent label) { // can't get this from the flow var gle = Gle; if (gle != null) { - var varDefinitions = gle.PlayerVariableDefinitions; + var varDefinitions = VariableDefinition(gle); if (varDefinitions == null || varDefinitions.Count(p => !string.IsNullOrEmpty(p.Name)) == 0) { ErrorMessage = "No variables defined."; @@ -41,11 +67,11 @@ protected override void OnGUI(Rect position, GUIContent label) var varNames = new List { "None" } .Concat(varDefinitions.Select(d => d.Name)) .ToArray(); - var currentVarDef = metadata.value as PlayerVariableDefinition; + var currentVarDef = metadata.value as VariableDefinition; var currentIndex = 0; if (currentVarDef != null) { - var playerVarDef = varDefinitions.FirstOrDefault(p => p.Id == currentVarDef!.Id); - currentIndex = playerVarDef != null ? varDefinitions.IndexOf(playerVarDef) + 1 : 0; + var stateVarDef = varDefinitions.FirstOrDefault(p => p.Id == currentVarDef!.Id); + currentIndex = stateVarDef != null ? varDefinitions.IndexOf(stateVarDef) + 1 : 0; } var newIndex = EditorGUI.Popup(position, currentIndex, varNames); diff --git a/Editor/Inspectors/VariableDefinitionInspector.cs.meta b/Editor/Inspectors/VariableDefinitionInspector.cs.meta new file mode 100644 index 0000000..71587cf --- /dev/null +++ b/Editor/Inspectors/VariableDefinitionInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d4e39d70aaead34bab0655647cd1763 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs b/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs index e3f5d70..ced4847 100644 --- a/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs +++ b/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs @@ -30,6 +30,7 @@ public class VisualScriptingGamelogicEngineInspector : BaseEditor _playerVarFoldout = new(); @@ -42,6 +43,7 @@ private void OnEnable() _soilsProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.Coils)); _lampsProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.Lamps)); + _tableVariableDefinitionsProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.TableVariableDefinitions)); _playerVariableDefinitionsProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.PlayerVariableDefinitions)); } @@ -53,6 +55,7 @@ public override void OnInspectorGUI() EditorGUILayout.PropertyField(_soilsProperty); EditorGUILayout.PropertyField(_lampsProperty); + EditorGUILayout.PropertyField(_tableVariableDefinitionsProperty); EditorGUILayout.PropertyField(_playerVariableDefinitionsProperty); serializedObject.ApplyModifiedProperties(); @@ -61,6 +64,10 @@ public override void OnInspectorGUI() if (!Application.isPlaying) { return; } + + EditorGUILayout.TextField("Table Variables", new GUIStyle(EditorStyles.boldLabel)); + PrintState(_gle.TableState); + if (_gle.PlayerStates.Count == 0) { EditorGUILayout.HelpBox("No player states created.", MessageType.Info); return; @@ -73,20 +80,23 @@ public override void OnInspectorGUI() } if (_playerVarFoldout[playerId] = EditorGUILayout.BeginFoldoutHeaderGroup(_playerVarFoldout[playerId], $"Player {playerId}")) { EditorGUI.indentLevel++; - - var playerState = _gle.PlayerStates[playerId]; - if (_gle.CurrentPlayerState == playerState) { - EditorGUILayout.HelpBox("Current Player", MessageType.Info); - } - - foreach (var varDef in _gle.PlayerVariableDefinitions) { - EditorGUILayout.LabelField(varDef.Name, playerState.Get(varDef.Id).ToString()); - } - + PrintState(_gle.PlayerStates[playerId]); EditorGUI.indentLevel--; } EditorGUILayout.EndFoldoutHeaderGroup(); } } + + private void PrintState(State state) + { + + if (_gle.CurrentPlayerState == state) { + EditorGUILayout.HelpBox("Current Player", MessageType.Info); + } + + foreach (var varDef in _gle.PlayerVariableDefinitions) { + EditorGUILayout.LabelField(varDef.Name, state.Get(varDef.Id).ToString()); + } + } } } diff --git a/Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs.meta b/Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs.meta deleted file mode 100644 index 5577ee2..0000000 --- a/Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 195abac7c9631244da60e2b9cd38680a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs b/Editor/PropertyDrawers/VariableDefinitionPropertyDrawer.cs similarity index 68% rename from Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs rename to Editor/PropertyDrawers/VariableDefinitionPropertyDrawer.cs index cba49a2..97c7365 100644 --- a/Editor/PropertyDrawers/PlayerVariableDefinitionPropertyDrawer.cs +++ b/Editor/PropertyDrawers/VariableDefinitionPropertyDrawer.cs @@ -21,7 +21,16 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [CustomPropertyDrawer(typeof(PlayerVariableDefinition))] - public class PlayerVariableDefinitionPropertyDrawer : PropertyDrawer + public class PlayerVariableDefinitionPropertyDrawer : VariableDefinitionPropertyDrawer + { + } + + [CustomPropertyDrawer(typeof(TableVariableDefinition))] + public class TableVariableDefinitionPropertyDrawer : VariableDefinitionPropertyDrawer + { + } + + public class VariableDefinitionPropertyDrawer : PropertyDrawer { private const float Padding = 2f; @@ -34,23 +43,23 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten { EditorGUI.BeginProperty(position, label, property); - var nameProperty = property.FindPropertyRelative(nameof(PlayerVariableDefinition.Name)); - var typeProperty = property.FindPropertyRelative(nameof(PlayerVariableDefinition.Type)); + var nameProperty = property.FindPropertyRelative(nameof(VariableDefinition.Name)); + var typeProperty = property.FindPropertyRelative(nameof(VariableDefinition.Type)); var typeIndex = typeProperty.enumValueIndex; SerializedProperty valueProp; switch (typeIndex) { case (int)VariableType.String: - valueProp = property.FindPropertyRelative(nameof(PlayerVariableDefinition.StringDefaultValue)); + valueProp = property.FindPropertyRelative(nameof(VariableDefinition.StringDefaultValue)); break; case (int)VariableType.Integer: - valueProp = property.FindPropertyRelative(nameof(PlayerVariableDefinition.IntegerDefaultValue)); + valueProp = property.FindPropertyRelative(nameof(VariableDefinition.IntegerDefaultValue)); break; case (int)VariableType.Float: - valueProp = property.FindPropertyRelative(nameof(PlayerVariableDefinition.FloatDefaultValue)); + valueProp = property.FindPropertyRelative(nameof(VariableDefinition.FloatDefaultValue)); break; case (int)VariableType.Boolean: - valueProp = property.FindPropertyRelative(nameof(PlayerVariableDefinition.BooleanDefaultValue)); + valueProp = property.FindPropertyRelative(nameof(VariableDefinition.BooleanDefaultValue)); break; default: throw new ArgumentException($"Undefined type index {typeIndex}."); diff --git a/Editor/PropertyDrawers/VariableDefinitionPropertyDrawer.cs.meta b/Editor/PropertyDrawers/VariableDefinitionPropertyDrawer.cs.meta new file mode 100644 index 0000000..c791c5e --- /dev/null +++ b/Editor/PropertyDrawers/VariableDefinitionPropertyDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d6dd518bc4a998c488368c470a50a39a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/CreateBallUnitWidget.cs b/Editor/Widgets/CreateBallUnitWidget.cs new file mode 100644 index 0000000..951094f --- /dev/null +++ b/Editor/Widgets/CreateBallUnitWidget.cs @@ -0,0 +1,33 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(CreateBallUnit))] + public sealed class CreateBallUnitWidget : GleUnitWidget + { + public CreateBallUnitWidget(FlowCanvas canvas, CreateBallUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/CreateBallUnitWidget.cs.meta b/Editor/Widgets/CreateBallUnitWidget.cs.meta new file mode 100644 index 0000000..363b76f --- /dev/null +++ b/Editor/Widgets/CreateBallUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fb3210b2787102a46b94ecc9b9506e7a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs.meta b/Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs.meta deleted file mode 100644 index a5ee2dd..0000000 --- a/Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 11be2ce60cdd75e47ae00cafec44e9e2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Widgets/PlayerVariableGetUnitWidget.cs.meta b/Editor/Widgets/PlayerVariableGetUnitWidget.cs.meta deleted file mode 100644 index 4e91c11..0000000 --- a/Editor/Widgets/PlayerVariableGetUnitWidget.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: aaa28a6744387e348aa7f551a0dd486f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs.meta b/Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs.meta deleted file mode 100644 index 6081ba9..0000000 --- a/Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d28add77ca0342943be979b6ffb6e1d5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Widgets/PlayerVariableSetUnitWidget.cs.meta b/Editor/Widgets/PlayerVariableSetUnitWidget.cs.meta deleted file mode 100644 index c7d0222..0000000 --- a/Editor/Widgets/PlayerVariableSetUnitWidget.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b861c66352e21fe4693886e41e3aebdc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs b/Editor/Widgets/VariableChangedEventUnitWidget.cs similarity index 78% rename from Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs rename to Editor/Widgets/VariableChangedEventUnitWidget.cs index ba53a03..cec0141 100644 --- a/Editor/Widgets/PlayerVariableChangedEventUnitWidget.cs +++ b/Editor/Widgets/VariableChangedEventUnitWidget.cs @@ -27,4 +27,12 @@ public PlayerVariableChangedEventWidget(FlowCanvas canvas, PlayerVariableChanged { } } + + [Widget(typeof(TableVariableChangedEventUnit))] + public sealed class TableVariableChangedEventWidget : GleUnitWidget + { + public TableVariableChangedEventWidget(FlowCanvas canvas, TableVariableChangedEventUnit unit) : base(canvas, unit) + { + } + } } diff --git a/Editor/Widgets/VariableChangedEventUnitWidget.cs.meta b/Editor/Widgets/VariableChangedEventUnitWidget.cs.meta new file mode 100644 index 0000000..8e1395d --- /dev/null +++ b/Editor/Widgets/VariableChangedEventUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c3fcf5eb49511d4b980d230d859c903 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/PlayerVariableGetUnitWidget.cs b/Editor/Widgets/VariableGetUnitWidget.cs similarity index 79% rename from Editor/Widgets/PlayerVariableGetUnitWidget.cs rename to Editor/Widgets/VariableGetUnitWidget.cs index e5ceb06..de81cc1 100644 --- a/Editor/Widgets/PlayerVariableGetUnitWidget.cs +++ b/Editor/Widgets/VariableGetUnitWidget.cs @@ -27,4 +27,12 @@ public PlayerVariableGetUnitWidget(FlowCanvas canvas, PlayerVariableGetUnit unit { } } + + [Widget(typeof(TableVariableGetUnit))] + public sealed class TableVariableGetUnitWidget : GleUnitWidget + { + public TableVariableGetUnitWidget(FlowCanvas canvas, TableVariableGetUnit unit) : base(canvas, unit) + { + } + } } diff --git a/Editor/Widgets/VariableGetUnitWidget.cs.meta b/Editor/Widgets/VariableGetUnitWidget.cs.meta new file mode 100644 index 0000000..ef36586 --- /dev/null +++ b/Editor/Widgets/VariableGetUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd079d4a7c9a6b245820db7202f456b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs b/Editor/Widgets/VariableIncreaseUnitWidget.cs similarity index 78% rename from Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs rename to Editor/Widgets/VariableIncreaseUnitWidget.cs index e5ae2d3..160aff5 100644 --- a/Editor/Widgets/PlayerVariableIncreaseUnitWidget.cs +++ b/Editor/Widgets/VariableIncreaseUnitWidget.cs @@ -27,4 +27,12 @@ public PlayerVariableIncreaseUnitWidget(FlowCanvas canvas, PlayerVariableIncreas { } } + + [Widget(typeof(TableVariableIncreaseUnit))] + public sealed class TableVariableIncreaseUnitWidget : GleUnitWidget + { + public TableVariableIncreaseUnitWidget(FlowCanvas canvas, TableVariableIncreaseUnit unit) : base(canvas, unit) + { + } + } } diff --git a/Editor/Widgets/VariableIncreaseUnitWidget.cs.meta b/Editor/Widgets/VariableIncreaseUnitWidget.cs.meta new file mode 100644 index 0000000..bf749c3 --- /dev/null +++ b/Editor/Widgets/VariableIncreaseUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6682642f34160194b8673d2c03a5736b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/PlayerVariableSetUnitWidget.cs b/Editor/Widgets/VariableSetUnitWidget.cs similarity index 79% rename from Editor/Widgets/PlayerVariableSetUnitWidget.cs rename to Editor/Widgets/VariableSetUnitWidget.cs index bd03e2d..2aa58e1 100644 --- a/Editor/Widgets/PlayerVariableSetUnitWidget.cs +++ b/Editor/Widgets/VariableSetUnitWidget.cs @@ -27,4 +27,12 @@ public PlayerVariableSetUnitWidget(FlowCanvas canvas, PlayerVariableSetUnit unit { } } + + [Widget(typeof(TableVariableSetUnit))] + public sealed class TableVariableSetUnitWidget : GleUnitWidget + { + public TableVariableSetUnitWidget(FlowCanvas canvas, TableVariableSetUnit unit) : base(canvas, unit) + { + } + } } diff --git a/Editor/Widgets/VariableSetUnitWidget.cs.meta b/Editor/Widgets/VariableSetUnitWidget.cs.meta new file mode 100644 index 0000000..53c825c --- /dev/null +++ b/Editor/Widgets/VariableSetUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4769b0eb13d593040abd66e817dcada5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Gamelogic/PlayerState.cs.meta b/Runtime/Gamelogic/PlayerState.cs.meta deleted file mode 100644 index edc18e1..0000000 --- a/Runtime/Gamelogic/PlayerState.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0fab504153838564799572c83cc37bd2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Gamelogic/PlayerVariable.cs.meta b/Runtime/Gamelogic/PlayerVariable.cs.meta deleted file mode 100644 index a80b05d..0000000 --- a/Runtime/Gamelogic/PlayerVariable.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1c93ce3b96af4be4d958aca3af6fb268 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Gamelogic/PlayerVariableDefinition.cs.meta b/Runtime/Gamelogic/PlayerVariableDefinition.cs.meta deleted file mode 100644 index 8c01e1c..0000000 --- a/Runtime/Gamelogic/PlayerVariableDefinition.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ef351adb3f965a04aa317b8e25e85df9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Gamelogic/PlayerState.cs b/Runtime/Gamelogic/State.cs similarity index 82% rename from Runtime/Gamelogic/PlayerState.cs rename to Runtime/Gamelogic/State.cs index 7d7e4ef..a9b2626 100644 --- a/Runtime/Gamelogic/PlayerState.cs +++ b/Runtime/Gamelogic/State.cs @@ -20,18 +20,31 @@ namespace VisualPinball.Unity.VisualScripting { - public class PlayerState + [Serializable] + public class PlayerState : State { public readonly int Id; - private readonly Dictionary _variables = new(); - public PlayerState(int id) { Id = id; } + protected override string VariableChangedEventName => VisualScriptingEventNames.PlayerVariableChanged; + } + + [Serializable] + public class TableState : State + { + protected override string VariableChangedEventName => VisualScriptingEventNames.TableVariableChanged; + } + + public abstract class State + { + protected abstract string VariableChangedEventName { get; } + + private readonly Dictionary _variables = new(); - public void AddProperty(PlayerVariable variable) + public void AddProperty(StateVariable variable) { _variables[variable.Id] = variable; } @@ -84,13 +97,14 @@ public void Set(string variableId, T value) where T : class if (currentValue != value) { EventBus.Trigger( - VisualScriptingEventNames.PlayerVariableChanged, - new PlayerVariableChangedArgs(variableId) + VariableChangedEventName, + new VariableChangedArgs(variableId) ); } } } + [Serializable] public class Integer { private readonly int _value; @@ -107,6 +121,7 @@ public Integer(int value) public override string ToString() => _value.ToString(); } + [Serializable] public class Float { private readonly float _value; @@ -123,6 +138,7 @@ public Float(float value) public override string ToString() => _value.ToString(); } + [Serializable] public class Bool { private readonly bool _value; @@ -135,11 +151,11 @@ public Bool(bool value) public override string ToString() => _value.ToString(); } - public readonly struct PlayerVariableChangedArgs + public readonly struct VariableChangedArgs { public readonly string VariableId; - public PlayerVariableChangedArgs(string variableId) + public VariableChangedArgs(string variableId) { VariableId = variableId; } diff --git a/Runtime/Gamelogic/State.cs.meta b/Runtime/Gamelogic/State.cs.meta new file mode 100644 index 0000000..ad6cf01 --- /dev/null +++ b/Runtime/Gamelogic/State.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6eb6c1f2a9e08ee429d86cefd79d92dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Gamelogic/PlayerVariable.cs b/Runtime/Gamelogic/StateVariable.cs similarity index 64% rename from Runtime/Gamelogic/PlayerVariable.cs rename to Runtime/Gamelogic/StateVariable.cs index fc929c9..f4d622e 100644 --- a/Runtime/Gamelogic/PlayerVariable.cs +++ b/Runtime/Gamelogic/StateVariable.cs @@ -18,27 +18,27 @@ namespace VisualPinball.Unity.VisualScripting { - public class PlayerVariable + public class StateVariable { public string Id; public string Name; public Type Type; // always *object* type (string, Integer, Float, Bool) private object _value; - public PlayerVariable(string id, string name, string initialValue) : this(id, name, typeof(string), initialValue) + public StateVariable(string id, string name, string initialValue) : this(id, name, typeof(string), initialValue) { } - public PlayerVariable(string id, string name, int initialValue) : this(id, name, typeof(Integer),new Integer(initialValue)) + public StateVariable(string id, string name, int initialValue) : this(id, name, typeof(Integer),new Integer(initialValue)) { } - public PlayerVariable(string id, string name, float initialValue) : this(id, name, typeof(Float), new Float(initialValue)) + public StateVariable(string id, string name, float initialValue) : this(id, name, typeof(Float), new Float(initialValue)) { } - public PlayerVariable(string id, string name, bool initialValue) : this(id, name, typeof(Bool), new Bool(initialValue)) + public StateVariable(string id, string name, bool initialValue) : this(id, name, typeof(Bool), new Bool(initialValue)) { } - private PlayerVariable(string id, string name, Type type, object initialValue) + private StateVariable(string id, string name, Type type, object initialValue) { Id = id; Name = name; diff --git a/Runtime/Gamelogic/StateVariable.cs.meta b/Runtime/Gamelogic/StateVariable.cs.meta new file mode 100644 index 0000000..964aafb --- /dev/null +++ b/Runtime/Gamelogic/StateVariable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b1a9c954a9a68a14ea503f77975b743a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Gamelogic/PlayerVariableDefinition.cs b/Runtime/Gamelogic/VariableDefinition.cs similarity index 72% rename from Runtime/Gamelogic/PlayerVariableDefinition.cs rename to Runtime/Gamelogic/VariableDefinition.cs index a9738f6..4adcefa 100644 --- a/Runtime/Gamelogic/PlayerVariableDefinition.cs +++ b/Runtime/Gamelogic/VariableDefinition.cs @@ -20,9 +20,17 @@ namespace VisualPinball.Unity.VisualScripting { + [Serializable] + public class PlayerVariableDefinition : VariableDefinition + { + } [Serializable] - public class PlayerVariableDefinition + public class TableVariableDefinition : VariableDefinition + { + } + + public abstract class VariableDefinition { public string Id; public string Name; @@ -33,17 +41,17 @@ public class PlayerVariableDefinition public float FloatDefaultValue; public bool BooleanDefaultValue; - public PlayerVariable Instantiate() + public StateVariable Instantiate() { switch (Type) { case VariableType.String: - return new PlayerVariable(Id, Name, StringDefaultValue); + return new StateVariable(Id, Name, StringDefaultValue); case VariableType.Integer: - return new PlayerVariable(Id, Name, IntegerDefaultValue); + return new StateVariable(Id, Name, IntegerDefaultValue); case VariableType.Float: - return new PlayerVariable(Id, Name, FloatDefaultValue); + return new StateVariable(Id, Name, FloatDefaultValue); case VariableType.Boolean: - return new PlayerVariable(Id, Name, BooleanDefaultValue); + return new StateVariable(Id, Name, BooleanDefaultValue); default: throw new ArgumentOutOfRangeException(); } diff --git a/Runtime/Gamelogic/VariableDefinition.cs.meta b/Runtime/Gamelogic/VariableDefinition.cs.meta new file mode 100644 index 0000000..617b879 --- /dev/null +++ b/Runtime/Gamelogic/VariableDefinition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6630e10b701f88d4ebfbfc4e45efc52d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Gamelogic/VisualScriptingEventNames.cs b/Runtime/Gamelogic/VisualScriptingEventNames.cs index 6569641..ec14b74 100644 --- a/Runtime/Gamelogic/VisualScriptingEventNames.cs +++ b/Runtime/Gamelogic/VisualScriptingEventNames.cs @@ -24,5 +24,6 @@ public static class VisualScriptingEventNames public const string CoilEvent = "CoilEvent"; public const string CurrentPlayerChanged = "CurrentPlayerChanged"; public const string PlayerVariableChanged = "PlayerVariableChanged"; + public const string TableVariableChanged = "TableVariableChanged"; } } diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index b61785d..26e7582 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -31,11 +31,19 @@ public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine, I { public string Name => "Visual Scripting Gamelogic Engine"; + [Tooltip("Define here the global variables of the Visual Scripting engine.")] + public List TableVariableDefinitions; + + [Tooltip("Define here the player-specific variables of the Visual Scripting engine.")] public List PlayerVariableDefinitions; [Tooltip("The switches that are exposed in the Visual Scripting nodes.")] public VisualScriptingSwitch[] Switches; + + [Tooltip("The coils that are exposed in the Visual Scripting nodes.")] public VisualScriptingCoil[] Coils; + + [Tooltip("The lamps that are exposed in the Visual Scripting nodes.")] public VisualScriptingLamp[] Lamps; public GamelogicEngineWire[] Wires; @@ -60,6 +68,7 @@ public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine, I [NonSerialized] private Player _player; [NonSerialized] private int _currentPlayer; + [NonSerialized] public readonly TableState TableState = new (); [NonSerialized] public readonly Dictionary PlayerStates = new (); public PlayerState CurrentPlayerState { @@ -164,6 +173,13 @@ public void OnBeforeSerialize() } ids.Add(def.Id); } + ids.Clear(); + foreach (var def in TableVariableDefinitions) { + if (!def.HasId || ids.Contains(def.Id)) { + def.GenerateId(); + } + ids.Add(def.Id); + } #endif } public void OnAfterDeserialize() diff --git a/Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs.meta deleted file mode 100644 index 37ce21e..0000000 --- a/Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 39808e80b0493814f9242f200797dbaa -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs.meta deleted file mode 100644 index f959b14..0000000 --- a/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c8f895af4882d9146b7ef2373b6722f4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs.meta deleted file mode 100644 index b6c028a..0000000 --- a/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 195f5e217e66d2b428c7a6ab84c46170 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs.meta deleted file mode 100644 index 19a96ed..0000000 --- a/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: aace145fc931b28408479d7b651a603d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs b/Runtime/Nodes/PlayerState/VariableChangedEventUnit.cs similarity index 51% rename from Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs rename to Runtime/Nodes/PlayerState/VariableChangedEventUnit.cs index 3245974..8b9d945 100644 --- a/Runtime/Nodes/PlayerState/PlayerVariableChangedEventUnit.cs +++ b/Runtime/Nodes/PlayerState/VariableChangedEventUnit.cs @@ -20,28 +20,52 @@ namespace VisualPinball.Unity.VisualScripting { [UnitTitle("On Player Variable Changed")] - [UnitSurtitle("Gamelogic Engine")] + [UnitSurtitle("Player State")] [UnitCategory("Events\\Visual Pinball")] - public class PlayerVariableChangedEventUnit : GleEventUnit + public class PlayerVariableChangedEventUnit : VariableChangedEventUnit { [Serialize, Inspectable, UnitHeaderInspectable] public PlayerVariableDefinition Variable { get; set; } + protected override State State => VsGle.CurrentPlayerState; + protected override VariableDefinition VariableDefinition => Variable; + protected override string EventHookName => VisualScriptingEventNames.PlayerVariableChanged; + } + + [UnitTitle("On Table Variable Changed")] + [UnitSurtitle("Table State")] + [UnitCategory("Events\\Visual Pinball")] + public class TableVariableChangedEventUnit : VariableChangedEventUnit + { + [Serialize, Inspectable, UnitHeaderInspectable] + public TableVariableDefinition Variable { get; set; } + + protected override State State => VsGle.TableState; + protected override VariableDefinition VariableDefinition => Variable; + protected override string EventHookName => VisualScriptingEventNames.TableVariableChanged; + } + + public abstract class VariableChangedEventUnit : GleEventUnit + { [DoNotSerialize, PortLabel("Value"), Inspectable] public ValueOutput Value { get; private set; } - public override EventHook GetHook(GraphReference reference) => new EventHook(VisualScriptingEventNames.PlayerVariableChanged); + public override EventHook GetHook(GraphReference reference) => new(EventHookName); protected override bool register => true; + protected abstract State State { get; } + protected abstract VariableDefinition VariableDefinition { get; } + protected abstract string EventHookName { get; } + protected override void Definition() { base.Definition(); - if (Variable == null) { + if (VariableDefinition == null) { return; } - Value = Variable.Type switch { + Value = VariableDefinition.Type switch { VariableType.String => ValueOutput(nameof(Value)), VariableType.Integer => ValueOutput(nameof(Value)), VariableType.Float => ValueOutput(nameof(Value)), @@ -50,29 +74,29 @@ protected override void Definition() }; } - protected override bool ShouldTrigger(Flow flow, PlayerVariableChangedArgs args) + protected override bool ShouldTrigger(Flow flow, VariableChangedArgs args) { - return Variable.Id == args.VariableId; + return VariableDefinition.Id == args.VariableId; } - protected override void AssignArguments(Flow flow, PlayerVariableChangedArgs args) + protected override void AssignArguments(Flow flow, VariableChangedArgs args) { if (!AssertVsGle(flow)) { throw new InvalidOperationException("Cannot retrieve GLE from unit."); } - switch (Variable.Type) { + switch (VariableDefinition.Type) { case VariableType.String: - flow.SetValue(Value, VsGle.CurrentPlayerState.Get(Variable.Id)); + flow.SetValue(Value, State.Get(VariableDefinition.Id)); break; case VariableType.Integer: - flow.SetValue(Value, (int)VsGle.CurrentPlayerState.Get(Variable.Id)); + flow.SetValue(Value, (int)State.Get(VariableDefinition.Id)); break; case VariableType.Float: - flow.SetValue(Value, (float)VsGle.CurrentPlayerState.Get(Variable.Id)); + flow.SetValue(Value, (float)State.Get(VariableDefinition.Id)); break; case VariableType.Boolean: - flow.SetValue(Value, (bool)VsGle.CurrentPlayerState.Get(Variable.Id)); + flow.SetValue(Value, (bool)State.Get(VariableDefinition.Id)); break; default: throw new ArgumentOutOfRangeException(); diff --git a/Runtime/Nodes/PlayerState/VariableChangedEventUnit.cs.meta b/Runtime/Nodes/PlayerState/VariableChangedEventUnit.cs.meta new file mode 100644 index 0000000..f766c1c --- /dev/null +++ b/Runtime/Nodes/PlayerState/VariableChangedEventUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8d68d23dd11076b4a9ba3c791d2b29ae +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs b/Runtime/Nodes/PlayerState/VariableGetUnit.cs similarity index 64% rename from Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs rename to Runtime/Nodes/PlayerState/VariableGetUnit.cs index 784ab76..25abf7f 100644 --- a/Runtime/Nodes/PlayerState/PlayerVariableGetUnit.cs +++ b/Runtime/Nodes/PlayerState/VariableGetUnit.cs @@ -22,21 +22,42 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("Get Player Variable")] [UnitSurtitle("Player State")] [UnitCategory("Visual Pinball/Variables")] - public class PlayerVariableGetUnit : GleUnit + public class PlayerVariableGetUnit : VariableGetUnit { [Serialize, Inspectable, UnitHeaderInspectable] public PlayerVariableDefinition Variable { get; set; } + protected override VariableDefinition VariableDefinition => Variable; + protected override State State => VsGle.CurrentPlayerState; + } + + [UnitTitle("Get Table Variable")] + [UnitSurtitle("Table State")] + [UnitCategory("Visual Pinball/Variables")] + public class TableVariableGetUnit : VariableGetUnit + { + [Serialize, Inspectable, UnitHeaderInspectable] + public TableVariableDefinition Variable { get; set; } + protected override VariableDefinition VariableDefinition => Variable; + + protected override State State => VsGle.TableState; + } + + public abstract class VariableGetUnit : GleUnit + { [DoNotSerialize, PortLabel("Value"), Inspectable] public ValueOutput Value { get; private set; } + protected abstract State State { get; } + protected abstract VariableDefinition VariableDefinition { get; } + protected override void Definition() { - if (Variable == null) { + if (VariableDefinition == null) { return; } - Value = Variable.Type switch { + Value = VariableDefinition.Type switch { VariableType.String => ValueOutput(nameof(Value), GetString), VariableType.Integer => ValueOutput(nameof(Value), GetInt), VariableType.Float => ValueOutput(nameof(Value), GetFloat), @@ -50,7 +71,7 @@ private string GetString(Flow flow) if (!AssertVsGle(flow)) { throw new InvalidOperationException("Cannot retrieve GLE from unit."); } - return VsGle.CurrentPlayerState.Get(Variable.Id); + return State.Get(VariableDefinition.Id); } private bool GetBool(Flow flow) @@ -58,7 +79,7 @@ private bool GetBool(Flow flow) if (!AssertVsGle(flow)) { throw new InvalidOperationException("Cannot retrieve GLE from unit."); } - return (bool)VsGle.CurrentPlayerState.Get(Variable.Id); + return (bool)State.Get(VariableDefinition.Id); } private float GetFloat(Flow flow) @@ -66,7 +87,7 @@ private float GetFloat(Flow flow) if (!AssertVsGle(flow)) { throw new InvalidOperationException("Cannot retrieve GLE from unit."); } - return (float)VsGle.CurrentPlayerState.Get(Variable.Id); + return (float)State.Get(VariableDefinition.Id); } private int GetInt(Flow flow) @@ -74,7 +95,7 @@ private int GetInt(Flow flow) if (!AssertVsGle(flow)) { throw new InvalidOperationException("Cannot retrieve GLE from unit."); } - return (int)VsGle.CurrentPlayerState.Get(Variable.Id); + return (int)State.Get(VariableDefinition.Id); } } } diff --git a/Runtime/Nodes/PlayerState/VariableGetUnit.cs.meta b/Runtime/Nodes/PlayerState/VariableGetUnit.cs.meta new file mode 100644 index 0000000..82fda92 --- /dev/null +++ b/Runtime/Nodes/PlayerState/VariableGetUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3eff501f75250d34c92e0a81f24dab94 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs b/Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs similarity index 62% rename from Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs rename to Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs index 076ccd1..32d3ecd 100644 --- a/Runtime/Nodes/PlayerState/PlayerVariableIncreaseUnit.cs +++ b/Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs @@ -22,7 +22,28 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("Increase Player Variable")] [UnitSurtitle("Player State")] [UnitCategory("Visual Pinball/Variables")] - public class PlayerVariableIncreaseUnit : GleUnit + public class PlayerVariableIncreaseUnit : VariableIncreaseUnit + { + [Serialize, Inspectable, UnitHeaderInspectable] + public PlayerVariableDefinition Variable { get; set; } + + protected override State State => VsGle.CurrentPlayerState; + protected override VariableDefinition VariableDefinition => Variable; + } + + [UnitTitle("Increase Table Variable")] + [UnitSurtitle("Table State")] + [UnitCategory("Visual Pinball/Variables")] + public class TableVariableIncreaseUnit : VariableIncreaseUnit + { + [Serialize, Inspectable, UnitHeaderInspectable] + public TableVariableDefinition Variable { get; set; } + + protected override State State => VsGle.TableState; + protected override VariableDefinition VariableDefinition => Variable; + } + + public abstract class VariableIncreaseUnit : GleUnit { [DoNotSerialize, PortLabelHidden] public ControlInput InputTrigger; @@ -30,12 +51,13 @@ public class PlayerVariableIncreaseUnit : GleUnit [DoNotSerialize, PortLabelHidden] public ControlOutput OutputTrigger; - [Serialize, Inspectable, UnitHeaderInspectable] - public PlayerVariableDefinition Variable { get; set; } [DoNotSerialize, PortLabel("Value"), Inspectable] public ValueInput Value { get; private set; } + protected abstract State State { get; } + protected abstract VariableDefinition VariableDefinition { get; } + protected override void Definition() { InputTrigger = ControlInput(nameof(InputTrigger), Process); @@ -43,11 +65,11 @@ protected override void Definition() Succession(InputTrigger, OutputTrigger); - if (Variable == null) { + if (VariableDefinition == null) { return; } - Value = Variable.Type switch { + Value = VariableDefinition.Type switch { VariableType.Integer => ValueInput(nameof(Value), 0), VariableType.Float => ValueInput(nameof(Value), 0f), _ => throw new ArgumentOutOfRangeException($"Type must be integer or float.") @@ -61,15 +83,15 @@ private ControlOutput Process(Flow flow) throw new InvalidOperationException("Cannot retrieve GLE from unit."); } - switch (Variable.Type) { + switch (VariableDefinition.Type) { case VariableType.Integer: { - var current = (int)VsGle.CurrentPlayerState.Get(Variable.Id); - VsGle.CurrentPlayerState.Set(Variable.Id, new Integer(current + flow.GetValue(Value))); + var current = (int)State.Get(VariableDefinition.Id); + State.Set(VariableDefinition.Id, new Integer(current + flow.GetValue(Value))); break; } case VariableType.Float: { - var current = (float)VsGle.CurrentPlayerState.Get(Variable.Id); - VsGle.CurrentPlayerState.Set(Variable.Id, new Float(current + flow.GetValue(Value))); + var current = (float)State.Get(VariableDefinition.Id); + State.Set(VariableDefinition.Id, new Float(current + flow.GetValue(Value))); break; } default: diff --git a/Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs.meta b/Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs.meta new file mode 100644 index 0000000..a01fb64 --- /dev/null +++ b/Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d1467aed8a0856f45a8c12d8baf151c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs b/Runtime/Nodes/PlayerState/VariableSetUnit.cs similarity index 64% rename from Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs rename to Runtime/Nodes/PlayerState/VariableSetUnit.cs index 7057bc7..57408ec 100644 --- a/Runtime/Nodes/PlayerState/PlayerVariableSetUnit.cs +++ b/Runtime/Nodes/PlayerState/VariableSetUnit.cs @@ -23,7 +23,28 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("Set Player Variable")] [UnitSurtitle("Player State")] [UnitCategory("Visual Pinball/Variables")] - public class PlayerVariableSetUnit : GleUnit + public class PlayerVariableSetUnit : VariableSetUnit + { + [Serialize, Inspectable, UnitHeaderInspectable] + public PlayerVariableDefinition Variable { get; set; } + + protected override State State => VsGle.CurrentPlayerState; + protected override VariableDefinition VariableDefinition => Variable; + } + + [UnitTitle("Set Table Variable")] + [UnitSurtitle("Table State")] + [UnitCategory("Visual Pinball/Variables")] + public class TableVariableSetUnit : VariableSetUnit + { + [Serialize, Inspectable, UnitHeaderInspectable] + public TableVariableDefinition Variable { get; set; } + + protected override State State => VsGle.TableState; + protected override VariableDefinition VariableDefinition => Variable; + } + + public abstract class VariableSetUnit : GleUnit { [DoNotSerialize, PortLabelHidden] public ControlInput InputTrigger; @@ -31,12 +52,12 @@ public class PlayerVariableSetUnit : GleUnit [DoNotSerialize, PortLabelHidden] public ControlOutput OutputTrigger; - [Serialize, Inspectable, UnitHeaderInspectable] - public PlayerVariableDefinition Variable { get; set; } - [DoNotSerialize, PortLabel("Value"), Inspectable] public ValueInput Value { get; private set; } + protected abstract State State { get; } + protected abstract VariableDefinition VariableDefinition { get; } + protected override void Definition() { InputTrigger = ControlInput(nameof(InputTrigger), Process); @@ -44,11 +65,11 @@ protected override void Definition() Succession(InputTrigger, OutputTrigger); - if (Variable == null) { + if (VariableDefinition == null) { return; } - Value = Variable.Type switch { + Value = VariableDefinition.Type switch { VariableType.String => ValueInput(nameof(Value), string.Empty), VariableType.Integer => ValueInput(nameof(Value), 0), VariableType.Float => ValueInput(nameof(Value), 0f), @@ -64,18 +85,18 @@ private ControlOutput Process(Flow flow) throw new InvalidOperationException("Cannot retrieve GLE from unit."); } - switch (Variable.Type) { + switch (VariableDefinition.Type) { case VariableType.String: - VsGle.CurrentPlayerState.Set(Variable.Id, flow.GetValue(Value)); + State.Set(VariableDefinition.Id, flow.GetValue(Value)); break; case VariableType.Integer: - VsGle.CurrentPlayerState.Set(Variable.Id, new Integer(flow.GetValue(Value))); + State.Set(VariableDefinition.Id, new Integer(flow.GetValue(Value))); break; case VariableType.Float: - VsGle.CurrentPlayerState.Set(Variable.Id, new Float(flow.GetValue(Value))); + State.Set(VariableDefinition.Id, new Float(flow.GetValue(Value))); break; case VariableType.Boolean: - VsGle.CurrentPlayerState.Set(Variable.Id, new Bool(flow.GetValue(Value))); + State.Set(VariableDefinition.Id, new Bool(flow.GetValue(Value))); break; default: throw new ArgumentOutOfRangeException(); diff --git a/Runtime/Nodes/PlayerState/VariableSetUnit.cs.meta b/Runtime/Nodes/PlayerState/VariableSetUnit.cs.meta new file mode 100644 index 0000000..83592fd --- /dev/null +++ b/Runtime/Nodes/PlayerState/VariableSetUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0d5aa3398e6736d4faad20bca3138c45 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From dd48e0763bfc339720e8d07e94c028ab90f5378b Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 3 Feb 2022 22:41:51 +0100 Subject: [PATCH 14/54] Add missing widgets. --- Editor/Widgets/GleStartedEventUnitWidget.cs | 30 +++++++++++++++++++ .../Widgets/GleStartedEventUnitWidget.cs.meta | 11 +++++++ Editor/Widgets/SetLightSequenceUnitWidget.cs | 2 +- Editor/Widgets/SetLightUnitWidget.cs | 2 +- Runtime/Nodes/GleStartedEventUnit.cs | 2 +- 5 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 Editor/Widgets/GleStartedEventUnitWidget.cs create mode 100644 Editor/Widgets/GleStartedEventUnitWidget.cs.meta diff --git a/Editor/Widgets/GleStartedEventUnitWidget.cs b/Editor/Widgets/GleStartedEventUnitWidget.cs new file mode 100644 index 0000000..dacf921 --- /dev/null +++ b/Editor/Widgets/GleStartedEventUnitWidget.cs @@ -0,0 +1,30 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(GleStartedEventUnit))] + public sealed class GleStartedEventUnitWidget : GleUnitWidget + { + public GleStartedEventUnitWidget(FlowCanvas canvas, GleStartedEventUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/GleStartedEventUnitWidget.cs.meta b/Editor/Widgets/GleStartedEventUnitWidget.cs.meta new file mode 100644 index 0000000..e6bfd5d --- /dev/null +++ b/Editor/Widgets/GleStartedEventUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 45080ca839581524da47bc355e4466b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/SetLightSequenceUnitWidget.cs b/Editor/Widgets/SetLightSequenceUnitWidget.cs index a316ce8..0689e76 100644 --- a/Editor/Widgets/SetLightSequenceUnitWidget.cs +++ b/Editor/Widgets/SetLightSequenceUnitWidget.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(SetLightSequenceUnit))] - public sealed class SetLightSequenceUnitWidget : UnitWidget + public sealed class SetLightSequenceUnitWidget : GleUnitWidget { private ObjectPickerInspector _objectInspector; private readonly Func> _setObjectInspectorConstructor; diff --git a/Editor/Widgets/SetLightUnitWidget.cs b/Editor/Widgets/SetLightUnitWidget.cs index 9043f95..45233d0 100644 --- a/Editor/Widgets/SetLightUnitWidget.cs +++ b/Editor/Widgets/SetLightUnitWidget.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(SetLightUnit))] - public sealed class SetLightUnitWidget : UnitWidget + public sealed class SetLightUnitWidget : GleUnitWidget { private ObjectPickerInspector _objectInspector; private readonly Func> _setObjectInspectorConstructor; diff --git a/Runtime/Nodes/GleStartedEventUnit.cs b/Runtime/Nodes/GleStartedEventUnit.cs index ceb0be4..b86afee 100644 --- a/Runtime/Nodes/GleStartedEventUnit.cs +++ b/Runtime/Nodes/GleStartedEventUnit.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity.VisualScripting { [UnitTitle("On Gamelogic Engine Started Event")] [UnitCategory("Events\\Visual Pinball")] - public sealed class GleStartedEventUnit : EventUnit + public sealed class GleStartedEventUnit : GleEventUnit { protected override bool register => true; From ac06cfdb5d6b43b4ff49032634ed48ee09aaf782 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 3 Feb 2022 23:04:37 +0100 Subject: [PATCH 15/54] Rename state nodes to be more coherent. --- ....cs => ChangePlayerStateUnitDescriptor.cs} | 8 +- ...> ChangePlayerStateUnitDescriptor.cs.meta} | 2 +- ....cs => CreatePlayerStateUnitDescriptor.cs} | 10 +- ...> CreatePlayerStateUnitDescriptor.cs.meta} | 2 +- ...riptor.cs => GetVariableUnitDescriptor.cs} | 16 +- ...meta => GetVariableUnitDescriptor.cs.meta} | 2 +- ...r.cs => IncreaseVariableUnitDescriptor.cs} | 16 +- ...=> IncreaseVariableUnitDescriptor.cs.meta} | 2 +- ...r.cs => SetLampComponentUnitDescriptor.cs} | 12 +- .../SetLampComponentUnitDescriptor.cs.meta | 11 ++ ...riptor.cs => SetVariableUnitDescriptor.cs} | 16 +- .../SetVariableUnitDescriptor.cs.meta | 11 ++ .../VariableIncreaseUnitDescriptor.cs.meta | 11 -- .../VariableSetUnitDescriptor.cs.meta | 11 -- ...dget.cs => ChangePlayerStateUnitWidget.cs} | 6 +- .../ChangePlayerStateUnitWidget.cs.meta | 11 ++ ...dget.cs => CreatePlayerStateUnitWidget.cs} | 6 +- .../CreatePlayerStateUnitWidget.cs.meta | 11 ++ ...UnitWidget.cs => GetVariableUnitWidget.cs} | 12 +- Editor/Widgets/GetVariableUnitWidget.cs.meta | 11 ++ ...idget.cs => IncreaseVariableUnitWidget.cs} | 12 +- .../IncreaseVariableUnitWidget.cs.meta | 11 ++ .../PlayerStateChangeUnitWidget.cs.meta | 11 -- .../PlayerStateCreateUnitWidget.cs.meta | 11 -- ...idget.cs => SetLampComponentUnitWidget.cs} | 6 +- .../SetLampComponentUnitWidget.cs.meta | 11 ++ Editor/Widgets/SetLightUnitWidget.cs.meta | 11 -- ...UnitWidget.cs => SetVariableUnitWidget.cs} | 12 +- Editor/Widgets/SetVariableUnitWidget.cs.meta | 11 ++ Editor/Widgets/VariableGetUnitWidget.cs.meta | 11 -- .../VariableIncreaseUnitWidget.cs.meta | 11 -- Editor/Widgets/VariableSetUnitWidget.cs.meta | 11 -- ...etLightUnit.cs => SetLampComponentUnit.cs} | 2 +- .../Nodes/Lamps/SetLampComponentUnit.cs.meta | 11 ++ Runtime/Nodes/Lamps/SetLightUnit.cs.meta | 11 -- ...ChangeUnit.cs => ChangePlayerStateUnit.cs} | 2 +- .../PlayerState/ChangePlayerStateUnit.cs.meta | 11 ++ ...CreateUnit.cs => CreatePlayerStateUnit.cs} | 168 +++++++++--------- .../PlayerState/CreatePlayerStateUnit.cs.meta | 11 ++ ...{VariableGetUnit.cs => GetVariableUnit.cs} | 6 +- .../Nodes/PlayerState/GetVariableUnit.cs.meta | 11 ++ ...ncreaseUnit.cs => IncreaseVariableUnit.cs} | 6 +- .../PlayerState/IncreaseVariableUnit.cs.meta | 11 ++ .../PlayerState/PlayerStateChangeUnit.cs.meta | 11 -- .../PlayerState/PlayerStateCreateUnit.cs.meta | 11 -- ...{VariableSetUnit.cs => SetVariableUnit.cs} | 6 +- .../Nodes/PlayerState/SetVariableUnit.cs.meta | 11 ++ .../Nodes/PlayerState/VariableGetUnit.cs.meta | 11 -- .../PlayerState/VariableIncreaseUnit.cs.meta | 11 -- .../Nodes/PlayerState/VariableSetUnit.cs.meta | 11 -- 50 files changed, 319 insertions(+), 319 deletions(-) rename Editor/Descriptors/{PlayerStateChangeUnitDescriptor.cs => ChangePlayerStateUnitDescriptor.cs} (82%) rename Editor/Descriptors/{SetLightUnitDescriptor.cs.meta => ChangePlayerStateUnitDescriptor.cs.meta} (83%) rename Editor/Descriptors/{PlayerStateCreateUnitDescriptor.cs => CreatePlayerStateUnitDescriptor.cs} (82%) rename Editor/Descriptors/{PlayerStateChangeUnitDescriptor.cs.meta => CreatePlayerStateUnitDescriptor.cs.meta} (83%) rename Editor/Descriptors/{VariableGetUnitDescriptor.cs => GetVariableUnitDescriptor.cs} (76%) rename Editor/Descriptors/{VariableGetUnitDescriptor.cs.meta => GetVariableUnitDescriptor.cs.meta} (83%) rename Editor/Descriptors/{VariableIncreaseUnitDescriptor.cs => IncreaseVariableUnitDescriptor.cs} (74%) rename Editor/Descriptors/{PlayerStateCreateUnitDescriptor.cs.meta => IncreaseVariableUnitDescriptor.cs.meta} (83%) rename Editor/Descriptors/{SetLightUnitDescriptor.cs => SetLampComponentUnitDescriptor.cs} (81%) create mode 100644 Editor/Descriptors/SetLampComponentUnitDescriptor.cs.meta rename Editor/Descriptors/{VariableSetUnitDescriptor.cs => SetVariableUnitDescriptor.cs} (76%) create mode 100644 Editor/Descriptors/SetVariableUnitDescriptor.cs.meta delete mode 100644 Editor/Descriptors/VariableIncreaseUnitDescriptor.cs.meta delete mode 100644 Editor/Descriptors/VariableSetUnitDescriptor.cs.meta rename Editor/Widgets/{PlayerStateCreateUnitWidget.cs => ChangePlayerStateUnitWidget.cs} (76%) create mode 100644 Editor/Widgets/ChangePlayerStateUnitWidget.cs.meta rename Editor/Widgets/{PlayerStateChangeUnitWidget.cs => CreatePlayerStateUnitWidget.cs} (76%) create mode 100644 Editor/Widgets/CreatePlayerStateUnitWidget.cs.meta rename Editor/Widgets/{VariableSetUnitWidget.cs => GetVariableUnitWidget.cs} (63%) create mode 100644 Editor/Widgets/GetVariableUnitWidget.cs.meta rename Editor/Widgets/{VariableIncreaseUnitWidget.cs => IncreaseVariableUnitWidget.cs} (61%) create mode 100644 Editor/Widgets/IncreaseVariableUnitWidget.cs.meta delete mode 100644 Editor/Widgets/PlayerStateChangeUnitWidget.cs.meta delete mode 100644 Editor/Widgets/PlayerStateCreateUnitWidget.cs.meta rename Editor/Widgets/{SetLightUnitWidget.cs => SetLampComponentUnitWidget.cs} (84%) create mode 100644 Editor/Widgets/SetLampComponentUnitWidget.cs.meta delete mode 100644 Editor/Widgets/SetLightUnitWidget.cs.meta rename Editor/Widgets/{VariableGetUnitWidget.cs => SetVariableUnitWidget.cs} (63%) create mode 100644 Editor/Widgets/SetVariableUnitWidget.cs.meta delete mode 100644 Editor/Widgets/VariableGetUnitWidget.cs.meta delete mode 100644 Editor/Widgets/VariableIncreaseUnitWidget.cs.meta delete mode 100644 Editor/Widgets/VariableSetUnitWidget.cs.meta rename Runtime/Nodes/Lamps/{SetLightUnit.cs => SetLampComponentUnit.cs} (94%) create mode 100644 Runtime/Nodes/Lamps/SetLampComponentUnit.cs.meta delete mode 100644 Runtime/Nodes/Lamps/SetLightUnit.cs.meta rename Runtime/Nodes/PlayerState/{PlayerStateChangeUnit.cs => ChangePlayerStateUnit.cs} (94%) create mode 100644 Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs.meta rename Runtime/Nodes/PlayerState/{PlayerStateCreateUnit.cs => CreatePlayerStateUnit.cs} (94%) create mode 100644 Runtime/Nodes/PlayerState/CreatePlayerStateUnit.cs.meta rename Runtime/Nodes/PlayerState/{VariableGetUnit.cs => GetVariableUnit.cs} (92%) create mode 100644 Runtime/Nodes/PlayerState/GetVariableUnit.cs.meta rename Runtime/Nodes/PlayerState/{VariableIncreaseUnit.cs => IncreaseVariableUnit.cs} (91%) create mode 100644 Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs.meta delete mode 100644 Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs.meta delete mode 100644 Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs.meta rename Runtime/Nodes/PlayerState/{VariableSetUnit.cs => SetVariableUnit.cs} (92%) create mode 100644 Runtime/Nodes/PlayerState/SetVariableUnit.cs.meta delete mode 100644 Runtime/Nodes/PlayerState/VariableGetUnit.cs.meta delete mode 100644 Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs.meta delete mode 100644 Runtime/Nodes/PlayerState/VariableSetUnit.cs.meta diff --git a/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs b/Editor/Descriptors/ChangePlayerStateUnitDescriptor.cs similarity index 82% rename from Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs rename to Editor/Descriptors/ChangePlayerStateUnitDescriptor.cs index 854d77f..d6c3343 100644 --- a/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs +++ b/Editor/Descriptors/ChangePlayerStateUnitDescriptor.cs @@ -20,10 +20,10 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Descriptor(typeof(PlayerStateChangeUnit))] - public class PlayerStateChangeUnitDescriptor : UnitDescriptor + [Descriptor(typeof(ChangePlayerStateUnit))] + public class ChangePlayerStateUnitDescriptor : UnitDescriptor { - public PlayerStateChangeUnitDescriptor(PlayerStateChangeUnit target) : base(target) + public ChangePlayerStateUnitDescriptor(ChangePlayerStateUnit target) : base(target) { } @@ -39,7 +39,7 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(PlayerStateChangeUnit.PlayerId): + case nameof(ChangePlayerStateUnit.PlayerId): desc.summary = "The player ID of the desired state"; break; } diff --git a/Editor/Descriptors/SetLightUnitDescriptor.cs.meta b/Editor/Descriptors/ChangePlayerStateUnitDescriptor.cs.meta similarity index 83% rename from Editor/Descriptors/SetLightUnitDescriptor.cs.meta rename to Editor/Descriptors/ChangePlayerStateUnitDescriptor.cs.meta index a685b04..09268f7 100644 --- a/Editor/Descriptors/SetLightUnitDescriptor.cs.meta +++ b/Editor/Descriptors/ChangePlayerStateUnitDescriptor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e56287af571309349a1ef10db3293889 +guid: 77a8b54096b355b45a2c1f19644007d8 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs b/Editor/Descriptors/CreatePlayerStateUnitDescriptor.cs similarity index 82% rename from Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs rename to Editor/Descriptors/CreatePlayerStateUnitDescriptor.cs index af6af33..ad1b533 100644 --- a/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs +++ b/Editor/Descriptors/CreatePlayerStateUnitDescriptor.cs @@ -20,10 +20,10 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Descriptor(typeof(PlayerStateCreateUnit))] - public class PlayerStateCreateUnitDescriptor : UnitDescriptor + [Descriptor(typeof(CreatePlayerStateUnit))] + public class CreatePlayerStateUnitDescriptor : UnitDescriptor { - public PlayerStateCreateUnitDescriptor(PlayerStateCreateUnit target) : base(target) + public CreatePlayerStateUnitDescriptor(CreatePlayerStateUnit target) : base(target) { } @@ -39,13 +39,13 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(PlayerStateCreateUnit.PlayerId): + case nameof(CreatePlayerStateUnit.PlayerId): desc.summary = "The player ID of the new state"; break; // case nameof(PlayerStateCreateUnit.AutoIncrement): // desc.summary = "If set, the new player ID will be the currently largest ID, plus one."; // break; - case nameof(PlayerStateCreateUnit.SetAsActive): + case nameof(CreatePlayerStateUnit.SetAsActive): desc.summary = "If set, the new state will be the current state. Otherwise, it will only be the current state if there is no state set."; break; } diff --git a/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs.meta b/Editor/Descriptors/CreatePlayerStateUnitDescriptor.cs.meta similarity index 83% rename from Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs.meta rename to Editor/Descriptors/CreatePlayerStateUnitDescriptor.cs.meta index 75e43b6..ce0a62f 100644 --- a/Editor/Descriptors/PlayerStateChangeUnitDescriptor.cs.meta +++ b/Editor/Descriptors/CreatePlayerStateUnitDescriptor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 949972332a27ccc47a095d67b5a5a278 +guid: a0cab1524e6146a48ac09dc7694e6b25 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Descriptors/VariableGetUnitDescriptor.cs b/Editor/Descriptors/GetVariableUnitDescriptor.cs similarity index 76% rename from Editor/Descriptors/VariableGetUnitDescriptor.cs rename to Editor/Descriptors/GetVariableUnitDescriptor.cs index 60f02db..d5584ac 100644 --- a/Editor/Descriptors/VariableGetUnitDescriptor.cs +++ b/Editor/Descriptors/GetVariableUnitDescriptor.cs @@ -20,10 +20,10 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Descriptor(typeof(PlayerVariableGetUnit))] - public class PlayerVariableGetUnitDescriptor : UnitDescriptor + [Descriptor(typeof(GetPlayerVariableUnit))] + public class GetPlayerVariableUnitDescriptor : UnitDescriptor { - public PlayerVariableGetUnitDescriptor(PlayerVariableGetUnit target) : base(target) + public GetPlayerVariableUnitDescriptor(GetPlayerVariableUnit target) : base(target) { } @@ -39,17 +39,17 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(PlayerVariableGetUnit.Value): + case nameof(GetPlayerVariableUnit.Value): desc.summary = "The current value of the player variable."; break; } } } - [Descriptor(typeof(TableVariableGetUnit))] - public class TableVariableGetUnitDescriptor : UnitDescriptor + [Descriptor(typeof(GetTableVariableUnit))] + public class GetTableVariableUnitDescriptor : UnitDescriptor { - public TableVariableGetUnitDescriptor(TableVariableGetUnit target) : base(target) + public GetTableVariableUnitDescriptor(GetTableVariableUnit target) : base(target) { } @@ -65,7 +65,7 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(TableVariableGetUnit.Value): + case nameof(GetTableVariableUnit.Value): desc.summary = "The current value of the table variable."; break; } diff --git a/Editor/Descriptors/VariableGetUnitDescriptor.cs.meta b/Editor/Descriptors/GetVariableUnitDescriptor.cs.meta similarity index 83% rename from Editor/Descriptors/VariableGetUnitDescriptor.cs.meta rename to Editor/Descriptors/GetVariableUnitDescriptor.cs.meta index 79233ec..643c6c6 100644 --- a/Editor/Descriptors/VariableGetUnitDescriptor.cs.meta +++ b/Editor/Descriptors/GetVariableUnitDescriptor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9a2cd70bf3bbec240b902074eece32e4 +guid: 5692d07afb030ce4cae7363be616d4ff MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Descriptors/VariableIncreaseUnitDescriptor.cs b/Editor/Descriptors/IncreaseVariableUnitDescriptor.cs similarity index 74% rename from Editor/Descriptors/VariableIncreaseUnitDescriptor.cs rename to Editor/Descriptors/IncreaseVariableUnitDescriptor.cs index 1643525..93eddbb 100644 --- a/Editor/Descriptors/VariableIncreaseUnitDescriptor.cs +++ b/Editor/Descriptors/IncreaseVariableUnitDescriptor.cs @@ -20,10 +20,10 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Descriptor(typeof(PlayerVariableIncreaseUnit))] - public class PlayerVariableIncreaseUnitDescriptor : UnitDescriptor + [Descriptor(typeof(IncreasePlayerVariableUnit))] + public class IncreasePlayerVariableUnitDescriptor : UnitDescriptor { - public PlayerVariableIncreaseUnitDescriptor(PlayerVariableIncreaseUnit target) : base(target) + public IncreasePlayerVariableUnitDescriptor(IncreasePlayerVariableUnit target) : base(target) { } @@ -39,17 +39,17 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(PlayerVariableIncreaseUnit.Value): + case nameof(IncreasePlayerVariableUnit.Value): desc.summary = "The value to add to the existing value."; break; } } } - [Descriptor(typeof(TableVariableIncreaseUnit))] - public class TableVariableIncreaseUnitDescriptor : UnitDescriptor + [Descriptor(typeof(IncreaseTableVariableUnit))] + public class IncreaseTableVariableUnitDescriptor : UnitDescriptor { - public TableVariableIncreaseUnitDescriptor(TableVariableIncreaseUnit target) : base(target) + public IncreaseTableVariableUnitDescriptor(IncreaseTableVariableUnit target) : base(target) { } @@ -65,7 +65,7 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(TableVariableIncreaseUnit.Value): + case nameof(IncreaseTableVariableUnit.Value): desc.summary = "The value to add to the existing value."; break; } diff --git a/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs.meta b/Editor/Descriptors/IncreaseVariableUnitDescriptor.cs.meta similarity index 83% rename from Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs.meta rename to Editor/Descriptors/IncreaseVariableUnitDescriptor.cs.meta index d9095d8..9bb7cb1 100644 --- a/Editor/Descriptors/PlayerStateCreateUnitDescriptor.cs.meta +++ b/Editor/Descriptors/IncreaseVariableUnitDescriptor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5b366a38d0f35b5449719e64ced1938b +guid: 2d7e9d26e5a2b9245874e431b7a419ce MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Descriptors/SetLightUnitDescriptor.cs b/Editor/Descriptors/SetLampComponentUnitDescriptor.cs similarity index 81% rename from Editor/Descriptors/SetLightUnitDescriptor.cs rename to Editor/Descriptors/SetLampComponentUnitDescriptor.cs index f50d9d5..1e97bc0 100644 --- a/Editor/Descriptors/SetLightUnitDescriptor.cs +++ b/Editor/Descriptors/SetLampComponentUnitDescriptor.cs @@ -22,10 +22,10 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Descriptor(typeof(SetLightUnit))] - public class SetLightUnitDescriptor : UnitDescriptor + [Descriptor(typeof(SetLampComponentUnit))] + public class SetLampComponentUnitDescriptor : UnitDescriptor { - public SetLightUnitDescriptor(SetLightUnit target) : base(target) + public SetLampComponentUnitDescriptor(SetLampComponentUnit target) : base(target) { } @@ -41,15 +41,15 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(SetLightUnit.LampComponent): + case nameof(SetLampComponentUnit.LampComponent): desc.summary = "The light component whose value you want to change. Assigning a light group will change all lights in the group."; break; - case nameof(SetLightUnit.Value): + case nameof(SetLampComponentUnit.Value): desc.summary = "The intensity to apply (0-1)."; break; - case nameof(SetLightUnit.ColorChannel): + case nameof(SetLampComponentUnit.ColorChannel): desc.summary = "Which color channel to use. For non-RGB lights, use alpha."; break; } diff --git a/Editor/Descriptors/SetLampComponentUnitDescriptor.cs.meta b/Editor/Descriptors/SetLampComponentUnitDescriptor.cs.meta new file mode 100644 index 0000000..8602719 --- /dev/null +++ b/Editor/Descriptors/SetLampComponentUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6843a9d0a62de5548bdd314153e6780e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Descriptors/VariableSetUnitDescriptor.cs b/Editor/Descriptors/SetVariableUnitDescriptor.cs similarity index 76% rename from Editor/Descriptors/VariableSetUnitDescriptor.cs rename to Editor/Descriptors/SetVariableUnitDescriptor.cs index 07b4365..94cc47e 100644 --- a/Editor/Descriptors/VariableSetUnitDescriptor.cs +++ b/Editor/Descriptors/SetVariableUnitDescriptor.cs @@ -20,10 +20,10 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Descriptor(typeof(PlayerVariableSetUnit))] - public class PlayerVariableSetUnitDescriptor : UnitDescriptor + [Descriptor(typeof(SetPlayerVariableUnit))] + public class SetPlayerVariableUnitDescriptor : UnitDescriptor { - public PlayerVariableSetUnitDescriptor(PlayerVariableSetUnit target) : base(target) + public SetPlayerVariableUnitDescriptor(SetPlayerVariableUnit target) : base(target) { } @@ -39,17 +39,17 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(PlayerVariableSetUnit.Value): + case nameof(SetPlayerVariableUnit.Value): desc.summary = "The new value of the player variable."; break; } } } - [Descriptor(typeof(TableVariableSetUnit))] - public class TableVariableSetUnitDescriptor : UnitDescriptor + [Descriptor(typeof(SetTableVariableUnit))] + public class SetTableVariableUnitDescriptor : UnitDescriptor { - public TableVariableSetUnitDescriptor(TableVariableSetUnit target) : base(target) + public SetTableVariableUnitDescriptor(SetTableVariableUnit target) : base(target) { } @@ -65,7 +65,7 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(TableVariableSetUnit.Value): + case nameof(SetTableVariableUnit.Value): desc.summary = "The new value of the table variable."; break; } diff --git a/Editor/Descriptors/SetVariableUnitDescriptor.cs.meta b/Editor/Descriptors/SetVariableUnitDescriptor.cs.meta new file mode 100644 index 0000000..769832b --- /dev/null +++ b/Editor/Descriptors/SetVariableUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c6e91a4afe68844ebd38d53896e3ca4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Descriptors/VariableIncreaseUnitDescriptor.cs.meta b/Editor/Descriptors/VariableIncreaseUnitDescriptor.cs.meta deleted file mode 100644 index 3681797..0000000 --- a/Editor/Descriptors/VariableIncreaseUnitDescriptor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5dba1ea52bfa9724bb0e65ab8e0d5bae -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Descriptors/VariableSetUnitDescriptor.cs.meta b/Editor/Descriptors/VariableSetUnitDescriptor.cs.meta deleted file mode 100644 index 4e9a54f..0000000 --- a/Editor/Descriptors/VariableSetUnitDescriptor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: efddfac3f198bd441b263ca2dc1f17a3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Widgets/PlayerStateCreateUnitWidget.cs b/Editor/Widgets/ChangePlayerStateUnitWidget.cs similarity index 76% rename from Editor/Widgets/PlayerStateCreateUnitWidget.cs rename to Editor/Widgets/ChangePlayerStateUnitWidget.cs index 3692564..1a460fa 100644 --- a/Editor/Widgets/PlayerStateCreateUnitWidget.cs +++ b/Editor/Widgets/ChangePlayerStateUnitWidget.cs @@ -20,10 +20,10 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Widget(typeof(PlayerStateCreateUnit))] - public sealed class PlayerStateCreateUnitWidget : GleUnitWidget + [Widget(typeof(ChangePlayerStateUnit))] + public sealed class ChangePlayerStateUnitWidget : GleUnitWidget { - public PlayerStateCreateUnitWidget(FlowCanvas canvas, PlayerStateCreateUnit unit) : base(canvas, unit) + public ChangePlayerStateUnitWidget(FlowCanvas canvas, ChangePlayerStateUnit unit) : base(canvas, unit) { } } diff --git a/Editor/Widgets/ChangePlayerStateUnitWidget.cs.meta b/Editor/Widgets/ChangePlayerStateUnitWidget.cs.meta new file mode 100644 index 0000000..4c83cca --- /dev/null +++ b/Editor/Widgets/ChangePlayerStateUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fd85a3e9145ab0e4ab4da48948b23eb2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/PlayerStateChangeUnitWidget.cs b/Editor/Widgets/CreatePlayerStateUnitWidget.cs similarity index 76% rename from Editor/Widgets/PlayerStateChangeUnitWidget.cs rename to Editor/Widgets/CreatePlayerStateUnitWidget.cs index 5aef645..4f9ae05 100644 --- a/Editor/Widgets/PlayerStateChangeUnitWidget.cs +++ b/Editor/Widgets/CreatePlayerStateUnitWidget.cs @@ -20,10 +20,10 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Widget(typeof(PlayerStateChangeUnit))] - public sealed class PlayerStateChangeUnitWidget : GleUnitWidget + [Widget(typeof(CreatePlayerStateUnit))] + public sealed class CreatePlayerStateUnitWidget : GleUnitWidget { - public PlayerStateChangeUnitWidget(FlowCanvas canvas, PlayerStateChangeUnit unit) : base(canvas, unit) + public CreatePlayerStateUnitWidget(FlowCanvas canvas, CreatePlayerStateUnit unit) : base(canvas, unit) { } } diff --git a/Editor/Widgets/CreatePlayerStateUnitWidget.cs.meta b/Editor/Widgets/CreatePlayerStateUnitWidget.cs.meta new file mode 100644 index 0000000..3fb12e1 --- /dev/null +++ b/Editor/Widgets/CreatePlayerStateUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f5f89faf861c39f4eb877a19ee7944af +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/VariableSetUnitWidget.cs b/Editor/Widgets/GetVariableUnitWidget.cs similarity index 63% rename from Editor/Widgets/VariableSetUnitWidget.cs rename to Editor/Widgets/GetVariableUnitWidget.cs index 2aa58e1..ef7e0f3 100644 --- a/Editor/Widgets/VariableSetUnitWidget.cs +++ b/Editor/Widgets/GetVariableUnitWidget.cs @@ -20,18 +20,18 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Widget(typeof(PlayerVariableSetUnit))] - public sealed class PlayerVariableSetUnitWidget : GleUnitWidget + [Widget(typeof(GetPlayerVariableUnit))] + public sealed class GetPlayerVariableUnitWidget : GleUnitWidget { - public PlayerVariableSetUnitWidget(FlowCanvas canvas, PlayerVariableSetUnit unit) : base(canvas, unit) + public GetPlayerVariableUnitWidget(FlowCanvas canvas, GetPlayerVariableUnit unit) : base(canvas, unit) { } } - [Widget(typeof(TableVariableSetUnit))] - public sealed class TableVariableSetUnitWidget : GleUnitWidget + [Widget(typeof(GetTableVariableUnit))] + public sealed class GetTableVariableUnitWidget : GleUnitWidget { - public TableVariableSetUnitWidget(FlowCanvas canvas, TableVariableSetUnit unit) : base(canvas, unit) + public GetTableVariableUnitWidget(FlowCanvas canvas, GetTableVariableUnit unit) : base(canvas, unit) { } } diff --git a/Editor/Widgets/GetVariableUnitWidget.cs.meta b/Editor/Widgets/GetVariableUnitWidget.cs.meta new file mode 100644 index 0000000..ab8b8e0 --- /dev/null +++ b/Editor/Widgets/GetVariableUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5cfa006a94c6fbf46ae5d3b199a9603e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/VariableIncreaseUnitWidget.cs b/Editor/Widgets/IncreaseVariableUnitWidget.cs similarity index 61% rename from Editor/Widgets/VariableIncreaseUnitWidget.cs rename to Editor/Widgets/IncreaseVariableUnitWidget.cs index 160aff5..9d8766e 100644 --- a/Editor/Widgets/VariableIncreaseUnitWidget.cs +++ b/Editor/Widgets/IncreaseVariableUnitWidget.cs @@ -20,18 +20,18 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Widget(typeof(PlayerVariableIncreaseUnit))] - public sealed class PlayerVariableIncreaseUnitWidget : GleUnitWidget + [Widget(typeof(IncreasePlayerVariableUnit))] + public sealed class IncreasePlayerVariableUnitWidget : GleUnitWidget { - public PlayerVariableIncreaseUnitWidget(FlowCanvas canvas, PlayerVariableIncreaseUnit unit) : base(canvas, unit) + public IncreasePlayerVariableUnitWidget(FlowCanvas canvas, IncreasePlayerVariableUnit unit) : base(canvas, unit) { } } - [Widget(typeof(TableVariableIncreaseUnit))] - public sealed class TableVariableIncreaseUnitWidget : GleUnitWidget + [Widget(typeof(IncreaseTableVariableUnit))] + public sealed class IncreaseTableVariableUnitWidget : GleUnitWidget { - public TableVariableIncreaseUnitWidget(FlowCanvas canvas, TableVariableIncreaseUnit unit) : base(canvas, unit) + public IncreaseTableVariableUnitWidget(FlowCanvas canvas, IncreaseTableVariableUnit unit) : base(canvas, unit) { } } diff --git a/Editor/Widgets/IncreaseVariableUnitWidget.cs.meta b/Editor/Widgets/IncreaseVariableUnitWidget.cs.meta new file mode 100644 index 0000000..3703573 --- /dev/null +++ b/Editor/Widgets/IncreaseVariableUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2d12ac9db2285cd408046a05dfba71b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/PlayerStateChangeUnitWidget.cs.meta b/Editor/Widgets/PlayerStateChangeUnitWidget.cs.meta deleted file mode 100644 index f6a00c7..0000000 --- a/Editor/Widgets/PlayerStateChangeUnitWidget.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 016523a0c515dde429e154cca811d244 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Widgets/PlayerStateCreateUnitWidget.cs.meta b/Editor/Widgets/PlayerStateCreateUnitWidget.cs.meta deleted file mode 100644 index f78a25d..0000000 --- a/Editor/Widgets/PlayerStateCreateUnitWidget.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6c279332e7dd3fe4eaa8c0e801e20fbb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Widgets/SetLightUnitWidget.cs b/Editor/Widgets/SetLampComponentUnitWidget.cs similarity index 84% rename from Editor/Widgets/SetLightUnitWidget.cs rename to Editor/Widgets/SetLampComponentUnitWidget.cs index 45233d0..759991f 100644 --- a/Editor/Widgets/SetLightUnitWidget.cs +++ b/Editor/Widgets/SetLampComponentUnitWidget.cs @@ -21,13 +21,13 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Widget(typeof(SetLightUnit))] - public sealed class SetLightUnitWidget : GleUnitWidget + [Widget(typeof(SetLampComponentUnit))] + public sealed class SetLampComponentUnitWidget : GleUnitWidget { private ObjectPickerInspector _objectInspector; private readonly Func> _setObjectInspectorConstructor; - public SetLightUnitWidget(FlowCanvas canvas, SetLightUnit unit) : base(canvas, unit) + public SetLampComponentUnitWidget(FlowCanvas canvas, SetLampComponentUnit unit) : base(canvas, unit) { var tc = reference.gameObject.GetComponentInParent(); _setObjectInspectorConstructor = meta => new ObjectPickerInspector(meta, "Lamps", tc); diff --git a/Editor/Widgets/SetLampComponentUnitWidget.cs.meta b/Editor/Widgets/SetLampComponentUnitWidget.cs.meta new file mode 100644 index 0000000..a3b95ad --- /dev/null +++ b/Editor/Widgets/SetLampComponentUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f291d79296189034489ec69582d06d41 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/SetLightUnitWidget.cs.meta b/Editor/Widgets/SetLightUnitWidget.cs.meta deleted file mode 100644 index 6b81dce..0000000 --- a/Editor/Widgets/SetLightUnitWidget.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7df567d7db6847548a21f012b1118cd2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Widgets/VariableGetUnitWidget.cs b/Editor/Widgets/SetVariableUnitWidget.cs similarity index 63% rename from Editor/Widgets/VariableGetUnitWidget.cs rename to Editor/Widgets/SetVariableUnitWidget.cs index de81cc1..cf6609a 100644 --- a/Editor/Widgets/VariableGetUnitWidget.cs +++ b/Editor/Widgets/SetVariableUnitWidget.cs @@ -20,18 +20,18 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Widget(typeof(PlayerVariableGetUnit))] - public sealed class PlayerVariableGetUnitWidget : GleUnitWidget + [Widget(typeof(SetPlayerVariableUnit))] + public sealed class SetPlayerVariableUnitWidget : GleUnitWidget { - public PlayerVariableGetUnitWidget(FlowCanvas canvas, PlayerVariableGetUnit unit) : base(canvas, unit) + public SetPlayerVariableUnitWidget(FlowCanvas canvas, SetPlayerVariableUnit unit) : base(canvas, unit) { } } - [Widget(typeof(TableVariableGetUnit))] - public sealed class TableVariableGetUnitWidget : GleUnitWidget + [Widget(typeof(SetTableVariableUnit))] + public sealed class SetTableVariableUnitWidget : GleUnitWidget { - public TableVariableGetUnitWidget(FlowCanvas canvas, TableVariableGetUnit unit) : base(canvas, unit) + public SetTableVariableUnitWidget(FlowCanvas canvas, SetTableVariableUnit unit) : base(canvas, unit) { } } diff --git a/Editor/Widgets/SetVariableUnitWidget.cs.meta b/Editor/Widgets/SetVariableUnitWidget.cs.meta new file mode 100644 index 0000000..fc7991b --- /dev/null +++ b/Editor/Widgets/SetVariableUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e8a3a02b5f6b414795248941a42d19a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/VariableGetUnitWidget.cs.meta b/Editor/Widgets/VariableGetUnitWidget.cs.meta deleted file mode 100644 index ef36586..0000000 --- a/Editor/Widgets/VariableGetUnitWidget.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cd079d4a7c9a6b245820db7202f456b6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Widgets/VariableIncreaseUnitWidget.cs.meta b/Editor/Widgets/VariableIncreaseUnitWidget.cs.meta deleted file mode 100644 index bf749c3..0000000 --- a/Editor/Widgets/VariableIncreaseUnitWidget.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6682642f34160194b8673d2c03a5736b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Widgets/VariableSetUnitWidget.cs.meta b/Editor/Widgets/VariableSetUnitWidget.cs.meta deleted file mode 100644 index 53c825c..0000000 --- a/Editor/Widgets/VariableSetUnitWidget.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4769b0eb13d593040abd66e817dcada5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/Lamps/SetLightUnit.cs b/Runtime/Nodes/Lamps/SetLampComponentUnit.cs similarity index 94% rename from Runtime/Nodes/Lamps/SetLightUnit.cs rename to Runtime/Nodes/Lamps/SetLampComponentUnit.cs index f899bc4..6d43537 100644 --- a/Runtime/Nodes/Lamps/SetLightUnit.cs +++ b/Runtime/Nodes/Lamps/SetLampComponentUnit.cs @@ -24,7 +24,7 @@ namespace VisualPinball.Unity.VisualScripting [UnitShortTitle("Set Lamp")] [UnitSurtitle("Scene")] [UnitCategory("Visual Pinball")] - public class SetLightUnit : GleUnit + public class SetLampComponentUnit : GleUnit { [DoNotSerialize] [PortLabelHidden] diff --git a/Runtime/Nodes/Lamps/SetLampComponentUnit.cs.meta b/Runtime/Nodes/Lamps/SetLampComponentUnit.cs.meta new file mode 100644 index 0000000..5c4bf53 --- /dev/null +++ b/Runtime/Nodes/Lamps/SetLampComponentUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 40170555ebd5580468c2a20163c10954 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Lamps/SetLightUnit.cs.meta b/Runtime/Nodes/Lamps/SetLightUnit.cs.meta deleted file mode 100644 index db927d6..0000000 --- a/Runtime/Nodes/Lamps/SetLightUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6df211a440aa1004e8ec3774ca529cd2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs b/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs similarity index 94% rename from Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs rename to Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs index 2a4881a..d250a3b 100644 --- a/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs +++ b/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs @@ -23,7 +23,7 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("Change Player State")] [UnitSurtitle("Player State")] [UnitCategory("Visual Pinball/Variables")] - public class PlayerStateChangeUnit : GleUnit + public class ChangePlayerStateUnit : GleUnit { [DoNotSerialize] [PortLabelHidden] diff --git a/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs.meta b/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs.meta new file mode 100644 index 0000000..6051dab --- /dev/null +++ b/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ce86bae940d6e24c96620a150f330cc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs b/Runtime/Nodes/PlayerState/CreatePlayerStateUnit.cs similarity index 94% rename from Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs rename to Runtime/Nodes/PlayerState/CreatePlayerStateUnit.cs index c7f7ad7..d43b251 100644 --- a/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs +++ b/Runtime/Nodes/PlayerState/CreatePlayerStateUnit.cs @@ -1,84 +1,84 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using System.Linq; -using Unity.VisualScripting; - -namespace VisualPinball.Unity.VisualScripting -{ - [UnitTitle("Create Player State")] - [UnitSurtitle("Player State")] - [UnitCategory("Visual Pinball/Variables")] - public class PlayerStateCreateUnit : GleUnit - { - [Serialize, Inspectable, UnitHeaderInspectable("Auto-increment")] - public bool AutoIncrement { get; set; } - - [DoNotSerialize] - [PortLabelHidden] - public ControlInput InputTrigger; - - [DoNotSerialize] - [PortLabelHidden] - public ControlOutput OutputTrigger; - - [DoNotSerialize] - [PortLabel("Player ID")] - public ValueInput PlayerId { get; private set; } - - [DoNotSerialize] - [PortLabel("Set as Active")] - public ValueInput SetAsActive { get; set; } - - protected override void Definition() - { - InputTrigger = ControlInput(nameof(InputTrigger), Process); - OutputTrigger = ControlOutput(nameof(OutputTrigger)); - - if (!AutoIncrement) { - PlayerId = ValueInput(nameof(PlayerId), 0); - Requirement(PlayerId, InputTrigger); - } - - SetAsActive = ValueInput(nameof(SetAsActive), false); - - Succession(InputTrigger, OutputTrigger); - } - - private ControlOutput Process(Flow flow) - { - if (!AssertVsGle(flow)) { - throw new InvalidOperationException("Cannot retrieve GLE from unit."); - } - - // determine new player id - var newPlayerId = AutoIncrement && VsGle.PlayerStates.Count > 0 - ? VsGle.PlayerStates.Keys.Max() + 1 - : VsGle.PlayerStates.Count == 0 ? 0 : flow.GetValue(PlayerId); - - // create new state - VsGle.CreatePlayerState(newPlayerId); - - // set as active - if (flow.GetValue(SetAsActive)) { - VsGle.CurrentPlayer = newPlayerId; - } - - return OutputTrigger; - } - } -} +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Create Player State")] + [UnitSurtitle("Player State")] + [UnitCategory("Visual Pinball/Variables")] + public class CreatePlayerStateUnit : GleUnit + { + [Serialize, Inspectable, UnitHeaderInspectable("Auto-increment")] + public bool AutoIncrement { get; set; } + + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + + [DoNotSerialize] + [PortLabel("Player ID")] + public ValueInput PlayerId { get; private set; } + + [DoNotSerialize] + [PortLabel("Set as Active")] + public ValueInput SetAsActive { get; set; } + + protected override void Definition() + { + InputTrigger = ControlInput(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + if (!AutoIncrement) { + PlayerId = ValueInput(nameof(PlayerId), 0); + Requirement(PlayerId, InputTrigger); + } + + SetAsActive = ValueInput(nameof(SetAsActive), false); + + Succession(InputTrigger, OutputTrigger); + } + + private ControlOutput Process(Flow flow) + { + if (!AssertVsGle(flow)) { + throw new InvalidOperationException("Cannot retrieve GLE from unit."); + } + + // determine new player id + var newPlayerId = AutoIncrement && VsGle.PlayerStates.Count > 0 + ? VsGle.PlayerStates.Keys.Max() + 1 + : VsGle.PlayerStates.Count == 0 ? 0 : flow.GetValue(PlayerId); + + // create new state + VsGle.CreatePlayerState(newPlayerId); + + // set as active + if (flow.GetValue(SetAsActive)) { + VsGle.CurrentPlayer = newPlayerId; + } + + return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/PlayerState/CreatePlayerStateUnit.cs.meta b/Runtime/Nodes/PlayerState/CreatePlayerStateUnit.cs.meta new file mode 100644 index 0000000..6789ed6 --- /dev/null +++ b/Runtime/Nodes/PlayerState/CreatePlayerStateUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 49dce4f81de192943af7fd6302c70c8e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/VariableGetUnit.cs b/Runtime/Nodes/PlayerState/GetVariableUnit.cs similarity index 92% rename from Runtime/Nodes/PlayerState/VariableGetUnit.cs rename to Runtime/Nodes/PlayerState/GetVariableUnit.cs index 25abf7f..7a46ef3 100644 --- a/Runtime/Nodes/PlayerState/VariableGetUnit.cs +++ b/Runtime/Nodes/PlayerState/GetVariableUnit.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("Get Player Variable")] [UnitSurtitle("Player State")] [UnitCategory("Visual Pinball/Variables")] - public class PlayerVariableGetUnit : VariableGetUnit + public class GetPlayerVariableUnit : GetVariableUnit { [Serialize, Inspectable, UnitHeaderInspectable] public PlayerVariableDefinition Variable { get; set; } @@ -34,7 +34,7 @@ public class PlayerVariableGetUnit : VariableGetUnit [UnitTitle("Get Table Variable")] [UnitSurtitle("Table State")] [UnitCategory("Visual Pinball/Variables")] - public class TableVariableGetUnit : VariableGetUnit + public class GetTableVariableUnit : GetVariableUnit { [Serialize, Inspectable, UnitHeaderInspectable] public TableVariableDefinition Variable { get; set; } @@ -43,7 +43,7 @@ public class TableVariableGetUnit : VariableGetUnit protected override State State => VsGle.TableState; } - public abstract class VariableGetUnit : GleUnit + public abstract class GetVariableUnit : GleUnit { [DoNotSerialize, PortLabel("Value"), Inspectable] public ValueOutput Value { get; private set; } diff --git a/Runtime/Nodes/PlayerState/GetVariableUnit.cs.meta b/Runtime/Nodes/PlayerState/GetVariableUnit.cs.meta new file mode 100644 index 0000000..58f517f --- /dev/null +++ b/Runtime/Nodes/PlayerState/GetVariableUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8308019eab154104b8ba31ce6e500090 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs b/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs similarity index 91% rename from Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs rename to Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs index 32d3ecd..4a69df9 100644 --- a/Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs +++ b/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("Increase Player Variable")] [UnitSurtitle("Player State")] [UnitCategory("Visual Pinball/Variables")] - public class PlayerVariableIncreaseUnit : VariableIncreaseUnit + public class IncreasePlayerVariableUnit : IncreaseVariableUnit { [Serialize, Inspectable, UnitHeaderInspectable] public PlayerVariableDefinition Variable { get; set; } @@ -34,7 +34,7 @@ public class PlayerVariableIncreaseUnit : VariableIncreaseUnit [UnitTitle("Increase Table Variable")] [UnitSurtitle("Table State")] [UnitCategory("Visual Pinball/Variables")] - public class TableVariableIncreaseUnit : VariableIncreaseUnit + public class IncreaseTableVariableUnit : IncreaseVariableUnit { [Serialize, Inspectable, UnitHeaderInspectable] public TableVariableDefinition Variable { get; set; } @@ -43,7 +43,7 @@ public class TableVariableIncreaseUnit : VariableIncreaseUnit protected override VariableDefinition VariableDefinition => Variable; } - public abstract class VariableIncreaseUnit : GleUnit + public abstract class IncreaseVariableUnit : GleUnit { [DoNotSerialize, PortLabelHidden] public ControlInput InputTrigger; diff --git a/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs.meta b/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs.meta new file mode 100644 index 0000000..7f1c027 --- /dev/null +++ b/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5cafbd98b8fb37445857dae9786b4801 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs.meta deleted file mode 100644 index c6f9b8c..0000000 --- a/Runtime/Nodes/PlayerState/PlayerStateChangeUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3de30daf34bec214eb96ac39398fbc19 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs.meta b/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs.meta deleted file mode 100644 index d8edede..0000000 --- a/Runtime/Nodes/PlayerState/PlayerStateCreateUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f58bc7f875f7f7446ae915edfeeb9203 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/VariableSetUnit.cs b/Runtime/Nodes/PlayerState/SetVariableUnit.cs similarity index 92% rename from Runtime/Nodes/PlayerState/VariableSetUnit.cs rename to Runtime/Nodes/PlayerState/SetVariableUnit.cs index 57408ec..b3e515c 100644 --- a/Runtime/Nodes/PlayerState/VariableSetUnit.cs +++ b/Runtime/Nodes/PlayerState/SetVariableUnit.cs @@ -23,7 +23,7 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("Set Player Variable")] [UnitSurtitle("Player State")] [UnitCategory("Visual Pinball/Variables")] - public class PlayerVariableSetUnit : VariableSetUnit + public class SetPlayerVariableUnit : SetVariableUnit { [Serialize, Inspectable, UnitHeaderInspectable] public PlayerVariableDefinition Variable { get; set; } @@ -35,7 +35,7 @@ public class PlayerVariableSetUnit : VariableSetUnit [UnitTitle("Set Table Variable")] [UnitSurtitle("Table State")] [UnitCategory("Visual Pinball/Variables")] - public class TableVariableSetUnit : VariableSetUnit + public class SetTableVariableUnit : SetVariableUnit { [Serialize, Inspectable, UnitHeaderInspectable] public TableVariableDefinition Variable { get; set; } @@ -44,7 +44,7 @@ public class TableVariableSetUnit : VariableSetUnit protected override VariableDefinition VariableDefinition => Variable; } - public abstract class VariableSetUnit : GleUnit + public abstract class SetVariableUnit : GleUnit { [DoNotSerialize, PortLabelHidden] public ControlInput InputTrigger; diff --git a/Runtime/Nodes/PlayerState/SetVariableUnit.cs.meta b/Runtime/Nodes/PlayerState/SetVariableUnit.cs.meta new file mode 100644 index 0000000..430ec06 --- /dev/null +++ b/Runtime/Nodes/PlayerState/SetVariableUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a525259e500cec348a2b697b863409bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/VariableGetUnit.cs.meta b/Runtime/Nodes/PlayerState/VariableGetUnit.cs.meta deleted file mode 100644 index 82fda92..0000000 --- a/Runtime/Nodes/PlayerState/VariableGetUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3eff501f75250d34c92e0a81f24dab94 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs.meta b/Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs.meta deleted file mode 100644 index a01fb64..0000000 --- a/Runtime/Nodes/PlayerState/VariableIncreaseUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d1467aed8a0856f45a8c12d8baf151c2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/VariableSetUnit.cs.meta b/Runtime/Nodes/PlayerState/VariableSetUnit.cs.meta deleted file mode 100644 index 83592fd..0000000 --- a/Runtime/Nodes/PlayerState/VariableSetUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0d5aa3398e6736d4faad20bca3138c45 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From c8ceeb0ea7a1114ed06601b0fc18e40612a61ab3 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 3 Feb 2022 23:20:49 +0100 Subject: [PATCH 16/54] Add node for toggling lights. --- .../SetLampEnabledUnitDescriptor.cs | 53 ++++++++++++++ .../SetLampEnabledUnitDescriptor.cs.meta | 11 +++ Editor/Widgets/SetLampEnabledUnitWidget.cs | 56 +++++++++++++++ .../Widgets/SetLampEnabledUnitWidget.cs.meta | 11 +++ Runtime/Nodes/Lamps/SetLampEnabledUnit.cs | 71 +++++++++++++++++++ .../Nodes/Lamps/SetLampEnabledUnit.cs.meta | 11 +++ Runtime/Nodes/Lamps/SetLampUnit.cs | 2 +- 7 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 Editor/Descriptors/SetLampEnabledUnitDescriptor.cs create mode 100644 Editor/Descriptors/SetLampEnabledUnitDescriptor.cs.meta create mode 100644 Editor/Widgets/SetLampEnabledUnitWidget.cs create mode 100644 Editor/Widgets/SetLampEnabledUnitWidget.cs.meta create mode 100644 Runtime/Nodes/Lamps/SetLampEnabledUnit.cs create mode 100644 Runtime/Nodes/Lamps/SetLampEnabledUnit.cs.meta diff --git a/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs b/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs new file mode 100644 index 0000000..0798b1d --- /dev/null +++ b/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs @@ -0,0 +1,53 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; +using VisualPinball.Unity.Editor; +using IconSize = VisualPinball.Unity.Editor.IconSize; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(SetLampEnabledUnit))] + public class SetLampEnabledUnitDescriptor : UnitDescriptor + { + public SetLampEnabledUnitDescriptor(SetLampEnabledUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node turns a lamp defined by its mapped ID on or off."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Light(IconSize.Large, IconColor.Orange)); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(SetLampEnabledUnit.Id): + desc.summary = "The ID of the lamp to toggle."; + break; + case nameof(SetLampEnabledUnit.IsEnabled): + desc.summary = "Whether to turn on or off."; + break; + } + } + } +} diff --git a/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs.meta b/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs.meta new file mode 100644 index 0000000..b96f91f --- /dev/null +++ b/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 69273ae986e7721468526571a67857cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/SetLampEnabledUnitWidget.cs b/Editor/Widgets/SetLampEnabledUnitWidget.cs new file mode 100644 index 0000000..9b06492 --- /dev/null +++ b/Editor/Widgets/SetLampEnabledUnitWidget.cs @@ -0,0 +1,56 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(SetLampEnabledUnit))] + public sealed class SetLampEnabledUnitWidget : GleUnitWidget + { + private VariableNameInspector _lampIdInspector; + private readonly Func _setLampInspectorConstructor; + + public SetLampEnabledUnitWidget(FlowCanvas canvas, SetLampEnabledUnit unit) : base(canvas, unit) + { + _setLampInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + } + + public override Inspector GetPortInspector(IUnitPort port, Metadata meta) + { + if (port == unit.Id) { + InspectorProvider.instance.Renew(ref _lampIdInspector, meta, _setLampInspectorConstructor); + return _lampIdInspector; + } + + return base.GetPortInspector(port, meta); + } + + private IEnumerable GetNameSuggestions() + { + if (!GameObjectAvailable) { + return new List(); + } + var gle = Gle; + return gle == null ? new List() : gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); + } + } +} diff --git a/Editor/Widgets/SetLampEnabledUnitWidget.cs.meta b/Editor/Widgets/SetLampEnabledUnitWidget.cs.meta new file mode 100644 index 0000000..7bdb300 --- /dev/null +++ b/Editor/Widgets/SetLampEnabledUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 17c418e0eddfad24bbdad8eed199a493 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs b/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs new file mode 100644 index 0000000..dddaf8a --- /dev/null +++ b/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs @@ -0,0 +1,71 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitShortTitle("Set Lamp")] + [UnitTitle("Set Lamp (ID, on/off)")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Visual Pinball")] + public class SetLampEnabledUnit : GleUnit + { + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + + [DoNotSerialize] + [PortLabel("Lamp ID")] + public ValueInput Id { get; private set; } + + [DoNotSerialize] + [PortLabel("Is Enabled")] + public ValueInput IsEnabled { get; private set; } + + protected override void Definition() + { + InputTrigger = ControlInput(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + Id = ValueInput(nameof(Id), string.Empty); + IsEnabled = ValueInput(nameof(IsEnabled), false); + + Requirement(Id, InputTrigger); + Succession(InputTrigger, OutputTrigger); + } + + private ControlOutput Process(Flow flow) + { + if (!AssertGle(flow)) { + Debug.LogError("Cannot find GLE."); + return OutputTrigger; + } + + var id = flow.GetValue(Id); + var isEnabled = flow.GetValue(IsEnabled); + + Gle.SetLamp(id, isEnabled ? 255f : 0f); + + return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs.meta b/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs.meta new file mode 100644 index 0000000..bddd5bb --- /dev/null +++ b/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1cbbd5a69057dc1468a14b70495fa46a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Lamps/SetLampUnit.cs b/Runtime/Nodes/Lamps/SetLampUnit.cs index 97754f3..0e233ec 100644 --- a/Runtime/Nodes/Lamps/SetLampUnit.cs +++ b/Runtime/Nodes/Lamps/SetLampUnit.cs @@ -20,7 +20,7 @@ namespace VisualPinball.Unity.VisualScripting { [UnitShortTitle("Set Lamp")] - [UnitTitle("Set Lamp (ID, Value)")] + [UnitTitle("Set Lamp (ID, Intensity)")] [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Visual Pinball")] public class SetLampUnit : GleUnit From d29eb7cc3e2d5624e41e80d21febd8249ef6911f Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 4 Feb 2022 00:03:21 +0100 Subject: [PATCH 17/54] gle: Fix table variable errors. --- .../VisualScriptingGamelogicEngineInspector.cs | 18 +++++++++--------- .../VisualScriptingGamelogicEngine.cs | 4 ++++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs b/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs index ced4847..b441103 100644 --- a/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs +++ b/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs @@ -66,7 +66,7 @@ public override void OnInspectorGUI() } EditorGUILayout.TextField("Table Variables", new GUIStyle(EditorStyles.boldLabel)); - PrintState(_gle.TableState); + PrintState(_gle.TableState, _gle.TableVariableDefinitions); if (_gle.PlayerStates.Count == 0) { EditorGUILayout.HelpBox("No player states created.", MessageType.Info); @@ -80,21 +80,21 @@ public override void OnInspectorGUI() } if (_playerVarFoldout[playerId] = EditorGUILayout.BeginFoldoutHeaderGroup(_playerVarFoldout[playerId], $"Player {playerId}")) { EditorGUI.indentLevel++; - PrintState(_gle.PlayerStates[playerId]); + + if (_gle.CurrentPlayerState == _gle.PlayerStates[playerId]) { + EditorGUILayout.HelpBox("Current Player", MessageType.Info); + } + + PrintState(_gle.PlayerStates[playerId], _gle.PlayerVariableDefinitions); EditorGUI.indentLevel--; } EditorGUILayout.EndFoldoutHeaderGroup(); } } - private void PrintState(State state) + private static void PrintState(State state, IEnumerable definitions) { - - if (_gle.CurrentPlayerState == state) { - EditorGUILayout.HelpBox("Current Player", MessageType.Info); - } - - foreach (var varDef in _gle.PlayerVariableDefinitions) { + foreach (var varDef in definitions) { EditorGUILayout.LabelField(varDef.Name, state.Get(varDef.Id).ToString()); } } diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index 26e7582..e53156b 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -118,6 +118,10 @@ public void OnInit(Player player, TableApi tableApi, BallManager ballManager) _player = player; BallManager = ballManager; + // create table variables + foreach (var propertyDefinition in TableVariableDefinitions) { + TableState.AddProperty(propertyDefinition.Instantiate()); + } OnStarted?.Invoke(this, EventArgs.Empty); EventBus.Trigger(VisualScriptingEventNames.GleStartedEvent, EventArgs.Empty); } From 48b9424bdba6edc065933316bd4889b81307ddd6 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 4 Feb 2022 00:41:47 +0100 Subject: [PATCH 18/54] fix: Retrieve table and GLE globally instead from reference. --- Editor/Widgets/GetLampUnitWidget.cs | 8 +++---- Editor/Widgets/GetSwitchUnitWidget.cs | 8 +++---- Editor/Widgets/GleUnitWidget.cs | 22 ++++++++++--------- Editor/Widgets/LampEventUnitWidget.cs | 8 +++---- Editor/Widgets/PulseCoilUnitWidget.cs | 8 +++---- Editor/Widgets/SetCoilUnitWidget.cs | 8 +++---- Editor/Widgets/SetLampEnabledUnitWidget.cs | 8 +++---- Editor/Widgets/SetLampUnitWidget.cs | 8 +++---- .../Widgets/SwitchEnabledEventUnitWidget.cs | 8 +++---- Editor/Widgets/SwitchEventUnitWidget.cs | 8 +++---- 10 files changed, 39 insertions(+), 55 deletions(-) diff --git a/Editor/Widgets/GetLampUnitWidget.cs b/Editor/Widgets/GetLampUnitWidget.cs index 4929af3..113e2d3 100644 --- a/Editor/Widgets/GetLampUnitWidget.cs +++ b/Editor/Widgets/GetLampUnitWidget.cs @@ -47,11 +47,9 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) private IEnumerable GetNameSuggestions() { - if (!GameObjectAvailable) { - return new List(); - } - var gle = Gle; - return gle == null ? new List() : gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); + return !GleAvailable + ? new List() + : Gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); } } } diff --git a/Editor/Widgets/GetSwitchUnitWidget.cs b/Editor/Widgets/GetSwitchUnitWidget.cs index 19090d0..4a384ff 100644 --- a/Editor/Widgets/GetSwitchUnitWidget.cs +++ b/Editor/Widgets/GetSwitchUnitWidget.cs @@ -55,11 +55,9 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) private IEnumerable GetNameSuggestions() { - if (!GameObjectAvailable) { - return new List(); - } - var gle = Gle; - return gle == null ? new List() : gle.AvailableSwitches.Select(sw => sw.Id).ToList(); + return !GleAvailable + ? new List() + : Gle.AvailableSwitches.Select(sw => sw.Id).ToList(); } } } diff --git a/Editor/Widgets/GleUnitWidget.cs b/Editor/Widgets/GleUnitWidget.cs index 3e82515..89bb19d 100644 --- a/Editor/Widgets/GleUnitWidget.cs +++ b/Editor/Widgets/GleUnitWidget.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using Unity.VisualScripting; +using UnityEngine; namespace VisualPinball.Unity.VisualScripting.Editor { @@ -30,19 +31,20 @@ public static class GleUnitWidget public abstract class GleUnitWidget : UnitWidget where TUnit : Unit, IGleUnit { protected override NodeColorMix baseColor => GleAvailable ? GleUnitWidget.Color : NodeColor.Red; - protected bool GameObjectAvailable => reference != null && reference.gameObject != null; - protected IGamelogicEngine Gle => reference.gameObject.GetComponentInParent(); - protected VisualScriptingGamelogicEngine VsGle => reference.gameObject.GetComponentInParent(); - private bool GleAvailable => GameObjectAvailable && Gle != null; - private bool VsGleAvailable => GameObjectAvailable && VsGle != null; + protected IGamelogicEngine Gle; + protected VisualScriptingGamelogicEngine VsGle; + protected bool GleAvailable => Gle != null; + protected bool VsGleAvailable => VsGle != null; protected GleUnitWidget(FlowCanvas canvas, TUnit unit) : base(canvas, unit) { - if (!GameObjectAvailable) { - unit.Errors.Add("Not attached to GameObject. You need to attach this graph to a flow machine sitting on a GameObject in order to use it."); - - } else if (!GleAvailable) { - unit.Errors.Add("No gamelogic engine found. One of the GameObject's parents must have a gamelogic engine component."); + var table = TableSelector.Instance.SelectedOrFirstTable; + if (table != null) { + Gle = table.GetComponentInChildren(); + VsGle = table.GetComponentInChildren(); + } + if (!GleAvailable) { + Debug.LogError($"Cannot find GLE for {GetType()}."); } } } diff --git a/Editor/Widgets/LampEventUnitWidget.cs b/Editor/Widgets/LampEventUnitWidget.cs index 09aa9f3..4f86ed4 100644 --- a/Editor/Widgets/LampEventUnitWidget.cs +++ b/Editor/Widgets/LampEventUnitWidget.cs @@ -47,12 +47,10 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) private IEnumerable GetNameSuggestions() { - if (!GameObjectAvailable) { - return new List(); - } + return !GleAvailable + ? new List() + : Gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); - var gle = Gle; - return gle == null ? new List() : gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); } } } diff --git a/Editor/Widgets/PulseCoilUnitWidget.cs b/Editor/Widgets/PulseCoilUnitWidget.cs index 6e33904..50ab4db 100644 --- a/Editor/Widgets/PulseCoilUnitWidget.cs +++ b/Editor/Widgets/PulseCoilUnitWidget.cs @@ -55,11 +55,9 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) private IEnumerable GetNameSuggestions() { - if (!GameObjectAvailable) { - return new List(); - } - var gle = Gle; - return gle == null ? new List() : gle.AvailableCoils.Select(coil => coil.Id).ToList(); + return !GleAvailable + ? new List() + : Gle.AvailableCoils.Select(coil => coil.Id).ToList(); } } } diff --git a/Editor/Widgets/SetCoilUnitWidget.cs b/Editor/Widgets/SetCoilUnitWidget.cs index 788dcc4..0b6ca6a 100644 --- a/Editor/Widgets/SetCoilUnitWidget.cs +++ b/Editor/Widgets/SetCoilUnitWidget.cs @@ -55,11 +55,9 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) private IEnumerable GetNameSuggestions() { - if (!GameObjectAvailable) { - return new List(); - } - var gle = Gle; - return gle == null ? new List() : gle.AvailableCoils.Select(coil => coil.Id).ToList(); + return !GleAvailable + ? new List() + : Gle.AvailableCoils.Select(coil => coil.Id).ToList(); } } } diff --git a/Editor/Widgets/SetLampEnabledUnitWidget.cs b/Editor/Widgets/SetLampEnabledUnitWidget.cs index 9b06492..ce4efb3 100644 --- a/Editor/Widgets/SetLampEnabledUnitWidget.cs +++ b/Editor/Widgets/SetLampEnabledUnitWidget.cs @@ -46,11 +46,9 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) private IEnumerable GetNameSuggestions() { - if (!GameObjectAvailable) { - return new List(); - } - var gle = Gle; - return gle == null ? new List() : gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); + return !GleAvailable + ? new List() + : Gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); } } } diff --git a/Editor/Widgets/SetLampUnitWidget.cs b/Editor/Widgets/SetLampUnitWidget.cs index 32ab8c0..e8fc460 100644 --- a/Editor/Widgets/SetLampUnitWidget.cs +++ b/Editor/Widgets/SetLampUnitWidget.cs @@ -46,11 +46,9 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) private IEnumerable GetNameSuggestions() { - if (!GameObjectAvailable) { - return new List(); - } - var gle = Gle; - return gle == null ? new List() : gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); + return !GleAvailable + ? new List() + : Gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); } } } diff --git a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs index 0c1abef..50ebfb3 100644 --- a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs @@ -55,11 +55,9 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) private IEnumerable GetNameSuggestions() { - if (!GameObjectAvailable) { - return new List(); - } - var gle = Gle; - return gle == null ? new List() : gle.AvailableSwitches.Select(sw => sw.Id).ToList(); + return !GleAvailable + ? new List() + : Gle.AvailableSwitches.Select(sw => sw.Id).ToList(); } } } diff --git a/Editor/Widgets/SwitchEventUnitWidget.cs b/Editor/Widgets/SwitchEventUnitWidget.cs index 538e8da..0be4719 100644 --- a/Editor/Widgets/SwitchEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEventUnitWidget.cs @@ -47,11 +47,9 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) private IEnumerable GetNameSuggestions() { - if (!GameObjectAvailable) { - return new List(); - } - var gle = Gle; - return gle == null ? new List() : gle.AvailableSwitches.Select(sw => sw.Id).ToList(); + return !GleAvailable + ? new List() + : Gle.AvailableSwitches.Select(sw => sw.Id).ToList(); } } } From d7c59854e92d931c2bec1d83e51da0e3b4ba2923 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 4 Feb 2022 01:13:14 +0100 Subject: [PATCH 19/54] gle: Fix state notifications. --- .../CreatePlayerStateUnitDescriptor.cs | 3 ++ .../IncreaseVariableUnitDescriptor.cs | 6 +++ .../Descriptors/SetVariableUnitDescriptor.cs | 7 +++ Editor/Widgets/GetSwitchUnitWidget.cs | 1 + Runtime/Gamelogic/State.cs | 2 + Runtime/Gamelogic/StateVariable.cs | 47 ++++++++++++++++++- .../VisualScriptingGamelogicEngine.cs | 43 ++++++++++++----- .../PlayerState/ChangePlayerStateUnit.cs | 2 +- .../PlayerState/CreatePlayerStateUnit.cs | 12 ++++- .../Nodes/PlayerState/IncreaseVariableUnit.cs | 14 +++++- Runtime/Nodes/PlayerState/SetVariableUnit.cs | 15 ++++++ 11 files changed, 135 insertions(+), 17 deletions(-) diff --git a/Editor/Descriptors/CreatePlayerStateUnitDescriptor.cs b/Editor/Descriptors/CreatePlayerStateUnitDescriptor.cs index ad1b533..f87522d 100644 --- a/Editor/Descriptors/CreatePlayerStateUnitDescriptor.cs +++ b/Editor/Descriptors/CreatePlayerStateUnitDescriptor.cs @@ -48,6 +48,9 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) case nameof(CreatePlayerStateUnit.SetAsActive): desc.summary = "If set, the new state will be the current state. Otherwise, it will only be the current state if there is no state set."; break; + case nameof(CreatePlayerStateUnit.DestroyPrevious): + desc.summary = "If set, all player states are destroyed before creating a new one. This is typically used when starting the first ball."; + break; } } } diff --git a/Editor/Descriptors/IncreaseVariableUnitDescriptor.cs b/Editor/Descriptors/IncreaseVariableUnitDescriptor.cs index 93eddbb..816de6a 100644 --- a/Editor/Descriptors/IncreaseVariableUnitDescriptor.cs +++ b/Editor/Descriptors/IncreaseVariableUnitDescriptor.cs @@ -42,6 +42,9 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) case nameof(IncreasePlayerVariableUnit.Value): desc.summary = "The value to add to the existing value."; break; + case nameof(IncreasePlayerVariableUnit.OutputValue): + desc.summary = "The final increased value."; + break; } } } @@ -68,6 +71,9 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) case nameof(IncreaseTableVariableUnit.Value): desc.summary = "The value to add to the existing value."; break; + case nameof(IncreasePlayerVariableUnit.OutputValue): + desc.summary = "The final increased value."; + break; } } } diff --git a/Editor/Descriptors/SetVariableUnitDescriptor.cs b/Editor/Descriptors/SetVariableUnitDescriptor.cs index 94cc47e..6e8c4d1 100644 --- a/Editor/Descriptors/SetVariableUnitDescriptor.cs +++ b/Editor/Descriptors/SetVariableUnitDescriptor.cs @@ -42,6 +42,9 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) case nameof(SetPlayerVariableUnit.Value): desc.summary = "The new value of the player variable."; break; + case nameof(SetPlayerVariableUnit.OutputValue): + desc.summary = "The new value of the player variable."; + break; } } } @@ -68,6 +71,10 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) case nameof(SetTableVariableUnit.Value): desc.summary = "The new value of the table variable."; break; + + case nameof(SetTableVariableUnit.OutputValue): + desc.summary = "The new value of the table variable."; + break; } } } diff --git a/Editor/Widgets/GetSwitchUnitWidget.cs b/Editor/Widgets/GetSwitchUnitWidget.cs index 4a384ff..4e35176 100644 --- a/Editor/Widgets/GetSwitchUnitWidget.cs +++ b/Editor/Widgets/GetSwitchUnitWidget.cs @@ -50,6 +50,7 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) } } + return base.GetPortInspector(port, meta); } diff --git a/Runtime/Gamelogic/State.cs b/Runtime/Gamelogic/State.cs index a9b2626..3c950c7 100644 --- a/Runtime/Gamelogic/State.cs +++ b/Runtime/Gamelogic/State.cs @@ -61,6 +61,8 @@ public T Get(string variableId) where T : class return _variables[variableId].Get(); } + public StateVariable GetVariable(string variableId) => _variables[variableId]; + public object Get(string variableId) { if (!_variables.ContainsKey(variableId)) { diff --git a/Runtime/Gamelogic/StateVariable.cs b/Runtime/Gamelogic/StateVariable.cs index f4d622e..06b1433 100644 --- a/Runtime/Gamelogic/StateVariable.cs +++ b/Runtime/Gamelogic/StateVariable.cs @@ -18,7 +18,7 @@ namespace VisualPinball.Unity.VisualScripting { - public class StateVariable + public class StateVariable : IEquatable { public string Id; public string Name; @@ -55,5 +55,50 @@ public void Set(T value) { _value = value; } + + public bool Equals(StateVariable other) + { + if (ReferenceEquals(null, other)) { + return false; + } + if (ReferenceEquals(this, other)) { + return true; + } + + if (other.Type != Type) { + return false; + } + + if (Type == typeof(string)) { + return string.Equals(_value as string, other._value as string); + } + if (Type == typeof(int)) { + return (int)_value == (int)other._value; + } + if (Type == typeof(float)) { + return (float)_value == (float)other._value; + } + if (Type == typeof(bool)) { + return (bool)_value == (bool)other._value; + } + return false; + } + + public override bool Equals(object obj) => Equals(obj as StateVariable); + + public override int GetHashCode() + { + return (Id, Name, Type, _value).GetHashCode(); + } + + public static bool operator ==(StateVariable lhs, StateVariable rhs) + { + if (lhs is null) { + return rhs is null; + } + return lhs.Equals(rhs); + } + + public static bool operator !=(StateVariable lhs, StateVariable rhs) => !(lhs == rhs); } } diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index e53156b..e6cd04b 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -80,17 +80,29 @@ public PlayerState CurrentPlayerState { } } - public int CurrentPlayer { - get => _currentPlayer; - set { - if (!PlayerStates.ContainsKey(value)) { - Debug.LogError($"Cannot change to non-existing player {value}."); - return; - } - var previousPlayer = _currentPlayer; - _currentPlayer = value; - if (previousPlayer != _currentPlayer) { - EventBus.Trigger(VisualScriptingEventNames.CurrentPlayerChanged, EventArgs.Empty); + public void SetCurrentPlayer(int value, bool forceNotify = false) + { + if (!PlayerStates.ContainsKey(value)) { + Debug.LogError($"Cannot change to non-existing player {value}."); + return; + } + var previousPlayer = _currentPlayer; + _currentPlayer = value; + if (forceNotify || previousPlayer != _currentPlayer) { + EventBus.Trigger(VisualScriptingEventNames.CurrentPlayerChanged, EventArgs.Empty); + } + + // also trigger updates for each variable + foreach (var varDef in PlayerVariableDefinitions) { + if (PlayerStates.ContainsKey(previousPlayer)) { + var before = PlayerStates[previousPlayer].GetVariable(varDef.Id); + var now = PlayerStates[_currentPlayer].GetVariable(varDef.Id); + if (forceNotify || before != now) { + EventBus.Trigger(VisualScriptingEventNames.PlayerVariableChanged, new VariableChangedArgs(varDef.Id)); + } + + } else { + EventBus.Trigger(VisualScriptingEventNames.PlayerVariableChanged, new VariableChangedArgs(varDef.Id)); } } } @@ -109,10 +121,16 @@ public void CreatePlayerState(int playerId) // switch to this state if current state is invalid if (!PlayerStates.ContainsKey(_currentPlayer)) { - CurrentPlayer = playerId; + SetCurrentPlayer(playerId, true); } } + public void DestroyPlayerStates() + { + PlayerStates.Clear(); + _currentPlayer = 0; + } + public void OnInit(Player player, TableApi tableApi, BallManager ballManager) { _player = player; @@ -191,3 +209,4 @@ public void OnAfterDeserialize() } } } + diff --git a/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs b/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs index d250a3b..9ed3778 100644 --- a/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs +++ b/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs @@ -54,7 +54,7 @@ private ControlOutput Process(Flow flow) throw new InvalidOperationException("Cannot retrieve GLE from unit."); } - VsGle.CurrentPlayer = flow.GetValue(PlayerId); + VsGle.SetCurrentPlayer(flow.GetValue(PlayerId)); return OutputTrigger; } diff --git a/Runtime/Nodes/PlayerState/CreatePlayerStateUnit.cs b/Runtime/Nodes/PlayerState/CreatePlayerStateUnit.cs index d43b251..69858b3 100644 --- a/Runtime/Nodes/PlayerState/CreatePlayerStateUnit.cs +++ b/Runtime/Nodes/PlayerState/CreatePlayerStateUnit.cs @@ -44,6 +44,10 @@ public class CreatePlayerStateUnit : GleUnit [PortLabel("Set as Active")] public ValueInput SetAsActive { get; set; } + [DoNotSerialize] + [PortLabel("Destroy Previous")] + public ValueInput DestroyPrevious { get; set; } + protected override void Definition() { InputTrigger = ControlInput(nameof(InputTrigger), Process); @@ -55,6 +59,7 @@ protected override void Definition() } SetAsActive = ValueInput(nameof(SetAsActive), false); + DestroyPrevious = ValueInput(nameof(DestroyPrevious), false); Succession(InputTrigger, OutputTrigger); } @@ -65,6 +70,11 @@ private ControlOutput Process(Flow flow) throw new InvalidOperationException("Cannot retrieve GLE from unit."); } + // destroy previous + if (flow.GetValue(DestroyPrevious)) { + VsGle.DestroyPlayerStates(); + } + // determine new player id var newPlayerId = AutoIncrement && VsGle.PlayerStates.Count > 0 ? VsGle.PlayerStates.Keys.Max() + 1 @@ -75,7 +85,7 @@ private ControlOutput Process(Flow flow) // set as active if (flow.GetValue(SetAsActive)) { - VsGle.CurrentPlayer = newPlayerId; + VsGle.SetCurrentPlayer(newPlayerId, flow.GetValue(DestroyPrevious)); } return OutputTrigger; diff --git a/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs b/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs index 4a69df9..902b4de 100644 --- a/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs +++ b/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs @@ -51,10 +51,12 @@ public abstract class IncreaseVariableUnit : GleUnit [DoNotSerialize, PortLabelHidden] public ControlOutput OutputTrigger; - - [DoNotSerialize, PortLabel("Value"), Inspectable] + [DoNotSerialize, PortLabel("Increase By"), Inspectable] public ValueInput Value { get; private set; } + [DoNotSerialize, PortLabel("Updated Value"), Inspectable] + public ValueOutput OutputValue { get; private set; } + protected abstract State State { get; } protected abstract VariableDefinition VariableDefinition { get; } @@ -74,6 +76,12 @@ protected override void Definition() VariableType.Float => ValueInput(nameof(Value), 0f), _ => throw new ArgumentOutOfRangeException($"Type must be integer or float.") }; + + OutputValue = VariableDefinition.Type switch { + VariableType.Integer => ValueOutput(nameof(Value)), + VariableType.Float => ValueOutput(nameof(Value)), + _ => throw new ArgumentOutOfRangeException($"Type must be integer or float.") + }; Requirement(Value, InputTrigger); } @@ -87,11 +95,13 @@ private ControlOutput Process(Flow flow) case VariableType.Integer: { var current = (int)State.Get(VariableDefinition.Id); State.Set(VariableDefinition.Id, new Integer(current + flow.GetValue(Value))); + flow.SetValue(OutputValue, current + flow.GetValue(Value)); break; } case VariableType.Float: { var current = (float)State.Get(VariableDefinition.Id); State.Set(VariableDefinition.Id, new Float(current + flow.GetValue(Value))); + flow.SetValue(OutputValue, current + flow.GetValue(Value)); break; } default: diff --git a/Runtime/Nodes/PlayerState/SetVariableUnit.cs b/Runtime/Nodes/PlayerState/SetVariableUnit.cs index b3e515c..b7f6c5a 100644 --- a/Runtime/Nodes/PlayerState/SetVariableUnit.cs +++ b/Runtime/Nodes/PlayerState/SetVariableUnit.cs @@ -55,6 +55,9 @@ public abstract class SetVariableUnit : GleUnit [DoNotSerialize, PortLabel("Value"), Inspectable] public ValueInput Value { get; private set; } + [DoNotSerialize, PortLabel("Value"), Inspectable] + public ValueOutput OutputValue { get; private set; } + protected abstract State State { get; } protected abstract VariableDefinition VariableDefinition { get; } @@ -76,6 +79,14 @@ protected override void Definition() VariableType.Boolean => ValueInput(nameof(Value), false), _ => throw new ArgumentOutOfRangeException() }; + + OutputValue = VariableDefinition.Type switch { + VariableType.String => ValueOutput(nameof(Value)), + VariableType.Integer => ValueOutput(nameof(Value)), + VariableType.Float => ValueOutput(nameof(Value)), + VariableType.Boolean => ValueOutput(nameof(Value)), + _ => throw new ArgumentOutOfRangeException() + }; Requirement(Value, InputTrigger); } @@ -88,15 +99,19 @@ private ControlOutput Process(Flow flow) switch (VariableDefinition.Type) { case VariableType.String: State.Set(VariableDefinition.Id, flow.GetValue(Value)); + flow.SetValue(OutputValue, flow.GetValue(Value)); break; case VariableType.Integer: State.Set(VariableDefinition.Id, new Integer(flow.GetValue(Value))); + flow.SetValue(OutputValue, flow.GetValue(Value)); break; case VariableType.Float: State.Set(VariableDefinition.Id, new Float(flow.GetValue(Value))); + flow.SetValue(OutputValue, flow.GetValue(Value)); break; case VariableType.Boolean: State.Set(VariableDefinition.Id, new Bool(flow.GetValue(Value))); + flow.SetValue(OutputValue, flow.GetValue(Value)); break; default: throw new ArgumentOutOfRangeException(); From 5aacdd98a945170b6281603c1cc8c306d4b23c10 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Tue, 8 Feb 2022 16:58:07 -0500 Subject: [PATCH 20/54] unit: add switch lamp unit. --- .../Descriptors/SwitchLampUnitDescriptor.cs | 50 ++++++ .../SwitchLampUnitDescriptor.cs.meta | 11 ++ Editor/Inspectors/LampIdValueInspector.cs | 147 ++++++++++++++++++ .../Inspectors/LampIdValueInspector.cs.meta | 11 ++ Editor/Widgets/SwitchLampUnitWidget.cs | 63 ++++++++ Editor/Widgets/SwitchLampUnitWidget.cs.meta | 11 ++ Runtime/Nodes/Lamps/SwitchLampUnit.cs | 105 +++++++++++++ Runtime/Nodes/Lamps/SwitchLampUnit.cs.meta | 11 ++ 8 files changed, 409 insertions(+) create mode 100644 Editor/Descriptors/SwitchLampUnitDescriptor.cs create mode 100644 Editor/Descriptors/SwitchLampUnitDescriptor.cs.meta create mode 100644 Editor/Inspectors/LampIdValueInspector.cs create mode 100644 Editor/Inspectors/LampIdValueInspector.cs.meta create mode 100644 Editor/Widgets/SwitchLampUnitWidget.cs create mode 100644 Editor/Widgets/SwitchLampUnitWidget.cs.meta create mode 100644 Runtime/Nodes/Lamps/SwitchLampUnit.cs create mode 100644 Runtime/Nodes/Lamps/SwitchLampUnit.cs.meta diff --git a/Editor/Descriptors/SwitchLampUnitDescriptor.cs b/Editor/Descriptors/SwitchLampUnitDescriptor.cs new file mode 100644 index 0000000..f36d5f0 --- /dev/null +++ b/Editor/Descriptors/SwitchLampUnitDescriptor.cs @@ -0,0 +1,50 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; +using VisualPinball.Unity.Editor; +using IconSize = VisualPinball.Unity.Editor.IconSize; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(SwitchLampUnit))] + public class SwitchLampUnitDescriptor : UnitDescriptor + { + public SwitchLampUnitDescriptor(SwitchLampUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node triggers an event when a switch in the list of given ID is enabled."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Light(IconSize.Large, IconColor.Orange)); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(SwitchLampUnit.LampIdValues): + desc.summary = "The Lamp ID and value"; + break; + } + } + } +} diff --git a/Editor/Descriptors/SwitchLampUnitDescriptor.cs.meta b/Editor/Descriptors/SwitchLampUnitDescriptor.cs.meta new file mode 100644 index 0000000..37dc01b --- /dev/null +++ b/Editor/Descriptors/SwitchLampUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 93c352919cdce4676b64df9c635d6ad7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Inspectors/LampIdValueInspector.cs b/Editor/Inspectors/LampIdValueInspector.cs new file mode 100644 index 0000000..07a3ead --- /dev/null +++ b/Editor/Inspectors/LampIdValueInspector.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEngine; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + + public sealed class LampIdValueInspector : Inspector + { + public LampIdValueInspector(Metadata metadata, Func> getSuggestions) : base(metadata) + { + Ensure.That(nameof(getSuggestions)).IsNotNull(getSuggestions); + + this.getSuggestions = getSuggestions; + } + + public Func> getSuggestions { get; } + + + protected override float GetHeight(float width, GUIContent label) + { + return HeightWithLabel(metadata, width, GetFieldHeight(width, label), label); + } + + private float GetFieldHeight(float width, GUIContent label) + { + return EditorGUIUtility.singleLineHeight; + } + + private List suggestions = new List(); + + protected override void OnGUI(Rect position, GUIContent label) + { + position = BeginLabeledBlock(metadata, position, label); + + var fieldPosition = position.VerticalSection(ref y, GetFieldHeight(position.width, GUIContent.none)); + + LampIdValue lampIdValue = (LampIdValue)metadata.value; + + var valueWidth = LudiqGUI.GetTextFieldAdaptiveWidth(lampIdValue.value); + + var textFieldPosition = new Rect + ( + fieldPosition.x, + fieldPosition.y, + fieldPosition.width - Styles.popup.fixedWidth - valueWidth - 60, + fieldPosition.height + ); + + var popupPosition = new Rect + ( + textFieldPosition.xMax, + fieldPosition.y, + Styles.popup.fixedWidth, + fieldPosition.height + ); + + var newIdValue = EditorGUI.TextField(textFieldPosition, lampIdValue.id, Styles.textField); + + // Micro optimizing memory here because it's a pretty substantial alloc + + suggestions.Clear(); + suggestions.AddRange(getSuggestions()); + + EditorGUI.BeginDisabledGroup(suggestions.Count == 0); + + var suggestionsArray = getSuggestions().ToArray(); + var currentSuggestionIndex = Array.IndexOf(suggestionsArray, lampIdValue.id); + + EditorGUI.BeginChangeCheck(); + + var newSuggestionIndex = EditorGUI.Popup(popupPosition, currentSuggestionIndex, suggestionsArray, Styles.popup); + + if (EditorGUI.EndChangeCheck()) + { + newIdValue = suggestions[newSuggestionIndex]; + } + + EditorGUI.EndDisabledGroup(); + + var valueFieldPosition = new Rect + ( + fieldPosition.x + fieldPosition.width - valueWidth, + fieldPosition.y, + valueWidth, + fieldPosition.height + ); + + var valueLabelFieldPosition = new Rect + ( + fieldPosition.x + fieldPosition.width - valueWidth - 50, + fieldPosition.y, + 50, + fieldPosition.height + ); + + + EditorGUI.LabelField(valueLabelFieldPosition, "Value"); + + var newValue = LudiqGUI.DraggableIntField(valueFieldPosition, lampIdValue.value); + + if (EndBlock(metadata)) + { + metadata.RecordUndo(); + metadata.value = new LampIdValue + { + id = newIdValue, + value = newValue + }; + } + } + + public override float GetAdaptiveWidth() + { + LampIdValue lampIdValue = (LampIdValue)metadata.value; + + return Mathf.Max(30, EditorStyles.textField.CalcSize(new GUIContent(lampIdValue.id)).x + 1 + Styles.popup.fixedWidth) + + LudiqGUI.GetTextFieldAdaptiveWidth(lampIdValue.value) + 70; + } + + public static class Styles + { + static Styles() + { + textField = new GUIStyle(EditorStyles.textField); + + popup = new GUIStyle("TextFieldDropDown"); + popup.fixedWidth = 18; + popup.clipping = TextClipping.Clip; + popup.normal.textColor = ColorPalette.transparent; + popup.active.textColor = ColorPalette.transparent; + popup.hover.textColor = ColorPalette.transparent; + popup.focused.textColor = ColorPalette.transparent; + popup.onNormal.textColor = ColorPalette.transparent; + popup.onActive.textColor = ColorPalette.transparent; + popup.onHover.textColor = ColorPalette.transparent; + popup.onFocused.textColor = ColorPalette.transparent; + } + + public static readonly GUIStyle textField; + public static readonly GUIStyle popup; + } + } +} diff --git a/Editor/Inspectors/LampIdValueInspector.cs.meta b/Editor/Inspectors/LampIdValueInspector.cs.meta new file mode 100644 index 0000000..7d0de85 --- /dev/null +++ b/Editor/Inspectors/LampIdValueInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d13acec859f34990b640564525464c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/SwitchLampUnitWidget.cs b/Editor/Widgets/SwitchLampUnitWidget.cs new file mode 100644 index 0000000..a211b5d --- /dev/null +++ b/Editor/Widgets/SwitchLampUnitWidget.cs @@ -0,0 +1,63 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(SwitchLampUnit))] + public sealed class SwitchLampUnitWidget : GleUnitWidget + { + private readonly List> _lampIdInspectorConstructorList; + + public SwitchLampUnitWidget(FlowCanvas canvas, SwitchLampUnit unit) : base(canvas, unit) + { + _lampIdInspectorConstructorList = new List>(); + } + + public override Inspector GetPortInspector(IUnitPort port, Metadata meta) + { + if (_lampIdInspectorConstructorList.Count() < unit.idCount) { + for (var index = 0; index < unit.idCount - _lampIdInspectorConstructorList.Count(); index++) { + _lampIdInspectorConstructorList.Add(meta => new LampIdValueInspector(meta, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.idCount; index++) { + if (unit.LampIdValues[index] == port) { + LampIdValueInspector lampIdInspector = new LampIdValueInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); + + return lampIdInspector; + } + } + + return base.GetPortInspector(port, meta); + } + + private IEnumerable GetNameSuggestions() + { + return !GleAvailable + ? new List() + : Gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); + } + } +} diff --git a/Editor/Widgets/SwitchLampUnitWidget.cs.meta b/Editor/Widgets/SwitchLampUnitWidget.cs.meta new file mode 100644 index 0000000..a3f8f09 --- /dev/null +++ b/Editor/Widgets/SwitchLampUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb81ebf5658344079b2463a97cc60251 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Lamps/SwitchLampUnit.cs b/Runtime/Nodes/Lamps/SwitchLampUnit.cs new file mode 100644 index 0000000..8d7e15a --- /dev/null +++ b/Runtime/Nodes/Lamps/SwitchLampUnit.cs @@ -0,0 +1,105 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using Unity.VisualScripting; +using UnityEngine; +using UnityObject = UnityEngine.Object; + +namespace VisualPinball.Unity.VisualScripting +{ + [Serializable] + public class LampIdValue : UnityObject + { + public string id; + public int value; + + public static LampIdValue Empty = new LampIdValue { id = string.Empty, value = 0 }; + } + + [UnitShortTitle("Switch Lamp")] + [UnitTitle("Switch Lamp (ID, match value)")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Visual Pinball")] + public class SwitchLampUnit : GleUnit + { + [SerializeAs(nameof(idCount))] + private int _idCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Lamp IDs")] + public int idCount + { + get => _idCount; + set => _idCount = Mathf.Clamp(value, 1, 10); + } + + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + + [DoNotSerialize] + [PortLabel("Value")] + public ValueInput Value { get; private set; } + + [DoNotSerialize] + public List LampIdValues { get; private set; } + + protected override void Definition() + { + InputTrigger = ControlInput(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + Value = ValueInput(nameof(Value)); + + LampIdValues = new List(); + + for (var i = 0; i < idCount; i++) + { + var lampIdValue = ValueInput("Lamp ID " + (i + 1), LampIdValue.Empty); + LampIdValues.Add(lampIdValue); + + Requirement(lampIdValue, InputTrigger); + } + + + Succession(InputTrigger, OutputTrigger); + } + + private ControlOutput Process(Flow flow) + { + if (!AssertGle(flow)) { + Debug.LogError("Cannot find GLE."); + return OutputTrigger; + } + + var value = flow.GetValue(Value); + + foreach (var lampIdValue in LampIdValues) + { + var lampIdValueStruct = flow.GetValue(lampIdValue); + Gle.SetLamp(lampIdValueStruct.id, lampIdValueStruct.value == value ? 255f : 0f); + } + + return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/Lamps/SwitchLampUnit.cs.meta b/Runtime/Nodes/Lamps/SwitchLampUnit.cs.meta new file mode 100644 index 0000000..21f19df --- /dev/null +++ b/Runtime/Nodes/Lamps/SwitchLampUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c6f6ca79d45bb4133845d06126820a47 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 6656ead5dc5f55150a3105e5336623a9ebf6fa21 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Wed, 9 Feb 2022 21:00:03 -0500 Subject: [PATCH 21/54] unit: update LampIdValue to convert to/from JSON --- Editor/Inspectors/LampIdValueInspector.cs | 14 ++++----- Runtime/Nodes/Lamps/SwitchLampUnit.cs | 37 ++++++++++++++--------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/Editor/Inspectors/LampIdValueInspector.cs b/Editor/Inspectors/LampIdValueInspector.cs index 07a3ead..4ee8ad6 100644 --- a/Editor/Inspectors/LampIdValueInspector.cs +++ b/Editor/Inspectors/LampIdValueInspector.cs @@ -38,7 +38,7 @@ protected override void OnGUI(Rect position, GUIContent label) var fieldPosition = position.VerticalSection(ref y, GetFieldHeight(position.width, GUIContent.none)); - LampIdValue lampIdValue = (LampIdValue)metadata.value; + LampIdValue lampIdValue = LampIdValue.FromJson((string)metadata.value); var valueWidth = LudiqGUI.GetTextFieldAdaptiveWidth(lampIdValue.value); @@ -105,17 +105,17 @@ protected override void OnGUI(Rect position, GUIContent label) if (EndBlock(metadata)) { metadata.RecordUndo(); - metadata.value = new LampIdValue - { - id = newIdValue, - value = newValue - }; + + lampIdValue.id = newIdValue; + lampIdValue.value = newValue; + + metadata.value = lampIdValue.ToJson(); } } public override float GetAdaptiveWidth() { - LampIdValue lampIdValue = (LampIdValue)metadata.value; + LampIdValue lampIdValue = LampIdValue.FromJson((string)metadata.value); return Mathf.Max(30, EditorStyles.textField.CalcSize(new GUIContent(lampIdValue.id)).x + 1 + Styles.popup.fixedWidth) + LudiqGUI.GetTextFieldAdaptiveWidth(lampIdValue.value) + 70; diff --git a/Runtime/Nodes/Lamps/SwitchLampUnit.cs b/Runtime/Nodes/Lamps/SwitchLampUnit.cs index 8d7e15a..6e282a4 100644 --- a/Runtime/Nodes/Lamps/SwitchLampUnit.cs +++ b/Runtime/Nodes/Lamps/SwitchLampUnit.cs @@ -18,17 +18,26 @@ using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; -using UnityObject = UnityEngine.Object; namespace VisualPinball.Unity.VisualScripting { [Serializable] - public class LampIdValue : UnityObject + public struct LampIdValue { public string id; public int value; - public static LampIdValue Empty = new LampIdValue { id = string.Empty, value = 0 }; + public static LampIdValue FromJson(string json) + { + return JsonUtility.FromJson(json); + } + + public string ToJson() + { + return JsonUtility.ToJson(this); + } + + public static readonly LampIdValue Empty = new LampIdValue { id = string.Empty, value = 0 }; } [UnitShortTitle("Switch Lamp")] @@ -63,6 +72,9 @@ public int idCount [DoNotSerialize] public List LampIdValues { get; private set; } + private List _lampIdValueList; + private int _hash; + protected override void Definition() { InputTrigger = ControlInput(nameof(InputTrigger), Process); @@ -72,15 +84,13 @@ protected override void Definition() LampIdValues = new List(); - for (var i = 0; i < idCount; i++) - { - var lampIdValue = ValueInput("Lamp ID " + (i + 1), LampIdValue.Empty); - LampIdValues.Add(lampIdValue); + for (var i = 0; i < idCount; i++) { + var valueInput = ValueInput($"Lamp ID {i + 1}", LampIdValue.Empty.ToJson()); + LampIdValues.Add(valueInput); - Requirement(lampIdValue, InputTrigger); + Requirement(valueInput, InputTrigger); } - Succession(InputTrigger, OutputTrigger); } @@ -90,13 +100,12 @@ private ControlOutput Process(Flow flow) Debug.LogError("Cannot find GLE."); return OutputTrigger; } - + var value = flow.GetValue(Value); - foreach (var lampIdValue in LampIdValues) - { - var lampIdValueStruct = flow.GetValue(lampIdValue); - Gle.SetLamp(lampIdValueStruct.id, lampIdValueStruct.value == value ? 255f : 0f); + foreach (var lampIdValue in LampIdValues) { + var obj = LampIdValue.FromJson(flow.GetValue(lampIdValue)); + Gle.SetLamp(obj.id, obj.value == value ? 255f : 0f); } return OutputTrigger; From f6046aa76f407e7060a7ee06a1e01e2295f3527b Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Thu, 10 Feb 2022 07:39:09 -0500 Subject: [PATCH 22/54] unit: update SwitchLampUnit to cache based on json hash --- Runtime/Nodes/Lamps/SwitchLampUnit.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Runtime/Nodes/Lamps/SwitchLampUnit.cs b/Runtime/Nodes/Lamps/SwitchLampUnit.cs index 6e282a4..2e34f47 100644 --- a/Runtime/Nodes/Lamps/SwitchLampUnit.cs +++ b/Runtime/Nodes/Lamps/SwitchLampUnit.cs @@ -72,8 +72,7 @@ public int idCount [DoNotSerialize] public List LampIdValues { get; private set; } - private List _lampIdValueList; - private int _hash; + private Dictionary _lampIdValueCache = new Dictionary(); protected override void Definition() { @@ -91,6 +90,8 @@ protected override void Definition() Requirement(valueInput, InputTrigger); } + _lampIdValueCache.Clear(); + Succession(InputTrigger, OutputTrigger); } @@ -104,7 +105,13 @@ private ControlOutput Process(Flow flow) var value = flow.GetValue(Value); foreach (var lampIdValue in LampIdValues) { - var obj = LampIdValue.FromJson(flow.GetValue(lampIdValue)); + var json = flow.GetValue(lampIdValue); + + if (!_lampIdValueCache.ContainsKey(json.GetHashCode())) { + _lampIdValueCache[json.GetHashCode()] = LampIdValue.FromJson(json); + } + + var obj = _lampIdValueCache[json.GetHashCode()]; Gle.SetLamp(obj.id, obj.value == value ? 255f : 0f); } From 93f7c475920e8347a34089f58eeb552ad3225328 Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 8 Feb 2022 22:44:58 +0100 Subject: [PATCH 23/54] Add display unit. --- .../UpdateDisplayUnitDescriptor.cs | 56 +++++++ .../UpdateDisplayUnitDescriptor.cs.meta | 11 ++ .../Inspectors/DisplayDefinitionInspector.cs | 76 +++++++++ .../DisplayDefinitionInspector.cs.meta | 11 ++ ...VisualScriptingGamelogicEngineInspector.cs | 3 + .../DisplayDefinitionPropertyDrawer.cs | 98 ++++++++++++ .../DisplayDefinitionPropertyDrawer.cs.meta | 11 ++ Editor/Widgets/GetLampUnitWidget.cs | 2 +- Editor/Widgets/GetSwitchUnitWidget.cs | 2 +- Editor/Widgets/LampEventUnitWidget.cs | 2 +- Editor/Widgets/PulseCoilUnitWidget.cs | 2 +- Editor/Widgets/SetCoilUnitWidget.cs | 2 +- Editor/Widgets/SetLampEnabledUnitWidget.cs | 2 +- Editor/Widgets/SetLampUnitWidget.cs | 2 +- .../Widgets/SwitchEnabledEventUnitWidget.cs | 2 +- Editor/Widgets/SwitchEventUnitWidget.cs | 2 +- Editor/Widgets/SwitchLampUnitWidget.cs | 2 +- Editor/Widgets/UpdateDisplayUnitWidget.cs | 30 ++++ .../Widgets/UpdateDisplayUnitWidget.cs.meta | 11 ++ Runtime/Display.meta | 3 + Runtime/Display/DisplayDefinition.cs | 36 +++++ Runtime/Display/DisplayDefinition.cs.meta | 11 ++ Runtime/Display/ScoreConverter.cs | 149 ++++++++++++++++++ Runtime/Display/ScoreConverter.cs.meta | 11 ++ .../VisualScriptingGamelogicEngine.cs | 21 ++- Runtime/Nodes/Display.meta | 8 + Runtime/Nodes/Display/UpdateDisplayUnit.cs | 98 ++++++++++++ .../Nodes/Display/UpdateDisplayUnit.cs.meta | 11 ++ 28 files changed, 661 insertions(+), 14 deletions(-) create mode 100644 Editor/Descriptors/UpdateDisplayUnitDescriptor.cs create mode 100644 Editor/Descriptors/UpdateDisplayUnitDescriptor.cs.meta create mode 100644 Editor/Inspectors/DisplayDefinitionInspector.cs create mode 100644 Editor/Inspectors/DisplayDefinitionInspector.cs.meta create mode 100644 Editor/PropertyDrawers/DisplayDefinitionPropertyDrawer.cs create mode 100644 Editor/PropertyDrawers/DisplayDefinitionPropertyDrawer.cs.meta create mode 100644 Editor/Widgets/UpdateDisplayUnitWidget.cs create mode 100644 Editor/Widgets/UpdateDisplayUnitWidget.cs.meta create mode 100644 Runtime/Display.meta create mode 100644 Runtime/Display/DisplayDefinition.cs create mode 100644 Runtime/Display/DisplayDefinition.cs.meta create mode 100644 Runtime/Display/ScoreConverter.cs create mode 100644 Runtime/Display/ScoreConverter.cs.meta create mode 100644 Runtime/Nodes/Display.meta create mode 100644 Runtime/Nodes/Display/UpdateDisplayUnit.cs create mode 100644 Runtime/Nodes/Display/UpdateDisplayUnit.cs.meta diff --git a/Editor/Descriptors/UpdateDisplayUnitDescriptor.cs b/Editor/Descriptors/UpdateDisplayUnitDescriptor.cs new file mode 100644 index 0000000..518e739 --- /dev/null +++ b/Editor/Descriptors/UpdateDisplayUnitDescriptor.cs @@ -0,0 +1,56 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; +using VisualPinball.Unity.Editor; +using IconSize = VisualPinball.Unity.Editor.IconSize; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(UpdateDisplayUnit))] + public class UpdateDisplayUnitDescriptor : UnitDescriptor + { + public UpdateDisplayUnitDescriptor(UpdateDisplayUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node takes in a value and sends it to the display connected through the given ID.\n\nDisplay might be able display different types of data, so depending on how you configure your display in the Visual Scripting Gamelogic Engine, you might get multiple data inputs."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.UpdateDisplay); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(UpdateDisplayUnit.NumericInput): + desc.summary = "Sets the display to a new numerical value."; + break; + case nameof(UpdateDisplayUnit.TextInput): + desc.summary = "Sets the display to a new text value."; + break; + case nameof(UpdateDisplayUnit.FrameInput): + desc.summary = "Updates the display with new frame data."; + break; + } + } + } +} diff --git a/Editor/Descriptors/UpdateDisplayUnitDescriptor.cs.meta b/Editor/Descriptors/UpdateDisplayUnitDescriptor.cs.meta new file mode 100644 index 0000000..2406c9a --- /dev/null +++ b/Editor/Descriptors/UpdateDisplayUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9880082450879fd4788ce30e6c79ede0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Inspectors/DisplayDefinitionInspector.cs b/Editor/Inspectors/DisplayDefinitionInspector.cs new file mode 100644 index 0000000..a88e57c --- /dev/null +++ b/Editor/Inspectors/DisplayDefinitionInspector.cs @@ -0,0 +1,76 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Inspector(typeof(DisplayDefinition))] + public class DisplayDefinitionInspector : GleInspector + { + public DisplayDefinitionInspector(Metadata metadata) : base(metadata) { } + + protected override void OnGUI(Rect position, GUIContent label) + { + // can't get this from the flow + var gle = Gle; + if (gle != null) { + if (gle.Displays == null || gle.Displays.Count(p => !string.IsNullOrEmpty(p.Id)) == 0) { + ErrorMessage = "No displays defined."; + + } else { + var varNames = new List { "None" } + .Concat(gle.Displays.Select(d => d.Id)) + .ToArray(); + var currentDisplayDef = metadata.value as DisplayDefinition; + var currentIndex = 0; + if (currentDisplayDef != null) { + var displayDef = gle.Displays.FirstOrDefault(p => p.Id == currentDisplayDef!.Id); + currentIndex = displayDef != null ? Array.IndexOf(gle.Displays, displayDef) + 1 : 0; + } + + var newIndex = EditorGUI.Popup(position, currentIndex, varNames); + metadata.RecordUndo(); + metadata.value = newIndex == 0 ? null : gle.Displays[newIndex - 1]; + ErrorMessage = null; + } + } + + if (ErrorMessage != null) { + position.height -= EditorGUIUtility.standardVerticalSpacing; + EditorGUI.HelpBox(position, ErrorMessage, MessageType.Error); + } + } + + public override float GetAdaptiveWidth() => LudiqGUIUtility.currentInspectorWidth; + + protected override float GetHeight(float width, GUIContent label) + { + if (ErrorMessage != null) { + var height = LudiqGUIUtility.GetHelpBoxHeight(ErrorMessage, MessageType.Error, width); + height += EditorGUIUtility.standardVerticalSpacing; + return height; + } + + return EditorGUIUtility.singleLineHeight; + } + } +} diff --git a/Editor/Inspectors/DisplayDefinitionInspector.cs.meta b/Editor/Inspectors/DisplayDefinitionInspector.cs.meta new file mode 100644 index 0000000..67d58be --- /dev/null +++ b/Editor/Inspectors/DisplayDefinitionInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ad1b15551c31b94e97bb65c02b01551 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs b/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs index b441103..ab99294 100644 --- a/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs +++ b/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs @@ -27,6 +27,7 @@ namespace VisualPinball.Unity.VisualScripting.Editor public class VisualScriptingGamelogicEngineInspector : BaseEditor { private VisualScriptingGamelogicEngine _gle; + private SerializedProperty _displaysProperty; private SerializedProperty _switchesProperty; private SerializedProperty _soilsProperty; private SerializedProperty _lampsProperty; @@ -39,6 +40,7 @@ private void OnEnable() { _gle = target as VisualScriptingGamelogicEngine; + _displaysProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.Displays)); _switchesProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.Switches)); _soilsProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.Coils)); _lampsProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.Lamps)); @@ -51,6 +53,7 @@ public override void OnInspectorGUI() { serializedObject.Update(); + EditorGUILayout.PropertyField(_displaysProperty); EditorGUILayout.PropertyField(_switchesProperty); EditorGUILayout.PropertyField(_soilsProperty); EditorGUILayout.PropertyField(_lampsProperty); diff --git a/Editor/PropertyDrawers/DisplayDefinitionPropertyDrawer.cs b/Editor/PropertyDrawers/DisplayDefinitionPropertyDrawer.cs new file mode 100644 index 0000000..f594b4f --- /dev/null +++ b/Editor/PropertyDrawers/DisplayDefinitionPropertyDrawer.cs @@ -0,0 +1,98 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [CustomPropertyDrawer(typeof(DisplayDefinition))] + public class DisplayDefinitionPropertyDrawer : PropertyDrawer + { + private const float Padding = 2f; + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return 5 * (EditorGUIUtility.singleLineHeight + Padding); + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + var idProperty = property.FindPropertyRelative(nameof(DisplayDefinition.Id)); + var widthProperty = property.FindPropertyRelative(nameof(DisplayDefinition.Width)); + var heightProperty = property.FindPropertyRelative(nameof(DisplayDefinition.Height)); + + var contentPosition = position; + contentPosition.height = EditorGUIUtility.singleLineHeight; + + //EditorGUI.BeginProperty(position, label, property); + EditorGUI.PropertyField(contentPosition, idProperty, new GUIContent("ID:")); + //EditorGUI.EndProperty(); + position.y += EditorGUIUtility.singleLineHeight + Padding; + + contentPosition = EditorGUI.PrefixLabel(position, new GUIContent("Size:")); + contentPosition.height = EditorGUIUtility.singleLineHeight; + + var half = contentPosition.width / 2; + GUI.skin.label.padding = new RectOffset(3, 3, 6, 6); + + //show the X and Y from the point + var oldLabelWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 14f; + contentPosition.width *= 0.5f; + EditorGUI.indentLevel = 0; + + // Begin/end property & change check make each field + // behave correctly when multi-object editing. + EditorGUI.BeginProperty(contentPosition, label, widthProperty); + { + EditorGUI.BeginChangeCheck(); + var newVal = EditorGUI.IntField(contentPosition, new GUIContent("W"), widthProperty.intValue); + if (EditorGUI.EndChangeCheck()) + widthProperty.intValue = newVal; + } + EditorGUI.EndProperty(); + + contentPosition.x += half; + EditorGUI.BeginProperty(contentPosition, label, heightProperty); + { + EditorGUI.BeginChangeCheck(); + var newVal = EditorGUI.IntField(contentPosition, new GUIContent("H"), heightProperty.intValue); + if (EditorGUI.EndChangeCheck()) + heightProperty.intValue = newVal; + } + EditorGUI.EndProperty(); + + EditorGUIUtility.labelWidth = oldLabelWidth; + + var supportsNumericInputProperty = property.FindPropertyRelative(nameof(DisplayDefinition.SupportsNumericInput)); + var supportsTextInputProperty = property.FindPropertyRelative(nameof(DisplayDefinition.SupportsTextInput)); + var supportsImageInputProperty = property.FindPropertyRelative(nameof(DisplayDefinition.SupportsImageInput)); + + + position.y += EditorGUIUtility.singleLineHeight + Padding; + contentPosition = position; + contentPosition.height = EditorGUIUtility.singleLineHeight; + EditorGUI.PropertyField(contentPosition, supportsNumericInputProperty, new GUIContent("Numeric:")); + contentPosition.y += EditorGUIUtility.singleLineHeight + Padding; + EditorGUI.PropertyField(contentPosition, supportsTextInputProperty, new GUIContent("Text:")); + contentPosition.y += EditorGUIUtility.singleLineHeight + Padding; + EditorGUI.PropertyField(contentPosition, supportsImageInputProperty, new GUIContent("Data:")); + } + } +} + diff --git a/Editor/PropertyDrawers/DisplayDefinitionPropertyDrawer.cs.meta b/Editor/PropertyDrawers/DisplayDefinitionPropertyDrawer.cs.meta new file mode 100644 index 0000000..b9820d0 --- /dev/null +++ b/Editor/PropertyDrawers/DisplayDefinitionPropertyDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d6182e48489a56a49a67f3841551a094 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/GetLampUnitWidget.cs b/Editor/Widgets/GetLampUnitWidget.cs index 113e2d3..2372846 100644 --- a/Editor/Widgets/GetLampUnitWidget.cs +++ b/Editor/Widgets/GetLampUnitWidget.cs @@ -49,7 +49,7 @@ private IEnumerable GetNameSuggestions() { return !GleAvailable ? new List() - : Gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); + : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); } } } diff --git a/Editor/Widgets/GetSwitchUnitWidget.cs b/Editor/Widgets/GetSwitchUnitWidget.cs index 4e35176..86a0413 100644 --- a/Editor/Widgets/GetSwitchUnitWidget.cs +++ b/Editor/Widgets/GetSwitchUnitWidget.cs @@ -58,7 +58,7 @@ private IEnumerable GetNameSuggestions() { return !GleAvailable ? new List() - : Gle.AvailableSwitches.Select(sw => sw.Id).ToList(); + : Gle.RequestedSwitches.Select(sw => sw.Id).ToList(); } } } diff --git a/Editor/Widgets/LampEventUnitWidget.cs b/Editor/Widgets/LampEventUnitWidget.cs index 4f86ed4..1ff4988 100644 --- a/Editor/Widgets/LampEventUnitWidget.cs +++ b/Editor/Widgets/LampEventUnitWidget.cs @@ -49,7 +49,7 @@ private IEnumerable GetNameSuggestions() { return !GleAvailable ? new List() - : Gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); + : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); } } diff --git a/Editor/Widgets/PulseCoilUnitWidget.cs b/Editor/Widgets/PulseCoilUnitWidget.cs index 50ab4db..8b1de17 100644 --- a/Editor/Widgets/PulseCoilUnitWidget.cs +++ b/Editor/Widgets/PulseCoilUnitWidget.cs @@ -57,7 +57,7 @@ private IEnumerable GetNameSuggestions() { return !GleAvailable ? new List() - : Gle.AvailableCoils.Select(coil => coil.Id).ToList(); + : Gle.RequestedCoils.Select(coil => coil.Id).ToList(); } } } diff --git a/Editor/Widgets/SetCoilUnitWidget.cs b/Editor/Widgets/SetCoilUnitWidget.cs index 0b6ca6a..37e74f9 100644 --- a/Editor/Widgets/SetCoilUnitWidget.cs +++ b/Editor/Widgets/SetCoilUnitWidget.cs @@ -57,7 +57,7 @@ private IEnumerable GetNameSuggestions() { return !GleAvailable ? new List() - : Gle.AvailableCoils.Select(coil => coil.Id).ToList(); + : Gle.RequestedCoils.Select(coil => coil.Id).ToList(); } } } diff --git a/Editor/Widgets/SetLampEnabledUnitWidget.cs b/Editor/Widgets/SetLampEnabledUnitWidget.cs index ce4efb3..2921a94 100644 --- a/Editor/Widgets/SetLampEnabledUnitWidget.cs +++ b/Editor/Widgets/SetLampEnabledUnitWidget.cs @@ -48,7 +48,7 @@ private IEnumerable GetNameSuggestions() { return !GleAvailable ? new List() - : Gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); + : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); } } } diff --git a/Editor/Widgets/SetLampUnitWidget.cs b/Editor/Widgets/SetLampUnitWidget.cs index e8fc460..0d783c1 100644 --- a/Editor/Widgets/SetLampUnitWidget.cs +++ b/Editor/Widgets/SetLampUnitWidget.cs @@ -48,7 +48,7 @@ private IEnumerable GetNameSuggestions() { return !GleAvailable ? new List() - : Gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); + : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); } } } diff --git a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs index 50ebfb3..2628e78 100644 --- a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs @@ -57,7 +57,7 @@ private IEnumerable GetNameSuggestions() { return !GleAvailable ? new List() - : Gle.AvailableSwitches.Select(sw => sw.Id).ToList(); + : Gle.RequestedSwitches.Select(sw => sw.Id).ToList(); } } } diff --git a/Editor/Widgets/SwitchEventUnitWidget.cs b/Editor/Widgets/SwitchEventUnitWidget.cs index 0be4719..a3cb05a 100644 --- a/Editor/Widgets/SwitchEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEventUnitWidget.cs @@ -49,7 +49,7 @@ private IEnumerable GetNameSuggestions() { return !GleAvailable ? new List() - : Gle.AvailableSwitches.Select(sw => sw.Id).ToList(); + : Gle.RequestedSwitches.Select(sw => sw.Id).ToList(); } } } diff --git a/Editor/Widgets/SwitchLampUnitWidget.cs b/Editor/Widgets/SwitchLampUnitWidget.cs index a211b5d..caccb76 100644 --- a/Editor/Widgets/SwitchLampUnitWidget.cs +++ b/Editor/Widgets/SwitchLampUnitWidget.cs @@ -57,7 +57,7 @@ private IEnumerable GetNameSuggestions() { return !GleAvailable ? new List() - : Gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); + : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); } } } diff --git a/Editor/Widgets/UpdateDisplayUnitWidget.cs b/Editor/Widgets/UpdateDisplayUnitWidget.cs new file mode 100644 index 0000000..6c58163 --- /dev/null +++ b/Editor/Widgets/UpdateDisplayUnitWidget.cs @@ -0,0 +1,30 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(UpdateDisplayUnit))] + public sealed class UpdateDisplayUnitWidget : GleUnitWidget + { + public UpdateDisplayUnitWidget(FlowCanvas canvas, UpdateDisplayUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/UpdateDisplayUnitWidget.cs.meta b/Editor/Widgets/UpdateDisplayUnitWidget.cs.meta new file mode 100644 index 0000000..f7e2da1 --- /dev/null +++ b/Editor/Widgets/UpdateDisplayUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d01edfa85b5aaa440a46ba9425b8ea0e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Display.meta b/Runtime/Display.meta new file mode 100644 index 0000000..a15249f --- /dev/null +++ b/Runtime/Display.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1e0c1c31f7904ee7b6a97fae6157da9f +timeCreated: 1644188526 \ No newline at end of file diff --git a/Runtime/Display/DisplayDefinition.cs b/Runtime/Display/DisplayDefinition.cs new file mode 100644 index 0000000..1cc9857 --- /dev/null +++ b/Runtime/Display/DisplayDefinition.cs @@ -0,0 +1,36 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable InconsistentNaming + +using System; + +namespace VisualPinball.Unity.VisualScripting +{ + [Serializable] + public class DisplayDefinition + { + public string Id = "display0"; + public int Width = 128; + public int Height = 32; + + public bool SupportsNumericInput; + public bool SupportsTextInput; + public bool SupportsImageInput = true; + + public DisplayConfig DisplayConfig => new(Id, Width, Height); + } +} diff --git a/Runtime/Display/DisplayDefinition.cs.meta b/Runtime/Display/DisplayDefinition.cs.meta new file mode 100644 index 0000000..14f6b74 --- /dev/null +++ b/Runtime/Display/DisplayDefinition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7318cd2d8e566247adaaa3ea00572dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Display/ScoreConverter.cs b/Runtime/Display/ScoreConverter.cs new file mode 100644 index 0000000..3f60bfa --- /dev/null +++ b/Runtime/Display/ScoreConverter.cs @@ -0,0 +1,149 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; + +namespace VisualPinball.Unity.VisualScripting +{ + public static class ScoreConverter + { + public static byte[] Convert(int score, int displaySize) + { + return Text(score.ToString().PadLeft(displaySize, ' ')[..displaySize], displaySize); + } + + public static byte[] Text(string text, int displaySize) + { + var source = GenerateAlphaNumeric(text); + const int size = sizeof(short); + var target = new byte[displaySize * size]; + Buffer.BlockCopy(source, 0, target, 0, System.Math.Min(source.Length, displaySize) * size); + return target; + } + + private static ushort[] GenerateAlphaNumeric(string text) + { + var data = new ushort[text.Length]; + for (var i = 0; i < text.Length; i++) { + if (AlphaNumericMap.ContainsKey(text[i])) { + data[i] = AlphaNumericMap[text[i]]; + } else { + data[i] = AlphaNumericMap[' ']; + } + } + return data; + } + + private static readonly Dictionary AlphaNumericMap = new Dictionary { + { '0', 0x443f }, + { '1', 0x406 }, + { '2', 0x85b }, + { '3', 0x80f }, + { '4', 0x866 }, + { '5', 0x1069 }, + { '6', 0x87d }, + { '7', 0x7 }, + { '8', 0x87f }, + { '9', 0x86f }, + { ' ', 0x0 }, + { '!', 0x86 }, + { '"', 0x202 }, + { '#', 0x2a4e }, + { '$', 0x2a6d }, + { '%', 0x7f64 }, + { '&', 0x1359 }, + { '\'', 0x200 }, + { '(', 0x1400 }, + { ')', 0x4100 }, + { '*', 0x7f40 }, + { '+', 0x2a40 }, + { ',', 0x4000 }, + { '-', 0x840 }, + { '.', 0x80 }, + { '/', 0x4400 }, + { ':', 0x2200 }, + { ';', 0x4200 }, + { '<', 0x1440 }, + { '=', 0x848 }, + { '>', 0x4900 }, + { '?', 0x2883 }, + { '@', 0xa3b }, + { 'A', 0x877 }, + { 'B', 0x2a0f }, + { 'C', 0x39 }, + { 'D', 0x220f }, + { 'E', 0x79 }, + { 'F', 0x71 }, + { 'G', 0x83d }, + { 'H', 0x876 }, + { 'I', 0x2209 }, + { 'J', 0x1e }, + { 'K', 0x1470 }, + { 'L', 0x38 }, + { 'M', 0x536 }, + { 'N', 0x1136 }, + { 'O', 0x3f }, + { 'P', 0x873 }, + { 'Q', 0x103f }, + { 'R', 0x1873 }, + { 'S', 0x86d }, + { 'T', 0x2201 }, + { 'U', 0x3e }, + { 'V', 0x4430 }, + { 'W', 0x5036 }, + { 'X', 0x5500 }, + { 'Y', 0x86e }, + { 'Z', 0x4409 }, + { '[', 0x39 }, + { '\\', 0x1100 }, + { ']', 0xf }, + { '^', 0x5000 }, + { '_', 0x8 }, + { '`', 0x100 }, + { 'a', 0x2058 }, + { 'b', 0x1078 }, + { 'c', 0x858 }, + { 'd', 0x480e }, + { 'e', 0x4058 }, + { 'f', 0x2c40 }, + { 'g', 0xc0e }, + { 'h', 0x2070 }, + { 'i', 0x2000 }, + { 'j', 0x4210 }, + { 'k', 0x3600 }, + { 'l', 0x30 }, + { 'm', 0x2854 }, + { 'n', 0x2050 }, + { 'o', 0x85c }, + { 'p', 0x170 }, + { 'q', 0xc06 }, + { 'r', 0x50 }, + { 's', 0x1808 }, + { 't', 0x78 }, + { 'u', 0x1c }, + { 'v', 0x4010 }, + { 'w', 0x5014 }, + { 'x', 0x5500 }, + { 'y', 0xa0e }, + { 'z', 0x4048 }, + { '{', 0x4149 }, + { '|', 0x2200 }, + { '}', 0x1c09 }, + { '~', 0x4c40 }, + }; + } +} diff --git a/Runtime/Display/ScoreConverter.cs.meta b/Runtime/Display/ScoreConverter.cs.meta new file mode 100644 index 0000000..054d987 --- /dev/null +++ b/Runtime/Display/ScoreConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e7455488440dc144880395ae63d2bc4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index e6cd04b..968e05e 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -37,6 +37,9 @@ public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine, I [Tooltip("Define here the player-specific variables of the Visual Scripting engine.")] public List PlayerVariableDefinitions; + [Tooltip("Define the displays this game is going to use.")] + public DisplayDefinition[] Displays; + [Tooltip("The switches that are exposed in the Visual Scripting nodes.")] public VisualScriptingSwitch[] Switches; @@ -47,15 +50,17 @@ public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine, I public VisualScriptingLamp[] Lamps; public GamelogicEngineWire[] Wires; - public GamelogicEngineSwitch[] AvailableSwitches => Switches.Select(sw => sw as GamelogicEngineSwitch).ToArray(); + public DisplayConfig[] RequiredDisplays => Displays.Select(d => d.DisplayConfig).ToArray(); + + public GamelogicEngineSwitch[] RequestedSwitches => Switches.Select(sw => sw as GamelogicEngineSwitch).ToArray(); - public GamelogicEngineLamp[] AvailableLamps => Lamps.Select(lamp => lamp as GamelogicEngineLamp).ToArray(); + public GamelogicEngineLamp[] RequestedLamps => Lamps.Select(lamp => lamp as GamelogicEngineLamp).ToArray(); - public GamelogicEngineCoil[] AvailableCoils => Coils.Select(c => c as GamelogicEngineCoil).ToArray(); + public GamelogicEngineCoil[] RequestedCoils => Coils.Select(c => c as GamelogicEngineCoil).ToArray(); public GamelogicEngineWire[] AvailableWires => Wires; - public event EventHandler OnDisplaysAvailable; + public event EventHandler OnDisplaysRequested; public event EventHandler OnDisplayFrame; public event EventHandler OnLampChanged; public event EventHandler OnLampsChanged; @@ -80,6 +85,11 @@ public PlayerState CurrentPlayerState { } } + public void DisplayFrame(DisplayFrameData data) + { + OnDisplayFrame?.Invoke(this, data); + } + public void SetCurrentPlayer(int value, bool forceNotify = false) { if (!PlayerStates.ContainsKey(value)) { @@ -136,6 +146,9 @@ public void OnInit(Player player, TableApi tableApi, BallManager ballManager) _player = player; BallManager = ballManager; + // request displays + OnDisplaysRequested?.Invoke(this, new RequestedDisplays(Displays.Select(d => d.DisplayConfig).ToArray())); + // create table variables foreach (var propertyDefinition in TableVariableDefinitions) { TableState.AddProperty(propertyDefinition.Instantiate()); diff --git a/Runtime/Nodes/Display.meta b/Runtime/Nodes/Display.meta new file mode 100644 index 0000000..5e05f55 --- /dev/null +++ b/Runtime/Nodes/Display.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4b4aaa88783ab0440a09c493d57aa178 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Display/UpdateDisplayUnit.cs b/Runtime/Nodes/Display/UpdateDisplayUnit.cs new file mode 100644 index 0000000..e645b69 --- /dev/null +++ b/Runtime/Nodes/Display/UpdateDisplayUnit.cs @@ -0,0 +1,98 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Update Display")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Visual Pinball")] + public class UpdateDisplayUnit : GleUnit + { + [Serialize, Inspectable, UnitHeaderInspectable("ID")] + public DisplayDefinition Display { get; private set; } + + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + + [DoNotSerialize] + [PortLabel("Numeric")] + public ValueInput NumericInput { get; private set; } + + [DoNotSerialize] + [PortLabel("Text")] + public ValueInput TextInput { get; private set; } + + [DoNotSerialize] + [PortLabel("Data")] + public ValueInput FrameInput { get; private set; } + + protected override void Definition() + { + InputTrigger = ControlInput(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + if (Display != null) { + if (Display.SupportsNumericInput) { + NumericInput = ValueInput(nameof(NumericInput)); + } + if (Display.SupportsTextInput) { + TextInput = ValueInput(nameof(TextInput)); + } + if (Display.SupportsImageInput) { + TextInput = ValueInput(nameof(FrameInput)); + } + } + + Succession(InputTrigger, OutputTrigger); + } + + private ControlOutput Process(Flow flow) + { + if (!AssertVsGle(flow)) { + throw new InvalidOperationException("Cannot retrieve GLE from unit."); + } + + if (Display != null) { + if (Display.SupportsNumericInput) { + var numValue = (int)flow.GetValue(NumericInput); + VsGle.DisplayFrame(new DisplayFrameData(Display.Id, DisplayFrameFormat.Segment, ScoreConverter.Convert(numValue, Display.Width))); + } + if (Display.SupportsTextInput) { + var strValue = flow.GetValue(TextInput); + if (!string.IsNullOrEmpty(strValue)) { + VsGle.DisplayFrame(new DisplayFrameData(Display.Id, DisplayFrameFormat.Segment, ScoreConverter.Text(strValue, Display.Width))); + } + } + if (Display.SupportsImageInput) { + var byteValue = flow.GetValue(TextInput); + if (byteValue is { Length: > 0 }) { + VsGle.DisplayFrame(new DisplayFrameData(Display.Id, DisplayFrameFormat.Segment, byteValue)); + } + } + } + + return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/Display/UpdateDisplayUnit.cs.meta b/Runtime/Nodes/Display/UpdateDisplayUnit.cs.meta new file mode 100644 index 0000000..1e56842 --- /dev/null +++ b/Runtime/Nodes/Display/UpdateDisplayUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f9d549305547ef04ba8a3f0ffc4af51b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 92b7513bf7233f27faba9b937440b4e0a26682d5 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Thu, 10 Feb 2022 20:26:42 -0500 Subject: [PATCH 24/54] unit: cleanup switch lamp unit before renaming --- .../Descriptors/SwitchLampUnitDescriptor.cs | 20 ++++++-- Editor/Inspectors/LampIdValueInspector.cs | 48 +++++++++++-------- Editor/Widgets/SwitchLampUnitWidget.cs | 4 +- Runtime/Nodes/Lamps/SwitchLampUnit.cs | 22 ++++----- 4 files changed, 55 insertions(+), 39 deletions(-) diff --git a/Editor/Descriptors/SwitchLampUnitDescriptor.cs b/Editor/Descriptors/SwitchLampUnitDescriptor.cs index f36d5f0..1547d44 100644 --- a/Editor/Descriptors/SwitchLampUnitDescriptor.cs +++ b/Editor/Descriptors/SwitchLampUnitDescriptor.cs @@ -16,6 +16,8 @@ // ReSharper disable UnusedType.Global +using System; +using System.Text.RegularExpressions; using Unity.VisualScripting; using VisualPinball.Unity.Editor; using IconSize = VisualPinball.Unity.Editor.IconSize; @@ -31,7 +33,7 @@ public SwitchLampUnitDescriptor(SwitchLampUnit target) : base(target) protected override string DefinedSummary() { - return "This node triggers an event when a switch in the list of given ID is enabled."; + return "This node enabled or disables lamps based on matching a source value with a specifed value."; } protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Light(IconSize.Large, IconColor.Orange)); @@ -40,10 +42,18 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - switch (port.key) { - case nameof(SwitchLampUnit.LampIdValues): - desc.summary = "The Lamp ID and value"; - break; + if (port.key == nameof(SwitchLampUnit.SourceValue)) { + desc.summary = "Source value to use for matching"; + } + else { + var match = new Regex("^(item)([0-9]+)$").Match(port.key); + + if (match.Success) { + var id = int.Parse(match.Groups[2].Value); + + desc.label = $"Lamp ID {id}"; + desc.summary = "Lamp ID to enable if specified Value matches source Value, or disable if specified Value does not match source Value"; + } } } } diff --git a/Editor/Inspectors/LampIdValueInspector.cs b/Editor/Inspectors/LampIdValueInspector.cs index 4ee8ad6..b53b437 100644 --- a/Editor/Inspectors/LampIdValueInspector.cs +++ b/Editor/Inspectors/LampIdValueInspector.cs @@ -10,6 +10,8 @@ namespace VisualPinball.Unity.VisualScripting.Editor public sealed class LampIdValueInspector : Inspector { + private static readonly int LabelPadding = 5; + public LampIdValueInspector(Metadata metadata, Func> getSuggestions) : base(metadata) { Ensure.That(nameof(getSuggestions)).IsNotNull(getSuggestions); @@ -34,19 +36,20 @@ private float GetFieldHeight(float width, GUIContent label) protected override void OnGUI(Rect position, GUIContent label) { + LampIdValue lampIdValue = LampIdValue.FromJson((string)metadata.value); + + var valueLabelWidth = EditorStyles.label.CalcSize(new GUIContent("Value")).x; + var valueWidth = EditorStyles.textField.CalcSize(new GUIContent($"{lampIdValue.value}")).x; + position = BeginLabeledBlock(metadata, position, label); var fieldPosition = position.VerticalSection(ref y, GetFieldHeight(position.width, GUIContent.none)); - - LampIdValue lampIdValue = LampIdValue.FromJson((string)metadata.value); - - var valueWidth = LudiqGUI.GetTextFieldAdaptiveWidth(lampIdValue.value); var textFieldPosition = new Rect ( fieldPosition.x, fieldPosition.y, - fieldPosition.width - Styles.popup.fixedWidth - valueWidth - 60, + fieldPosition.width - valueWidth - LabelPadding - valueLabelWidth - LabelPadding - Styles.popup.fixedWidth, fieldPosition.height ); @@ -81,26 +84,25 @@ protected override void OnGUI(Rect position, GUIContent label) EditorGUI.EndDisabledGroup(); - var valueFieldPosition = new Rect + var valueLabelPosition = new Rect + ( + fieldPosition.x + fieldPosition.width - valueWidth - LabelPadding - valueLabelWidth, + fieldPosition.y, + valueLabelWidth, + fieldPosition.height + ); + + EditorGUI.LabelField(valueLabelPosition, "Value"); + + var valueIntFieldPosition = new Rect ( fieldPosition.x + fieldPosition.width - valueWidth, fieldPosition.y, valueWidth, fieldPosition.height - ); - - var valueLabelFieldPosition = new Rect - ( - fieldPosition.x + fieldPosition.width - valueWidth - 50, - fieldPosition.y, - 50, - fieldPosition.height - ); - - - EditorGUI.LabelField(valueLabelFieldPosition, "Value"); + ); - var newValue = LudiqGUI.DraggableIntField(valueFieldPosition, lampIdValue.value); + var newValue = LudiqGUI.DraggableIntField(valueIntFieldPosition, lampIdValue.value); if (EndBlock(metadata)) { @@ -117,8 +119,12 @@ public override float GetAdaptiveWidth() { LampIdValue lampIdValue = LampIdValue.FromJson((string)metadata.value); - return Mathf.Max(30, EditorStyles.textField.CalcSize(new GUIContent(lampIdValue.id)).x + 1 + Styles.popup.fixedWidth) + - LudiqGUI.GetTextFieldAdaptiveWidth(lampIdValue.value) + 70; + return Mathf.Max(30, + EditorStyles.textField.CalcSize(new GUIContent(lampIdValue.id)).x + 1 + Styles.popup.fixedWidth) + + LabelPadding + + EditorStyles.label.CalcSize(new GUIContent("Value")).x + + LabelPadding + + EditorStyles.textField.CalcSize(new GUIContent($"{lampIdValue.value}")).x; } public static class Styles diff --git a/Editor/Widgets/SwitchLampUnitWidget.cs b/Editor/Widgets/SwitchLampUnitWidget.cs index caccb76..83d415f 100644 --- a/Editor/Widgets/SwitchLampUnitWidget.cs +++ b/Editor/Widgets/SwitchLampUnitWidget.cs @@ -42,7 +42,7 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) } for (var index = 0; index < unit.idCount; index++) { - if (unit.LampIdValues[index] == port) { + if (unit.Items[index] == port) { LampIdValueInspector lampIdInspector = new LampIdValueInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); @@ -57,7 +57,7 @@ private IEnumerable GetNameSuggestions() { return !GleAvailable ? new List() - : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); + : Gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); } } } diff --git a/Runtime/Nodes/Lamps/SwitchLampUnit.cs b/Runtime/Nodes/Lamps/SwitchLampUnit.cs index 2e34f47..1ebbcd7 100644 --- a/Runtime/Nodes/Lamps/SwitchLampUnit.cs +++ b/Runtime/Nodes/Lamps/SwitchLampUnit.cs @@ -66,11 +66,11 @@ public int idCount public ControlOutput OutputTrigger; [DoNotSerialize] - [PortLabel("Value")] - public ValueInput Value { get; private set; } + [PortLabel("Source Value")] + public ValueInput SourceValue { get; private set; } [DoNotSerialize] - public List LampIdValues { get; private set; } + public List Items { get; private set; } private Dictionary _lampIdValueCache = new Dictionary(); @@ -79,15 +79,15 @@ protected override void Definition() InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - Value = ValueInput(nameof(Value)); + SourceValue = ValueInput(nameof(SourceValue)); - LampIdValues = new List(); + Items = new List(); for (var i = 0; i < idCount; i++) { - var valueInput = ValueInput($"Lamp ID {i + 1}", LampIdValue.Empty.ToJson()); - LampIdValues.Add(valueInput); + var item = ValueInput($"item{i + 1}", LampIdValue.Empty.ToJson()); + Items.Add(item); - Requirement(valueInput, InputTrigger); + Requirement(item, InputTrigger); } _lampIdValueCache.Clear(); @@ -102,10 +102,10 @@ private ControlOutput Process(Flow flow) return OutputTrigger; } - var value = flow.GetValue(Value); + var value = flow.GetValue(SourceValue); - foreach (var lampIdValue in LampIdValues) { - var json = flow.GetValue(lampIdValue); + foreach (var item in Items) { + var json = flow.GetValue(item); if (!_lampIdValueCache.ContainsKey(json.GetHashCode())) { _lampIdValueCache[json.GetHashCode()] = LampIdValue.FromJson(json); From ed6f49f260f08e29445bb39bafd4f4e2e2ce52a4 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Thu, 10 Feb 2022 20:31:58 -0500 Subject: [PATCH 25/54] deps: bump visual scripting to 1.7.7 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7b18c80..33ef1f6 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,9 @@ "Visual" ], "unity": "2021.2", - "unityRelease": "8f1", + "unityRelease": "11f1", "dependencies": { - "com.unity.visualscripting": "1.7.6", + "com.unity.visualscripting": "1.7.7", "org.visualpinball.engine.unity": "0.0.1-preview.90" }, "author": "freezy ", From a5746e8a29492de9e868364d1a7a61a8039458e2 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Fri, 11 Feb 2022 06:59:05 -0500 Subject: [PATCH 26/54] misc: fix switch lamp unit to use RequestedLamps --- Editor/Widgets/SwitchLampUnitWidget.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Editor/Widgets/SwitchLampUnitWidget.cs b/Editor/Widgets/SwitchLampUnitWidget.cs index 83d415f..655d600 100644 --- a/Editor/Widgets/SwitchLampUnitWidget.cs +++ b/Editor/Widgets/SwitchLampUnitWidget.cs @@ -57,7 +57,7 @@ private IEnumerable GetNameSuggestions() { return !GleAvailable ? new List() - : Gle.AvailableLamps.Select(lamp => lamp.Id).ToList(); + : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); } } } From 739b1f81f6521417c96343021fc54c0634761340 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 11 Feb 2022 21:27:35 +0100 Subject: [PATCH 27/54] Update score reel scoring. --- .../UpdateDisplayUnitDescriptor.cs | 2 +- .../DisplayDefinitionPropertyDrawer.cs | 185 +++++++++--------- Runtime/Display/DisplayDefinition.cs | 12 +- Runtime/Display/ScoreConverter.cs | 149 -------------- Runtime/Display/ScoreConverter.cs.meta | 11 -- Runtime/Nodes/Display/UpdateDisplayUnit.cs | 79 ++++++-- 6 files changed, 166 insertions(+), 272 deletions(-) delete mode 100644 Runtime/Display/ScoreConverter.cs delete mode 100644 Runtime/Display/ScoreConverter.cs.meta diff --git a/Editor/Descriptors/UpdateDisplayUnitDescriptor.cs b/Editor/Descriptors/UpdateDisplayUnitDescriptor.cs index 518e739..34bf0da 100644 --- a/Editor/Descriptors/UpdateDisplayUnitDescriptor.cs +++ b/Editor/Descriptors/UpdateDisplayUnitDescriptor.cs @@ -47,7 +47,7 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) case nameof(UpdateDisplayUnit.TextInput): desc.summary = "Sets the display to a new text value."; break; - case nameof(UpdateDisplayUnit.FrameInput): + case nameof(UpdateDisplayUnit.SegmentInput): desc.summary = "Updates the display with new frame data."; break; } diff --git a/Editor/PropertyDrawers/DisplayDefinitionPropertyDrawer.cs b/Editor/PropertyDrawers/DisplayDefinitionPropertyDrawer.cs index f594b4f..cfffc74 100644 --- a/Editor/PropertyDrawers/DisplayDefinitionPropertyDrawer.cs +++ b/Editor/PropertyDrawers/DisplayDefinitionPropertyDrawer.cs @@ -1,98 +1,93 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team +// // Visual Pinball Engine +// // Copyright (C) 2022 freezy and VPE Team +// // +// // This program is free software: you can redistribute it and/or modify +// // it under the terms of the GNU General Public License as published by +// // the Free Software Foundation, either version 3 of the License, or +// // (at your option) any later version. +// // +// // This program is distributed in the hope that it will be useful, +// // but WITHOUT ANY WARRANTY; without even the implied warranty of +// // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// // GNU General Public License for more details. +// // +// // You should have received a copy of the GNU General Public License +// // along with this program. If not, see . // -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. +// using UnityEditor; +// using UnityEngine; // -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// namespace VisualPinball.Unity.VisualScripting.Editor +// { +// [CustomPropertyDrawer(typeof(DisplayDefinition))] +// public class DisplayDefinitionPropertyDrawer : PropertyDrawer +// { +// private const float Padding = 2f; +// +// public override float GetPropertyHeight(SerializedProperty property, GUIContent label) +// { +// return base.GetPropertyHeight(property, label); +// // var f = property.FindPropertyRelative(nameof(DisplayDefinition.SupportedFormats)); +// // +// // return 5 * (EditorGUIUtility.singleLineHeight + Padding); +// } +// +// public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) +// { +// var idProperty = property.FindPropertyRelative(nameof(DisplayDefinition.Id)); +// var widthProperty = property.FindPropertyRelative(nameof(DisplayDefinition.Width)); +// var heightProperty = property.FindPropertyRelative(nameof(DisplayDefinition.Height)); +// +// var contentPosition = position; +// contentPosition.height = EditorGUIUtility.singleLineHeight; +// +// //EditorGUI.BeginProperty(position, label, property); +// EditorGUI.PropertyField(contentPosition, idProperty, new GUIContent("ID:")); +// //EditorGUI.EndProperty(); +// position.y += EditorGUIUtility.singleLineHeight + Padding; +// +// contentPosition = EditorGUI.PrefixLabel(position, new GUIContent("Size:")); +// contentPosition.height = EditorGUIUtility.singleLineHeight; +// +// var half = contentPosition.width / 2; +// GUI.skin.label.padding = new RectOffset(3, 3, 6, 6); +// +// //show the X and Y from the point +// var oldLabelWidth = EditorGUIUtility.labelWidth; +// EditorGUIUtility.labelWidth = 14f; +// contentPosition.width *= 0.5f; +// EditorGUI.indentLevel = 0; +// +// // Begin/end property & change check make each field +// // behave correctly when multi-object editing. +// EditorGUI.BeginProperty(contentPosition, label, widthProperty); +// { +// EditorGUI.BeginChangeCheck(); +// var newVal = EditorGUI.IntField(contentPosition, new GUIContent("W"), widthProperty.intValue); +// if (EditorGUI.EndChangeCheck()) +// widthProperty.intValue = newVal; +// } +// EditorGUI.EndProperty(); +// +// contentPosition.x += half; +// EditorGUI.BeginProperty(contentPosition, label, heightProperty); +// { +// EditorGUI.BeginChangeCheck(); +// var newVal = EditorGUI.IntField(contentPosition, new GUIContent("H"), heightProperty.intValue); +// if (EditorGUI.EndChangeCheck()) +// heightProperty.intValue = newVal; +// } +// EditorGUI.EndProperty(); +// +// EditorGUIUtility.labelWidth = oldLabelWidth; +// +// var supportedFormatsProperty = property.FindPropertyRelative(nameof(DisplayDefinition.SupportedFormats)); +// +// position.y += EditorGUIUtility.singleLineHeight + Padding; +// contentPosition = position; +// contentPosition.height = EditorGUIUtility.singleLineHeight; +// EditorGUI.PropertyField(contentPosition, supportedFormatsProperty, new GUIContent("Supported Formats:")); +// } +// } +// } // -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using UnityEditor; -using UnityEngine; - -namespace VisualPinball.Unity.VisualScripting.Editor -{ - [CustomPropertyDrawer(typeof(DisplayDefinition))] - public class DisplayDefinitionPropertyDrawer : PropertyDrawer - { - private const float Padding = 2f; - - public override float GetPropertyHeight(SerializedProperty property, GUIContent label) - { - return 5 * (EditorGUIUtility.singleLineHeight + Padding); - } - - public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) - { - var idProperty = property.FindPropertyRelative(nameof(DisplayDefinition.Id)); - var widthProperty = property.FindPropertyRelative(nameof(DisplayDefinition.Width)); - var heightProperty = property.FindPropertyRelative(nameof(DisplayDefinition.Height)); - - var contentPosition = position; - contentPosition.height = EditorGUIUtility.singleLineHeight; - - //EditorGUI.BeginProperty(position, label, property); - EditorGUI.PropertyField(contentPosition, idProperty, new GUIContent("ID:")); - //EditorGUI.EndProperty(); - position.y += EditorGUIUtility.singleLineHeight + Padding; - - contentPosition = EditorGUI.PrefixLabel(position, new GUIContent("Size:")); - contentPosition.height = EditorGUIUtility.singleLineHeight; - - var half = contentPosition.width / 2; - GUI.skin.label.padding = new RectOffset(3, 3, 6, 6); - - //show the X and Y from the point - var oldLabelWidth = EditorGUIUtility.labelWidth; - EditorGUIUtility.labelWidth = 14f; - contentPosition.width *= 0.5f; - EditorGUI.indentLevel = 0; - - // Begin/end property & change check make each field - // behave correctly when multi-object editing. - EditorGUI.BeginProperty(contentPosition, label, widthProperty); - { - EditorGUI.BeginChangeCheck(); - var newVal = EditorGUI.IntField(contentPosition, new GUIContent("W"), widthProperty.intValue); - if (EditorGUI.EndChangeCheck()) - widthProperty.intValue = newVal; - } - EditorGUI.EndProperty(); - - contentPosition.x += half; - EditorGUI.BeginProperty(contentPosition, label, heightProperty); - { - EditorGUI.BeginChangeCheck(); - var newVal = EditorGUI.IntField(contentPosition, new GUIContent("H"), heightProperty.intValue); - if (EditorGUI.EndChangeCheck()) - heightProperty.intValue = newVal; - } - EditorGUI.EndProperty(); - - EditorGUIUtility.labelWidth = oldLabelWidth; - - var supportsNumericInputProperty = property.FindPropertyRelative(nameof(DisplayDefinition.SupportsNumericInput)); - var supportsTextInputProperty = property.FindPropertyRelative(nameof(DisplayDefinition.SupportsTextInput)); - var supportsImageInputProperty = property.FindPropertyRelative(nameof(DisplayDefinition.SupportsImageInput)); - - - position.y += EditorGUIUtility.singleLineHeight + Padding; - contentPosition = position; - contentPosition.height = EditorGUIUtility.singleLineHeight; - EditorGUI.PropertyField(contentPosition, supportsNumericInputProperty, new GUIContent("Numeric:")); - contentPosition.y += EditorGUIUtility.singleLineHeight + Padding; - EditorGUI.PropertyField(contentPosition, supportsTextInputProperty, new GUIContent("Text:")); - contentPosition.y += EditorGUIUtility.singleLineHeight + Padding; - EditorGUI.PropertyField(contentPosition, supportsImageInputProperty, new GUIContent("Data:")); - } - } -} - diff --git a/Runtime/Display/DisplayDefinition.cs b/Runtime/Display/DisplayDefinition.cs index 1cc9857..6fc5cce 100644 --- a/Runtime/Display/DisplayDefinition.cs +++ b/Runtime/Display/DisplayDefinition.cs @@ -17,6 +17,7 @@ // ReSharper disable InconsistentNaming using System; +using System.Collections.Generic; namespace VisualPinball.Unity.VisualScripting { @@ -27,9 +28,14 @@ public class DisplayDefinition public int Width = 128; public int Height = 32; - public bool SupportsNumericInput; - public bool SupportsTextInput; - public bool SupportsImageInput = true; + public DisplayFrameFormat[] SupportedFormats = { + DisplayFrameFormat.AlphaNumeric + }; + + public bool Supports(DisplayFrameFormat format) + { + return SupportedFormats != null && Array.IndexOf(SupportedFormats, format) >= 0; + } public DisplayConfig DisplayConfig => new(Id, Width, Height); } diff --git a/Runtime/Display/ScoreConverter.cs b/Runtime/Display/ScoreConverter.cs deleted file mode 100644 index 3f60bfa..0000000 --- a/Runtime/Display/ScoreConverter.cs +++ /dev/null @@ -1,149 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using System.Collections.Generic; - -namespace VisualPinball.Unity.VisualScripting -{ - public static class ScoreConverter - { - public static byte[] Convert(int score, int displaySize) - { - return Text(score.ToString().PadLeft(displaySize, ' ')[..displaySize], displaySize); - } - - public static byte[] Text(string text, int displaySize) - { - var source = GenerateAlphaNumeric(text); - const int size = sizeof(short); - var target = new byte[displaySize * size]; - Buffer.BlockCopy(source, 0, target, 0, System.Math.Min(source.Length, displaySize) * size); - return target; - } - - private static ushort[] GenerateAlphaNumeric(string text) - { - var data = new ushort[text.Length]; - for (var i = 0; i < text.Length; i++) { - if (AlphaNumericMap.ContainsKey(text[i])) { - data[i] = AlphaNumericMap[text[i]]; - } else { - data[i] = AlphaNumericMap[' ']; - } - } - return data; - } - - private static readonly Dictionary AlphaNumericMap = new Dictionary { - { '0', 0x443f }, - { '1', 0x406 }, - { '2', 0x85b }, - { '3', 0x80f }, - { '4', 0x866 }, - { '5', 0x1069 }, - { '6', 0x87d }, - { '7', 0x7 }, - { '8', 0x87f }, - { '9', 0x86f }, - { ' ', 0x0 }, - { '!', 0x86 }, - { '"', 0x202 }, - { '#', 0x2a4e }, - { '$', 0x2a6d }, - { '%', 0x7f64 }, - { '&', 0x1359 }, - { '\'', 0x200 }, - { '(', 0x1400 }, - { ')', 0x4100 }, - { '*', 0x7f40 }, - { '+', 0x2a40 }, - { ',', 0x4000 }, - { '-', 0x840 }, - { '.', 0x80 }, - { '/', 0x4400 }, - { ':', 0x2200 }, - { ';', 0x4200 }, - { '<', 0x1440 }, - { '=', 0x848 }, - { '>', 0x4900 }, - { '?', 0x2883 }, - { '@', 0xa3b }, - { 'A', 0x877 }, - { 'B', 0x2a0f }, - { 'C', 0x39 }, - { 'D', 0x220f }, - { 'E', 0x79 }, - { 'F', 0x71 }, - { 'G', 0x83d }, - { 'H', 0x876 }, - { 'I', 0x2209 }, - { 'J', 0x1e }, - { 'K', 0x1470 }, - { 'L', 0x38 }, - { 'M', 0x536 }, - { 'N', 0x1136 }, - { 'O', 0x3f }, - { 'P', 0x873 }, - { 'Q', 0x103f }, - { 'R', 0x1873 }, - { 'S', 0x86d }, - { 'T', 0x2201 }, - { 'U', 0x3e }, - { 'V', 0x4430 }, - { 'W', 0x5036 }, - { 'X', 0x5500 }, - { 'Y', 0x86e }, - { 'Z', 0x4409 }, - { '[', 0x39 }, - { '\\', 0x1100 }, - { ']', 0xf }, - { '^', 0x5000 }, - { '_', 0x8 }, - { '`', 0x100 }, - { 'a', 0x2058 }, - { 'b', 0x1078 }, - { 'c', 0x858 }, - { 'd', 0x480e }, - { 'e', 0x4058 }, - { 'f', 0x2c40 }, - { 'g', 0xc0e }, - { 'h', 0x2070 }, - { 'i', 0x2000 }, - { 'j', 0x4210 }, - { 'k', 0x3600 }, - { 'l', 0x30 }, - { 'm', 0x2854 }, - { 'n', 0x2050 }, - { 'o', 0x85c }, - { 'p', 0x170 }, - { 'q', 0xc06 }, - { 'r', 0x50 }, - { 's', 0x1808 }, - { 't', 0x78 }, - { 'u', 0x1c }, - { 'v', 0x4010 }, - { 'w', 0x5014 }, - { 'x', 0x5500 }, - { 'y', 0xa0e }, - { 'z', 0x4048 }, - { '{', 0x4149 }, - { '|', 0x2200 }, - { '}', 0x1c09 }, - { '~', 0x4c40 }, - }; - } -} diff --git a/Runtime/Display/ScoreConverter.cs.meta b/Runtime/Display/ScoreConverter.cs.meta deleted file mode 100644 index 054d987..0000000 --- a/Runtime/Display/ScoreConverter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8e7455488440dc144880395ae63d2bc4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/Display/UpdateDisplayUnit.cs b/Runtime/Nodes/Display/UpdateDisplayUnit.cs index e645b69..3bc4cc2 100644 --- a/Runtime/Nodes/Display/UpdateDisplayUnit.cs +++ b/Runtime/Nodes/Display/UpdateDisplayUnit.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using System; +using System.Text; using Unity.VisualScripting; namespace VisualPinball.Unity.VisualScripting @@ -44,8 +45,24 @@ public class UpdateDisplayUnit : GleUnit public ValueInput TextInput { get; private set; } [DoNotSerialize] - [PortLabel("Data")] - public ValueInput FrameInput { get; private set; } + [PortLabel("Segment Data")] + public ValueInput SegmentInput { get; private set; } + + [DoNotSerialize] + [PortLabel("DMD (2-bit)")] + public ValueInput Dmd2Input { get; private set; } + + [DoNotSerialize] + [PortLabel("DMD (4-bit)")] + public ValueInput Dmd4Input { get; private set; } + + [DoNotSerialize] + [PortLabel("DMD (8-bit)")] + public ValueInput Dmd8Input { get; private set; } + + [DoNotSerialize] + [PortLabel("DMD (RGB24)")] + public ValueInput Dmd24Input { get; private set; } protected override void Definition() { @@ -53,14 +70,26 @@ protected override void Definition() OutputTrigger = ControlOutput(nameof(OutputTrigger)); if (Display != null) { - if (Display.SupportsNumericInput) { + if (Display.Supports(DisplayFrameFormat.Numeric)) { NumericInput = ValueInput(nameof(NumericInput)); } - if (Display.SupportsTextInput) { + if (Display.Supports(DisplayFrameFormat.AlphaNumeric)) { TextInput = ValueInput(nameof(TextInput)); } - if (Display.SupportsImageInput) { - TextInput = ValueInput(nameof(FrameInput)); + if (Display.Supports(DisplayFrameFormat.Segment)) { + SegmentInput = ValueInput(nameof(SegmentInput)); + } + if (Display.Supports(DisplayFrameFormat.Dmd2)) { + Dmd2Input = ValueInput(nameof(Dmd2Input)); + } + if (Display.Supports(DisplayFrameFormat.Dmd4)) { + Dmd4Input = ValueInput(nameof(Dmd4Input)); + } + if (Display.Supports(DisplayFrameFormat.Dmd8)) { + Dmd8Input = ValueInput(nameof(Dmd8Input)); + } + if (Display.Supports(DisplayFrameFormat.Dmd24)) { + Dmd24Input = ValueInput(nameof(Dmd24Input)); } } @@ -74,22 +103,46 @@ private ControlOutput Process(Flow flow) } if (Display != null) { - if (Display.SupportsNumericInput) { - var numValue = (int)flow.GetValue(NumericInput); - VsGle.DisplayFrame(new DisplayFrameData(Display.Id, DisplayFrameFormat.Segment, ScoreConverter.Convert(numValue, Display.Width))); + if (Display.Supports(DisplayFrameFormat.Numeric) && NumericInput.hasValidConnection) { + var numValue = flow.GetValue(NumericInput); + VsGle.DisplayFrame(new DisplayFrameData(Display.Id, DisplayFrameFormat.Numeric, BitConverter.GetBytes(numValue))); } - if (Display.SupportsTextInput) { + if (Display.Supports(DisplayFrameFormat.AlphaNumeric) && flow.IsLocal(TextInput)) { var strValue = flow.GetValue(TextInput); if (!string.IsNullOrEmpty(strValue)) { - VsGle.DisplayFrame(new DisplayFrameData(Display.Id, DisplayFrameFormat.Segment, ScoreConverter.Text(strValue, Display.Width))); + VsGle.DisplayFrame(new DisplayFrameData(Display.Id, DisplayFrameFormat.AlphaNumeric, Encoding.UTF8.GetBytes(strValue))); } } - if (Display.SupportsImageInput) { - var byteValue = flow.GetValue(TextInput); + if (Display.Supports(DisplayFrameFormat.Segment) && SegmentInput.hasValidConnection) { + var byteValue = flow.GetValue(SegmentInput); if (byteValue is { Length: > 0 }) { VsGle.DisplayFrame(new DisplayFrameData(Display.Id, DisplayFrameFormat.Segment, byteValue)); } } + if (Display.Supports(DisplayFrameFormat.Dmd2) && Dmd2Input.hasValidConnection) { + var byteValue = flow.GetValue(Dmd2Input); + if (byteValue is { Length: > 0 }) { + VsGle.DisplayFrame(new DisplayFrameData(Display.Id, DisplayFrameFormat.Dmd2, byteValue)); + } + } + if (Display.Supports(DisplayFrameFormat.Dmd4) && Dmd4Input.hasValidConnection) { + var byteValue = flow.GetValue(Dmd4Input); + if (byteValue is { Length: > 0 }) { + VsGle.DisplayFrame(new DisplayFrameData(Display.Id, DisplayFrameFormat.Dmd4, byteValue)); + } + } + if (Display.Supports(DisplayFrameFormat.Dmd8) && Dmd8Input.hasValidConnection) { + var byteValue = flow.GetValue(Dmd8Input); + if (byteValue is { Length: > 0 }) { + VsGle.DisplayFrame(new DisplayFrameData(Display.Id, DisplayFrameFormat.Dmd8, byteValue)); + } + } + if (Display.Supports(DisplayFrameFormat.Dmd24) && Dmd24Input.hasValidConnection) { + var byteValue = flow.GetValue(Dmd24Input); + if (byteValue is { Length: > 0 }) { + VsGle.DisplayFrame(new DisplayFrameData(Display.Id, DisplayFrameFormat.Dmd24, byteValue)); + } + } } return OutputTrigger; From 8c8ec42bf6a146d04d30728201d216916effcd87 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Sat, 12 Feb 2022 08:04:43 -0500 Subject: [PATCH 28/54] misc: cleanup default value keys --- Editor/Descriptors/GetSwitchUnitDescriptor.cs | 20 +++++---- Editor/Descriptors/PulseCoilUnitDescriptor.cs | 20 +++++---- Editor/Descriptors/SetCoilUnitDescriptor.cs | 20 +++++---- .../SwitchEnabledEventUnitDescriptor.cs | 12 ++++-- .../Descriptors/SwitchLampUnitDescriptor.cs | 4 +- Editor/Widgets/GetSwitchUnitWidget.cs | 8 ++-- Editor/Widgets/PulseCoilUnitWidget.cs | 8 ++-- Editor/Widgets/SetCoilUnitWidget.cs | 8 ++-- .../Widgets/SwitchEnabledEventUnitWidget.cs | 8 ++-- Editor/Widgets/SwitchLampUnitWidget.cs | 6 +-- Runtime/Nodes/Coils/PulseCoilUnit.cs | 32 +++++++------- Runtime/Nodes/Coils/SetCoilUnit.cs | 30 ++++++------- Runtime/Nodes/Lamps/LampIdValue.cs | 42 +++++++++++++++++++ Runtime/Nodes/Lamps/LampIdValue.cs.meta | 11 +++++ Runtime/Nodes/Lamps/SwitchLampUnit.cs | 38 ++++------------- Runtime/Nodes/Switches/GetSwitchUnit.cs | 24 +++++------ .../Nodes/Switches/SwitchEnabledEventUnit.cs | 24 +++++------ 17 files changed, 185 insertions(+), 130 deletions(-) create mode 100644 Runtime/Nodes/Lamps/LampIdValue.cs create mode 100644 Runtime/Nodes/Lamps/LampIdValue.cs.meta diff --git a/Editor/Descriptors/GetSwitchUnitDescriptor.cs b/Editor/Descriptors/GetSwitchUnitDescriptor.cs index 01e59a8..a9fc660 100644 --- a/Editor/Descriptors/GetSwitchUnitDescriptor.cs +++ b/Editor/Descriptors/GetSwitchUnitDescriptor.cs @@ -16,6 +16,7 @@ // ReSharper disable UnusedType.Global +using System.Text.RegularExpressions; using Unity.VisualScripting; using VisualPinball.Unity.Editor; using IconSize = VisualPinball.Unity.Editor.IconSize; @@ -40,13 +41,18 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - switch (port.key) { - case nameof(GetSwitchUnit.Ids): - desc.summary = "The IDs of the switches for which to get the current status."; - break; - case nameof(GetSwitchUnit.IsEnabled): - desc.summary = "Whether the switch is enabled."; - break; + if (port.key == nameof(GetSwitchUnit.IsEnabled)) { + desc.summary = "Whether the switch is enabled."; + } + else { + var match = new Regex("^(item)([0-9]+)$").Match(port.key); + + if (match.Success) { + var id = int.Parse(match.Groups[2].Value) + 1; + + desc.label = $"Switch ID {id}"; + desc.summary = $"Switch ID {id} to check if enabled."; + } } } } diff --git a/Editor/Descriptors/PulseCoilUnitDescriptor.cs b/Editor/Descriptors/PulseCoilUnitDescriptor.cs index 86c5443..80a6c67 100644 --- a/Editor/Descriptors/PulseCoilUnitDescriptor.cs +++ b/Editor/Descriptors/PulseCoilUnitDescriptor.cs @@ -16,6 +16,7 @@ // ReSharper disable UnusedType.Global +using System.Text.RegularExpressions; using Unity.VisualScripting; using VisualPinball.Unity.Editor; @@ -43,13 +44,18 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - switch (port.key) { - case nameof(PulseCoilUnit.Ids): - desc.summary = "The IDs of the coils to be pulsed."; - break; - case nameof(PulseCoilUnit.PulseDuration): - desc.summary = "The time in milliseconds until the coils are disabled again."; - break; + if (port.key == nameof(PulseCoilUnit.PulseDuration)) { + desc.summary = "The time in milliseconds until the coils are disabled again."; + } + else { + var match = new Regex("^(item)([0-9]+)$").Match(port.key); + + if (match.Success) { + var id = int.Parse(match.Groups[2].Value) + 1; + + desc.label = $"Coil ID {id}"; + desc.summary = $"Coil ID {id} of the coil to be pulsed."; + } } } } diff --git a/Editor/Descriptors/SetCoilUnitDescriptor.cs b/Editor/Descriptors/SetCoilUnitDescriptor.cs index 24222aa..a0f35bf 100644 --- a/Editor/Descriptors/SetCoilUnitDescriptor.cs +++ b/Editor/Descriptors/SetCoilUnitDescriptor.cs @@ -16,6 +16,7 @@ // ReSharper disable UnusedType.Global +using System.Text.RegularExpressions; using Unity.VisualScripting; using VisualPinball.Unity.Editor; @@ -43,13 +44,18 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - switch (port.key) { - case nameof(SetCoilUnit.Ids): - desc.summary = "The IDs of the coils to be set."; - break; - case nameof(SetCoilUnit.IsEnabled): - desc.summary = "The value to assign to the coils."; - break; + if (port.key == nameof(SetCoilUnit.IsEnabled)) { + desc.summary = "The value to assign to the coils."; + } + else { + var match = new Regex("^(item)([0-9]+)$").Match(port.key); + + if (match.Success) { + var id = int.Parse(match.Groups[2].Value) + 1; + + desc.label = $"Coil ID {id}"; + desc.summary = $"Coil ID {id} of the coil to be set."; + } } } } diff --git a/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs b/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs index 8b1fea0..f39197b 100644 --- a/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs +++ b/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs @@ -16,6 +16,7 @@ // ReSharper disable UnusedType.Global +using System.Text.RegularExpressions; using Unity.VisualScripting; namespace VisualPinball.Unity.VisualScripting.Editor @@ -38,10 +39,13 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - switch (port.key) { - case nameof(SwitchEnabledEventUnit.Ids): - desc.summary = "The IDs of the switches for which to look for enabled status."; - break; + var match = new Regex("^(item)([0-9]+)$").Match(port.key); + + if (match.Success) { + var id = int.Parse(match.Groups[2].Value) + 1; + + desc.label = $"Switch ID {id}"; + desc.summary = $"Switch ID {id} to look for enabled status."; } } } diff --git a/Editor/Descriptors/SwitchLampUnitDescriptor.cs b/Editor/Descriptors/SwitchLampUnitDescriptor.cs index 1547d44..2bf0ef5 100644 --- a/Editor/Descriptors/SwitchLampUnitDescriptor.cs +++ b/Editor/Descriptors/SwitchLampUnitDescriptor.cs @@ -49,10 +49,10 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) var match = new Regex("^(item)([0-9]+)$").Match(port.key); if (match.Success) { - var id = int.Parse(match.Groups[2].Value); + var id = int.Parse(match.Groups[2].Value) + 1; desc.label = $"Lamp ID {id}"; - desc.summary = "Lamp ID to enable if specified Value matches source Value, or disable if specified Value does not match source Value"; + desc.summary = $"Lamp ID {id} to enable if specified Value matches source Value, or disable if specified Value does not match source Value"; } } } diff --git a/Editor/Widgets/GetSwitchUnitWidget.cs b/Editor/Widgets/GetSwitchUnitWidget.cs index 86a0413..a93011e 100644 --- a/Editor/Widgets/GetSwitchUnitWidget.cs +++ b/Editor/Widgets/GetSwitchUnitWidget.cs @@ -35,14 +35,14 @@ public GetSwitchUnitWidget(FlowCanvas canvas, GetSwitchUnit unit) : base(canvas, public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (_switchIdInspectorConstructorList.Count() < unit.idCount) { - for (var index = 0; index < unit.idCount - _switchIdInspectorConstructorList.Count(); index++) { + if (_switchIdInspectorConstructorList.Count() < unit.itemCount) { + for (var index = 0; index < unit.itemCount - _switchIdInspectorConstructorList.Count(); index++) { _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); } } - for (var index = 0; index < unit.idCount; index++) { - if (unit.Ids[index] == port) { + for (var index = 0; index < unit.itemCount; index++) { + if (unit.Items[index] == port) { VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); diff --git a/Editor/Widgets/PulseCoilUnitWidget.cs b/Editor/Widgets/PulseCoilUnitWidget.cs index 8b1de17..70df50e 100644 --- a/Editor/Widgets/PulseCoilUnitWidget.cs +++ b/Editor/Widgets/PulseCoilUnitWidget.cs @@ -35,14 +35,14 @@ public PulseCoilUnitWidget(FlowCanvas canvas, PulseCoilUnit unit) : base(canvas, public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (_coilIdInspectorConstructorList.Count() < unit.idCount) { - for (var index = 0; index < unit.idCount - _coilIdInspectorConstructorList.Count(); index++) { + if (_coilIdInspectorConstructorList.Count() < unit.itemCount) { + for (var index = 0; index < unit.itemCount - _coilIdInspectorConstructorList.Count(); index++) { _coilIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); } } - for (var index = 0; index < unit.idCount; index++) { - if (unit.Ids[index] == port) { + for (var index = 0; index < unit.itemCount; index++) { + if (unit.Items[index] == port) { VariableNameInspector coilIdInspector = new VariableNameInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref coilIdInspector, meta, _coilIdInspectorConstructorList[index]); diff --git a/Editor/Widgets/SetCoilUnitWidget.cs b/Editor/Widgets/SetCoilUnitWidget.cs index 37e74f9..54fd412 100644 --- a/Editor/Widgets/SetCoilUnitWidget.cs +++ b/Editor/Widgets/SetCoilUnitWidget.cs @@ -35,14 +35,14 @@ public SetCoilUnitWidget(FlowCanvas canvas, SetCoilUnit unit) : base(canvas, uni public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (_coilIdInspectorConstructorList.Count() < unit.idCount) { - for (var index = 0; index < unit.idCount - _coilIdInspectorConstructorList.Count(); index++) { + if (_coilIdInspectorConstructorList.Count() < unit.itemCount) { + for (var index = 0; index < unit.itemCount - _coilIdInspectorConstructorList.Count(); index++) { _coilIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); } } - for (var index = 0; index < unit.idCount; index++) { - if (unit.Ids[index] == port) { + for (var index = 0; index < unit.itemCount; index++) { + if (unit.Items[index] == port) { VariableNameInspector coilIdInspector = new VariableNameInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref coilIdInspector, meta, _coilIdInspectorConstructorList[index]); diff --git a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs index 2628e78..beec3e8 100644 --- a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs @@ -35,14 +35,14 @@ public SwitchEnabledEventUnitWidget(FlowCanvas canvas, SwitchEnabledEventUnit un public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (_switchIdInspectorConstructorList.Count() < unit.idCount) { - for (var index = 0; index < unit.idCount - _switchIdInspectorConstructorList.Count(); index++) { + if (_switchIdInspectorConstructorList.Count() < unit.itemCount) { + for (var index = 0; index < unit.itemCount - _switchIdInspectorConstructorList.Count(); index++) { _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); } } - for (var index = 0; index < unit.idCount; index++) { - if (unit.Ids[index] == port) { + for (var index = 0; index < unit.itemCount; index++) { + if (unit.Items[index] == port) { VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); diff --git a/Editor/Widgets/SwitchLampUnitWidget.cs b/Editor/Widgets/SwitchLampUnitWidget.cs index 655d600..8ccf23b 100644 --- a/Editor/Widgets/SwitchLampUnitWidget.cs +++ b/Editor/Widgets/SwitchLampUnitWidget.cs @@ -35,13 +35,13 @@ public SwitchLampUnitWidget(FlowCanvas canvas, SwitchLampUnit unit) : base(canva public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (_lampIdInspectorConstructorList.Count() < unit.idCount) { - for (var index = 0; index < unit.idCount - _lampIdInspectorConstructorList.Count(); index++) { + if (_lampIdInspectorConstructorList.Count() < unit.itemCount) { + for (var index = 0; index < unit.itemCount - _lampIdInspectorConstructorList.Count(); index++) { _lampIdInspectorConstructorList.Add(meta => new LampIdValueInspector(meta, GetNameSuggestions)); } } - for (var index = 0; index < unit.idCount; index++) { + for (var index = 0; index < unit.itemCount; index++) { if (unit.Items[index] == port) { LampIdValueInspector lampIdInspector = new LampIdValueInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); diff --git a/Runtime/Nodes/Coils/PulseCoilUnit.cs b/Runtime/Nodes/Coils/PulseCoilUnit.cs index db8a3ce..5d99316 100644 --- a/Runtime/Nodes/Coils/PulseCoilUnit.cs +++ b/Runtime/Nodes/Coils/PulseCoilUnit.cs @@ -33,19 +33,19 @@ public class PulseCoilUnit : GleUnit [PortLabelHidden] public ControlOutput OutputTrigger; - [SerializeAs(nameof(idCount))] - private int _idCount = 1; + [SerializeAs(nameof(itemCount))] + private int _itemCount = 1; [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Coil IDs")] - public int idCount + public int itemCount { - get => _idCount; - set => _idCount = Mathf.Clamp(value, 1, 10); + get => _itemCount; + set => _itemCount = Mathf.Clamp(value, 1, 10); } [DoNotSerialize] - public List Ids { get; private set; } + public List Items { get; private set; } [DoNotSerialize] [PortLabel("Duration (ms)")] @@ -56,16 +56,16 @@ protected override void Definition() InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - Ids = new List(); + Items = new List(); - for (var i = 0; i < idCount; i++) { - var id = ValueInput("Coil ID " + (i + 1), string.Empty); - Ids.Add(id); + for (var i = 0; i < itemCount; i++) { + var item = ValueInput($"item{i}", string.Empty); + Items.Add(item); - Requirement(id, InputTrigger); + Requirement(item, InputTrigger); } - PulseDuration = ValueInput(nameof(PulseDuration), 80); + PulseDuration = ValueInput(nameof(PulseDuration), 80); Succession(InputTrigger, OutputTrigger); } @@ -84,11 +84,11 @@ private ControlOutput Process(Flow flow) var pulseDuration = flow.GetValue(PulseDuration); - foreach (var id in Ids) { - var idValue = flow.GetValue(id); + foreach (var item in Items) { + var id = flow.GetValue(item); - Gle.SetCoil(idValue, true); - Player.ScheduleAction(pulseDuration, () => Gle.SetCoil(idValue, false)); + Gle.SetCoil(id, true); + Player.ScheduleAction(pulseDuration, () => Gle.SetCoil(id, false)); } return OutputTrigger; diff --git a/Runtime/Nodes/Coils/SetCoilUnit.cs b/Runtime/Nodes/Coils/SetCoilUnit.cs index 4ebef76..c9ba861 100644 --- a/Runtime/Nodes/Coils/SetCoilUnit.cs +++ b/Runtime/Nodes/Coils/SetCoilUnit.cs @@ -33,19 +33,19 @@ public class SetCoilUnit : GleUnit [PortLabelHidden] public ControlOutput OutputTrigger; - [SerializeAs(nameof(idCount))] - private int _idCount = 1; + [SerializeAs(nameof(itemCount))] + private int _itemCount = 1; [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Coil IDs")] - public int idCount + public int itemCount { - get => _idCount; - set => _idCount = Mathf.Clamp(value, 1, 10); + get => _itemCount; + set => _itemCount = Mathf.Clamp(value, 1, 10); } [DoNotSerialize] - public List Ids { get; private set; } + public List Items { get; private set; } [DoNotSerialize] [PortLabel("Value")] @@ -56,16 +56,16 @@ protected override void Definition() InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - Ids = new List(); + Items = new List(); - for (var i = 0; i < idCount; i++) { - var id = ValueInput("Coil ID " + (i + 1), string.Empty); - Ids.Add(id); + for (var i = 0; i < itemCount; i++) { + var item = ValueInput($"item{i}", string.Empty); + Items.Add(item); - Requirement(id, InputTrigger); + Requirement(item, InputTrigger); } - IsEnabled = ValueInput(nameof(IsEnabled), false); + IsEnabled = ValueInput(nameof(IsEnabled), false); Succession(InputTrigger, OutputTrigger); } @@ -79,10 +79,10 @@ private ControlOutput Process(Flow flow) var isEnabled = flow.GetValue(IsEnabled); - foreach (var id in Ids) { - var idValue = flow.GetValue(id); + foreach (var item in Items) { + var id = flow.GetValue(item); - Gle.SetCoil(idValue, isEnabled); + Gle.SetCoil(id, isEnabled); } return OutputTrigger; diff --git a/Runtime/Nodes/Lamps/LampIdValue.cs b/Runtime/Nodes/Lamps/LampIdValue.cs new file mode 100644 index 0000000..23a1f0e --- /dev/null +++ b/Runtime/Nodes/Lamps/LampIdValue.cs @@ -0,0 +1,42 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [Serializable] + public struct LampIdValue + { + public string id; + public int value; + + public static LampIdValue FromJson(string json) + { + return JsonUtility.FromJson(json); + } + + public string ToJson() + { + return JsonUtility.ToJson(this); + } + + public static readonly LampIdValue Empty = new LampIdValue { id = string.Empty, value = 0 }; + } +} diff --git a/Runtime/Nodes/Lamps/LampIdValue.cs.meta b/Runtime/Nodes/Lamps/LampIdValue.cs.meta new file mode 100644 index 0000000..798744e --- /dev/null +++ b/Runtime/Nodes/Lamps/LampIdValue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 525f249f3873543de85effde500fc73c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Lamps/SwitchLampUnit.cs b/Runtime/Nodes/Lamps/SwitchLampUnit.cs index 1ebbcd7..0708416 100644 --- a/Runtime/Nodes/Lamps/SwitchLampUnit.cs +++ b/Runtime/Nodes/Lamps/SwitchLampUnit.cs @@ -14,47 +14,27 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; namespace VisualPinball.Unity.VisualScripting { - [Serializable] - public struct LampIdValue - { - public string id; - public int value; - - public static LampIdValue FromJson(string json) - { - return JsonUtility.FromJson(json); - } - - public string ToJson() - { - return JsonUtility.ToJson(this); - } - - public static readonly LampIdValue Empty = new LampIdValue { id = string.Empty, value = 0 }; - } - [UnitShortTitle("Switch Lamp")] [UnitTitle("Switch Lamp (ID, match value)")] [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Visual Pinball")] public class SwitchLampUnit : GleUnit { - [SerializeAs(nameof(idCount))] - private int _idCount = 1; + [SerializeAs(nameof(itemCount))] + private int _itemCount = 1; [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Lamp IDs")] - public int idCount + public int itemCount { - get => _idCount; - set => _idCount = Mathf.Clamp(value, 1, 10); + get => _itemCount; + set => _itemCount = Mathf.Clamp(value, 1, 10); } [DoNotSerialize] @@ -83,8 +63,8 @@ protected override void Definition() Items = new List(); - for (var i = 0; i < idCount; i++) { - var item = ValueInput($"item{i + 1}", LampIdValue.Empty.ToJson()); + for (var i = 0; i < itemCount; i++) { + var item = ValueInput($"item{i}", LampIdValue.Empty.ToJson()); Items.Add(item); Requirement(item, InputTrigger); @@ -111,8 +91,8 @@ private ControlOutput Process(Flow flow) _lampIdValueCache[json.GetHashCode()] = LampIdValue.FromJson(json); } - var obj = _lampIdValueCache[json.GetHashCode()]; - Gle.SetLamp(obj.id, obj.value == value ? 255f : 0f); + var lampIdValue = _lampIdValueCache[json.GetHashCode()]; + Gle.SetLamp(lampIdValue.id, lampIdValue.value == value ? 255f : 0f); } return OutputTrigger; diff --git a/Runtime/Nodes/Switches/GetSwitchUnit.cs b/Runtime/Nodes/Switches/GetSwitchUnit.cs index ab8c841..443d909 100644 --- a/Runtime/Nodes/Switches/GetSwitchUnit.cs +++ b/Runtime/Nodes/Switches/GetSwitchUnit.cs @@ -25,19 +25,19 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Visual Pinball")] public class GetSwitchUnit : GleUnit { - [SerializeAs(nameof(idCount))] - private int _idCount = 1; + [SerializeAs(nameof(itemCount))] + private int _itemCount = 1; [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Switch IDs")] - public int idCount + public int itemCount { - get => _idCount; - set => _idCount = Mathf.Clamp(value, 1, 10); + get => _itemCount; + set => _itemCount = Mathf.Clamp(value, 1, 10); } [DoNotSerialize] - public List Ids { get; private set; } + public List Items { get; private set; } [DoNotSerialize] [PortLabel("Is Enabled")] @@ -45,11 +45,11 @@ public int idCount protected override void Definition() { - Ids = new List(); + Items = new List(); - for (var i = 0; i < idCount; i++) { - var id = ValueInput("Switch ID " + (i + 1), string.Empty); - Ids.Add(id); + for (var i = 0; i < itemCount; i++) { + var item = ValueInput($"item{i}", string.Empty); + Items.Add(item); } IsEnabled = ValueOutput(nameof(IsEnabled), GetEnabled); @@ -62,8 +62,8 @@ private bool GetEnabled(Flow flow) return false; } - foreach (var id in Ids) { - if (!Gle.GetSwitch(flow.GetValue(id))) { + foreach (var item in Items) { + if (!Gle.GetSwitch(flow.GetValue(item))) { return false; } } diff --git a/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs index 2b371dc..71f7d83 100644 --- a/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs +++ b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs @@ -25,19 +25,19 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Events\\Visual Pinball")] public class SwitchEnabledEventUnit : GleEventUnit { - [SerializeAs(nameof(idCount))] - private int _idCount = 1; + [SerializeAs(nameof(itemCount))] + private int _itemCount = 1; [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Switch IDs")] - public int idCount + public int itemCount { - get => _idCount; - set => _idCount = Mathf.Clamp(value, 1, 10); + get => _itemCount; + set => _itemCount = Mathf.Clamp(value, 1, 10); } [DoNotSerialize] - public List Ids { get; private set; } + public List Items { get; private set; } [DoNotSerialize] protected override bool register => true; @@ -49,18 +49,18 @@ protected override void Definition() { base.Definition(); - Ids = new List(); + Items = new List(); - for (var i = 0; i < idCount; i++) { - var id = ValueInput("Switch ID " + (i + 1), string.Empty); - Ids.Add(id); + for (var i = 0; i < itemCount; i++) { + var item = ValueInput($"item{i}", string.Empty); + Items.Add(item); } } protected override bool ShouldTrigger(Flow flow, SwitchEventArgs2 args) { - foreach(var id in Ids) { - if (flow.GetValue(id) == args.Id && args.IsEnabled) { + foreach(var item in Items) { + if (flow.GetValue(item) == args.Id && args.IsEnabled) { return true; } } From 8033dbd61f4420ac74bfa008f4ce62c0772807c8 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 12 Feb 2022 23:33:02 +0100 Subject: [PATCH 29/54] Add "next player" option to player state change node. --- .../PlayerState/ChangePlayerStateUnit.cs | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs b/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs index 9ed3778..20b97e5 100644 --- a/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs +++ b/Runtime/Nodes/PlayerState/ChangePlayerStateUnit.cs @@ -15,8 +15,9 @@ // along with this program. If not, see . using System; +using System.Linq; +using NLog; using Unity.VisualScripting; -using UnityEngine; namespace VisualPinball.Unity.VisualScripting { @@ -25,6 +26,9 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Visual Pinball/Variables")] public class ChangePlayerStateUnit : GleUnit { + [Serialize, Inspectable, UnitHeaderInspectable("Next Player")] + public bool NextPlayer { get; set; } + [DoNotSerialize] [PortLabelHidden] public ControlInput InputTrigger; @@ -37,14 +41,18 @@ public class ChangePlayerStateUnit : GleUnit [PortLabel("Player ID")] public ValueInput PlayerId { get; private set; } + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + protected override void Definition() { - PlayerId = ValueInput(nameof(PlayerId), 0); - InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - Requirement(PlayerId, InputTrigger); + if (!NextPlayer) { + PlayerId = ValueInput(nameof(PlayerId), 0); + Requirement(PlayerId, InputTrigger); + } + Succession(InputTrigger, OutputTrigger); } @@ -54,7 +62,24 @@ private ControlOutput Process(Flow flow) throw new InvalidOperationException("Cannot retrieve GLE from unit."); } - VsGle.SetCurrentPlayer(flow.GetValue(PlayerId)); + int playerId; + if (NextPlayer) { + var lastPlayer = VsGle.PlayerStates.Keys.Max(); + if (VsGle.CurrentPlayerState.Id == lastPlayer) { + playerId = VsGle.PlayerStates.Keys.Min(); + + } else if (VsGle.PlayerStates.ContainsKey(VsGle.CurrentPlayerState.Id + 1)) { + playerId = VsGle.CurrentPlayerState.Id + 1; + + } else { + Logger.Warn($"Non-existent next player {VsGle.CurrentPlayerState.Id + 1}."); + playerId = VsGle.CurrentPlayerState.Id; + } + } else { + playerId = flow.GetValue(PlayerId); + } + + VsGle.SetCurrentPlayer(playerId); return OutputTrigger; } From 7a3ee705cf26a4aefd6453d7f4733643347edb10 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 13 Feb 2022 00:03:06 +0100 Subject: [PATCH 30/54] Add get player ID node. --- .../Descriptors/GetPlayerIdUnitDescriptor.cs | 50 ++++++++++++++++ .../GetPlayerIdUnitDescriptor.cs.meta | 11 ++++ Editor/Widgets/GetPlayerIdWidget.cs | 30 ++++++++++ Editor/Widgets/GetPlayerIdWidget.cs.meta | 11 ++++ Runtime/Nodes/PlayerState/GetPlayerIdUnit.cs | 58 +++++++++++++++++++ .../Nodes/PlayerState/GetPlayerIdUnit.cs.meta | 11 ++++ 6 files changed, 171 insertions(+) create mode 100644 Editor/Descriptors/GetPlayerIdUnitDescriptor.cs create mode 100644 Editor/Descriptors/GetPlayerIdUnitDescriptor.cs.meta create mode 100644 Editor/Widgets/GetPlayerIdWidget.cs create mode 100644 Editor/Widgets/GetPlayerIdWidget.cs.meta create mode 100644 Runtime/Nodes/PlayerState/GetPlayerIdUnit.cs create mode 100644 Runtime/Nodes/PlayerState/GetPlayerIdUnit.cs.meta diff --git a/Editor/Descriptors/GetPlayerIdUnitDescriptor.cs b/Editor/Descriptors/GetPlayerIdUnitDescriptor.cs new file mode 100644 index 0000000..78be8b1 --- /dev/null +++ b/Editor/Descriptors/GetPlayerIdUnitDescriptor.cs @@ -0,0 +1,50 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; +using VisualPinball.Unity.Editor; +using IconSize = VisualPinball.Unity.Editor.IconSize; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(GetPlayerIdUnit))] + public class GetPlayerIdUnitDescriptor : UnitDescriptor + { + public GetPlayerIdUnitDescriptor(GetPlayerIdUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node returns either the first, the last, or the current player ID."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.PlayerVariable); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(GetPlayerIdUnit.PlayerId): + desc.summary = "The player ID as configured in the node header."; + break; + } + } + } +} diff --git a/Editor/Descriptors/GetPlayerIdUnitDescriptor.cs.meta b/Editor/Descriptors/GetPlayerIdUnitDescriptor.cs.meta new file mode 100644 index 0000000..cb49c1a --- /dev/null +++ b/Editor/Descriptors/GetPlayerIdUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7cf09367a2092594fb8a9aef111becd2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/GetPlayerIdWidget.cs b/Editor/Widgets/GetPlayerIdWidget.cs new file mode 100644 index 0000000..5c4a8f2 --- /dev/null +++ b/Editor/Widgets/GetPlayerIdWidget.cs @@ -0,0 +1,30 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(GetPlayerIdUnit))] + public sealed class GetPlayerIdWidget : GleUnitWidget + { + public GetPlayerIdWidget(FlowCanvas canvas, GetPlayerIdUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/GetPlayerIdWidget.cs.meta b/Editor/Widgets/GetPlayerIdWidget.cs.meta new file mode 100644 index 0000000..0727cfb --- /dev/null +++ b/Editor/Widgets/GetPlayerIdWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 95515a3dee20c4e48b35018c852d635a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/PlayerState/GetPlayerIdUnit.cs b/Runtime/Nodes/PlayerState/GetPlayerIdUnit.cs new file mode 100644 index 0000000..70921d3 --- /dev/null +++ b/Runtime/Nodes/PlayerState/GetPlayerIdUnit.cs @@ -0,0 +1,58 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Get Player ID")] + [UnitSurtitle("Player State")] + [UnitCategory("Visual Pinball/Variables")] + public class GetPlayerIdUnit : GleUnit + { + [Serialize, Inspectable, UnitHeaderInspectable] + public WhichPlayer Which { get; set; } + + [DoNotSerialize, PortLabel("Player ID"), Inspectable] + public ValueOutput PlayerId { get; private set; } + + protected override void Definition() + { + PlayerId = ValueOutput(nameof(PlayerId), GetPlayerId); + } + + private int GetPlayerId(Flow flow) + { + if (!AssertVsGle(flow)) { + throw new InvalidOperationException("Cannot retrieve GLE from unit."); + } + + return Which switch { + WhichPlayer.First => VsGle.PlayerStates.Keys.Min(), + WhichPlayer.Last => VsGle.PlayerStates.Keys.Max(), + WhichPlayer.Current => VsGle.CurrentPlayerState.Id, + _ => throw new ArgumentOutOfRangeException() + }; + } + } + + public enum WhichPlayer + { + Current, First, Last + } +} diff --git a/Runtime/Nodes/PlayerState/GetPlayerIdUnit.cs.meta b/Runtime/Nodes/PlayerState/GetPlayerIdUnit.cs.meta new file mode 100644 index 0000000..448a913 --- /dev/null +++ b/Runtime/Nodes/PlayerState/GetPlayerIdUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 17f6b99539e3a5944b08a9b1d16f7ddf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 0169ee5db9ad8be61019d96f890c1effd7041ca3 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 13 Feb 2022 21:28:52 +0100 Subject: [PATCH 31/54] Add string and boolean support to increase variable node. --- .../Nodes/PlayerState/IncreaseVariableUnit.cs | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs b/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs index 902b4de..55fc942 100644 --- a/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs +++ b/Runtime/Nodes/PlayerState/IncreaseVariableUnit.cs @@ -74,13 +74,17 @@ protected override void Definition() Value = VariableDefinition.Type switch { VariableType.Integer => ValueInput(nameof(Value), 0), VariableType.Float => ValueInput(nameof(Value), 0f), - _ => throw new ArgumentOutOfRangeException($"Type must be integer or float.") + VariableType.Boolean => ValueInput(nameof(Value), false), + VariableType.String => ValueInput(nameof(Value), string.Empty), + _ => throw new ArgumentOutOfRangeException() }; OutputValue = VariableDefinition.Type switch { VariableType.Integer => ValueOutput(nameof(Value)), VariableType.Float => ValueOutput(nameof(Value)), - _ => throw new ArgumentOutOfRangeException($"Type must be integer or float.") + VariableType.Boolean => ValueOutput(nameof(Value)), + VariableType.String => ValueOutput(nameof(Value)), + _ => throw new ArgumentOutOfRangeException() }; Requirement(Value, InputTrigger); } @@ -104,8 +108,23 @@ private ControlOutput Process(Flow flow) flow.SetValue(OutputValue, current + flow.GetValue(Value)); break; } + case VariableType.Boolean: { + if (flow.GetValue(Value)) { + var current = (bool)State.Get(VariableDefinition.Id); + State.Set(VariableDefinition.Id, new Bool(!current)); + flow.SetValue(OutputValue, !current); + } + break; + } + case VariableType.String: { + var current = State.Get(VariableDefinition.Id); + var next = current + flow.GetValue(Value); + State.Set(VariableDefinition.Id, next); + flow.SetValue(OutputValue, next); + break; + } default: - throw new ArgumentOutOfRangeException($"Type must be integer or float."); + throw new ArgumentOutOfRangeException(); } return OutputTrigger; From ecfe6ea10bc938dff3bfdd27c3d6c336f8dc7d61 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 13 Feb 2022 22:03:15 +0100 Subject: [PATCH 32/54] Provide both old and new value in variables changed event. --- .../VariableChangedEventUnitDescriptor.cs | 10 ++++- Runtime/Gamelogic/State.cs | 9 ++++- .../VisualScriptingGamelogicEngine.cs | 8 ++-- .../PlayerState/VariableChangedEventUnit.cs | 37 +++++++++++++------ 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/Editor/Descriptors/VariableChangedEventUnitDescriptor.cs b/Editor/Descriptors/VariableChangedEventUnitDescriptor.cs index 4ce193d..4d91de4 100644 --- a/Editor/Descriptors/VariableChangedEventUnitDescriptor.cs +++ b/Editor/Descriptors/VariableChangedEventUnitDescriptor.cs @@ -39,7 +39,10 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(PlayerVariableChangedEventUnit.Value): + case nameof(PlayerVariableChangedEventUnit.OldValue): + desc.summary = "The previous value of the player variable."; + break; + case nameof(PlayerVariableChangedEventUnit.NewValue): desc.summary = "The new value of the player variable."; break; } @@ -66,7 +69,10 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { - case nameof(TableVariableChangedEventUnit.Value): + case nameof(TableVariableChangedEventUnit.OldValue): + desc.summary = "The previous value of the table variable."; + break; + case nameof(TableVariableChangedEventUnit.NewValue): desc.summary = "The new value of the table variable."; break; } diff --git a/Runtime/Gamelogic/State.cs b/Runtime/Gamelogic/State.cs index 3c950c7..3663421 100644 --- a/Runtime/Gamelogic/State.cs +++ b/Runtime/Gamelogic/State.cs @@ -100,7 +100,7 @@ public void Set(string variableId, T value) where T : class if (currentValue != value) { EventBus.Trigger( VariableChangedEventName, - new VariableChangedArgs(variableId) + new VariableChangedArgs(variableId, currentValue, value) ); } } @@ -157,9 +157,14 @@ public readonly struct VariableChangedArgs { public readonly string VariableId; - public VariableChangedArgs(string variableId) + public readonly object OldValue; + public readonly object NewValue; + + public VariableChangedArgs(string variableId, object oldValue, object newValue) { VariableId = variableId; + OldValue = oldValue; + NewValue = newValue; } } } diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index 968e05e..cb30ea5 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -104,15 +104,15 @@ public void SetCurrentPlayer(int value, bool forceNotify = false) // also trigger updates for each variable foreach (var varDef in PlayerVariableDefinitions) { + var before = PlayerStates[previousPlayer].GetVariable(varDef.Id); + var now = PlayerStates[_currentPlayer].GetVariable(varDef.Id); if (PlayerStates.ContainsKey(previousPlayer)) { - var before = PlayerStates[previousPlayer].GetVariable(varDef.Id); - var now = PlayerStates[_currentPlayer].GetVariable(varDef.Id); if (forceNotify || before != now) { - EventBus.Trigger(VisualScriptingEventNames.PlayerVariableChanged, new VariableChangedArgs(varDef.Id)); + EventBus.Trigger(VisualScriptingEventNames.PlayerVariableChanged, new VariableChangedArgs(varDef.Id, before.Get(), now.Get())); } } else { - EventBus.Trigger(VisualScriptingEventNames.PlayerVariableChanged, new VariableChangedArgs(varDef.Id)); + EventBus.Trigger(VisualScriptingEventNames.PlayerVariableChanged, new VariableChangedArgs(varDef.Id, before.Get(), now.Get())); } } } diff --git a/Runtime/Nodes/PlayerState/VariableChangedEventUnit.cs b/Runtime/Nodes/PlayerState/VariableChangedEventUnit.cs index 8b9d945..0056ece 100644 --- a/Runtime/Nodes/PlayerState/VariableChangedEventUnit.cs +++ b/Runtime/Nodes/PlayerState/VariableChangedEventUnit.cs @@ -47,8 +47,11 @@ public class TableVariableChangedEventUnit : VariableChangedEventUnit public abstract class VariableChangedEventUnit : GleEventUnit { - [DoNotSerialize, PortLabel("Value"), Inspectable] - public ValueOutput Value { get; private set; } + [DoNotSerialize, PortLabel("Old Value"), Inspectable] + public ValueOutput OldValue { get; private set; } + + [DoNotSerialize, PortLabel("New Value"), Inspectable] + public ValueOutput NewValue { get; private set; } public override EventHook GetHook(GraphReference reference) => new(EventHookName); protected override bool register => true; @@ -65,11 +68,19 @@ protected override void Definition() return; } - Value = VariableDefinition.Type switch { - VariableType.String => ValueOutput(nameof(Value)), - VariableType.Integer => ValueOutput(nameof(Value)), - VariableType.Float => ValueOutput(nameof(Value)), - VariableType.Boolean => ValueOutput(nameof(Value)), + OldValue = VariableDefinition.Type switch { + VariableType.String => ValueOutput(nameof(OldValue)), + VariableType.Integer => ValueOutput(nameof(OldValue)), + VariableType.Float => ValueOutput(nameof(OldValue)), + VariableType.Boolean => ValueOutput(nameof(OldValue)), + _ => throw new ArgumentOutOfRangeException() + }; + + NewValue = VariableDefinition.Type switch { + VariableType.String => ValueOutput(nameof(NewValue)), + VariableType.Integer => ValueOutput(nameof(NewValue)), + VariableType.Float => ValueOutput(nameof(NewValue)), + VariableType.Boolean => ValueOutput(nameof(NewValue)), _ => throw new ArgumentOutOfRangeException() }; } @@ -87,16 +98,20 @@ protected override void AssignArguments(Flow flow, VariableChangedArgs args) switch (VariableDefinition.Type) { case VariableType.String: - flow.SetValue(Value, State.Get(VariableDefinition.Id)); + flow.SetValue(OldValue, (string)args.OldValue); + flow.SetValue(NewValue, (string)args.NewValue); break; case VariableType.Integer: - flow.SetValue(Value, (int)State.Get(VariableDefinition.Id)); + flow.SetValue(OldValue, (int)(Integer)args.OldValue); + flow.SetValue(NewValue, (int)(Integer)args.NewValue); break; case VariableType.Float: - flow.SetValue(Value, (float)State.Get(VariableDefinition.Id)); + flow.SetValue(OldValue, (float)(Float)args.OldValue); + flow.SetValue(NewValue, (float)(Float)args.NewValue); break; case VariableType.Boolean: - flow.SetValue(Value, (bool)State.Get(VariableDefinition.Id)); + flow.SetValue(OldValue, (bool)(Bool)args.OldValue); + flow.SetValue(NewValue, (bool)(Bool)args.NewValue); break; default: throw new ArgumentOutOfRangeException(); From 778317a5b6fa52848319b00eff254b59bbd126fb Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 14 Feb 2022 00:27:21 +0100 Subject: [PATCH 33/54] Add all switches enabled node. --- Editor/Descriptors/MultiUnitDescriptor.cs | 54 +++++++++++++ .../Descriptors/MultiUnitDescriptor.cs.meta | 11 +++ Editor/Widgets/GleMultiUnitWidget.cs | 69 ++++++++++++++++ Editor/Widgets/GleMultiUnitWidget.cs.meta | 11 +++ Runtime/Nodes/GleUnit.cs | 12 +++ .../Switches/AllSwitchesEnabledEventUnit.cs | 81 +++++++++++++++++++ .../AllSwitchesEnabledEventUnit.cs.meta | 11 +++ 7 files changed, 249 insertions(+) create mode 100644 Editor/Descriptors/MultiUnitDescriptor.cs create mode 100644 Editor/Descriptors/MultiUnitDescriptor.cs.meta create mode 100644 Editor/Widgets/GleMultiUnitWidget.cs create mode 100644 Editor/Widgets/GleMultiUnitWidget.cs.meta create mode 100644 Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs create mode 100644 Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs.meta diff --git a/Editor/Descriptors/MultiUnitDescriptor.cs b/Editor/Descriptors/MultiUnitDescriptor.cs new file mode 100644 index 0000000..0f38327 --- /dev/null +++ b/Editor/Descriptors/MultiUnitDescriptor.cs @@ -0,0 +1,54 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System.Text.RegularExpressions; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(AllSwitchesEnabledEventUnit))] + public class AllSwitchesEnabledEventUnitDescriptor : MultiUnitDescriptor + { + public AllSwitchesEnabledEventUnitDescriptor(AllSwitchesEnabledEventUnit target) : base(target) { } + protected override string ItemLabel(int id) => $"Switch ID {id}"; + protected override string ItemDescription(int id) => $"Switch ID {id} to look for enabled status."; + protected override string DefinedSummary() => "This node triggers an event when the last switch in the list gets enabled."; + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.SwitchEvent); + } + + public abstract class MultiUnitDescriptor : UnitDescriptor where TUnit : class, IUnit + { + protected abstract string ItemLabel(int id); + protected abstract string ItemDescription(int id); + + protected MultiUnitDescriptor(TUnit target) : base(target) + { + } + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + var match = new Regex("^(item)([0-9]+)$").Match(port.key); + if (match.Success) { + var id = int.Parse(match.Groups[2].Value) + 1; + desc.label = ItemLabel(id); + desc.summary = ItemDescription(id); + } + } + } +} diff --git a/Editor/Descriptors/MultiUnitDescriptor.cs.meta b/Editor/Descriptors/MultiUnitDescriptor.cs.meta new file mode 100644 index 0000000..ea51305 --- /dev/null +++ b/Editor/Descriptors/MultiUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9e20ce6742d43d040b9cb4d05b343275 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/GleMultiUnitWidget.cs b/Editor/Widgets/GleMultiUnitWidget.cs new file mode 100644 index 0000000..8a477d6 --- /dev/null +++ b/Editor/Widgets/GleMultiUnitWidget.cs @@ -0,0 +1,69 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(AllSwitchesEnabledEventUnit))] + public sealed class AllSwitchesEnabledEventUnitWidget : GleMultiUnitWidget + { + public AllSwitchesEnabledEventUnitWidget(FlowCanvas canvas, AllSwitchesEnabledEventUnit unit) : base(canvas, unit) + { + } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedSwitches.Select(sw => sw.Id); + } + + public abstract class GleMultiUnitWidget : GleUnitWidget where TUnit : Unit, IGleUnit, IMultiInputUnit + { + protected abstract IEnumerable IdSuggestions(IGamelogicEngine gle); + + private readonly List> _idInspectorConstructorList; + + protected GleMultiUnitWidget(FlowCanvas canvas, TUnit unit) : base(canvas, unit) + { + _idInspectorConstructorList = new List>(); + } + + public override Inspector GetPortInspector(IUnitPort port, Metadata meta) + { + if (_idInspectorConstructorList.Count() < unit.inputCount) { + for (var index = 0; index < unit.inputCount - _idInspectorConstructorList.Count(); index++) { + _idInspectorConstructorList.Add(m => new VariableNameInspector(m, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.inputCount; index++) { + if (unit.multiInputs[index] == port) { + var idInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref idInspector, meta, _idInspectorConstructorList[index]); + + return idInspector; + } + } + + return base.GetPortInspector(port, meta); + } + + private IEnumerable GetNameSuggestions() + { + return !GleAvailable ? new List() : IdSuggestions(Gle).ToList(); + } + } +} diff --git a/Editor/Widgets/GleMultiUnitWidget.cs.meta b/Editor/Widgets/GleMultiUnitWidget.cs.meta new file mode 100644 index 0000000..a0d1884 --- /dev/null +++ b/Editor/Widgets/GleMultiUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fe225b58cd15fa94fb99874e34e616f5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/GleUnit.cs b/Runtime/Nodes/GleUnit.cs index 1c84975..6ab961c 100644 --- a/Runtime/Nodes/GleUnit.cs +++ b/Runtime/Nodes/GleUnit.cs @@ -24,9 +24,21 @@ public abstract class GleEventUnit : EventUnit, IGleUnit [DoNotSerialize] public List Errors { get; } = new(); + [DoNotSerialize] + protected IGamelogicEngine Gle; + [DoNotSerialize] protected VisualScriptingGamelogicEngine VsGle; + protected bool AssertGle(Flow flow) + { + if (!Gle.IsUnityNull()) { + return true; + } + Gle = flow.stack.gameObject.GetComponentInParent(); + return Gle != null; + } + protected bool AssertVsGle(Flow flow) { if (!VsGle.IsUnityNull()) { diff --git a/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs b/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs new file mode 100644 index 0000000..6fa1a07 --- /dev/null +++ b/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs @@ -0,0 +1,81 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("On All Switches Enabled")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Events\\Visual Pinball")] + public class AllSwitchesEnabledEventUnit : GleEventUnit, IMultiInputUnit + { + [SerializeAs(nameof(inputCount))] + private int _itemCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Switch IDs")] + public int inputCount + { + get => _itemCount; + set => _itemCount = Mathf.Clamp(value, 1, 10); + } + + [DoNotSerialize] + public ReadOnlyCollection multiInputs { get; private set; } + + [DoNotSerialize] + protected override bool register => true; + + public override EventHook GetHook(GraphReference reference) => new EventHook(VisualScriptingEventNames.SwitchEvent); + + protected override void Definition() + { + base.Definition(); + + var list = new List(); + for (var i = 0; i < inputCount; i++) { + var item = ValueInput($"item{i}", string.Empty); + list.Add(item); + } + + multiInputs = new ReadOnlyCollection(list); + } + + protected override bool ShouldTrigger(Flow flow, SwitchEventArgs2 args) + { + if (!AssertGle(flow)) { + Debug.LogError("Cannot find GLE."); + return false; + } + + var validSwitch = false; + foreach(var item in multiInputs) { + var swId = flow.GetValue(item); + if (swId == args.Id) { + validSwitch = true; + } + if (!Gle.GetSwitch(swId)) { + return false; + } + } + return validSwitch; + } + } +} diff --git a/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs.meta b/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs.meta new file mode 100644 index 0000000..1826117 --- /dev/null +++ b/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c328f0dcce0b9a46b827d189ffd180a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 0fde182d04d3f9208993c989f85ae1d3ae7008ce Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Mon, 14 Feb 2022 16:31:50 -0500 Subject: [PATCH 34/54] units: rework itemCount/item keys to match MultiInput units --- .../AllSwitchesEnabledEventUnitDescriptor.cs | 32 +++++++++++++++++++ ...SwitchesEnabledEventUnitDescriptor.cs.meta | 11 +++++++ Editor/Descriptors/GetSwitchUnitDescriptor.cs | 13 +++----- Editor/Descriptors/MultiUnitDescriptor.cs | 18 +++-------- Editor/Descriptors/PulseCoilUnitDescriptor.cs | 13 +++----- Editor/Descriptors/SetCoilUnitDescriptor.cs | 13 +++----- .../SwitchEnabledEventUnitDescriptor.cs | 7 ++-- .../Descriptors/SwitchLampUnitDescriptor.cs | 14 +++----- Editor/Widgets/GetSwitchUnitWidget.cs | 6 ++-- Editor/Widgets/PulseCoilUnitWidget.cs | 6 ++-- Editor/Widgets/SetCoilUnitWidget.cs | 6 ++-- .../Widgets/SwitchEnabledEventUnitWidget.cs | 6 ++-- Editor/Widgets/SwitchLampUnitWidget.cs | 6 ++-- Runtime/Nodes/Coils/PulseCoilUnit.cs | 14 ++++---- Runtime/Nodes/Coils/SetCoilUnit.cs | 14 ++++---- Runtime/Nodes/Lamps/SwitchLampUnit.cs | 14 ++++---- .../Switches/AllSwitchesEnabledEventUnit.cs | 16 +++++----- Runtime/Nodes/Switches/GetSwitchUnit.cs | 14 ++++---- .../Nodes/Switches/SwitchEnabledEventUnit.cs | 14 ++++---- 19 files changed, 123 insertions(+), 114 deletions(-) create mode 100644 Editor/Descriptors/AllSwitchesEnabledEventUnitDescriptor.cs create mode 100644 Editor/Descriptors/AllSwitchesEnabledEventUnitDescriptor.cs.meta diff --git a/Editor/Descriptors/AllSwitchesEnabledEventUnitDescriptor.cs b/Editor/Descriptors/AllSwitchesEnabledEventUnitDescriptor.cs new file mode 100644 index 0000000..9a48155 --- /dev/null +++ b/Editor/Descriptors/AllSwitchesEnabledEventUnitDescriptor.cs @@ -0,0 +1,32 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(AllSwitchesEnabledEventUnit))] + public class AllSwitchesEnabledEventUnitDescriptor : MultiUnitDescriptor + { + public AllSwitchesEnabledEventUnitDescriptor(AllSwitchesEnabledEventUnit target) : base(target) { } + protected override string ItemLabel(int id) => $"Switch ID {id}"; + protected override string ItemDescription(int id) => $"Switch ID {id} to look for enabled status."; + protected override string DefinedSummary() => "This node triggers an event when the last switch in the list gets enabled."; + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.SwitchEvent); + } +} diff --git a/Editor/Descriptors/AllSwitchesEnabledEventUnitDescriptor.cs.meta b/Editor/Descriptors/AllSwitchesEnabledEventUnitDescriptor.cs.meta new file mode 100644 index 0000000..fe57f10 --- /dev/null +++ b/Editor/Descriptors/AllSwitchesEnabledEventUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 50e4a21f16b43417c874257c215d8611 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Descriptors/GetSwitchUnitDescriptor.cs b/Editor/Descriptors/GetSwitchUnitDescriptor.cs index a9fc660..79a7a4a 100644 --- a/Editor/Descriptors/GetSwitchUnitDescriptor.cs +++ b/Editor/Descriptors/GetSwitchUnitDescriptor.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System.Text.RegularExpressions; using Unity.VisualScripting; using VisualPinball.Unity.Editor; using IconSize = VisualPinball.Unity.Editor.IconSize; @@ -44,15 +43,11 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) if (port.key == nameof(GetSwitchUnit.IsEnabled)) { desc.summary = "Whether the switch is enabled."; } - else { - var match = new Regex("^(item)([0-9]+)$").Match(port.key); + else if (int.TryParse(port.key, out int id)) { + id += 1; - if (match.Success) { - var id = int.Parse(match.Groups[2].Value) + 1; - - desc.label = $"Switch ID {id}"; - desc.summary = $"Switch ID {id} to check if enabled."; - } + desc.label = $"Switch ID {id}"; + desc.summary = $"Switch ID {id} to check if enabled."; } } } diff --git a/Editor/Descriptors/MultiUnitDescriptor.cs b/Editor/Descriptors/MultiUnitDescriptor.cs index 0f38327..bc987bc 100644 --- a/Editor/Descriptors/MultiUnitDescriptor.cs +++ b/Editor/Descriptors/MultiUnitDescriptor.cs @@ -16,21 +16,10 @@ // ReSharper disable UnusedType.Global -using System.Text.RegularExpressions; using Unity.VisualScripting; namespace VisualPinball.Unity.VisualScripting.Editor { - [Descriptor(typeof(AllSwitchesEnabledEventUnit))] - public class AllSwitchesEnabledEventUnitDescriptor : MultiUnitDescriptor - { - public AllSwitchesEnabledEventUnitDescriptor(AllSwitchesEnabledEventUnit target) : base(target) { } - protected override string ItemLabel(int id) => $"Switch ID {id}"; - protected override string ItemDescription(int id) => $"Switch ID {id} to look for enabled status."; - protected override string DefinedSummary() => "This node triggers an event when the last switch in the list gets enabled."; - protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.SwitchEvent); - } - public abstract class MultiUnitDescriptor : UnitDescriptor where TUnit : class, IUnit { protected abstract string ItemLabel(int id); @@ -43,9 +32,10 @@ protected MultiUnitDescriptor(TUnit target) : base(target) protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - var match = new Regex("^(item)([0-9]+)$").Match(port.key); - if (match.Success) { - var id = int.Parse(match.Groups[2].Value) + 1; + + if (int.TryParse(port.key, out int id)) { + id += 1; + desc.label = ItemLabel(id); desc.summary = ItemDescription(id); } diff --git a/Editor/Descriptors/PulseCoilUnitDescriptor.cs b/Editor/Descriptors/PulseCoilUnitDescriptor.cs index 80a6c67..201f107 100644 --- a/Editor/Descriptors/PulseCoilUnitDescriptor.cs +++ b/Editor/Descriptors/PulseCoilUnitDescriptor.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System.Text.RegularExpressions; using Unity.VisualScripting; using VisualPinball.Unity.Editor; @@ -47,15 +46,11 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) if (port.key == nameof(PulseCoilUnit.PulseDuration)) { desc.summary = "The time in milliseconds until the coils are disabled again."; } - else { - var match = new Regex("^(item)([0-9]+)$").Match(port.key); + else if (int.TryParse(port.key, out int id)) { + id += 1; - if (match.Success) { - var id = int.Parse(match.Groups[2].Value) + 1; - - desc.label = $"Coil ID {id}"; - desc.summary = $"Coil ID {id} of the coil to be pulsed."; - } + desc.label = $"Coil ID {id}"; + desc.summary = $"Coil ID {id} of the coil to be pulsed."; } } } diff --git a/Editor/Descriptors/SetCoilUnitDescriptor.cs b/Editor/Descriptors/SetCoilUnitDescriptor.cs index a0f35bf..41e3cb0 100644 --- a/Editor/Descriptors/SetCoilUnitDescriptor.cs +++ b/Editor/Descriptors/SetCoilUnitDescriptor.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System.Text.RegularExpressions; using Unity.VisualScripting; using VisualPinball.Unity.Editor; @@ -47,15 +46,11 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) if (port.key == nameof(SetCoilUnit.IsEnabled)) { desc.summary = "The value to assign to the coils."; } - else { - var match = new Regex("^(item)([0-9]+)$").Match(port.key); + else if (int.TryParse(port.key, out int id)) { + id += 1; - if (match.Success) { - var id = int.Parse(match.Groups[2].Value) + 1; - - desc.label = $"Coil ID {id}"; - desc.summary = $"Coil ID {id} of the coil to be set."; - } + desc.label = $"Coil ID {id}"; + desc.summary = $"Coil ID {id} of the coil to be set."; } } } diff --git a/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs b/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs index f39197b..1e20d18 100644 --- a/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs +++ b/Editor/Descriptors/SwitchEnabledEventUnitDescriptor.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System.Text.RegularExpressions; using Unity.VisualScripting; namespace VisualPinball.Unity.VisualScripting.Editor @@ -39,10 +38,8 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - var match = new Regex("^(item)([0-9]+)$").Match(port.key); - - if (match.Success) { - var id = int.Parse(match.Groups[2].Value) + 1; + if (int.TryParse(port.key, out int id)) { + id += 1; desc.label = $"Switch ID {id}"; desc.summary = $"Switch ID {id} to look for enabled status."; diff --git a/Editor/Descriptors/SwitchLampUnitDescriptor.cs b/Editor/Descriptors/SwitchLampUnitDescriptor.cs index 2bf0ef5..37c4f23 100644 --- a/Editor/Descriptors/SwitchLampUnitDescriptor.cs +++ b/Editor/Descriptors/SwitchLampUnitDescriptor.cs @@ -16,8 +16,6 @@ // ReSharper disable UnusedType.Global -using System; -using System.Text.RegularExpressions; using Unity.VisualScripting; using VisualPinball.Unity.Editor; using IconSize = VisualPinball.Unity.Editor.IconSize; @@ -45,15 +43,11 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) if (port.key == nameof(SwitchLampUnit.SourceValue)) { desc.summary = "Source value to use for matching"; } - else { - var match = new Regex("^(item)([0-9]+)$").Match(port.key); + else if (int.TryParse(port.key, out int id)) { + id += 1; - if (match.Success) { - var id = int.Parse(match.Groups[2].Value) + 1; - - desc.label = $"Lamp ID {id}"; - desc.summary = $"Lamp ID {id} to enable if specified Value matches source Value, or disable if specified Value does not match source Value"; - } + desc.label = $"Lamp ID {id}"; + desc.summary = $"Lamp ID {id} to enable if specified Value matches source Value, or disable if specified Value does not match source Value"; } } } diff --git a/Editor/Widgets/GetSwitchUnitWidget.cs b/Editor/Widgets/GetSwitchUnitWidget.cs index a93011e..b210730 100644 --- a/Editor/Widgets/GetSwitchUnitWidget.cs +++ b/Editor/Widgets/GetSwitchUnitWidget.cs @@ -35,13 +35,13 @@ public GetSwitchUnitWidget(FlowCanvas canvas, GetSwitchUnit unit) : base(canvas, public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (_switchIdInspectorConstructorList.Count() < unit.itemCount) { - for (var index = 0; index < unit.itemCount - _switchIdInspectorConstructorList.Count(); index++) { + if (_switchIdInspectorConstructorList.Count() < unit.inputCount) { + for (var index = 0; index < unit.inputCount - _switchIdInspectorConstructorList.Count(); index++) { _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); } } - for (var index = 0; index < unit.itemCount; index++) { + for (var index = 0; index < unit.inputCount; index++) { if (unit.Items[index] == port) { VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); diff --git a/Editor/Widgets/PulseCoilUnitWidget.cs b/Editor/Widgets/PulseCoilUnitWidget.cs index 70df50e..cc3248f 100644 --- a/Editor/Widgets/PulseCoilUnitWidget.cs +++ b/Editor/Widgets/PulseCoilUnitWidget.cs @@ -35,13 +35,13 @@ public PulseCoilUnitWidget(FlowCanvas canvas, PulseCoilUnit unit) : base(canvas, public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (_coilIdInspectorConstructorList.Count() < unit.itemCount) { - for (var index = 0; index < unit.itemCount - _coilIdInspectorConstructorList.Count(); index++) { + if (_coilIdInspectorConstructorList.Count() < unit.inputCount) { + for (var index = 0; index < unit.inputCount - _coilIdInspectorConstructorList.Count(); index++) { _coilIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); } } - for (var index = 0; index < unit.itemCount; index++) { + for (var index = 0; index < unit.inputCount; index++) { if (unit.Items[index] == port) { VariableNameInspector coilIdInspector = new VariableNameInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref coilIdInspector, meta, _coilIdInspectorConstructorList[index]); diff --git a/Editor/Widgets/SetCoilUnitWidget.cs b/Editor/Widgets/SetCoilUnitWidget.cs index 54fd412..b26703a 100644 --- a/Editor/Widgets/SetCoilUnitWidget.cs +++ b/Editor/Widgets/SetCoilUnitWidget.cs @@ -35,13 +35,13 @@ public SetCoilUnitWidget(FlowCanvas canvas, SetCoilUnit unit) : base(canvas, uni public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (_coilIdInspectorConstructorList.Count() < unit.itemCount) { - for (var index = 0; index < unit.itemCount - _coilIdInspectorConstructorList.Count(); index++) { + if (_coilIdInspectorConstructorList.Count() < unit.inputCount) { + for (var index = 0; index < unit.inputCount - _coilIdInspectorConstructorList.Count(); index++) { _coilIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); } } - for (var index = 0; index < unit.itemCount; index++) { + for (var index = 0; index < unit.inputCount; index++) { if (unit.Items[index] == port) { VariableNameInspector coilIdInspector = new VariableNameInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref coilIdInspector, meta, _coilIdInspectorConstructorList[index]); diff --git a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs index beec3e8..20d5d92 100644 --- a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs @@ -35,13 +35,13 @@ public SwitchEnabledEventUnitWidget(FlowCanvas canvas, SwitchEnabledEventUnit un public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (_switchIdInspectorConstructorList.Count() < unit.itemCount) { - for (var index = 0; index < unit.itemCount - _switchIdInspectorConstructorList.Count(); index++) { + if (_switchIdInspectorConstructorList.Count() < unit.inputCount) { + for (var index = 0; index < unit.inputCount - _switchIdInspectorConstructorList.Count(); index++) { _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); } } - for (var index = 0; index < unit.itemCount; index++) { + for (var index = 0; index < unit.inputCount; index++) { if (unit.Items[index] == port) { VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); diff --git a/Editor/Widgets/SwitchLampUnitWidget.cs b/Editor/Widgets/SwitchLampUnitWidget.cs index 8ccf23b..d5ee526 100644 --- a/Editor/Widgets/SwitchLampUnitWidget.cs +++ b/Editor/Widgets/SwitchLampUnitWidget.cs @@ -35,13 +35,13 @@ public SwitchLampUnitWidget(FlowCanvas canvas, SwitchLampUnit unit) : base(canva public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (_lampIdInspectorConstructorList.Count() < unit.itemCount) { - for (var index = 0; index < unit.itemCount - _lampIdInspectorConstructorList.Count(); index++) { + if (_lampIdInspectorConstructorList.Count() < unit.inputCount) { + for (var index = 0; index < unit.inputCount - _lampIdInspectorConstructorList.Count(); index++) { _lampIdInspectorConstructorList.Add(meta => new LampIdValueInspector(meta, GetNameSuggestions)); } } - for (var index = 0; index < unit.itemCount; index++) { + for (var index = 0; index < unit.inputCount; index++) { if (unit.Items[index] == port) { LampIdValueInspector lampIdInspector = new LampIdValueInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); diff --git a/Runtime/Nodes/Coils/PulseCoilUnit.cs b/Runtime/Nodes/Coils/PulseCoilUnit.cs index 5d99316..2cc3c05 100644 --- a/Runtime/Nodes/Coils/PulseCoilUnit.cs +++ b/Runtime/Nodes/Coils/PulseCoilUnit.cs @@ -33,15 +33,15 @@ public class PulseCoilUnit : GleUnit [PortLabelHidden] public ControlOutput OutputTrigger; - [SerializeAs(nameof(itemCount))] - private int _itemCount = 1; + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Coil IDs")] - public int itemCount + public int inputCount { - get => _itemCount; - set => _itemCount = Mathf.Clamp(value, 1, 10); + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); } [DoNotSerialize] @@ -58,8 +58,8 @@ protected override void Definition() Items = new List(); - for (var i = 0; i < itemCount; i++) { - var item = ValueInput($"item{i}", string.Empty); + for (var i = 0; i < inputCount; i++) { + var item = ValueInput(i.ToString(), string.Empty); Items.Add(item); Requirement(item, InputTrigger); diff --git a/Runtime/Nodes/Coils/SetCoilUnit.cs b/Runtime/Nodes/Coils/SetCoilUnit.cs index c9ba861..336b7d9 100644 --- a/Runtime/Nodes/Coils/SetCoilUnit.cs +++ b/Runtime/Nodes/Coils/SetCoilUnit.cs @@ -33,15 +33,15 @@ public class SetCoilUnit : GleUnit [PortLabelHidden] public ControlOutput OutputTrigger; - [SerializeAs(nameof(itemCount))] - private int _itemCount = 1; + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Coil IDs")] - public int itemCount + public int inputCount { - get => _itemCount; - set => _itemCount = Mathf.Clamp(value, 1, 10); + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); } [DoNotSerialize] @@ -58,8 +58,8 @@ protected override void Definition() Items = new List(); - for (var i = 0; i < itemCount; i++) { - var item = ValueInput($"item{i}", string.Empty); + for (var i = 0; i < inputCount; i++) { + var item = ValueInput(i.ToString(), string.Empty); Items.Add(item); Requirement(item, InputTrigger); diff --git a/Runtime/Nodes/Lamps/SwitchLampUnit.cs b/Runtime/Nodes/Lamps/SwitchLampUnit.cs index 0708416..d954ee2 100644 --- a/Runtime/Nodes/Lamps/SwitchLampUnit.cs +++ b/Runtime/Nodes/Lamps/SwitchLampUnit.cs @@ -26,15 +26,15 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Visual Pinball")] public class SwitchLampUnit : GleUnit { - [SerializeAs(nameof(itemCount))] - private int _itemCount = 1; + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Lamp IDs")] - public int itemCount + public int inputCount { - get => _itemCount; - set => _itemCount = Mathf.Clamp(value, 1, 10); + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); } [DoNotSerialize] @@ -63,8 +63,8 @@ protected override void Definition() Items = new List(); - for (var i = 0; i < itemCount; i++) { - var item = ValueInput($"item{i}", LampIdValue.Empty.ToJson()); + for (var i = 0; i < inputCount; i++) { + var item = ValueInput(i.ToString(), LampIdValue.Empty.ToJson()); Items.Add(item); Requirement(item, InputTrigger); diff --git a/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs b/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs index 6fa1a07..6af163a 100644 --- a/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs +++ b/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs @@ -27,14 +27,14 @@ namespace VisualPinball.Unity.VisualScripting public class AllSwitchesEnabledEventUnit : GleEventUnit, IMultiInputUnit { [SerializeAs(nameof(inputCount))] - private int _itemCount = 1; + private int _inputCount = 1; [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Switch IDs")] public int inputCount { - get => _itemCount; - set => _itemCount = Mathf.Clamp(value, 1, 10); + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); } [DoNotSerialize] @@ -49,13 +49,13 @@ protected override void Definition() { base.Definition(); - var list = new List(); + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); + for (var i = 0; i < inputCount; i++) { - var item = ValueInput($"item{i}", string.Empty); - list.Add(item); + _multiInputs.Add(ValueInput(i.ToString(), string.Empty)); } - - multiInputs = new ReadOnlyCollection(list); } protected override bool ShouldTrigger(Flow flow, SwitchEventArgs2 args) diff --git a/Runtime/Nodes/Switches/GetSwitchUnit.cs b/Runtime/Nodes/Switches/GetSwitchUnit.cs index 443d909..d23d5b2 100644 --- a/Runtime/Nodes/Switches/GetSwitchUnit.cs +++ b/Runtime/Nodes/Switches/GetSwitchUnit.cs @@ -25,15 +25,15 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Visual Pinball")] public class GetSwitchUnit : GleUnit { - [SerializeAs(nameof(itemCount))] - private int _itemCount = 1; + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Switch IDs")] - public int itemCount + public int inputCount { - get => _itemCount; - set => _itemCount = Mathf.Clamp(value, 1, 10); + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); } [DoNotSerialize] @@ -47,8 +47,8 @@ protected override void Definition() { Items = new List(); - for (var i = 0; i < itemCount; i++) { - var item = ValueInput($"item{i}", string.Empty); + for (var i = 0; i < inputCount; i++) { + var item = ValueInput(i.ToString(), string.Empty); Items.Add(item); } diff --git a/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs index 71f7d83..76cdece 100644 --- a/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs +++ b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs @@ -25,15 +25,15 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Events\\Visual Pinball")] public class SwitchEnabledEventUnit : GleEventUnit { - [SerializeAs(nameof(itemCount))] - private int _itemCount = 1; + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Switch IDs")] - public int itemCount + public int inputCount { - get => _itemCount; - set => _itemCount = Mathf.Clamp(value, 1, 10); + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); } [DoNotSerialize] @@ -51,8 +51,8 @@ protected override void Definition() Items = new List(); - for (var i = 0; i < itemCount; i++) { - var item = ValueInput($"item{i}", string.Empty); + for (var i = 0; i < inputCount; i++) { + var item = ValueInput(i.ToString(), string.Empty); Items.Add(item); } } From b2655f86d31a922fbb3b992bea024a078ed7fb52 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Mon, 14 Feb 2022 19:45:14 -0500 Subject: [PATCH 35/54] misc: update to SetLampUnit/SwitchLampUnit to use IMultiInputUnit --- Editor/Descriptors/SetLampUnitDescriptor.cs | 15 +++---- Editor/Widgets/SetLampUnitWidget.cs | 21 +++++++--- Editor/Widgets/SwitchLampUnitWidget.cs | 2 +- Runtime/Nodes/Lamps/SetLampUnit.cs | 44 +++++++++++++++------ Runtime/Nodes/Lamps/SwitchLampUnit.cs | 19 +++++---- 5 files changed, 68 insertions(+), 33 deletions(-) diff --git a/Editor/Descriptors/SetLampUnitDescriptor.cs b/Editor/Descriptors/SetLampUnitDescriptor.cs index bcfc324..e9d3c1b 100644 --- a/Editor/Descriptors/SetLampUnitDescriptor.cs +++ b/Editor/Descriptors/SetLampUnitDescriptor.cs @@ -40,13 +40,14 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - switch (port.key) { - case nameof(SetLampUnit.Id): - desc.summary = "The ID of the lamp for which the intensity is returned."; - break; - case nameof(SetLampUnit.Value): - desc.summary = "The intensity of the lamp (0-1)."; - break; + if (port.key == nameof(SetLampUnit.Value)) { + desc.summary = "The intensity of the lamp (0-1)."; + } + else if (int.TryParse(port.key, out int id)) { + id += 1; + + desc.label = $"Lamp ID {id}"; + desc.summary = $"Lamp ID {id} of the lamp to set the intensity"; } } } diff --git a/Editor/Widgets/SetLampUnitWidget.cs b/Editor/Widgets/SetLampUnitWidget.cs index 0d783c1..0b569b3 100644 --- a/Editor/Widgets/SetLampUnitWidget.cs +++ b/Editor/Widgets/SetLampUnitWidget.cs @@ -26,19 +26,28 @@ namespace VisualPinball.Unity.VisualScripting.Editor [Widget(typeof(SetLampUnit))] public sealed class SetLampUnitWidget : GleUnitWidget { - private VariableNameInspector _lampIdInspector; - private readonly Func _setLampInspectorConstructor; + private readonly List> _lampIdInspectorConstructorList; public SetLampUnitWidget(FlowCanvas canvas, SetLampUnit unit) : base(canvas, unit) { - _setLampInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + _lampIdInspectorConstructorList = new List>(); } public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (port == unit.Id) { - InspectorProvider.instance.Renew(ref _lampIdInspector, meta, _setLampInspectorConstructor); - return _lampIdInspector; + if (_lampIdInspectorConstructorList.Count() < unit.inputCount) { + for (var index = 0; index < unit.inputCount - _lampIdInspectorConstructorList.Count(); index++) { + _lampIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.inputCount; index++) { + if (unit.multiInputs[index] == port) { + VariableNameInspector lampIdInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); + + return lampIdInspector; + } } return base.GetPortInspector(port, meta); diff --git a/Editor/Widgets/SwitchLampUnitWidget.cs b/Editor/Widgets/SwitchLampUnitWidget.cs index d5ee526..9ae0e1e 100644 --- a/Editor/Widgets/SwitchLampUnitWidget.cs +++ b/Editor/Widgets/SwitchLampUnitWidget.cs @@ -42,7 +42,7 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) } for (var index = 0; index < unit.inputCount; index++) { - if (unit.Items[index] == port) { + if (unit.multiInputs[index] == port) { LampIdValueInspector lampIdInspector = new LampIdValueInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); diff --git a/Runtime/Nodes/Lamps/SetLampUnit.cs b/Runtime/Nodes/Lamps/SetLampUnit.cs index 0e233ec..1fe459b 100644 --- a/Runtime/Nodes/Lamps/SetLampUnit.cs +++ b/Runtime/Nodes/Lamps/SetLampUnit.cs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System.Collections.Generic; +using System.Collections.ObjectModel; using Unity.VisualScripting; using UnityEngine; @@ -23,7 +25,7 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("Set Lamp (ID, Intensity)")] [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Visual Pinball")] - public class SetLampUnit : GleUnit + public class SetLampUnit : GleUnit, IMultiInputUnit { [DoNotSerialize] [PortLabelHidden] @@ -33,9 +35,19 @@ public class SetLampUnit : GleUnit [PortLabelHidden] public ControlOutput OutputTrigger; + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + [DoNotSerialize] - [PortLabel("Lamp ID")] - public ValueInput Id { get; private set; } + [Inspectable, UnitHeaderInspectable("Lamp IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } + + [DoNotSerialize] + public ReadOnlyCollection multiInputs { get; private set; } [DoNotSerialize] [PortLabel("Value")] @@ -46,26 +58,36 @@ protected override void Definition() InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - Id = ValueInput(nameof(Id), string.Empty); - Value = ValueInput(nameof(Value), 0f); + var _multiInputs = new List(); - Requirement(Id, InputTrigger); - Succession(InputTrigger, OutputTrigger); + multiInputs = _multiInputs.AsReadOnly(); + + for (var i = 0; i < inputCount; i++) + { + var input = ValueInput(i.ToString(), string.Empty); + _multiInputs.Add(input); + Requirement(input, InputTrigger); + } + + Value = ValueInput(nameof(Value), 0f); + + Succession(InputTrigger, OutputTrigger); } private ControlOutput Process(Flow flow) { - if (!AssertGle(flow)) { Debug.LogError("Cannot find GLE."); return OutputTrigger; } - var id = flow.GetValue(Id); - var value = flow.GetValue(Value); + var value = flow.GetValue(Value) * 255f; - Gle.SetLamp(id, value * 255f); + foreach (var input in multiInputs) { + var lampId = flow.GetValue(input); + Gle.SetLamp(lampId, value); + } return OutputTrigger; } diff --git a/Runtime/Nodes/Lamps/SwitchLampUnit.cs b/Runtime/Nodes/Lamps/SwitchLampUnit.cs index d954ee2..ed80cad 100644 --- a/Runtime/Nodes/Lamps/SwitchLampUnit.cs +++ b/Runtime/Nodes/Lamps/SwitchLampUnit.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using System.Collections.Generic; +using System.Collections.ObjectModel; using Unity.VisualScripting; using UnityEngine; @@ -24,7 +25,7 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("Switch Lamp (ID, match value)")] [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Visual Pinball")] - public class SwitchLampUnit : GleUnit + public class SwitchLampUnit : GleUnit, IMultiInputUnit { [SerializeAs(nameof(inputCount))] private int _inputCount = 1; @@ -50,7 +51,7 @@ public int inputCount public ValueInput SourceValue { get; private set; } [DoNotSerialize] - public List Items { get; private set; } + public ReadOnlyCollection multiInputs { get; private set; } private Dictionary _lampIdValueCache = new Dictionary(); @@ -61,13 +62,15 @@ protected override void Definition() SourceValue = ValueInput(nameof(SourceValue)); - Items = new List(); + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); for (var i = 0; i < inputCount; i++) { - var item = ValueInput(i.ToString(), LampIdValue.Empty.ToJson()); - Items.Add(item); + var input = ValueInput(i.ToString(), LampIdValue.Empty.ToJson()); + _multiInputs.Add(input); - Requirement(item, InputTrigger); + Requirement(input, InputTrigger); } _lampIdValueCache.Clear(); @@ -84,8 +87,8 @@ private ControlOutput Process(Flow flow) var value = flow.GetValue(SourceValue); - foreach (var item in Items) { - var json = flow.GetValue(item); + foreach (var input in multiInputs) { + var json = flow.GetValue(input); if (!_lampIdValueCache.ContainsKey(json.GetHashCode())) { _lampIdValueCache[json.GetHashCode()] = LampIdValue.FromJson(json); From f54634eca025d1e36537e87fc4f7f3ce43ce31bc Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Mon, 14 Feb 2022 20:11:32 -0500 Subject: [PATCH 36/54] misc: updated SetLampEnabledUnit to support IMultiInput --- .../SetLampEnabledUnitDescriptor.cs | 15 ++++---- Editor/Widgets/SetLampEnabledUnitWidget.cs | 21 ++++++++--- Runtime/Nodes/Lamps/SetLampEnabledUnit.cs | 37 +++++++++++++++---- Runtime/Nodes/Lamps/SetLampUnit.cs | 3 +- .../Switches/AllSwitchesEnabledEventUnit.cs | 4 +- 5 files changed, 56 insertions(+), 24 deletions(-) diff --git a/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs b/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs index 0798b1d..4fbb546 100644 --- a/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs +++ b/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs @@ -40,13 +40,14 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - switch (port.key) { - case nameof(SetLampEnabledUnit.Id): - desc.summary = "The ID of the lamp to toggle."; - break; - case nameof(SetLampEnabledUnit.IsEnabled): - desc.summary = "Whether to turn on or off."; - break; + if (port.key == nameof(SetLampEnabledUnit.IsEnabled)) { + desc.summary = "Whether to turn on or off."; + } + else if (int.TryParse(port.key, out int id)) { + id += 1; + + desc.label = $"Lamp ID {id}"; + desc.summary = $"Lamp ID {id} of the lamp to toggle."; } } } diff --git a/Editor/Widgets/SetLampEnabledUnitWidget.cs b/Editor/Widgets/SetLampEnabledUnitWidget.cs index 2921a94..9daa679 100644 --- a/Editor/Widgets/SetLampEnabledUnitWidget.cs +++ b/Editor/Widgets/SetLampEnabledUnitWidget.cs @@ -26,19 +26,28 @@ namespace VisualPinball.Unity.VisualScripting.Editor [Widget(typeof(SetLampEnabledUnit))] public sealed class SetLampEnabledUnitWidget : GleUnitWidget { - private VariableNameInspector _lampIdInspector; - private readonly Func _setLampInspectorConstructor; + private readonly List> _lampIdInspectorConstructorList; public SetLampEnabledUnitWidget(FlowCanvas canvas, SetLampEnabledUnit unit) : base(canvas, unit) { - _setLampInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + _lampIdInspectorConstructorList = new List>(); } public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (port == unit.Id) { - InspectorProvider.instance.Renew(ref _lampIdInspector, meta, _setLampInspectorConstructor); - return _lampIdInspector; + if (_lampIdInspectorConstructorList.Count() < unit.inputCount) { + for (var index = 0; index < unit.inputCount - _lampIdInspectorConstructorList.Count(); index++) { + _lampIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.inputCount; index++) { + if (unit.multiInputs[index] == port) { + VariableNameInspector lampIdInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); + + return lampIdInspector; + } } return base.GetPortInspector(port, meta); diff --git a/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs b/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs index dddaf8a..b2213cc 100644 --- a/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs +++ b/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System.Collections.Generic; +using System.Collections.ObjectModel; using Unity.VisualScripting; using UnityEngine; @@ -23,7 +25,7 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("Set Lamp (ID, on/off)")] [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Visual Pinball")] - public class SetLampEnabledUnit : GleUnit + public class SetLampEnabledUnit : GleUnit, IMultiInputUnit { [DoNotSerialize] [PortLabelHidden] @@ -33,9 +35,19 @@ public class SetLampEnabledUnit : GleUnit [PortLabelHidden] public ControlOutput OutputTrigger; + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Lamp IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } + [DoNotSerialize] - [PortLabel("Lamp ID")] - public ValueInput Id { get; private set; } + public ReadOnlyCollection multiInputs { get; private set; } [DoNotSerialize] [PortLabel("Is Enabled")] @@ -46,10 +58,19 @@ protected override void Definition() InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - Id = ValueInput(nameof(Id), string.Empty); + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); + + for (var i = 0; i < inputCount; i++) { + var input = ValueInput(i.ToString(), string.Empty); + _multiInputs.Add(input); + + Requirement(input, InputTrigger); + } + IsEnabled = ValueInput(nameof(IsEnabled), false); - Requirement(Id, InputTrigger); Succession(InputTrigger, OutputTrigger); } @@ -60,10 +81,12 @@ private ControlOutput Process(Flow flow) return OutputTrigger; } - var id = flow.GetValue(Id); var isEnabled = flow.GetValue(IsEnabled); - Gle.SetLamp(id, isEnabled ? 255f : 0f); + foreach (var input in multiInputs) { + var lampId = flow.GetValue(input); + Gle.SetLamp(lampId, isEnabled ? 255f : 0f); + } return OutputTrigger; } diff --git a/Runtime/Nodes/Lamps/SetLampUnit.cs b/Runtime/Nodes/Lamps/SetLampUnit.cs index 1fe459b..935b056 100644 --- a/Runtime/Nodes/Lamps/SetLampUnit.cs +++ b/Runtime/Nodes/Lamps/SetLampUnit.cs @@ -62,8 +62,7 @@ protected override void Definition() multiInputs = _multiInputs.AsReadOnly(); - for (var i = 0; i < inputCount; i++) - { + for (var i = 0; i < inputCount; i++) { var input = ValueInput(i.ToString(), string.Empty); _multiInputs.Add(input); diff --git a/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs b/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs index 6af163a..63d5d4b 100644 --- a/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs +++ b/Runtime/Nodes/Switches/AllSwitchesEnabledEventUnit.cs @@ -66,8 +66,8 @@ protected override bool ShouldTrigger(Flow flow, SwitchEventArgs2 args) } var validSwitch = false; - foreach(var item in multiInputs) { - var swId = flow.GetValue(item); + foreach(var input in multiInputs) { + var swId = flow.GetValue(input); if (swId == args.Id) { validSwitch = true; } From 6e213de20883fad43d4f7fbd027459b8a1792e06 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Mon, 14 Feb 2022 20:43:12 -0500 Subject: [PATCH 37/54] misc: cleanup. Added IMultiInputUnit to SwitchEvent --- .../Descriptors/SwitchEventUnitDescriptor.cs | 15 ++++---- Editor/Widgets/PulseCoilUnitWidget.cs | 2 +- Editor/Widgets/SetCoilUnitWidget.cs | 2 +- .../Widgets/SwitchEnabledEventUnitWidget.cs | 2 +- Editor/Widgets/SwitchEventUnitWidget.cs | 20 +++++++---- Runtime/Nodes/Coils/PulseCoilUnit.cs | 24 +++++++------ Runtime/Nodes/Coils/SetCoilUnit.cs | 22 ++++++------ .../Nodes/Switches/SwitchEnabledEventUnit.cs | 16 +++++---- Runtime/Nodes/Switches/SwitchEventUnit.cs | 36 ++++++++++++++++--- 9 files changed, 90 insertions(+), 49 deletions(-) diff --git a/Editor/Descriptors/SwitchEventUnitDescriptor.cs b/Editor/Descriptors/SwitchEventUnitDescriptor.cs index c655393..cb16d76 100644 --- a/Editor/Descriptors/SwitchEventUnitDescriptor.cs +++ b/Editor/Descriptors/SwitchEventUnitDescriptor.cs @@ -38,13 +38,14 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - switch (port.key) { - case nameof(SwitchEventUnit.Id): - desc.summary = "The ID of the switch that changed its value."; - break; - case nameof(SwitchEventUnit.IsEnabled): - desc.summary = "The new value of the switch, true if enabled, false otherwise."; - break; + if (port.key == nameof(SwitchEventUnit.IsEnabled)) { + desc.summary = "The new value of the switch, true if enabled, false otherwise."; + } + else if (int.TryParse(port.key, out int id)) { + id += 1; + + desc.label = $"Switch ID {id}"; + desc.summary = $"Switch ID {id} to look for a change status."; } } } diff --git a/Editor/Widgets/PulseCoilUnitWidget.cs b/Editor/Widgets/PulseCoilUnitWidget.cs index cc3248f..677ae1a 100644 --- a/Editor/Widgets/PulseCoilUnitWidget.cs +++ b/Editor/Widgets/PulseCoilUnitWidget.cs @@ -42,7 +42,7 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) } for (var index = 0; index < unit.inputCount; index++) { - if (unit.Items[index] == port) { + if (unit.multiInputs[index] == port) { VariableNameInspector coilIdInspector = new VariableNameInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref coilIdInspector, meta, _coilIdInspectorConstructorList[index]); diff --git a/Editor/Widgets/SetCoilUnitWidget.cs b/Editor/Widgets/SetCoilUnitWidget.cs index b26703a..946ba16 100644 --- a/Editor/Widgets/SetCoilUnitWidget.cs +++ b/Editor/Widgets/SetCoilUnitWidget.cs @@ -42,7 +42,7 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) } for (var index = 0; index < unit.inputCount; index++) { - if (unit.Items[index] == port) { + if (unit.multiInputs[index] == port) { VariableNameInspector coilIdInspector = new VariableNameInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref coilIdInspector, meta, _coilIdInspectorConstructorList[index]); diff --git a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs index 20d5d92..d2b8382 100644 --- a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs @@ -42,7 +42,7 @@ public override Inspector GetPortInspector(IUnitPort port, Metadata meta) } for (var index = 0; index < unit.inputCount; index++) { - if (unit.Items[index] == port) { + if (unit.multiInputs[index] == port) { VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); diff --git a/Editor/Widgets/SwitchEventUnitWidget.cs b/Editor/Widgets/SwitchEventUnitWidget.cs index a3cb05a..0518a07 100644 --- a/Editor/Widgets/SwitchEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEventUnitWidget.cs @@ -26,20 +26,28 @@ namespace VisualPinball.Unity.VisualScripting.Editor [Widget(typeof(SwitchEventUnit))] public sealed class SwitchEventUnitWidget : GleUnitWidget { - private VariableNameInspector _switchIdInspector; - private readonly Func _switchIdInspectorConstructor; + private readonly List> _switchIdInspectorConstructorList; public SwitchEventUnitWidget(FlowCanvas canvas, SwitchEventUnit unit) : base(canvas, unit) { - _switchIdInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + _switchIdInspectorConstructorList = new List>(); } public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (port == unit.Id) { - InspectorProvider.instance.Renew(ref _switchIdInspector, meta, _switchIdInspectorConstructor); + if (_switchIdInspectorConstructorList.Count() < unit.inputCount) { + for (var index = 0; index < unit.inputCount - _switchIdInspectorConstructorList.Count(); index++) { + _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.inputCount; index++) { + if (unit.multiInputs[index] == port) { + VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); - return _switchIdInspector; + return switchIdInspector; + } } return base.GetPortInspector(port, meta); diff --git a/Runtime/Nodes/Coils/PulseCoilUnit.cs b/Runtime/Nodes/Coils/PulseCoilUnit.cs index 2cc3c05..260ef8f 100644 --- a/Runtime/Nodes/Coils/PulseCoilUnit.cs +++ b/Runtime/Nodes/Coils/PulseCoilUnit.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using System.Collections.Generic; +using System.Collections.ObjectModel; using Unity.VisualScripting; using UnityEngine; @@ -23,7 +24,7 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("Pulse Coil")] [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Visual Pinball")] - public class PulseCoilUnit : GleUnit + public class PulseCoilUnit : GleUnit, IMultiInputUnit { [DoNotSerialize] [PortLabelHidden] @@ -45,7 +46,7 @@ public int inputCount } [DoNotSerialize] - public List Items { get; private set; } + public ReadOnlyCollection multiInputs { get; private set; } [DoNotSerialize] [PortLabel("Duration (ms)")] @@ -56,13 +57,15 @@ protected override void Definition() InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - Items = new List(); + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); for (var i = 0; i < inputCount; i++) { - var item = ValueInput(i.ToString(), string.Empty); - Items.Add(item); + var input = ValueInput(i.ToString(), string.Empty); + _multiInputs.Add(input); - Requirement(item, InputTrigger); + Requirement(input, InputTrigger); } PulseDuration = ValueInput(nameof(PulseDuration), 80); @@ -84,11 +87,10 @@ private ControlOutput Process(Flow flow) var pulseDuration = flow.GetValue(PulseDuration); - foreach (var item in Items) { - var id = flow.GetValue(item); - - Gle.SetCoil(id, true); - Player.ScheduleAction(pulseDuration, () => Gle.SetCoil(id, false)); + foreach (var input in multiInputs) { + var coilId = flow.GetValue(input); + Gle.SetCoil(coilId, true); + Player.ScheduleAction(pulseDuration, () => Gle.SetCoil(coilId, false)); } return OutputTrigger; diff --git a/Runtime/Nodes/Coils/SetCoilUnit.cs b/Runtime/Nodes/Coils/SetCoilUnit.cs index 336b7d9..ae37fcc 100644 --- a/Runtime/Nodes/Coils/SetCoilUnit.cs +++ b/Runtime/Nodes/Coils/SetCoilUnit.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using System.Collections.Generic; +using System.Collections.ObjectModel; using Unity.VisualScripting; using UnityEngine; @@ -23,7 +24,7 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("Set Coil")] [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Visual Pinball")] - public class SetCoilUnit : GleUnit + public class SetCoilUnit : GleUnit, IMultiInputUnit { [DoNotSerialize] [PortLabelHidden] @@ -45,7 +46,7 @@ public int inputCount } [DoNotSerialize] - public List Items { get; private set; } + public ReadOnlyCollection multiInputs { get; private set; } [DoNotSerialize] [PortLabel("Value")] @@ -56,13 +57,15 @@ protected override void Definition() InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - Items = new List(); + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); for (var i = 0; i < inputCount; i++) { - var item = ValueInput(i.ToString(), string.Empty); - Items.Add(item); + var input = ValueInput(i.ToString(), string.Empty); + _multiInputs.Add(input); - Requirement(item, InputTrigger); + Requirement(input, InputTrigger); } IsEnabled = ValueInput(nameof(IsEnabled), false); @@ -79,10 +82,9 @@ private ControlOutput Process(Flow flow) var isEnabled = flow.GetValue(IsEnabled); - foreach (var item in Items) { - var id = flow.GetValue(item); - - Gle.SetCoil(id, isEnabled); + foreach (var input in multiInputs) { + var coilId = flow.GetValue(input); + Gle.SetCoil(coilId, isEnabled); } return OutputTrigger; diff --git a/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs index 76cdece..f204534 100644 --- a/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs +++ b/Runtime/Nodes/Switches/SwitchEnabledEventUnit.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using System.Collections.Generic; +using System.Collections.ObjectModel; using Unity.VisualScripting; using UnityEngine; @@ -23,7 +24,7 @@ namespace VisualPinball.Unity.VisualScripting [UnitTitle("On Switch Enabled")] [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Events\\Visual Pinball")] - public class SwitchEnabledEventUnit : GleEventUnit + public class SwitchEnabledEventUnit : GleEventUnit, IMultiInputUnit { [SerializeAs(nameof(inputCount))] private int _inputCount = 1; @@ -37,7 +38,7 @@ public int inputCount } [DoNotSerialize] - public List Items { get; private set; } + public ReadOnlyCollection multiInputs { get; private set; } [DoNotSerialize] protected override bool register => true; @@ -49,18 +50,19 @@ protected override void Definition() { base.Definition(); - Items = new List(); + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); for (var i = 0; i < inputCount; i++) { - var item = ValueInput(i.ToString(), string.Empty); - Items.Add(item); + _multiInputs.Add(ValueInput(i.ToString(), string.Empty)); } } protected override bool ShouldTrigger(Flow flow, SwitchEventArgs2 args) { - foreach(var item in Items) { - if (flow.GetValue(item) == args.Id && args.IsEnabled) { + foreach(var input in multiInputs) { + if (flow.GetValue(input) == args.Id && args.IsEnabled) { return true; } } diff --git a/Runtime/Nodes/Switches/SwitchEventUnit.cs b/Runtime/Nodes/Switches/SwitchEventUnit.cs index c1696a7..aec13e2 100644 --- a/Runtime/Nodes/Switches/SwitchEventUnit.cs +++ b/Runtime/Nodes/Switches/SwitchEventUnit.cs @@ -14,18 +14,31 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System.Collections.Generic; +using System.Collections.ObjectModel; using Unity.VisualScripting; +using UnityEngine; namespace VisualPinball.Unity.VisualScripting { [UnitTitle("On Switch Changed")] [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Events\\Visual Pinball")] - public class SwitchEventUnit : GleEventUnit + public class SwitchEventUnit : GleEventUnit, IMultiInputUnit { + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Switch IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } + [DoNotSerialize] - [PortLabel("Switch ID")] - public ValueInput Id { get; private set; } + public ReadOnlyCollection multiInputs { get; private set; } [DoNotSerialize] [PortLabel("Is Enabled")] @@ -43,13 +56,26 @@ protected override void Definition() { base.Definition(); - Id = ValueInput(nameof(Id), string.Empty); + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); + + for (var i = 0; i < inputCount; i++) { + _multiInputs.Add(ValueInput(i.ToString(), string.Empty)); + } + IsEnabled = ValueOutput(nameof(IsEnabled)); } protected override bool ShouldTrigger(Flow flow, SwitchEventArgs2 args) { - return flow.GetValue(Id) == args.Id; + foreach (var input in multiInputs) { + if (flow.GetValue(input) == args.Id) { + return true; + } + } + + return false; } protected override void AssignArguments(Flow flow, SwitchEventArgs2 args) From d63630c14f4664bf2ad6bab1ff51b17acc1701a7 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Mon, 14 Feb 2022 21:05:59 -0500 Subject: [PATCH 38/54] misc: Added IMultiInputUnit support to LampEventUnit --- Editor/Descriptors/GetSwitchUnitDescriptor.cs | 15 ++-- Editor/Descriptors/LampEventUnitDescriptor.cs | 21 ++--- Editor/Widgets/GetSwitchUnitWidget.cs | 24 ++---- Editor/Widgets/LampEventUnitWidget.cs | 27 +++++-- Runtime/Nodes/Lamps/LampEventUnit.cs | 77 ++++++++++++------- Runtime/Nodes/Switches/GetSwitchUnit.cs | 31 +------- 6 files changed, 100 insertions(+), 95 deletions(-) diff --git a/Editor/Descriptors/GetSwitchUnitDescriptor.cs b/Editor/Descriptors/GetSwitchUnitDescriptor.cs index 79a7a4a..862b1f1 100644 --- a/Editor/Descriptors/GetSwitchUnitDescriptor.cs +++ b/Editor/Descriptors/GetSwitchUnitDescriptor.cs @@ -40,14 +40,13 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - if (port.key == nameof(GetSwitchUnit.IsEnabled)) { - desc.summary = "Whether the switch is enabled."; - } - else if (int.TryParse(port.key, out int id)) { - id += 1; - - desc.label = $"Switch ID {id}"; - desc.summary = $"Switch ID {id} to check if enabled."; + switch (port.key) { + case nameof(GetSwitchUnit.Id): + desc.summary = "Switch ID to check if enabled."; + break; + case nameof(GetSwitchUnit.IsEnabled): + desc.summary = "Whether the switch is enabled."; + break; } } } diff --git a/Editor/Descriptors/LampEventUnitDescriptor.cs b/Editor/Descriptors/LampEventUnitDescriptor.cs index ee9bb61..e6107f9 100644 --- a/Editor/Descriptors/LampEventUnitDescriptor.cs +++ b/Editor/Descriptors/LampEventUnitDescriptor.cs @@ -38,16 +38,17 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - switch (port.key) { - case nameof(LampEventUnit.Id): - desc.summary = "The ID of the lamp that changed its intensity."; - break; - case nameof(LampEventUnit.Value): - desc.summary = "The new intensity of the lamp (0-1)."; - break; - case nameof(LampEventUnit.IsEnabled): - desc.summary = "Whether the intensity is larger than 0."; - break; + if (port.key == nameof(LampEventUnit.IsEnabled)) { + desc.summary = "Whether the intensity is larger than 0."; + } + else if (port.key == nameof(LampEventUnit.Value)) { + desc.summary = "The new intensity of the lamp (0-1)."; + } + else if (int.TryParse(port.key, out int id)) { + id += 1; + + desc.label = $"Lamp ID {id}"; + desc.summary = $"Lamp ID {id} to look for a change in intensity."; } } } diff --git a/Editor/Widgets/GetSwitchUnitWidget.cs b/Editor/Widgets/GetSwitchUnitWidget.cs index b210730..b468469 100644 --- a/Editor/Widgets/GetSwitchUnitWidget.cs +++ b/Editor/Widgets/GetSwitchUnitWidget.cs @@ -26,31 +26,23 @@ namespace VisualPinball.Unity.VisualScripting.Editor [Widget(typeof(GetSwitchUnit))] public sealed class GetSwitchUnitWidget : GleUnitWidget { - private readonly List> _switchIdInspectorConstructorList; - public GetSwitchUnitWidget(FlowCanvas canvas, GetSwitchUnit unit) : base(canvas, unit) { - _switchIdInspectorConstructorList = new List>(); + _switchIdInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); } + private VariableNameInspector _switchIdInspector; + private readonly Func _switchIdInspectorConstructor; + public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (_switchIdInspectorConstructorList.Count() < unit.inputCount) { - for (var index = 0; index < unit.inputCount - _switchIdInspectorConstructorList.Count(); index++) { - _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); - } - } + if (port == unit.Id) + { + InspectorProvider.instance.Renew(ref _switchIdInspector, meta, _switchIdInspectorConstructor); - for (var index = 0; index < unit.inputCount; index++) { - if (unit.Items[index] == port) { - VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); - InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); - - return switchIdInspector; - } + return _switchIdInspector; } - return base.GetPortInspector(port, meta); } diff --git a/Editor/Widgets/LampEventUnitWidget.cs b/Editor/Widgets/LampEventUnitWidget.cs index 1ff4988..2b01ae3 100644 --- a/Editor/Widgets/LampEventUnitWidget.cs +++ b/Editor/Widgets/LampEventUnitWidget.cs @@ -26,20 +26,32 @@ namespace VisualPinball.Unity.VisualScripting.Editor [Widget(typeof(LampEventUnit))] public sealed class LampEventUnitWidget : GleUnitWidget { + private readonly List> _lampIdInspectorConstructorList; + public LampEventUnitWidget(FlowCanvas canvas, LampEventUnit unit) : base(canvas, unit) { - _lampIdInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + _lampIdInspectorConstructorList = new List>(); } - private VariableNameInspector _lampIdInspector; - private readonly Func _lampIdInspectorConstructor; - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (port == unit.Id) { - InspectorProvider.instance.Renew(ref _lampIdInspector, meta, _lampIdInspectorConstructor); + if (_lampIdInspectorConstructorList.Count() < unit.inputCount) + { + for (var index = 0; index < unit.inputCount - _lampIdInspectorConstructorList.Count(); index++) + { + _lampIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); + } + } - return _lampIdInspector; + for (var index = 0; index < unit.inputCount; index++) + { + if (unit.multiInputs[index] == port) + { + VariableNameInspector lampIdInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); + + return lampIdInspector; + } } return base.GetPortInspector(port, meta); @@ -50,7 +62,6 @@ private IEnumerable GetNameSuggestions() return !GleAvailable ? new List() : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); - } } } diff --git a/Runtime/Nodes/Lamps/LampEventUnit.cs b/Runtime/Nodes/Lamps/LampEventUnit.cs index f579ce5..0840e86 100644 --- a/Runtime/Nodes/Lamps/LampEventUnit.cs +++ b/Runtime/Nodes/Lamps/LampEventUnit.cs @@ -1,31 +1,44 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using System.Collections.ObjectModel; using Unity.VisualScripting; - +using UnityEngine; + namespace VisualPinball.Unity.VisualScripting { [UnitTitle("On Lamp Changed")] [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Events\\Visual Pinball")] - public sealed class LampEventUnit : GleEventUnit + public sealed class LampEventUnit : GleEventUnit, IMultiInputUnit { + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Lamp IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } + [DoNotSerialize] - [PortLabel("Lamp ID")] - public ValueInput Id { get; private set; } + public ReadOnlyCollection multiInputs { get; private set; } [DoNotSerialize] [PortLabel("Intensity")] @@ -46,10 +59,27 @@ protected override void Definition() { base.Definition(); - Id = ValueInput(nameof(Id), string.Empty); + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); + + for (var i = 0; i < inputCount; i++) { + _multiInputs.Add(ValueInput(i.ToString(), string.Empty)); + } Value = ValueOutput(nameof(Value)); IsEnabled = ValueOutput(nameof(IsEnabled)); + } + + protected override bool ShouldTrigger(Flow flow, LampEventArgs args) + { + foreach (var input in multiInputs) { + if (flow.GetValue(input) == args.Id) { + return true; + } + } + + return false; } protected override void AssignArguments(Flow flow, LampEventArgs args) @@ -57,10 +87,5 @@ protected override void AssignArguments(Flow flow, LampEventArgs args) flow.SetValue(Value, args.Value); flow.SetValue(IsEnabled, args.Value > 0); } - - protected override bool ShouldTrigger(Flow flow, LampEventArgs args) - { - return args.Id == flow.GetValue(Id); - } } } diff --git a/Runtime/Nodes/Switches/GetSwitchUnit.cs b/Runtime/Nodes/Switches/GetSwitchUnit.cs index d23d5b2..1cc8585 100644 --- a/Runtime/Nodes/Switches/GetSwitchUnit.cs +++ b/Runtime/Nodes/Switches/GetSwitchUnit.cs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; @@ -25,19 +24,9 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Visual Pinball")] public class GetSwitchUnit : GleUnit { - [SerializeAs(nameof(inputCount))] - private int _inputCount = 1; - - [DoNotSerialize] - [Inspectable, UnitHeaderInspectable("Switch IDs")] - public int inputCount - { - get => _inputCount; - set => _inputCount = Mathf.Clamp(value, 1, 10); - } - [DoNotSerialize] - public List Items { get; private set; } + [PortLabel("Switch ID")] + public ValueInput Id { get; private set; } [DoNotSerialize] [PortLabel("Is Enabled")] @@ -45,13 +34,7 @@ public int inputCount protected override void Definition() { - Items = new List(); - - for (var i = 0; i < inputCount; i++) { - var item = ValueInput(i.ToString(), string.Empty); - Items.Add(item); - } - + Id = ValueInput(nameof(Id), string.Empty); IsEnabled = ValueOutput(nameof(IsEnabled), GetEnabled); } @@ -62,13 +45,7 @@ private bool GetEnabled(Flow flow) return false; } - foreach (var item in Items) { - if (!Gle.GetSwitch(flow.GetValue(item))) { - return false; - } - } - - return true; + return Gle.GetSwitch(flow.GetValue(Id)); } } } From acbffb7061b9385286d152042e24a7b74202415a Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Tue, 15 Feb 2022 07:21:07 -0500 Subject: [PATCH 39/54] units: Add new SetSwitch and PulseSwitch units --- .../Descriptors/PulseSwitchUnitDescriptor.cs | 57 +++++++++++ .../PulseSwitchUnitDescriptor.cs.meta | 11 +++ Editor/Descriptors/SetSwitchUnitDescriptor.cs | 57 +++++++++++ .../SetSwitchUnitDescriptor.cs.meta | 11 +++ Editor/Widgets/PulseSwitchUnitWidget.cs | 63 ++++++++++++ Editor/Widgets/PulseSwitchUnitWidget.cs.meta | 11 +++ Editor/Widgets/SetSwitchUnitWidget.cs | 63 ++++++++++++ Editor/Widgets/SetSwitchUnitWidget.cs.meta | 11 +++ Runtime/Nodes/Switches/PulseSwitchUnit.cs | 99 +++++++++++++++++++ .../Nodes/Switches/PulseSwitchUnit.cs.meta | 11 +++ Runtime/Nodes/Switches/SetSwitchUnit.cs | 93 +++++++++++++++++ Runtime/Nodes/Switches/SetSwitchUnit.cs.meta | 11 +++ 12 files changed, 498 insertions(+) create mode 100644 Editor/Descriptors/PulseSwitchUnitDescriptor.cs create mode 100644 Editor/Descriptors/PulseSwitchUnitDescriptor.cs.meta create mode 100644 Editor/Descriptors/SetSwitchUnitDescriptor.cs create mode 100644 Editor/Descriptors/SetSwitchUnitDescriptor.cs.meta create mode 100644 Editor/Widgets/PulseSwitchUnitWidget.cs create mode 100644 Editor/Widgets/PulseSwitchUnitWidget.cs.meta create mode 100644 Editor/Widgets/SetSwitchUnitWidget.cs create mode 100644 Editor/Widgets/SetSwitchUnitWidget.cs.meta create mode 100644 Runtime/Nodes/Switches/PulseSwitchUnit.cs create mode 100644 Runtime/Nodes/Switches/PulseSwitchUnit.cs.meta create mode 100644 Runtime/Nodes/Switches/SetSwitchUnit.cs create mode 100644 Runtime/Nodes/Switches/SetSwitchUnit.cs.meta diff --git a/Editor/Descriptors/PulseSwitchUnitDescriptor.cs b/Editor/Descriptors/PulseSwitchUnitDescriptor.cs new file mode 100644 index 0000000..37f1209 --- /dev/null +++ b/Editor/Descriptors/PulseSwitchUnitDescriptor.cs @@ -0,0 +1,57 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; +using VisualPinball.Unity.Editor; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(PulseSwitchUnit))] + public class PulseSwitchUnitDescriptor : UnitDescriptor + { + public PulseSwitchUnitDescriptor(PulseSwitchUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node enables switches defined by their IDs and disables it after a given delay."; + } + + protected override EditorTexture DefinedIcon() + { + var texture = VisualPinball.Unity.Editor.Icons.Switch(false, VisualPinball.Unity.Editor.IconSize.Large, IconColor.Orange); + return EditorTexture.Single(texture); + } + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + if (port.key == nameof(PulseSwitchUnit.PulseDelay)) { + desc.summary = "The time in milliseconds until the switches are disabled again."; + } + else if (int.TryParse(port.key, out int id)) { + id += 1; + + desc.label = $"Switch ID {id}"; + desc.summary = $"Switch ID {id} of the switch to be pulsed."; + } + } + } +} diff --git a/Editor/Descriptors/PulseSwitchUnitDescriptor.cs.meta b/Editor/Descriptors/PulseSwitchUnitDescriptor.cs.meta new file mode 100644 index 0000000..26e4e9e --- /dev/null +++ b/Editor/Descriptors/PulseSwitchUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0e534243fbcfb4866bbd39ff3e0b2032 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Descriptors/SetSwitchUnitDescriptor.cs b/Editor/Descriptors/SetSwitchUnitDescriptor.cs new file mode 100644 index 0000000..4ff6c99 --- /dev/null +++ b/Editor/Descriptors/SetSwitchUnitDescriptor.cs @@ -0,0 +1,57 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; +using VisualPinball.Unity.Editor; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(SetSwitchUnit))] + public class SetSwitchUnitDescriptor : UnitDescriptor + { + public SetSwitchUnitDescriptor(SetSwitchUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node assigns a given value to switches defined by their IDs."; + } + + protected override EditorTexture DefinedIcon() + { + var texture = VisualPinball.Unity.Editor.Icons.Switch(false, VisualPinball.Unity.Editor.IconSize.Large, IconColor.Orange); + return EditorTexture.Single(texture); + } + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + if (port.key == nameof(SetSwitchUnit.IsEnabled)) { + desc.summary = "The value to assign to the switches."; + } + else if (int.TryParse(port.key, out int id)) { + id += 1; + + desc.label = $"Switch ID {id}"; + desc.summary = $"Switch ID {id} of the switch to be set."; + } + } + } +} diff --git a/Editor/Descriptors/SetSwitchUnitDescriptor.cs.meta b/Editor/Descriptors/SetSwitchUnitDescriptor.cs.meta new file mode 100644 index 0000000..a6077f4 --- /dev/null +++ b/Editor/Descriptors/SetSwitchUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a039bc39631d43e88527e8b99393b43 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/PulseSwitchUnitWidget.cs b/Editor/Widgets/PulseSwitchUnitWidget.cs new file mode 100644 index 0000000..5a1df2c --- /dev/null +++ b/Editor/Widgets/PulseSwitchUnitWidget.cs @@ -0,0 +1,63 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(PulseSwitchUnit))] + public sealed class PulseSwitchUnitWidget : GleUnitWidget + { + private readonly List> _switchIdInspectorConstructorList; + + public PulseSwitchUnitWidget(FlowCanvas canvas, PulseSwitchUnit unit) : base(canvas, unit) + { + _switchIdInspectorConstructorList = new List>(); + } + + public override Inspector GetPortInspector(IUnitPort port, Metadata meta) + { + if (_switchIdInspectorConstructorList.Count() < unit.inputCount) { + for (var index = 0; index < unit.inputCount - _switchIdInspectorConstructorList.Count(); index++) { + _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.inputCount; index++) { + if (unit.multiInputs[index] == port) { + VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); + + return switchIdInspector; + } + } + + return base.GetPortInspector(port, meta); + } + + private IEnumerable GetNameSuggestions() + { + return !GleAvailable + ? new List() + : Gle.RequestedSwitches.Select(sw => sw.Id).ToList(); + } + } +} diff --git a/Editor/Widgets/PulseSwitchUnitWidget.cs.meta b/Editor/Widgets/PulseSwitchUnitWidget.cs.meta new file mode 100644 index 0000000..129c454 --- /dev/null +++ b/Editor/Widgets/PulseSwitchUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee1bffdc400344c49bc77e8747ad2d23 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/SetSwitchUnitWidget.cs b/Editor/Widgets/SetSwitchUnitWidget.cs new file mode 100644 index 0000000..2ea3992 --- /dev/null +++ b/Editor/Widgets/SetSwitchUnitWidget.cs @@ -0,0 +1,63 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(SetSwitchUnit))] + public sealed class SetSwitchUnitWidget : GleUnitWidget + { + private readonly List> _switchIdInspectorConstructorList; + + public SetSwitchUnitWidget(FlowCanvas canvas, SetSwitchUnit unit) : base(canvas, unit) + { + _switchIdInspectorConstructorList = new List>(); + } + + public override Inspector GetPortInspector(IUnitPort port, Metadata meta) + { + if (_switchIdInspectorConstructorList.Count() < unit.inputCount) { + for (var index = 0; index < unit.inputCount - _switchIdInspectorConstructorList.Count(); index++) { + _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.inputCount; index++) { + if (unit.multiInputs[index] == port) { + VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); + + return switchIdInspector; + } + } + + return base.GetPortInspector(port, meta); + } + + private IEnumerable GetNameSuggestions() + { + return !GleAvailable + ? new List() + : Gle.RequestedSwitches.Select(sw => sw.Id).ToList(); + } + } +} diff --git a/Editor/Widgets/SetSwitchUnitWidget.cs.meta b/Editor/Widgets/SetSwitchUnitWidget.cs.meta new file mode 100644 index 0000000..d62d867 --- /dev/null +++ b/Editor/Widgets/SetSwitchUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fabf8156812a34b91913deac9310e0dc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Switches/PulseSwitchUnit.cs b/Runtime/Nodes/Switches/PulseSwitchUnit.cs new file mode 100644 index 0000000..da84be9 --- /dev/null +++ b/Runtime/Nodes/Switches/PulseSwitchUnit.cs @@ -0,0 +1,99 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Pulse Switch")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Visual Pinball")] + public class PulseSwitchUnit : GleUnit, IMultiInputUnit + { + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Switch IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } + + [DoNotSerialize] + public ReadOnlyCollection multiInputs { get; private set; } + + [DoNotSerialize] + [PortLabel("Delay (ms)")] + public ValueInput PulseDelay { get; private set; } + + protected override void Definition() + { + InputTrigger = ControlInput(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); + + for (var i = 0; i < inputCount; i++) { + var input = ValueInput(i.ToString(), string.Empty); + _multiInputs.Add(input); + + Requirement(input, InputTrigger); + } + + PulseDelay = ValueInput(nameof(PulseDelay), 250); + + Succession(InputTrigger, OutputTrigger); + } + + private ControlOutput Process(Flow flow) + { + if (!AssertGle(flow)) { + Debug.LogError("Cannot find GLE."); + return OutputTrigger; + } + + if (!AssertPlayer(flow)) { + Debug.LogError("Cannot find Player."); + return OutputTrigger; + } + + var pulseDuration = flow.GetValue(PulseDelay); + + foreach (var input in multiInputs) { + var switchId = flow.GetValue(input); + Gle.Switch(switchId, true); + Player.ScheduleAction(pulseDuration, () => Gle.Switch(switchId, false)); + } + + return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/Switches/PulseSwitchUnit.cs.meta b/Runtime/Nodes/Switches/PulseSwitchUnit.cs.meta new file mode 100644 index 0000000..1cff8fa --- /dev/null +++ b/Runtime/Nodes/Switches/PulseSwitchUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87c039580d29b44b98a54b1ca747ba26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Switches/SetSwitchUnit.cs b/Runtime/Nodes/Switches/SetSwitchUnit.cs new file mode 100644 index 0000000..901f08e --- /dev/null +++ b/Runtime/Nodes/Switches/SetSwitchUnit.cs @@ -0,0 +1,93 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Set Switch")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Visual Pinball")] + public class SetSwitchUnit : GleUnit, IMultiInputUnit + { + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Switch IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } + + [DoNotSerialize] + public ReadOnlyCollection multiInputs { get; private set; } + + [DoNotSerialize] + [PortLabel("Value")] + public ValueInput IsEnabled { get; private set; } + + protected override void Definition() + { + InputTrigger = ControlInput(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); + + for (var i = 0; i < inputCount; i++) { + var input = ValueInput(i.ToString(), string.Empty); + _multiInputs.Add(input); + + Requirement(input, InputTrigger); + } + + IsEnabled = ValueInput(nameof(IsEnabled), false); + + Succession(InputTrigger, OutputTrigger); + } + + private ControlOutput Process(Flow flow) + { + if (!AssertGle(flow)) { + Debug.LogError("Cannot find GLE."); + return OutputTrigger; + } + + var isEnabled = flow.GetValue(IsEnabled); + + foreach (var input in multiInputs) { + var switchId = flow.GetValue(input); + Gle.Switch(switchId, isEnabled); + } + + return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/Switches/SetSwitchUnit.cs.meta b/Runtime/Nodes/Switches/SetSwitchUnit.cs.meta new file mode 100644 index 0000000..e2e4677 --- /dev/null +++ b/Runtime/Nodes/Switches/SetSwitchUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e43245b55a5e94d4082380bedbe0bc42 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From de956768fdb067830a433207d5c237e1c20454fd Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Tue, 15 Feb 2022 07:36:10 -0500 Subject: [PATCH 40/54] units: refactored SetLampComponentUnit into SetLampColorUnit --- ...iptor.cs => SetLampColorUnitDescriptor.cs} | 28 ++++---- .../SetLampColorUnitDescriptor.cs.meta | 2 +- Editor/Widgets/SetLampColorUnitWidget.cs | 67 +++++++++++++++++++ .../SetLampColorUnitWidget.cs.meta} | 2 +- Editor/Widgets/SetLampComponentUnitWidget.cs | 46 ------------- ...mpComponentUnit.cs => SetLampColorUnit.cs} | 59 ++++++++++------ .../Nodes/Lamps/SetLampColorUnit.cs.meta | 2 +- 7 files changed, 120 insertions(+), 86 deletions(-) rename Editor/Descriptors/{SetLampComponentUnitDescriptor.cs => SetLampColorUnitDescriptor.cs} (56%) rename Runtime/Nodes/Lamps/SetLampComponentUnit.cs.meta => Editor/Descriptors/SetLampColorUnitDescriptor.cs.meta (83%) create mode 100644 Editor/Widgets/SetLampColorUnitWidget.cs rename Editor/{Descriptors/SetLampComponentUnitDescriptor.cs.meta => Widgets/SetLampColorUnitWidget.cs.meta} (83%) delete mode 100644 Editor/Widgets/SetLampComponentUnitWidget.cs rename Runtime/Nodes/Lamps/{SetLampComponentUnit.cs => SetLampColorUnit.cs} (54%) rename Editor/Widgets/SetLampComponentUnitWidget.cs.meta => Runtime/Nodes/Lamps/SetLampColorUnit.cs.meta (83%) diff --git a/Editor/Descriptors/SetLampComponentUnitDescriptor.cs b/Editor/Descriptors/SetLampColorUnitDescriptor.cs similarity index 56% rename from Editor/Descriptors/SetLampComponentUnitDescriptor.cs rename to Editor/Descriptors/SetLampColorUnitDescriptor.cs index 1e97bc0..b5594d4 100644 --- a/Editor/Descriptors/SetLampComponentUnitDescriptor.cs +++ b/Editor/Descriptors/SetLampColorUnitDescriptor.cs @@ -22,16 +22,16 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Descriptor(typeof(SetLampComponentUnit))] - public class SetLampComponentUnitDescriptor : UnitDescriptor + [Descriptor(typeof(SetLampColorUnit))] + public class SetLampColorUnitDescriptor : UnitDescriptor { - public SetLampComponentUnitDescriptor(SetLampComponentUnit target) : base(target) + public SetLampColorUnitDescriptor(SetLampColorUnit target) : base(target) { } protected override string DefinedSummary() { - return "This node assigns a given value to a light or light group in the scene. \n\nNote that this doesn't pass through the gamelogic engine, thus no event will be triggered. However, it allows you to drive non-mapped lights as well."; + return "This node assigns a given value to a lamp defined by its mapped ID. This will also trigger the lamp changed event and update the internal status."; } protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Light(IconSize.Large, IconColor.Orange)); @@ -40,18 +40,16 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { base.DefinedPort(port, desc); - switch (port.key) { - case nameof(SetLampComponentUnit.LampComponent): - desc.summary = "The light component whose value you want to change. Assigning a light group will change all lights in the group."; - break; - - case nameof(SetLampComponentUnit.Value): - desc.summary = "The intensity to apply (0-1)."; - break; + if (port.key == nameof(SetLampColorUnit.Value)) + { + desc.summary = "The color to set the lamp"; + } + else if (int.TryParse(port.key, out int id)) + { + id += 1; - case nameof(SetLampComponentUnit.ColorChannel): - desc.summary = "Which color channel to use. For non-RGB lights, use alpha."; - break; + desc.label = $"Lamp ID {id}"; + desc.summary = $"Lamp ID {id} of the lamp to set the intensity"; } } } diff --git a/Runtime/Nodes/Lamps/SetLampComponentUnit.cs.meta b/Editor/Descriptors/SetLampColorUnitDescriptor.cs.meta similarity index 83% rename from Runtime/Nodes/Lamps/SetLampComponentUnit.cs.meta rename to Editor/Descriptors/SetLampColorUnitDescriptor.cs.meta index 5c4bf53..a41263e 100644 --- a/Runtime/Nodes/Lamps/SetLampComponentUnit.cs.meta +++ b/Editor/Descriptors/SetLampColorUnitDescriptor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 40170555ebd5580468c2a20163c10954 +guid: 9377accfee39644cfb301e48ecb6829d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Widgets/SetLampColorUnitWidget.cs b/Editor/Widgets/SetLampColorUnitWidget.cs new file mode 100644 index 0000000..943227d --- /dev/null +++ b/Editor/Widgets/SetLampColorUnitWidget.cs @@ -0,0 +1,67 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(SetLampColorUnit))] + public sealed class SetLampColorUnitWidget : GleUnitWidget + { + private readonly List> _lampIdInspectorConstructorList; + + public SetLampColorUnitWidget(FlowCanvas canvas, SetLampColorUnit unit) : base(canvas, unit) + { + _lampIdInspectorConstructorList = new List>(); + } + + public override Inspector GetPortInspector(IUnitPort port, Metadata meta) + { + if (_lampIdInspectorConstructorList.Count() < unit.inputCount) + { + for (var index = 0; index < unit.inputCount - _lampIdInspectorConstructorList.Count(); index++) + { + _lampIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.inputCount; index++) + { + if (unit.multiInputs[index] == port) + { + VariableNameInspector lampIdInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); + + return lampIdInspector; + } + } + + return base.GetPortInspector(port, meta); + } + + private IEnumerable GetNameSuggestions() + { + return !GleAvailable + ? new List() + : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); + } + } +} diff --git a/Editor/Descriptors/SetLampComponentUnitDescriptor.cs.meta b/Editor/Widgets/SetLampColorUnitWidget.cs.meta similarity index 83% rename from Editor/Descriptors/SetLampComponentUnitDescriptor.cs.meta rename to Editor/Widgets/SetLampColorUnitWidget.cs.meta index 8602719..226c427 100644 --- a/Editor/Descriptors/SetLampComponentUnitDescriptor.cs.meta +++ b/Editor/Widgets/SetLampColorUnitWidget.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6843a9d0a62de5548bdd314153e6780e +guid: 47febd1d7ff91412b85814eb2a5c55c2 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Widgets/SetLampComponentUnitWidget.cs b/Editor/Widgets/SetLampComponentUnitWidget.cs deleted file mode 100644 index 759991f..0000000 --- a/Editor/Widgets/SetLampComponentUnitWidget.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable UnusedType.Global - -using System; -using Unity.VisualScripting; - -namespace VisualPinball.Unity.VisualScripting.Editor -{ - [Widget(typeof(SetLampComponentUnit))] - public sealed class SetLampComponentUnitWidget : GleUnitWidget - { - private ObjectPickerInspector _objectInspector; - private readonly Func> _setObjectInspectorConstructor; - - public SetLampComponentUnitWidget(FlowCanvas canvas, SetLampComponentUnit unit) : base(canvas, unit) - { - var tc = reference.gameObject.GetComponentInParent(); - _setObjectInspectorConstructor = meta => new ObjectPickerInspector(meta, "Lamps", tc); - } - - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (port == unit.LampComponent) { - InspectorProvider.instance.Renew(ref _objectInspector, meta, _setObjectInspectorConstructor); - return _objectInspector; - } - return base.GetPortInspector(port, meta); - } - - } -} diff --git a/Runtime/Nodes/Lamps/SetLampComponentUnit.cs b/Runtime/Nodes/Lamps/SetLampColorUnit.cs similarity index 54% rename from Runtime/Nodes/Lamps/SetLampComponentUnit.cs rename to Runtime/Nodes/Lamps/SetLampColorUnit.cs index 6d43537..10769b4 100644 --- a/Runtime/Nodes/Lamps/SetLampComponentUnit.cs +++ b/Runtime/Nodes/Lamps/SetLampColorUnit.cs @@ -14,17 +14,18 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System.Collections.Generic; +using System.Collections.ObjectModel; using Unity.VisualScripting; using UnityEngine; -using VisualPinball.Engine.Math; namespace VisualPinball.Unity.VisualScripting { - [UnitTitle("Set Lamp (Component, Value, Channel)")] [UnitShortTitle("Set Lamp")] - [UnitSurtitle("Scene")] + [UnitTitle("Set Lamp (ID, Color)")] + [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Visual Pinball")] - public class SetLampComponentUnit : GleUnit + public class SetLampColorUnit : GleUnit, IMultiInputUnit { [DoNotSerialize] [PortLabelHidden] @@ -34,49 +35,63 @@ public class SetLampComponentUnit : GleUnit [PortLabelHidden] public ControlOutput OutputTrigger; + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + [DoNotSerialize] - [PortLabel("Component")] - public ValueInput LampComponent; + [Inspectable, UnitHeaderInspectable("Lamp IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } [DoNotSerialize] - [PortLabel("Intensity")] - public ValueInput Value; + public ReadOnlyCollection multiInputs { get; private set; } [DoNotSerialize] - [PortLabel("Color Channel")] - public ValueInput ColorChannel; + [PortLabel("Value")] + public ValueInput Value { get; private set; } protected override void Definition() { InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - LampComponent = ValueInput(nameof(LampComponent), null); + var _multiInputs = new List(); - Value = ValueInput(nameof(Value), 0f); - ColorChannel = ValueInput(nameof(ColorChannel), Engine.Math.ColorChannel.Alpha); + multiInputs = _multiInputs.AsReadOnly(); + + for (var i = 0; i < inputCount; i++) + { + var input = ValueInput(i.ToString(), string.Empty); + _multiInputs.Add(input); + + Requirement(input, InputTrigger); + } + + Value = ValueInput(nameof(Value), Color.black); - Requirement(LampComponent, InputTrigger); Succession(InputTrigger, OutputTrigger); } private ControlOutput Process(Flow flow) { - if (!AssertPlayer(flow)) { - Debug.LogError("Cannot find player."); + if (!AssertGle(flow)) + { + Debug.LogError("Cannot find GLE."); return OutputTrigger; } - if (flow.GetValue(LampComponent) is ILampDeviceComponent lamp) { - var valueRaw = flow.GetValue(Value); - var colorChannelRaw = flow.GetValue(ColorChannel); + var value = flow.GetValue(Value); - Player.Lamp(lamp)?.OnLamp(valueRaw, colorChannelRaw); + foreach (var input in multiInputs) + { + var lampId = flow.GetValue(input); + Gle.SetLamp(lampId, value); } return OutputTrigger; } - - } } diff --git a/Editor/Widgets/SetLampComponentUnitWidget.cs.meta b/Runtime/Nodes/Lamps/SetLampColorUnit.cs.meta similarity index 83% rename from Editor/Widgets/SetLampComponentUnitWidget.cs.meta rename to Runtime/Nodes/Lamps/SetLampColorUnit.cs.meta index a3b95ad..cd12ff8 100644 --- a/Editor/Widgets/SetLampComponentUnitWidget.cs.meta +++ b/Runtime/Nodes/Lamps/SetLampColorUnit.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f291d79296189034489ec69582d06d41 +guid: 37c79aa6bbcac4c0f84443ec1f1ad747 MonoImporter: externalObjects: {} serializedVersion: 2 From bfbd43a33fd08ec461f6addd28556fc7cce1413b Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Tue, 15 Feb 2022 16:57:37 -0500 Subject: [PATCH 41/54] misc: refactor SetLightSequenceUnit to LampSequenceUnit --- .../Descriptors/LampSequenceUnitDescriptor.cs | 55 +++++++ .../LampSequenceUnitDescriptor.cs.meta | 2 +- .../SetLightSequenceUnitDescriptor.cs | 62 -------- Editor/Widgets/LampSequenceUnitWidget.cs | 63 ++++++++ .../LampSequenceUnitWidget.cs.meta} | 2 +- Editor/Widgets/SetLightSequenceUnitWidget.cs | 45 ------ Runtime/Nodes/Lamps/LampSequenceUnit.cs | 149 ++++++++++++++++++ .../Nodes/Lamps/LampSequenceUnit.cs.meta | 2 +- Runtime/Nodes/Lamps/SetLightSequenceUnit.cs | 95 ----------- 9 files changed, 270 insertions(+), 205 deletions(-) create mode 100644 Editor/Descriptors/LampSequenceUnitDescriptor.cs rename Runtime/Nodes/Lamps/SetLightSequenceUnit.cs.meta => Editor/Descriptors/LampSequenceUnitDescriptor.cs.meta (83%) delete mode 100644 Editor/Descriptors/SetLightSequenceUnitDescriptor.cs create mode 100644 Editor/Widgets/LampSequenceUnitWidget.cs rename Editor/{Descriptors/SetLightSequenceUnitDescriptor.cs.meta => Widgets/LampSequenceUnitWidget.cs.meta} (83%) delete mode 100644 Editor/Widgets/SetLightSequenceUnitWidget.cs create mode 100644 Runtime/Nodes/Lamps/LampSequenceUnit.cs rename Editor/Widgets/SetLightSequenceUnitWidget.cs.meta => Runtime/Nodes/Lamps/LampSequenceUnit.cs.meta (83%) delete mode 100644 Runtime/Nodes/Lamps/SetLightSequenceUnit.cs diff --git a/Editor/Descriptors/LampSequenceUnitDescriptor.cs b/Editor/Descriptors/LampSequenceUnitDescriptor.cs new file mode 100644 index 0000000..a51d8f4 --- /dev/null +++ b/Editor/Descriptors/LampSequenceUnitDescriptor.cs @@ -0,0 +1,55 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(LampSequenceUnit))] + public class LampSequenceUnitDescriptor : UnitDescriptor + { + public LampSequenceUnitDescriptor(LampSequenceUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node turns on/off lamps in a sequence defined by lamp ids."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.LampSequence); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + if (port.key == nameof(LampSequenceUnit.Step)) { + desc.summary = "How position is increased and to how many lights the intensity is applied to."; + } + else if (port.key == nameof(LampSequenceUnit.Value)) { + desc.summary = "The intensity to apply to the current step (0-1)."; + } + else if (int.TryParse(port.key, out int id)) { + id += 1; + + desc.label = $"Lamp ID {id}"; + desc.summary = $"Lamp ID {id} to cycle through."; + } + } + } +} diff --git a/Runtime/Nodes/Lamps/SetLightSequenceUnit.cs.meta b/Editor/Descriptors/LampSequenceUnitDescriptor.cs.meta similarity index 83% rename from Runtime/Nodes/Lamps/SetLightSequenceUnit.cs.meta rename to Editor/Descriptors/LampSequenceUnitDescriptor.cs.meta index 62cf318..bdcdba4 100644 --- a/Runtime/Nodes/Lamps/SetLightSequenceUnit.cs.meta +++ b/Editor/Descriptors/LampSequenceUnitDescriptor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 60a2132e0c1641742b3c4694db33e7e4 +guid: 238a5a8d7a46e47808155b5d126bab7c MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Descriptors/SetLightSequenceUnitDescriptor.cs b/Editor/Descriptors/SetLightSequenceUnitDescriptor.cs deleted file mode 100644 index b31266c..0000000 --- a/Editor/Descriptors/SetLightSequenceUnitDescriptor.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable UnusedType.Global - -using Unity.VisualScripting; -using VisualPinball.Unity.Editor; -using IconSize = VisualPinball.Unity.Editor.IconSize; - -namespace VisualPinball.Unity.VisualScripting.Editor -{ - [Descriptor(typeof(SetLightSequenceUnit))] - public class SetLightSequenceUnitDescriptor : UnitDescriptor - { - public SetLightSequenceUnitDescriptor(SetLightSequenceUnit target) : base(target) - { - } - - protected override string DefinedSummary() - { - return "This node sets the intensity of the lights at the next position within a light group. On each execution, the position increases by the number of steps. The number of lights set is the step number.\n\nExample: Four lights, A B C D, step size = 2. First run, lights A and B are set. Second run, lights C and D are set."; - } - - protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.LampSequence); - - protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) - { - base.DefinedPort(port, desc); - - switch (port.key) { - case nameof(SetLightSequenceUnit.LightGroup): - desc.summary = "The light group to cycle through."; - break; - - case nameof(SetLightSequenceUnit.Value): - desc.summary = "The intensity to apply to the current step (0-1)."; - break; - - case nameof(SetLightSequenceUnit.ColorChannel): - desc.summary = "Which color channel to use. For non-RGB lights, use alpha."; - break; - - case nameof(SetLightSequenceUnit.Step): - desc.summary = "How position is increased and to how many lights the intensity is applied to."; - break; - } - } - } -} diff --git a/Editor/Widgets/LampSequenceUnitWidget.cs b/Editor/Widgets/LampSequenceUnitWidget.cs new file mode 100644 index 0000000..3d0504c --- /dev/null +++ b/Editor/Widgets/LampSequenceUnitWidget.cs @@ -0,0 +1,63 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(LampSequenceUnit))] + public sealed class LampSequenceUnitWidget : GleUnitWidget + { + private readonly List> _lampIdInspectorConstructorList; + + public LampSequenceUnitWidget(FlowCanvas canvas, LampSequenceUnit unit) : base(canvas, unit) + { + _lampIdInspectorConstructorList = new List>(); + } + + public override Inspector GetPortInspector(IUnitPort port, Metadata meta) + { + if (_lampIdInspectorConstructorList.Count() < unit.inputCount) { + for (var index = 0; index < unit.inputCount - _lampIdInspectorConstructorList.Count(); index++) { + _lampIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); + } + } + + for (var index = 0; index < unit.inputCount; index++) { + if (unit.multiInputs[index] == port) { + VariableNameInspector lampIdInspector = new VariableNameInspector(meta, GetNameSuggestions); + InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); + + return lampIdInspector; + } + } + + return base.GetPortInspector(port, meta); + } + + private IEnumerable GetNameSuggestions() + { + return !GleAvailable + ? new List() + : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); + } + } +} diff --git a/Editor/Descriptors/SetLightSequenceUnitDescriptor.cs.meta b/Editor/Widgets/LampSequenceUnitWidget.cs.meta similarity index 83% rename from Editor/Descriptors/SetLightSequenceUnitDescriptor.cs.meta rename to Editor/Widgets/LampSequenceUnitWidget.cs.meta index 07d188a..bdec38c 100644 --- a/Editor/Descriptors/SetLightSequenceUnitDescriptor.cs.meta +++ b/Editor/Widgets/LampSequenceUnitWidget.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7b4ee905eeb80ec48946a1fa5cdfe58b +guid: 9361364ed5194461ab46a8c5e27e7916 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Widgets/SetLightSequenceUnitWidget.cs b/Editor/Widgets/SetLightSequenceUnitWidget.cs deleted file mode 100644 index 0689e76..0000000 --- a/Editor/Widgets/SetLightSequenceUnitWidget.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable UnusedType.Global - -using System; -using Unity.VisualScripting; - -namespace VisualPinball.Unity.VisualScripting.Editor -{ - [Widget(typeof(SetLightSequenceUnit))] - public sealed class SetLightSequenceUnitWidget : GleUnitWidget - { - private ObjectPickerInspector _objectInspector; - private readonly Func> _setObjectInspectorConstructor; - - public SetLightSequenceUnitWidget(FlowCanvas canvas, SetLightSequenceUnit unit) : base(canvas, unit) - { - var tc = reference.gameObject.GetComponentInParent(); - _setObjectInspectorConstructor = meta => new ObjectPickerInspector(meta, "Light Groups", tc); - } - - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (port == unit.LightGroup) { - InspectorProvider.instance.Renew(ref _objectInspector, meta, _setObjectInspectorConstructor); - return _objectInspector; - } - return base.GetPortInspector(port, meta); - } - } -} diff --git a/Runtime/Nodes/Lamps/LampSequenceUnit.cs b/Runtime/Nodes/Lamps/LampSequenceUnit.cs new file mode 100644 index 0000000..b03ac69 --- /dev/null +++ b/Runtime/Nodes/Lamps/LampSequenceUnit.cs @@ -0,0 +1,149 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Unity.VisualScripting; +using UnityEngine; +using VisualPinball.Engine.Math; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Lamp Sequence")] + [UnitSurtitle("Scene")] + [UnitCategory("Visual Pinball")] + public class LampSequenceUnit : GleUnit, IMultiInputUnit + { + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Lamp IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } + + [DoNotSerialize] + public ReadOnlyCollection multiInputs { get; private set; } + + [DoNotSerialize] + [PortLabel("Value")] + public ValueInput Value { get; private set; } + + [DoNotSerialize] + [PortLabel("Step")] + public ValueInput Step; + + private int _currentIndex; + private List _lightComponentCache = null; + + protected override void Definition() + { + InputTrigger = ControlInput(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); + + for (var i = 0; i < inputCount; i++) { + var input = ValueInput(i.ToString(), string.Empty); + _multiInputs.Add(input); + + Requirement(input, InputTrigger); + } + + Value = ValueInput(nameof(Value), 0f); + Step = ValueInput(nameof(Step), 1); + + Succession(InputTrigger, OutputTrigger); + + _lightComponentCache = null; + } + + private ControlOutput Process(Flow flow) + { + if (!AssertGle(flow)) + { + Debug.LogError("Cannot find GLE."); + return OutputTrigger; + } + + if (!AssertPlayer(flow)) { + Debug.LogError("Cannot find player."); + return OutputTrigger; + } + + var value = flow.GetValue(Value); + var stepRaw = flow.GetValue(Step); + + if (_lightComponentCache != null) { + foreach (var component in _lightComponentCache) { + if (component.IsUnityNull()) { + _lightComponentCache = null; + break; + } + } + } + + if (_lightComponentCache == null) { + _lightComponentCache = new List(); + + foreach (var input in multiInputs) { + var lampId = flow.GetValue(input); + _lightComponentCache.AddRange(Flatten(Player.LampDevice(lampId))); + } + } + + for (var index = 0; index < _lightComponentCache.Count; index++) { + Player.Lamp(_lightComponentCache[index]).OnLamp( + index >= _currentIndex * stepRaw && index < (_currentIndex + 1) * stepRaw ? value : 0, ColorChannel.Alpha); ; + } + + if (++_currentIndex >= _lightComponentCache.Count / stepRaw) { + _currentIndex = 0; + } + + return OutputTrigger; + } + + private List Flatten(List lampDeviceList) + { + List lights = new List(); + + foreach (ILampDeviceComponent device in lampDeviceList) { + if (device is LightComponent) { + lights.Add(device as LightComponent); + } + else if (device is LightGroupComponent) { + lights.AddRange(Flatten(((LightGroupComponent)device).Lights)); + } + } + + return lights; + } + } +} diff --git a/Editor/Widgets/SetLightSequenceUnitWidget.cs.meta b/Runtime/Nodes/Lamps/LampSequenceUnit.cs.meta similarity index 83% rename from Editor/Widgets/SetLightSequenceUnitWidget.cs.meta rename to Runtime/Nodes/Lamps/LampSequenceUnit.cs.meta index 976ea63..7072b6c 100644 --- a/Editor/Widgets/SetLightSequenceUnitWidget.cs.meta +++ b/Runtime/Nodes/Lamps/LampSequenceUnit.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e14ec4f39993ef2418a0309406658899 +guid: f534b9e12134d430db8c6c700be38fc8 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/Nodes/Lamps/SetLightSequenceUnit.cs b/Runtime/Nodes/Lamps/SetLightSequenceUnit.cs deleted file mode 100644 index a1ae9a5..0000000 --- a/Runtime/Nodes/Lamps/SetLightSequenceUnit.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.VisualScripting; -using UnityEngine; -using VisualPinball.Engine.Math; - -namespace VisualPinball.Unity.VisualScripting -{ - [UnitTitle("Set Light Sequence")] - [UnitSurtitle("Scene")] - [UnitCategory("Visual Pinball")] - public class SetLightSequenceUnit : GleUnit - { - [DoNotSerialize] - [PortLabelHidden] - public ControlInput InputTrigger; - - [DoNotSerialize] - [PortLabelHidden] - public ControlOutput OutputTrigger; - - [DoNotSerialize] - [PortLabel("Light Group")] - public ValueInput LightGroup; - - [DoNotSerialize] - [PortLabel("Intensity")] - public ValueInput Value; - - [DoNotSerialize] - [PortLabel("Color Channel")] - public ValueInput ColorChannel; - - [DoNotSerialize] - [PortLabel("Step")] - public ValueInput Step; - - private int _currentIndex; - - protected override void Definition() - { - InputTrigger = ControlInput(nameof(InputTrigger), Process); - OutputTrigger = ControlOutput(nameof(OutputTrigger)); - - LightGroup = ValueInput(nameof(LightGroup), null); - - Value = ValueInput(nameof(Value), 0); - ColorChannel = ValueInput(nameof(ColorChannel), Engine.Math.ColorChannel.Alpha); - Step = ValueInput(nameof(Step), 1); - - Requirement(LightGroup, InputTrigger); - Requirement(Value, InputTrigger); - Succession(InputTrigger, OutputTrigger); - } - - private ControlOutput Process(Flow flow) - { - if (!AssertPlayer(flow)) { - Debug.LogError("Cannot find player."); - return OutputTrigger; - } - - var valueRaw = flow.GetValue(Value); - var colorChannelRaw = flow.GetValue(ColorChannel); - var stepRaw = flow.GetValue(Step); - var lamps = flow.GetValue(LightGroup).Lights; - - for (var index = 0; index < lamps.Count; index++) { - Player.Lamp(lamps[index]).OnLamp( - index >= _currentIndex * stepRaw && index < (_currentIndex + 1) * stepRaw ? valueRaw : 0, - colorChannelRaw); - } - - if (++_currentIndex >= lamps.Count / stepRaw) { - _currentIndex = 0; - } - - return OutputTrigger; - } - } -} From f116e09302accaad6810e8ed8f098947ae9b8804 Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 15 Feb 2022 23:13:16 +0100 Subject: [PATCH 42/54] Refactor multi widgets to inherit from GleMultiUnitWidget. --- .../AllSwitchesEnabledEventUnitWidget.cs | 15 +++ .../AllSwitchesEnabledEventUnitWidget.cs.meta | 11 ++ Editor/Widgets/GleMultiUnitWidget.cs | 9 -- Editor/Widgets/LampEventUnitWidget.cs | 101 ++++++------------ Editor/Widgets/PulseCoilUnitWidget.cs | 32 +----- Editor/Widgets/PulseSwitchUnitWidget.cs | 33 +----- Editor/Widgets/SetCoilUnitWidget.cs | 33 +----- Editor/Widgets/SetLampColorUnitWidget.cs | 36 +------ Editor/Widgets/SetLampEnabledUnitWidget.cs | 33 +----- Editor/Widgets/SetLampUnitWidget.cs | 33 +----- Editor/Widgets/SetSwitchUnitWidget.cs | 33 +----- .../Widgets/SwitchEnabledEventUnitWidget.cs | 33 +----- Editor/Widgets/SwitchEventUnitWidget.cs | 34 +----- 13 files changed, 78 insertions(+), 358 deletions(-) create mode 100644 Editor/Widgets/AllSwitchesEnabledEventUnitWidget.cs create mode 100644 Editor/Widgets/AllSwitchesEnabledEventUnitWidget.cs.meta diff --git a/Editor/Widgets/AllSwitchesEnabledEventUnitWidget.cs b/Editor/Widgets/AllSwitchesEnabledEventUnitWidget.cs new file mode 100644 index 0000000..5fb459a --- /dev/null +++ b/Editor/Widgets/AllSwitchesEnabledEventUnitWidget.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(AllSwitchesEnabledEventUnit))] + public sealed class AllSwitchesEnabledEventUnitWidget : GleMultiUnitWidget + { + public AllSwitchesEnabledEventUnitWidget(FlowCanvas canvas, AllSwitchesEnabledEventUnit unit) : base(canvas, unit) + { + } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedSwitches.Select(sw => sw.Id); + } +} diff --git a/Editor/Widgets/AllSwitchesEnabledEventUnitWidget.cs.meta b/Editor/Widgets/AllSwitchesEnabledEventUnitWidget.cs.meta new file mode 100644 index 0000000..728d748 --- /dev/null +++ b/Editor/Widgets/AllSwitchesEnabledEventUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7872e03c03543244594aa193847f285e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/GleMultiUnitWidget.cs b/Editor/Widgets/GleMultiUnitWidget.cs index 8a477d6..e3f5d4a 100644 --- a/Editor/Widgets/GleMultiUnitWidget.cs +++ b/Editor/Widgets/GleMultiUnitWidget.cs @@ -21,15 +21,6 @@ namespace VisualPinball.Unity.VisualScripting.Editor { - [Widget(typeof(AllSwitchesEnabledEventUnit))] - public sealed class AllSwitchesEnabledEventUnitWidget : GleMultiUnitWidget - { - public AllSwitchesEnabledEventUnitWidget(FlowCanvas canvas, AllSwitchesEnabledEventUnit unit) : base(canvas, unit) - { - } - protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedSwitches.Select(sw => sw.Id); - } - public abstract class GleMultiUnitWidget : GleUnitWidget where TUnit : Unit, IGleUnit, IMultiInputUnit { protected abstract IEnumerable IdSuggestions(IGamelogicEngine gle); diff --git a/Editor/Widgets/LampEventUnitWidget.cs b/Editor/Widgets/LampEventUnitWidget.cs index 2b01ae3..e733e60 100644 --- a/Editor/Widgets/LampEventUnitWidget.cs +++ b/Editor/Widgets/LampEventUnitWidget.cs @@ -1,67 +1,34 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable UnusedType.Global - -using System; -using System.Collections.Generic; -using System.Linq; -using Unity.VisualScripting; - -namespace VisualPinball.Unity.VisualScripting.Editor -{ - [Widget(typeof(LampEventUnit))] - public sealed class LampEventUnitWidget : GleUnitWidget - { - private readonly List> _lampIdInspectorConstructorList; - - public LampEventUnitWidget(FlowCanvas canvas, LampEventUnit unit) : base(canvas, unit) - { - _lampIdInspectorConstructorList = new List>(); - } - - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (_lampIdInspectorConstructorList.Count() < unit.inputCount) - { - for (var index = 0; index < unit.inputCount - _lampIdInspectorConstructorList.Count(); index++) - { - _lampIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); - } - } - - for (var index = 0; index < unit.inputCount; index++) - { - if (unit.multiInputs[index] == port) - { - VariableNameInspector lampIdInspector = new VariableNameInspector(meta, GetNameSuggestions); - InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); - - return lampIdInspector; - } - } - - return base.GetPortInspector(port, meta); - } - - private IEnumerable GetNameSuggestions() - { - return !GleAvailable - ? new List() - : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); - } - } -} +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(LampEventUnit))] + public sealed class LampEventUnitWidget : GleMultiUnitWidget + { + public LampEventUnitWidget(FlowCanvas canvas, LampEventUnit unit) : base(canvas, unit) + { + } + + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedLamps.Select(lamp => lamp.Id); + } +} diff --git a/Editor/Widgets/PulseCoilUnitWidget.cs b/Editor/Widgets/PulseCoilUnitWidget.cs index 677ae1a..c2adf73 100644 --- a/Editor/Widgets/PulseCoilUnitWidget.cs +++ b/Editor/Widgets/PulseCoilUnitWidget.cs @@ -24,40 +24,12 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(PulseCoilUnit))] - public sealed class PulseCoilUnitWidget : GleUnitWidget + public sealed class PulseCoilUnitWidget : GleMultiUnitWidget { - private readonly List> _coilIdInspectorConstructorList; - public PulseCoilUnitWidget(FlowCanvas canvas, PulseCoilUnit unit) : base(canvas, unit) { - _coilIdInspectorConstructorList = new List>(); } - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (_coilIdInspectorConstructorList.Count() < unit.inputCount) { - for (var index = 0; index < unit.inputCount - _coilIdInspectorConstructorList.Count(); index++) { - _coilIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); - } - } - - for (var index = 0; index < unit.inputCount; index++) { - if (unit.multiInputs[index] == port) { - VariableNameInspector coilIdInspector = new VariableNameInspector(meta, GetNameSuggestions); - InspectorProvider.instance.Renew(ref coilIdInspector, meta, _coilIdInspectorConstructorList[index]); - - return coilIdInspector; - } - } - - return base.GetPortInspector(port, meta); - } - - private IEnumerable GetNameSuggestions() - { - return !GleAvailable - ? new List() - : Gle.RequestedCoils.Select(coil => coil.Id).ToList(); - } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedCoils.Select(coil => coil.Id); } } diff --git a/Editor/Widgets/PulseSwitchUnitWidget.cs b/Editor/Widgets/PulseSwitchUnitWidget.cs index 5a1df2c..985cc59 100644 --- a/Editor/Widgets/PulseSwitchUnitWidget.cs +++ b/Editor/Widgets/PulseSwitchUnitWidget.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System; using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; @@ -24,40 +23,12 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(PulseSwitchUnit))] - public sealed class PulseSwitchUnitWidget : GleUnitWidget + public sealed class PulseSwitchUnitWidget : GleMultiUnitWidget { - private readonly List> _switchIdInspectorConstructorList; - public PulseSwitchUnitWidget(FlowCanvas canvas, PulseSwitchUnit unit) : base(canvas, unit) { - _switchIdInspectorConstructorList = new List>(); } - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (_switchIdInspectorConstructorList.Count() < unit.inputCount) { - for (var index = 0; index < unit.inputCount - _switchIdInspectorConstructorList.Count(); index++) { - _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); - } - } - - for (var index = 0; index < unit.inputCount; index++) { - if (unit.multiInputs[index] == port) { - VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); - InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); - - return switchIdInspector; - } - } - - return base.GetPortInspector(port, meta); - } - - private IEnumerable GetNameSuggestions() - { - return !GleAvailable - ? new List() - : Gle.RequestedSwitches.Select(sw => sw.Id).ToList(); - } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedSwitches.Select(sw => sw.Id); } } diff --git a/Editor/Widgets/SetCoilUnitWidget.cs b/Editor/Widgets/SetCoilUnitWidget.cs index 946ba16..e8e3d1e 100644 --- a/Editor/Widgets/SetCoilUnitWidget.cs +++ b/Editor/Widgets/SetCoilUnitWidget.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System; using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; @@ -24,40 +23,12 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(SetCoilUnit))] - public sealed class SetCoilUnitWidget : GleUnitWidget + public sealed class SetCoilUnitWidget : GleMultiUnitWidget { - private readonly List> _coilIdInspectorConstructorList; - public SetCoilUnitWidget(FlowCanvas canvas, SetCoilUnit unit) : base(canvas, unit) { - _coilIdInspectorConstructorList = new List>(); } - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (_coilIdInspectorConstructorList.Count() < unit.inputCount) { - for (var index = 0; index < unit.inputCount - _coilIdInspectorConstructorList.Count(); index++) { - _coilIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); - } - } - - for (var index = 0; index < unit.inputCount; index++) { - if (unit.multiInputs[index] == port) { - VariableNameInspector coilIdInspector = new VariableNameInspector(meta, GetNameSuggestions); - InspectorProvider.instance.Renew(ref coilIdInspector, meta, _coilIdInspectorConstructorList[index]); - - return coilIdInspector; - } - } - - return base.GetPortInspector(port, meta); - } - - private IEnumerable GetNameSuggestions() - { - return !GleAvailable - ? new List() - : Gle.RequestedCoils.Select(coil => coil.Id).ToList(); - } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedCoils.Select(coil => coil.Id); } } diff --git a/Editor/Widgets/SetLampColorUnitWidget.cs b/Editor/Widgets/SetLampColorUnitWidget.cs index 943227d..0621a8b 100644 --- a/Editor/Widgets/SetLampColorUnitWidget.cs +++ b/Editor/Widgets/SetLampColorUnitWidget.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System; using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; @@ -24,44 +23,13 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(SetLampColorUnit))] - public sealed class SetLampColorUnitWidget : GleUnitWidget + public sealed class SetLampColorUnitWidget : GleMultiUnitWidget { - private readonly List> _lampIdInspectorConstructorList; - public SetLampColorUnitWidget(FlowCanvas canvas, SetLampColorUnit unit) : base(canvas, unit) { - _lampIdInspectorConstructorList = new List>(); } - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (_lampIdInspectorConstructorList.Count() < unit.inputCount) - { - for (var index = 0; index < unit.inputCount - _lampIdInspectorConstructorList.Count(); index++) - { - _lampIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); - } - } - - for (var index = 0; index < unit.inputCount; index++) - { - if (unit.multiInputs[index] == port) - { - VariableNameInspector lampIdInspector = new VariableNameInspector(meta, GetNameSuggestions); - InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); - - return lampIdInspector; - } - } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedLamps.Select(lamp => lamp.Id); - return base.GetPortInspector(port, meta); - } - - private IEnumerable GetNameSuggestions() - { - return !GleAvailable - ? new List() - : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); - } } } diff --git a/Editor/Widgets/SetLampEnabledUnitWidget.cs b/Editor/Widgets/SetLampEnabledUnitWidget.cs index 9daa679..ca1f73f 100644 --- a/Editor/Widgets/SetLampEnabledUnitWidget.cs +++ b/Editor/Widgets/SetLampEnabledUnitWidget.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System; using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; @@ -24,40 +23,12 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(SetLampEnabledUnit))] - public sealed class SetLampEnabledUnitWidget : GleUnitWidget + public sealed class SetLampEnabledUnitWidget : GleMultiUnitWidget { - private readonly List> _lampIdInspectorConstructorList; - public SetLampEnabledUnitWidget(FlowCanvas canvas, SetLampEnabledUnit unit) : base(canvas, unit) { - _lampIdInspectorConstructorList = new List>(); } - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (_lampIdInspectorConstructorList.Count() < unit.inputCount) { - for (var index = 0; index < unit.inputCount - _lampIdInspectorConstructorList.Count(); index++) { - _lampIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); - } - } - - for (var index = 0; index < unit.inputCount; index++) { - if (unit.multiInputs[index] == port) { - VariableNameInspector lampIdInspector = new VariableNameInspector(meta, GetNameSuggestions); - InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); - - return lampIdInspector; - } - } - - return base.GetPortInspector(port, meta); - } - - private IEnumerable GetNameSuggestions() - { - return !GleAvailable - ? new List() - : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); - } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedLamps.Select(lamp => lamp.Id); } } diff --git a/Editor/Widgets/SetLampUnitWidget.cs b/Editor/Widgets/SetLampUnitWidget.cs index 0b569b3..f93d404 100644 --- a/Editor/Widgets/SetLampUnitWidget.cs +++ b/Editor/Widgets/SetLampUnitWidget.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System; using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; @@ -24,40 +23,12 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(SetLampUnit))] - public sealed class SetLampUnitWidget : GleUnitWidget + public sealed class SetLampUnitWidget : GleMultiUnitWidget { - private readonly List> _lampIdInspectorConstructorList; - public SetLampUnitWidget(FlowCanvas canvas, SetLampUnit unit) : base(canvas, unit) { - _lampIdInspectorConstructorList = new List>(); } - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (_lampIdInspectorConstructorList.Count() < unit.inputCount) { - for (var index = 0; index < unit.inputCount - _lampIdInspectorConstructorList.Count(); index++) { - _lampIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); - } - } - - for (var index = 0; index < unit.inputCount; index++) { - if (unit.multiInputs[index] == port) { - VariableNameInspector lampIdInspector = new VariableNameInspector(meta, GetNameSuggestions); - InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); - - return lampIdInspector; - } - } - - return base.GetPortInspector(port, meta); - } - - private IEnumerable GetNameSuggestions() - { - return !GleAvailable - ? new List() - : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); - } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedLamps.Select(lamp => lamp.Id); } } diff --git a/Editor/Widgets/SetSwitchUnitWidget.cs b/Editor/Widgets/SetSwitchUnitWidget.cs index 2ea3992..78e8829 100644 --- a/Editor/Widgets/SetSwitchUnitWidget.cs +++ b/Editor/Widgets/SetSwitchUnitWidget.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System; using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; @@ -24,40 +23,12 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(SetSwitchUnit))] - public sealed class SetSwitchUnitWidget : GleUnitWidget + public sealed class SetSwitchUnitWidget : GleMultiUnitWidget { - private readonly List> _switchIdInspectorConstructorList; - public SetSwitchUnitWidget(FlowCanvas canvas, SetSwitchUnit unit) : base(canvas, unit) { - _switchIdInspectorConstructorList = new List>(); } - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (_switchIdInspectorConstructorList.Count() < unit.inputCount) { - for (var index = 0; index < unit.inputCount - _switchIdInspectorConstructorList.Count(); index++) { - _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); - } - } - - for (var index = 0; index < unit.inputCount; index++) { - if (unit.multiInputs[index] == port) { - VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); - InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); - - return switchIdInspector; - } - } - - return base.GetPortInspector(port, meta); - } - - private IEnumerable GetNameSuggestions() - { - return !GleAvailable - ? new List() - : Gle.RequestedSwitches.Select(sw => sw.Id).ToList(); - } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedSwitches.Select(sw => sw.Id); } } diff --git a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs index d2b8382..2f73b24 100644 --- a/Editor/Widgets/SwitchEnabledEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEnabledEventUnitWidget.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System; using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; @@ -24,40 +23,12 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(SwitchEnabledEventUnit))] - public sealed class SwitchEnabledEventUnitWidget : GleUnitWidget + public sealed class SwitchEnabledEventUnitWidget : GleMultiUnitWidget { - private readonly List> _switchIdInspectorConstructorList; - public SwitchEnabledEventUnitWidget(FlowCanvas canvas, SwitchEnabledEventUnit unit) : base(canvas, unit) { - _switchIdInspectorConstructorList = new List>(); } - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (_switchIdInspectorConstructorList.Count() < unit.inputCount) { - for (var index = 0; index < unit.inputCount - _switchIdInspectorConstructorList.Count(); index++) { - _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); - } - } - - for (var index = 0; index < unit.inputCount; index++) { - if (unit.multiInputs[index] == port) { - VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); - InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); - - return switchIdInspector; - } - } - - return base.GetPortInspector(port, meta); - } - - private IEnumerable GetNameSuggestions() - { - return !GleAvailable - ? new List() - : Gle.RequestedSwitches.Select(sw => sw.Id).ToList(); - } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedSwitches.Select(sw => sw.Id); } } diff --git a/Editor/Widgets/SwitchEventUnitWidget.cs b/Editor/Widgets/SwitchEventUnitWidget.cs index 0518a07..79d5d23 100644 --- a/Editor/Widgets/SwitchEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEventUnitWidget.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System; using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; @@ -24,40 +23,11 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(SwitchEventUnit))] - public sealed class SwitchEventUnitWidget : GleUnitWidget + public sealed class SwitchEventUnitWidget : GleMultiUnitWidget { - private readonly List> _switchIdInspectorConstructorList; - public SwitchEventUnitWidget(FlowCanvas canvas, SwitchEventUnit unit) : base(canvas, unit) { - _switchIdInspectorConstructorList = new List>(); - } - - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (_switchIdInspectorConstructorList.Count() < unit.inputCount) { - for (var index = 0; index < unit.inputCount - _switchIdInspectorConstructorList.Count(); index++) { - _switchIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); - } - } - - for (var index = 0; index < unit.inputCount; index++) { - if (unit.multiInputs[index] == port) { - VariableNameInspector switchIdInspector = new VariableNameInspector(meta, GetNameSuggestions); - InspectorProvider.instance.Renew(ref switchIdInspector, meta, _switchIdInspectorConstructorList[index]); - - return switchIdInspector; - } - } - - return base.GetPortInspector(port, meta); - } - - private IEnumerable GetNameSuggestions() - { - return !GleAvailable - ? new List() - : Gle.RequestedSwitches.Select(sw => sw.Id).ToList(); } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedSwitches.Select(sw => sw.Id); } } From 4d2f7ecf632cb7a1081dbdf7edd8e5aca8b0d720 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Tue, 15 Feb 2022 17:59:10 -0500 Subject: [PATCH 43/54] misc: update LampSequenceUnitWidget to use GleMultiUnitWidget --- Editor/Widgets/LampSequenceUnitWidget.cs | 33 ++---------------------- Editor/Widgets/SetLampColorUnitWidget.cs | 1 - Runtime/Nodes/Lamps/LampSequenceUnit.cs | 2 +- 3 files changed, 3 insertions(+), 33 deletions(-) diff --git a/Editor/Widgets/LampSequenceUnitWidget.cs b/Editor/Widgets/LampSequenceUnitWidget.cs index 3d0504c..44e5d21 100644 --- a/Editor/Widgets/LampSequenceUnitWidget.cs +++ b/Editor/Widgets/LampSequenceUnitWidget.cs @@ -16,7 +16,6 @@ // ReSharper disable UnusedType.Global -using System; using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; @@ -24,40 +23,12 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(LampSequenceUnit))] - public sealed class LampSequenceUnitWidget : GleUnitWidget + public sealed class LampSequenceUnitWidget : GleMultiUnitWidget { - private readonly List> _lampIdInspectorConstructorList; - public LampSequenceUnitWidget(FlowCanvas canvas, LampSequenceUnit unit) : base(canvas, unit) { - _lampIdInspectorConstructorList = new List>(); } - public override Inspector GetPortInspector(IUnitPort port, Metadata meta) - { - if (_lampIdInspectorConstructorList.Count() < unit.inputCount) { - for (var index = 0; index < unit.inputCount - _lampIdInspectorConstructorList.Count(); index++) { - _lampIdInspectorConstructorList.Add(meta => new VariableNameInspector(meta, GetNameSuggestions)); - } - } - - for (var index = 0; index < unit.inputCount; index++) { - if (unit.multiInputs[index] == port) { - VariableNameInspector lampIdInspector = new VariableNameInspector(meta, GetNameSuggestions); - InspectorProvider.instance.Renew(ref lampIdInspector, meta, _lampIdInspectorConstructorList[index]); - - return lampIdInspector; - } - } - - return base.GetPortInspector(port, meta); - } - - private IEnumerable GetNameSuggestions() - { - return !GleAvailable - ? new List() - : Gle.RequestedLamps.Select(lamp => lamp.Id).ToList(); - } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedLamps.Select(lamp => lamp.Id); } } diff --git a/Editor/Widgets/SetLampColorUnitWidget.cs b/Editor/Widgets/SetLampColorUnitWidget.cs index 0621a8b..1835aa8 100644 --- a/Editor/Widgets/SetLampColorUnitWidget.cs +++ b/Editor/Widgets/SetLampColorUnitWidget.cs @@ -30,6 +30,5 @@ public SetLampColorUnitWidget(FlowCanvas canvas, SetLampColorUnit unit) : base(c } protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedLamps.Select(lamp => lamp.Id); - } } diff --git a/Runtime/Nodes/Lamps/LampSequenceUnit.cs b/Runtime/Nodes/Lamps/LampSequenceUnit.cs index b03ac69..015ecd5 100644 --- a/Runtime/Nodes/Lamps/LampSequenceUnit.cs +++ b/Runtime/Nodes/Lamps/LampSequenceUnit.cs @@ -23,7 +23,7 @@ namespace VisualPinball.Unity.VisualScripting { [UnitTitle("Lamp Sequence")] - [UnitSurtitle("Scene")] + [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Visual Pinball")] public class LampSequenceUnit : GleUnit, IMultiInputUnit { From ead5de5fa17ec70df59ed82906ab110a0e89f04a Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 17 Feb 2022 22:07:04 +0100 Subject: [PATCH 44/54] api: Use LampState instead of float. --- .../VisualScriptingGamelogicEngine.cs | 4 ++-- Runtime/Nodes/Lamps/LampDataType.cs | 23 +++++++++++++++++++ Runtime/Nodes/Lamps/LampDataType.cs.meta | 11 +++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 Runtime/Nodes/Lamps/LampDataType.cs create mode 100644 Runtime/Nodes/Lamps/LampDataType.cs.meta diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index cb30ea5..7a8043f 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -181,9 +181,9 @@ public void SetLamp(string id, Color color) OnLampColorChanged?.Invoke(this, new LampColorEventArgs(id, color)); } - public float GetLamp(string id) + public LampState GetLamp(string id) { - return _player.LampStatuses.ContainsKey(id) ? _player.LampStatuses[id] : 0; + return _player.LampStatuses.ContainsKey(id) ? _player.LampStatuses[id] : LampState.Default; } public bool GetSwitch(string id) diff --git a/Runtime/Nodes/Lamps/LampDataType.cs b/Runtime/Nodes/Lamps/LampDataType.cs new file mode 100644 index 0000000..9a950b8 --- /dev/null +++ b/Runtime/Nodes/Lamps/LampDataType.cs @@ -0,0 +1,23 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace VisualPinball.Unity.VisualScripting +{ + public enum LampDataType + { + Status, Intensity, Color, + } +} diff --git a/Runtime/Nodes/Lamps/LampDataType.cs.meta b/Runtime/Nodes/Lamps/LampDataType.cs.meta new file mode 100644 index 0000000..395d58f --- /dev/null +++ b/Runtime/Nodes/Lamps/LampDataType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4ee1294d70683a049a7e50cbc1147674 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 9f1da0fd8e7dfc498edcf8a2f41d86de21440c19 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 21 Feb 2022 22:29:35 +0100 Subject: [PATCH 45/54] Refactor lamp nodes. --- Editor/Descriptors/GetLampUnitDescriptor.cs | 26 ++++- .../Descriptors/SetLampColorUnitDescriptor.cs | 56 --------- .../SetLampColorUnitDescriptor.cs.meta | 11 -- Editor/Descriptors/SetLampUnitDescriptor.cs | 24 +++- Editor/Widgets/SetLampColorUnitWidget.cs | 34 ------ Editor/Widgets/SetLampColorUnitWidget.cs.meta | 11 -- .../VisualScriptingGamelogicEngine.cs | 6 - Runtime/Nodes/Lamps/GetLampUnit.cs | 44 +++++-- Runtime/Nodes/Lamps/LampDataType.cs | 2 +- Runtime/Nodes/Lamps/LampSequenceUnit.cs | 108 +++++++++--------- Runtime/Nodes/Lamps/SetLampColorUnit.cs | 97 ---------------- Runtime/Nodes/Lamps/SetLampColorUnit.cs.meta | 11 -- Runtime/Nodes/Lamps/SetLampUnit.cs | 62 +++++++--- 13 files changed, 177 insertions(+), 315 deletions(-) delete mode 100644 Editor/Descriptors/SetLampColorUnitDescriptor.cs delete mode 100644 Editor/Descriptors/SetLampColorUnitDescriptor.cs.meta delete mode 100644 Editor/Widgets/SetLampColorUnitWidget.cs delete mode 100644 Editor/Widgets/SetLampColorUnitWidget.cs.meta delete mode 100644 Runtime/Nodes/Lamps/SetLampColorUnit.cs delete mode 100644 Runtime/Nodes/Lamps/SetLampColorUnit.cs.meta diff --git a/Editor/Descriptors/GetLampUnitDescriptor.cs b/Editor/Descriptors/GetLampUnitDescriptor.cs index 1361299..96a967e 100644 --- a/Editor/Descriptors/GetLampUnitDescriptor.cs +++ b/Editor/Descriptors/GetLampUnitDescriptor.cs @@ -16,6 +16,7 @@ // ReSharper disable UnusedType.Global +using System; using Unity.VisualScripting; using VisualPinball.Unity.Editor; using IconSize = VisualPinball.Unity.Editor.IconSize; @@ -45,10 +46,27 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) desc.summary = "The ID of the lamp for which the intensity is returned."; break; case nameof(GetLampUnit.Value): - desc.summary = "The intensity of the lamp (0-1)."; - break; - case nameof(GetLampUnit.IsEnabled): - desc.summary = "Whether the intensity is larger than 0."; + var getLampUnit = port.unit as GetLampUnit; + switch (getLampUnit!.DataType) { + case LampDataType.OnOff: + desc.label = "Lit"; + desc.summary = "On or off."; + break; + case LampDataType.Status: + desc.label = "Status"; + desc.summary = "On, off or blinking."; + break; + case LampDataType.Intensity: + desc.label = "Intensity"; + desc.summary = "The intensity of the lamp (value depends on the maximal intensity of the mapping)."; + break; + case LampDataType.Color: + desc.label = "Color"; + desc.summary = "The color of the lamp."; + break; + default: + throw new ArgumentOutOfRangeException(); + } break; } } diff --git a/Editor/Descriptors/SetLampColorUnitDescriptor.cs b/Editor/Descriptors/SetLampColorUnitDescriptor.cs deleted file mode 100644 index b5594d4..0000000 --- a/Editor/Descriptors/SetLampColorUnitDescriptor.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable UnusedType.Global - -using Unity.VisualScripting; -using VisualPinball.Unity.Editor; -using IconSize = VisualPinball.Unity.Editor.IconSize; - -namespace VisualPinball.Unity.VisualScripting.Editor -{ - [Descriptor(typeof(SetLampColorUnit))] - public class SetLampColorUnitDescriptor : UnitDescriptor - { - public SetLampColorUnitDescriptor(SetLampColorUnit target) : base(target) - { - } - - protected override string DefinedSummary() - { - return "This node assigns a given value to a lamp defined by its mapped ID. This will also trigger the lamp changed event and update the internal status."; - } - - protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Light(IconSize.Large, IconColor.Orange)); - - protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) - { - base.DefinedPort(port, desc); - - if (port.key == nameof(SetLampColorUnit.Value)) - { - desc.summary = "The color to set the lamp"; - } - else if (int.TryParse(port.key, out int id)) - { - id += 1; - - desc.label = $"Lamp ID {id}"; - desc.summary = $"Lamp ID {id} of the lamp to set the intensity"; - } - } - } -} diff --git a/Editor/Descriptors/SetLampColorUnitDescriptor.cs.meta b/Editor/Descriptors/SetLampColorUnitDescriptor.cs.meta deleted file mode 100644 index a41263e..0000000 --- a/Editor/Descriptors/SetLampColorUnitDescriptor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9377accfee39644cfb301e48ecb6829d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Descriptors/SetLampUnitDescriptor.cs b/Editor/Descriptors/SetLampUnitDescriptor.cs index e9d3c1b..b9bedf4 100644 --- a/Editor/Descriptors/SetLampUnitDescriptor.cs +++ b/Editor/Descriptors/SetLampUnitDescriptor.cs @@ -16,6 +16,7 @@ // ReSharper disable UnusedType.Global +using System; using Unity.VisualScripting; using VisualPinball.Unity.Editor; using IconSize = VisualPinball.Unity.Editor.IconSize; @@ -41,7 +42,28 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); if (port.key == nameof(SetLampUnit.Value)) { - desc.summary = "The intensity of the lamp (0-1)."; + var setLampUnit = port.unit as SetLampUnit; + switch (setLampUnit!.DataType) { + case LampDataType.OnOff: + desc.label = "Lit?"; + desc.summary = "On or off."; + break; + case LampDataType.Status: + desc.label = "Status"; + desc.summary = "On, off or blinking."; + break; + case LampDataType.Intensity: + desc.label = "Intensity"; + desc.summary = "The intensity of the lamp (0-1)."; + break; + case LampDataType.Color: + desc.label = "Color"; + desc.summary = "The color of the lamp."; + break; + + default: + throw new ArgumentOutOfRangeException(); + } } else if (int.TryParse(port.key, out int id)) { id += 1; diff --git a/Editor/Widgets/SetLampColorUnitWidget.cs b/Editor/Widgets/SetLampColorUnitWidget.cs deleted file mode 100644 index 1835aa8..0000000 --- a/Editor/Widgets/SetLampColorUnitWidget.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable UnusedType.Global - -using System.Collections.Generic; -using System.Linq; -using Unity.VisualScripting; - -namespace VisualPinball.Unity.VisualScripting.Editor -{ - [Widget(typeof(SetLampColorUnit))] - public sealed class SetLampColorUnitWidget : GleMultiUnitWidget - { - public SetLampColorUnitWidget(FlowCanvas canvas, SetLampColorUnit unit) : base(canvas, unit) - { - } - - protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedLamps.Select(lamp => lamp.Id); - } -} diff --git a/Editor/Widgets/SetLampColorUnitWidget.cs.meta b/Editor/Widgets/SetLampColorUnitWidget.cs.meta deleted file mode 100644 index 226c427..0000000 --- a/Editor/Widgets/SetLampColorUnitWidget.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 47febd1d7ff91412b85814eb2a5c55c2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index 7a8043f..289a382 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -64,7 +64,6 @@ public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine, I public event EventHandler OnDisplayFrame; public event EventHandler OnLampChanged; public event EventHandler OnLampsChanged; - public event EventHandler OnLampColorChanged; public event EventHandler OnCoilChanged; public event EventHandler OnSwitchChanged; public event EventHandler OnStarted; @@ -176,11 +175,6 @@ public void SetLamp(string id, float value, bool isCoil = false, LampSource sour OnLampChanged?.Invoke(this, new LampEventArgs(id, value, isCoil, source)); } - public void SetLamp(string id, Color color) - { - OnLampColorChanged?.Invoke(this, new LampColorEventArgs(id, color)); - } - public LampState GetLamp(string id) { return _player.LampStatuses.ContainsKey(id) ? _player.LampStatuses[id] : LampState.Default; diff --git a/Runtime/Nodes/Lamps/GetLampUnit.cs b/Runtime/Nodes/Lamps/GetLampUnit.cs index 22b5da5..4d96d2f 100644 --- a/Runtime/Nodes/Lamps/GetLampUnit.cs +++ b/Runtime/Nodes/Lamps/GetLampUnit.cs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; using Unity.VisualScripting; using UnityEngine; @@ -24,34 +25,45 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Visual Pinball")] public class GetLampUnit : GleUnit { + [Serialize, Inspectable, UnitHeaderInspectable] + public LampDataType DataType { get; set; } + [DoNotSerialize] [PortLabel("Lamp ID")] public ValueInput Id { get; private set; } [DoNotSerialize] - [PortLabel("Value")] public ValueOutput Value { get; private set; } - [DoNotSerialize] - [PortLabel("Is Enabled")] - public ValueOutput IsEnabled { get; private set; } - protected override void Definition() { Id = ValueInput(nameof(Id), string.Empty); - Value = ValueOutput(nameof(Value), GetValue); - IsEnabled = ValueOutput(nameof(IsEnabled), GetEnabled); + switch (DataType) { + case LampDataType.OnOff: + Value = ValueOutput(nameof(Value), GetEnabled); + break; + case LampDataType.Status: + Value = ValueOutput(nameof(Value), GetEnabled); + break; + case LampDataType.Intensity: + Value = ValueOutput(nameof(Value), GetIntensity); + break; + case LampDataType.Color: + Value = ValueOutput(nameof(Value), GetColor); + break; + default: + throw new ArgumentOutOfRangeException(); + } } - private float GetValue(Flow flow) + private float GetIntensity(Flow flow) { if (!AssertGle(flow)) { Debug.LogError("Cannot find GLE."); return 0; } - - return Gle.GetLamp(flow.GetValue(Id)); + return Gle.GetLamp(flow.GetValue(Id)).Intensity; } private bool GetEnabled(Flow flow) @@ -61,7 +73,17 @@ private bool GetEnabled(Flow flow) return false; } - return Gle.GetLamp(flow.GetValue(Id)) > 0; + return Gle.GetLamp(flow.GetValue(Id)).IsOn; + } + + private Color GetColor(Flow flow) + { + if (!AssertGle(flow)) { + Debug.LogError("Cannot find GLE."); + return Color.black; + } + + return Gle.GetLamp(flow.GetValue(Id)).Color.ToUnityColor(); } } } diff --git a/Runtime/Nodes/Lamps/LampDataType.cs b/Runtime/Nodes/Lamps/LampDataType.cs index 9a950b8..b58a93a 100644 --- a/Runtime/Nodes/Lamps/LampDataType.cs +++ b/Runtime/Nodes/Lamps/LampDataType.cs @@ -18,6 +18,6 @@ namespace VisualPinball.Unity.VisualScripting { public enum LampDataType { - Status, Intensity, Color, + OnOff, Status, Intensity, Color, } } diff --git a/Runtime/Nodes/Lamps/LampSequenceUnit.cs b/Runtime/Nodes/Lamps/LampSequenceUnit.cs index 015ecd5..67a00eb 100644 --- a/Runtime/Nodes/Lamps/LampSequenceUnit.cs +++ b/Runtime/Nodes/Lamps/LampSequenceUnit.cs @@ -16,34 +16,33 @@ using System.Collections.Generic; using System.Collections.ObjectModel; -using Unity.VisualScripting; -using UnityEngine; -using VisualPinball.Engine.Math; - -namespace VisualPinball.Unity.VisualScripting -{ - [UnitTitle("Lamp Sequence")] - [UnitSurtitle("Gamelogic Engine")] - [UnitCategory("Visual Pinball")] - public class LampSequenceUnit : GleUnit, IMultiInputUnit - { - [DoNotSerialize] - [PortLabelHidden] - public ControlInput InputTrigger; - - [DoNotSerialize] - [PortLabelHidden] +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Lamp Sequence")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Visual Pinball")] + public class LampSequenceUnit : GleUnit, IMultiInputUnit + { + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] public ControlOutput OutputTrigger; - [SerializeAs(nameof(inputCount))] - private int _inputCount = 1; - - [DoNotSerialize] - [Inspectable, UnitHeaderInspectable("Lamp IDs")] - public int inputCount - { - get => _inputCount; - set => _inputCount = Mathf.Clamp(value, 1, 10); + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Lamp IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); } [DoNotSerialize] @@ -53,16 +52,16 @@ public int inputCount [PortLabel("Value")] public ValueInput Value { get; private set; } - [DoNotSerialize] - [PortLabel("Step")] - public ValueInput Step; - - private int _currentIndex; - private List _lightComponentCache = null; - - protected override void Definition() - { - InputTrigger = ControlInput(nameof(InputTrigger), Process); + [DoNotSerialize] + [PortLabel("Step")] + public ValueInput Step; + + private int _currentIndex; + private List _lightComponentCache = null; + + protected override void Definition() + { + InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); var _multiInputs = new List(); @@ -76,25 +75,25 @@ protected override void Definition() Requirement(input, InputTrigger); } - Value = ValueInput(nameof(Value), 0f); - Step = ValueInput(nameof(Step), 1); - - Succession(InputTrigger, OutputTrigger); - - _lightComponentCache = null; - } - - private ControlOutput Process(Flow flow) + Value = ValueInput(nameof(Value), 0f); + Step = ValueInput(nameof(Step), 1); + + Succession(InputTrigger, OutputTrigger); + + _lightComponentCache = null; + } + + private ControlOutput Process(Flow flow) { if (!AssertGle(flow)) { Debug.LogError("Cannot find GLE."); return OutputTrigger; - } - - if (!AssertPlayer(flow)) { - Debug.LogError("Cannot find player."); - return OutputTrigger; + } + + if (!AssertPlayer(flow)) { + Debug.LogError("Cannot find player."); + return OutputTrigger; } var value = flow.GetValue(Value); @@ -119,8 +118,7 @@ private ControlOutput Process(Flow flow) } for (var index = 0; index < _lightComponentCache.Count; index++) { - Player.Lamp(_lightComponentCache[index]).OnLamp( - index >= _currentIndex * stepRaw && index < (_currentIndex + 1) * stepRaw ? value : 0, ColorChannel.Alpha); ; + ; } if (++_currentIndex >= _lightComponentCache.Count / stepRaw) { @@ -144,6 +142,6 @@ private List Flatten(List lampDeviceList) } return lights; - } - } -} + } + } +} diff --git a/Runtime/Nodes/Lamps/SetLampColorUnit.cs b/Runtime/Nodes/Lamps/SetLampColorUnit.cs deleted file mode 100644 index 10769b4..0000000 --- a/Runtime/Nodes/Lamps/SetLampColorUnit.cs +++ /dev/null @@ -1,97 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System.Collections.Generic; -using System.Collections.ObjectModel; -using Unity.VisualScripting; -using UnityEngine; - -namespace VisualPinball.Unity.VisualScripting -{ - [UnitShortTitle("Set Lamp")] - [UnitTitle("Set Lamp (ID, Color)")] - [UnitSurtitle("Gamelogic Engine")] - [UnitCategory("Visual Pinball")] - public class SetLampColorUnit : GleUnit, IMultiInputUnit - { - [DoNotSerialize] - [PortLabelHidden] - public ControlInput InputTrigger; - - [DoNotSerialize] - [PortLabelHidden] - public ControlOutput OutputTrigger; - - [SerializeAs(nameof(inputCount))] - private int _inputCount = 1; - - [DoNotSerialize] - [Inspectable, UnitHeaderInspectable("Lamp IDs")] - public int inputCount - { - get => _inputCount; - set => _inputCount = Mathf.Clamp(value, 1, 10); - } - - [DoNotSerialize] - public ReadOnlyCollection multiInputs { get; private set; } - - [DoNotSerialize] - [PortLabel("Value")] - public ValueInput Value { get; private set; } - - protected override void Definition() - { - InputTrigger = ControlInput(nameof(InputTrigger), Process); - OutputTrigger = ControlOutput(nameof(OutputTrigger)); - - var _multiInputs = new List(); - - multiInputs = _multiInputs.AsReadOnly(); - - for (var i = 0; i < inputCount; i++) - { - var input = ValueInput(i.ToString(), string.Empty); - _multiInputs.Add(input); - - Requirement(input, InputTrigger); - } - - Value = ValueInput(nameof(Value), Color.black); - - Succession(InputTrigger, OutputTrigger); - } - - private ControlOutput Process(Flow flow) - { - if (!AssertGle(flow)) - { - Debug.LogError("Cannot find GLE."); - return OutputTrigger; - } - - var value = flow.GetValue(Value); - - foreach (var input in multiInputs) - { - var lampId = flow.GetValue(input); - Gle.SetLamp(lampId, value); - } - - return OutputTrigger; - } - } -} diff --git a/Runtime/Nodes/Lamps/SetLampColorUnit.cs.meta b/Runtime/Nodes/Lamps/SetLampColorUnit.cs.meta deleted file mode 100644 index cd12ff8..0000000 --- a/Runtime/Nodes/Lamps/SetLampColorUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 37c79aa6bbcac4c0f84443ec1f1ad747 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/Lamps/SetLampUnit.cs b/Runtime/Nodes/Lamps/SetLampUnit.cs index 935b056..ef13f3e 100644 --- a/Runtime/Nodes/Lamps/SetLampUnit.cs +++ b/Runtime/Nodes/Lamps/SetLampUnit.cs @@ -14,10 +14,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using Unity.VisualScripting; using UnityEngine; +using VisualPinball.Engine.Game.Engines; +using Color = VisualPinball.Engine.Math.Color; namespace VisualPinball.Unity.VisualScripting { @@ -27,6 +30,18 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Visual Pinball")] public class SetLampUnit : GleUnit, IMultiInputUnit { + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Lamp IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } + + [Serialize, Inspectable, UnitHeaderInspectable] + public LampDataType DataType { get; set; } + [DoNotSerialize] [PortLabelHidden] public ControlInput InputTrigger; @@ -38,19 +53,10 @@ public class SetLampUnit : GleUnit, IMultiInputUnit [SerializeAs(nameof(inputCount))] private int _inputCount = 1; - [DoNotSerialize] - [Inspectable, UnitHeaderInspectable("Lamp IDs")] - public int inputCount - { - get => _inputCount; - set => _inputCount = Mathf.Clamp(value, 1, 10); - } - [DoNotSerialize] public ReadOnlyCollection multiInputs { get; private set; } [DoNotSerialize] - [PortLabel("Value")] public ValueInput Value { get; private set; } protected override void Definition() @@ -58,18 +64,22 @@ protected override void Definition() InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - var _multiInputs = new List(); - - multiInputs = _multiInputs.AsReadOnly(); + var mi = new List(); + multiInputs = mi.AsReadOnly(); for (var i = 0; i < inputCount; i++) { var input = ValueInput(i.ToString(), string.Empty); - _multiInputs.Add(input); - + mi.Add(input); Requirement(input, InputTrigger); } - Value = ValueInput(nameof(Value), 0f); + Value = DataType switch { + LampDataType.OnOff => ValueInput(nameof(Value), false), + LampDataType.Status => ValueInput(nameof(Value), LampStatus.Off), + LampDataType.Intensity => ValueInput(nameof(Value), 0f), + LampDataType.Color => ValueInput(nameof(Value), UnityEngine.Color.white), + _ => throw new ArgumentOutOfRangeException() + }; Succession(InputTrigger, OutputTrigger); } @@ -81,11 +91,29 @@ private ControlOutput Process(Flow flow) return OutputTrigger; } - var value = flow.GetValue(Value) * 255f; + if (!AssertPlayer(flow)) { + Debug.LogError("Cannot find player."); + return OutputTrigger; + } foreach (var input in multiInputs) { var lampId = flow.GetValue(input); - Gle.SetLamp(lampId, value); + switch (DataType) { + case LampDataType.OnOff: + Player.SetLamp(lampId, flow.GetValue(Value) ? LampStatus.On : LampStatus.Off); + break; + case LampDataType.Status: + Player.SetLamp(lampId, flow.GetValue(Value)); + break; + case LampDataType.Intensity: + Player.SetLamp(lampId, flow.GetValue(Value)); + break; + case LampDataType.Color: + Player.SetLamp(lampId, flow.GetValue(Value).ToEngineColor()); + break; + default: + throw new ArgumentOutOfRangeException(); + } } return OutputTrigger; From 5a25a21a9cb00a3a3b2826e9b8cc73d2b40cf358 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 21 Feb 2022 23:06:37 +0100 Subject: [PATCH 46/54] Remove obsolete lamp nodes. --- .../SetLampEnabledUnitDescriptor.cs | 54 ----------- .../SetLampEnabledUnitDescriptor.cs.meta | 11 --- Editor/Widgets/SetLampEnabledUnitWidget.cs | 34 ------- .../Widgets/SetLampEnabledUnitWidget.cs.meta | 11 --- Runtime/Nodes/Lamps/SetLampEnabledUnit.cs | 94 ------------------- .../Nodes/Lamps/SetLampEnabledUnit.cs.meta | 11 --- Runtime/Nodes/Lamps/SetLampUnit.cs | 7 +- 7 files changed, 3 insertions(+), 219 deletions(-) delete mode 100644 Editor/Descriptors/SetLampEnabledUnitDescriptor.cs delete mode 100644 Editor/Descriptors/SetLampEnabledUnitDescriptor.cs.meta delete mode 100644 Editor/Widgets/SetLampEnabledUnitWidget.cs delete mode 100644 Editor/Widgets/SetLampEnabledUnitWidget.cs.meta delete mode 100644 Runtime/Nodes/Lamps/SetLampEnabledUnit.cs delete mode 100644 Runtime/Nodes/Lamps/SetLampEnabledUnit.cs.meta diff --git a/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs b/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs deleted file mode 100644 index 4fbb546..0000000 --- a/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable UnusedType.Global - -using Unity.VisualScripting; -using VisualPinball.Unity.Editor; -using IconSize = VisualPinball.Unity.Editor.IconSize; - -namespace VisualPinball.Unity.VisualScripting.Editor -{ - [Descriptor(typeof(SetLampEnabledUnit))] - public class SetLampEnabledUnitDescriptor : UnitDescriptor - { - public SetLampEnabledUnitDescriptor(SetLampEnabledUnit target) : base(target) - { - } - - protected override string DefinedSummary() - { - return "This node turns a lamp defined by its mapped ID on or off."; - } - - protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Light(IconSize.Large, IconColor.Orange)); - - protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) - { - base.DefinedPort(port, desc); - - if (port.key == nameof(SetLampEnabledUnit.IsEnabled)) { - desc.summary = "Whether to turn on or off."; - } - else if (int.TryParse(port.key, out int id)) { - id += 1; - - desc.label = $"Lamp ID {id}"; - desc.summary = $"Lamp ID {id} of the lamp to toggle."; - } - } - } -} diff --git a/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs.meta b/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs.meta deleted file mode 100644 index b96f91f..0000000 --- a/Editor/Descriptors/SetLampEnabledUnitDescriptor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 69273ae986e7721468526571a67857cd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Widgets/SetLampEnabledUnitWidget.cs b/Editor/Widgets/SetLampEnabledUnitWidget.cs deleted file mode 100644 index ca1f73f..0000000 --- a/Editor/Widgets/SetLampEnabledUnitWidget.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable UnusedType.Global - -using System.Collections.Generic; -using System.Linq; -using Unity.VisualScripting; - -namespace VisualPinball.Unity.VisualScripting.Editor -{ - [Widget(typeof(SetLampEnabledUnit))] - public sealed class SetLampEnabledUnitWidget : GleMultiUnitWidget - { - public SetLampEnabledUnitWidget(FlowCanvas canvas, SetLampEnabledUnit unit) : base(canvas, unit) - { - } - - protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedLamps.Select(lamp => lamp.Id); - } -} diff --git a/Editor/Widgets/SetLampEnabledUnitWidget.cs.meta b/Editor/Widgets/SetLampEnabledUnitWidget.cs.meta deleted file mode 100644 index 7bdb300..0000000 --- a/Editor/Widgets/SetLampEnabledUnitWidget.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 17c418e0eddfad24bbdad8eed199a493 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs b/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs deleted file mode 100644 index b2213cc..0000000 --- a/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs +++ /dev/null @@ -1,94 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2022 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System.Collections.Generic; -using System.Collections.ObjectModel; -using Unity.VisualScripting; -using UnityEngine; - -namespace VisualPinball.Unity.VisualScripting -{ - [UnitShortTitle("Set Lamp")] - [UnitTitle("Set Lamp (ID, on/off)")] - [UnitSurtitle("Gamelogic Engine")] - [UnitCategory("Visual Pinball")] - public class SetLampEnabledUnit : GleUnit, IMultiInputUnit - { - [DoNotSerialize] - [PortLabelHidden] - public ControlInput InputTrigger; - - [DoNotSerialize] - [PortLabelHidden] - public ControlOutput OutputTrigger; - - [SerializeAs(nameof(inputCount))] - private int _inputCount = 1; - - [DoNotSerialize] - [Inspectable, UnitHeaderInspectable("Lamp IDs")] - public int inputCount - { - get => _inputCount; - set => _inputCount = Mathf.Clamp(value, 1, 10); - } - - [DoNotSerialize] - public ReadOnlyCollection multiInputs { get; private set; } - - [DoNotSerialize] - [PortLabel("Is Enabled")] - public ValueInput IsEnabled { get; private set; } - - protected override void Definition() - { - InputTrigger = ControlInput(nameof(InputTrigger), Process); - OutputTrigger = ControlOutput(nameof(OutputTrigger)); - - var _multiInputs = new List(); - - multiInputs = _multiInputs.AsReadOnly(); - - for (var i = 0; i < inputCount; i++) { - var input = ValueInput(i.ToString(), string.Empty); - _multiInputs.Add(input); - - Requirement(input, InputTrigger); - } - - IsEnabled = ValueInput(nameof(IsEnabled), false); - - Succession(InputTrigger, OutputTrigger); - } - - private ControlOutput Process(Flow flow) - { - if (!AssertGle(flow)) { - Debug.LogError("Cannot find GLE."); - return OutputTrigger; - } - - var isEnabled = flow.GetValue(IsEnabled); - - foreach (var input in multiInputs) { - var lampId = flow.GetValue(input); - Gle.SetLamp(lampId, isEnabled ? 255f : 0f); - } - - return OutputTrigger; - } - } -} diff --git a/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs.meta b/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs.meta deleted file mode 100644 index bddd5bb..0000000 --- a/Runtime/Nodes/Lamps/SetLampEnabledUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1cbbd5a69057dc1468a14b70495fa46a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Nodes/Lamps/SetLampUnit.cs b/Runtime/Nodes/Lamps/SetLampUnit.cs index ef13f3e..baa69f8 100644 --- a/Runtime/Nodes/Lamps/SetLampUnit.cs +++ b/Runtime/Nodes/Lamps/SetLampUnit.cs @@ -25,11 +25,13 @@ namespace VisualPinball.Unity.VisualScripting { [UnitShortTitle("Set Lamp")] - [UnitTitle("Set Lamp (ID, Intensity)")] + [UnitTitle("Set Lamp")] [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Visual Pinball")] public class SetLampUnit : GleUnit, IMultiInputUnit { + [Serialize, Inspectable, UnitHeaderInspectable] + public LampDataType DataType { get; set; } [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Lamp IDs")] @@ -39,9 +41,6 @@ public int inputCount set => _inputCount = Mathf.Clamp(value, 1, 10); } - [Serialize, Inspectable, UnitHeaderInspectable] - public LampDataType DataType { get; set; } - [DoNotSerialize] [PortLabelHidden] public ControlInput InputTrigger; From 6f7194e934cb97953b5c3ed07024f37982d269d6 Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 22 Feb 2022 00:29:24 +0100 Subject: [PATCH 47/54] Add pinball events. --- .../Descriptors/CreateBallUnitDescriptor.cs | 2 - Editor/Inspectors/EventDefinitionInspector.cs | 76 +++++++++++++++ .../EventDefinitionInspector.cs.meta | 11 +++ ...VisualScriptingGamelogicEngineInspector.cs | 4 + .../EventDefinitionPropertyDrawer.cs | 44 +++++++++ .../EventDefinitionPropertyDrawer.cs.meta | 11 +++ Editor/Widgets/CustomEventUnitWidget.cs | 34 +++++++ Editor/Widgets/CustomEventUnitWidget.cs.meta | 11 +++ Editor/Widgets/GleMultiUnitWidget.cs | 2 +- Runtime/Gamelogic/EventDefinition.cs | 32 ++++++ Runtime/Gamelogic/EventDefinition.cs.meta | 11 +++ .../Gamelogic/VisualScriptingEventNames.cs | 1 + .../VisualScriptingGamelogicEngine.cs | 12 +++ Runtime/Nodes/Event.meta | 8 ++ Runtime/Nodes/Event/PinballEventUnit.cs | 92 ++++++++++++++++++ Runtime/Nodes/Event/PinballEventUnit.cs.meta | 11 +++ .../Nodes/Event/TriggerPinballEventUnit.cs | 97 +++++++++++++++++++ .../Event/TriggerPinballEventUnit.cs.meta | 11 +++ 18 files changed, 467 insertions(+), 3 deletions(-) create mode 100644 Editor/Inspectors/EventDefinitionInspector.cs create mode 100644 Editor/Inspectors/EventDefinitionInspector.cs.meta create mode 100644 Editor/PropertyDrawers/EventDefinitionPropertyDrawer.cs create mode 100644 Editor/PropertyDrawers/EventDefinitionPropertyDrawer.cs.meta create mode 100644 Editor/Widgets/CustomEventUnitWidget.cs create mode 100644 Editor/Widgets/CustomEventUnitWidget.cs.meta create mode 100644 Runtime/Gamelogic/EventDefinition.cs create mode 100644 Runtime/Gamelogic/EventDefinition.cs.meta create mode 100644 Runtime/Nodes/Event.meta create mode 100644 Runtime/Nodes/Event/PinballEventUnit.cs create mode 100644 Runtime/Nodes/Event/PinballEventUnit.cs.meta create mode 100644 Runtime/Nodes/Event/TriggerPinballEventUnit.cs create mode 100644 Runtime/Nodes/Event/TriggerPinballEventUnit.cs.meta diff --git a/Editor/Descriptors/CreateBallUnitDescriptor.cs b/Editor/Descriptors/CreateBallUnitDescriptor.cs index 4082b2c..8965ab5 100644 --- a/Editor/Descriptors/CreateBallUnitDescriptor.cs +++ b/Editor/Descriptors/CreateBallUnitDescriptor.cs @@ -34,8 +34,6 @@ protected override string DefinedSummary() return "This node spawns a new ball at a given position."; } - - protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.BallRoller(IconSize.Large, IconColor.Orange)); protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) diff --git a/Editor/Inspectors/EventDefinitionInspector.cs b/Editor/Inspectors/EventDefinitionInspector.cs new file mode 100644 index 0000000..e8a359c --- /dev/null +++ b/Editor/Inspectors/EventDefinitionInspector.cs @@ -0,0 +1,76 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Inspector(typeof(EventDefinition))] + public class EventDefinitionInspector : GleInspector + { + public EventDefinitionInspector(Metadata metadata) : base(metadata) { } + + protected override void OnGUI(Rect position, GUIContent label) + { + // can't get this from the flow + var gle = Gle; + if (gle != null) { + var eventDefinitions = gle.EventDefinitions; + if (eventDefinitions == null || eventDefinitions.Count(p => !string.IsNullOrEmpty(p.Name)) == 0) { + ErrorMessage = "No events defined."; + + } else { + var eventNames = new List { "None" } + .Concat(eventDefinitions.Select(d => d.Name)) + .ToArray(); + var currentEventDef = metadata.value as EventDefinition; + var currentIndex = 0; + if (currentEventDef != null) { + var eventDef = eventDefinitions.FirstOrDefault(p => p.Id == currentEventDef!.Id); + currentIndex = eventDef != null ? eventDefinitions.IndexOf(eventDef) + 1 : 0; + } + + var newIndex = EditorGUI.Popup(position, currentIndex, eventNames); + metadata.RecordUndo(); + metadata.value = newIndex == 0 ? null : eventDefinitions[newIndex - 1]; + ErrorMessage = null; + } + } + + if (ErrorMessage != null) { + position.height -= EditorGUIUtility.standardVerticalSpacing; + EditorGUI.HelpBox(position, ErrorMessage, MessageType.Error); + } + } + + public override float GetAdaptiveWidth() => LudiqGUIUtility.currentInspectorWidth; + + protected override float GetHeight(float width, GUIContent label) + { + if (ErrorMessage != null) { + var height = LudiqGUIUtility.GetHelpBoxHeight(ErrorMessage, MessageType.Error, width); + height += EditorGUIUtility.standardVerticalSpacing; + return height; + } + + return EditorGUIUtility.singleLineHeight; + } + } +} diff --git a/Editor/Inspectors/EventDefinitionInspector.cs.meta b/Editor/Inspectors/EventDefinitionInspector.cs.meta new file mode 100644 index 0000000..d5c8960 --- /dev/null +++ b/Editor/Inspectors/EventDefinitionInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d3072639de8185c4eb378273be9ce25a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs b/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs index ab99294..a789460 100644 --- a/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs +++ b/Editor/Inspectors/VisualScriptingGamelogicEngineInspector.cs @@ -33,6 +33,7 @@ public class VisualScriptingGamelogicEngineInspector : BaseEditor _playerVarFoldout = new(); @@ -47,6 +48,8 @@ private void OnEnable() _tableVariableDefinitionsProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.TableVariableDefinitions)); _playerVariableDefinitionsProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.PlayerVariableDefinitions)); + + _eventDefinitionsProperty = serializedObject.FindProperty(nameof(VisualScriptingGamelogicEngine.EventDefinitions)); } public override void OnInspectorGUI() @@ -60,6 +63,7 @@ public override void OnInspectorGUI() EditorGUILayout.PropertyField(_tableVariableDefinitionsProperty); EditorGUILayout.PropertyField(_playerVariableDefinitionsProperty); + EditorGUILayout.PropertyField(_eventDefinitionsProperty); serializedObject.ApplyModifiedProperties(); diff --git a/Editor/PropertyDrawers/EventDefinitionPropertyDrawer.cs b/Editor/PropertyDrawers/EventDefinitionPropertyDrawer.cs new file mode 100644 index 0000000..bd65d10 --- /dev/null +++ b/Editor/PropertyDrawers/EventDefinitionPropertyDrawer.cs @@ -0,0 +1,44 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [CustomPropertyDrawer(typeof(EventDefinition))] + public class EventDefinitionPropertyDrawer : PropertyDrawer + { + private const float Padding = 2f; + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return EditorGUIUtility.singleLineHeight + Padding; + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + EditorGUI.BeginProperty(position, label, property); + + var nameProperty = property.FindPropertyRelative(nameof(EventDefinition.Name)); + position.height = EditorGUIUtility.singleLineHeight; + EditorGUI.PropertyField(position, nameProperty); + + EditorGUI.EndProperty(); + } + } +} + diff --git a/Editor/PropertyDrawers/EventDefinitionPropertyDrawer.cs.meta b/Editor/PropertyDrawers/EventDefinitionPropertyDrawer.cs.meta new file mode 100644 index 0000000..d6224d4 --- /dev/null +++ b/Editor/PropertyDrawers/EventDefinitionPropertyDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa3eade119d9f714c8bdfa28b37ad69f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/CustomEventUnitWidget.cs b/Editor/Widgets/CustomEventUnitWidget.cs new file mode 100644 index 0000000..d861d2f --- /dev/null +++ b/Editor/Widgets/CustomEventUnitWidget.cs @@ -0,0 +1,34 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(PinballEventUnit))] + public sealed class CustomEventUnitWidget : UnitWidget + { + public CustomEventUnitWidget(FlowCanvas canvas, PinballEventUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/CustomEventUnitWidget.cs.meta b/Editor/Widgets/CustomEventUnitWidget.cs.meta new file mode 100644 index 0000000..f9e22e4 --- /dev/null +++ b/Editor/Widgets/CustomEventUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 43ffe3ce77e8c3244aaa6f17725d1974 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/GleMultiUnitWidget.cs b/Editor/Widgets/GleMultiUnitWidget.cs index e3f5d4a..d4ee88d 100644 --- a/Editor/Widgets/GleMultiUnitWidget.cs +++ b/Editor/Widgets/GleMultiUnitWidget.cs @@ -34,7 +34,7 @@ protected GleMultiUnitWidget(FlowCanvas canvas, TUnit unit) : base(canvas, unit) public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (_idInspectorConstructorList.Count() < unit.inputCount) { + if (_idInspectorConstructorList.Count < unit.inputCount) { for (var index = 0; index < unit.inputCount - _idInspectorConstructorList.Count(); index++) { _idInspectorConstructorList.Add(m => new VariableNameInspector(m, GetNameSuggestions)); } diff --git a/Runtime/Gamelogic/EventDefinition.cs b/Runtime/Gamelogic/EventDefinition.cs new file mode 100644 index 0000000..fc3cb17 --- /dev/null +++ b/Runtime/Gamelogic/EventDefinition.cs @@ -0,0 +1,32 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable InconsistentNaming + +using System; + +namespace VisualPinball.Unity.VisualScripting +{ + [Serializable] + public class EventDefinition + { + public string Name; + public string Id; + + public bool HasId => !string.IsNullOrEmpty(Id); + public void GenerateId() => Id = Guid.NewGuid().ToString()[..13]; + } +} diff --git a/Runtime/Gamelogic/EventDefinition.cs.meta b/Runtime/Gamelogic/EventDefinition.cs.meta new file mode 100644 index 0000000..4cc854d --- /dev/null +++ b/Runtime/Gamelogic/EventDefinition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 035b10e41eafa234285fd151c7640158 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Gamelogic/VisualScriptingEventNames.cs b/Runtime/Gamelogic/VisualScriptingEventNames.cs index ec14b74..461b07f 100644 --- a/Runtime/Gamelogic/VisualScriptingEventNames.cs +++ b/Runtime/Gamelogic/VisualScriptingEventNames.cs @@ -25,5 +25,6 @@ public static class VisualScriptingEventNames public const string CurrentPlayerChanged = "CurrentPlayerChanged"; public const string PlayerVariableChanged = "PlayerVariableChanged"; public const string TableVariableChanged = "TableVariableChanged"; + public const string PinballEvent = "PinballEvent"; } } diff --git a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs index 289a382..de60734 100644 --- a/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs +++ b/Runtime/Gamelogic/VisualScriptingGamelogicEngine.cs @@ -37,6 +37,9 @@ public class VisualScriptingGamelogicEngine : MonoBehaviour, IGamelogicEngine, I [Tooltip("Define here the player-specific variables of the Visual Scripting engine.")] public List PlayerVariableDefinitions; + [Tooltip("Declare your custom events here for easy access with our event nodes.")] + public List EventDefinitions; + [Tooltip("Define the displays this game is going to use.")] public DisplayDefinition[] Displays; @@ -202,6 +205,7 @@ public void OnBeforeSerialize() } ids.Add(def.Id); } + ids.Clear(); foreach (var def in TableVariableDefinitions) { if (!def.HasId || ids.Contains(def.Id)) { @@ -209,6 +213,14 @@ public void OnBeforeSerialize() } ids.Add(def.Id); } + + ids.Clear(); + foreach (var def in EventDefinitions) { + if (!def.HasId || ids.Contains(def.Id)) { + def.GenerateId(); + } + ids.Add(def.Id); + } #endif } public void OnAfterDeserialize() diff --git a/Runtime/Nodes/Event.meta b/Runtime/Nodes/Event.meta new file mode 100644 index 0000000..f073979 --- /dev/null +++ b/Runtime/Nodes/Event.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7d5311bf13fb8344eb84e0d7efd211f9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Event/PinballEventUnit.cs b/Runtime/Nodes/Event/PinballEventUnit.cs new file mode 100644 index 0000000..c5f315f --- /dev/null +++ b/Runtime/Nodes/Event/PinballEventUnit.cs @@ -0,0 +1,92 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable InconsistentNaming + +using System; +using System.Collections.Generic; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + /// + /// A special named event with any amount of parameters called manually with the 'Trigger Custom Event' unit. + /// + [UnitTitle("On Pinball Event")] + [UnitCategory("Events/Visual Pinball")] + public class PinballEventUnit : GameObjectEventUnit + { + [Serialize, Inspectable, UnitHeaderInspectable] + public EventDefinition Event { get; set; } + + public override Type MessageListenerType => null; + protected override string hookName => VisualScriptingEventNames.PinballEvent; + + [SerializeAs(nameof(argumentCount))] + private int _argumentCount; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Arguments")] + public int argumentCount + { + get => _argumentCount; + set => _argumentCount = Mathf.Clamp(value, 0, 10); + } + + [DoNotSerialize] + public List argumentPorts { get; } = new List(); + + protected override void Definition() + { + base.Definition(); + argumentPorts.Clear(); + for (var i = 0; i < argumentCount; i++) { + argumentPorts.Add(ValueOutput("argument_" + i)); + } + } + + protected override bool ShouldTrigger(Flow flow, PinballEventArgs args) + { + return Event.Id.Equals(args.Id); + } + + protected override void AssignArguments(Flow flow, PinballEventArgs args) + { + for (var i = 0; i < argumentCount; i++) { + flow.SetValue(argumentPorts[i], args.Args[i]); + } + } + + public static void Trigger(GameObject target, string name, params object[] args) + { + EventBus.Trigger(VisualScriptingEventNames.PinballEvent, target, new PinballEventArgs(name, args)); + } + } + + public readonly struct PinballEventArgs + { + public readonly string Id; + + public readonly object[] Args; + + public PinballEventArgs(string id, params object[] args) + { + Id = id; + Args = args; + } + } +} diff --git a/Runtime/Nodes/Event/PinballEventUnit.cs.meta b/Runtime/Nodes/Event/PinballEventUnit.cs.meta new file mode 100644 index 0000000..41a97fb --- /dev/null +++ b/Runtime/Nodes/Event/PinballEventUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb0cb702e7961bf4abc39654881db52e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Event/TriggerPinballEventUnit.cs b/Runtime/Nodes/Event/TriggerPinballEventUnit.cs new file mode 100644 index 0000000..c259a43 --- /dev/null +++ b/Runtime/Nodes/Event/TriggerPinballEventUnit.cs @@ -0,0 +1,97 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable InconsistentNaming + +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + /// + /// Triggers a pinball event. + /// + [UnitTitle("Trigger Pinball Event")] + [UnitSurtitle("Pinball Event")] + [UnitShortTitle("Trigger")] + [TypeIcon(typeof(CustomEvent))] + [UnitCategory("Events/Visual Pinball")] + public sealed class TriggerPinballEventUnit : Unit + { + [Serialize, Inspectable, UnitHeaderInspectable] + public EventDefinition Event { get; set; } + + [SerializeAs(nameof(argumentCount))] + private int _argumentCount; + + [DoNotSerialize] + public List Arguments { get; private set; } + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Arguments")] + public int argumentCount { + get => _argumentCount; + set => _argumentCount = Mathf.Clamp(value, 0, 10); + } + + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger { get; private set; } + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger { get; private set; } + + /// + /// The target of the event. + /// + [DoNotSerialize] + [PortLabelHidden] + [NullMeansSelf] + public ValueInput target { get; private set; } + + protected override void Definition() + { + InputTrigger = ControlInput(nameof(InputTrigger), Trigger); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + + target = ValueInput(nameof(target), null).NullMeansSelf(); + Arguments = new List(); + + for (var i = 0; i < argumentCount; i++) { + var argument = ValueInput("argument_" + i); + Arguments.Add(argument); + Requirement(argument, InputTrigger); + } + + Requirement(target, InputTrigger); + Succession(InputTrigger, OutputTrigger); + } + + private ControlOutput Trigger(Flow flow) + { + var t = flow.GetValue(this.target); + var args = Arguments.Select(flow.GetConvertedValue).ToArray(); + + PinballEventUnit.Trigger(t, Event.Id, args); + + return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/Event/TriggerPinballEventUnit.cs.meta b/Runtime/Nodes/Event/TriggerPinballEventUnit.cs.meta new file mode 100644 index 0000000..4334edc --- /dev/null +++ b/Runtime/Nodes/Event/TriggerPinballEventUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e93ef3119452661459c6d560a91b8964 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 0ac09a8a2af2b53724cf142d3008d23a20bd5e88 Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 22 Feb 2022 23:42:15 +0100 Subject: [PATCH 48/54] Update pinball event nodes. --- ...nitWidget.cs => PinballEventUnitWidget.cs} | 4 +-- ...cs.meta => PinballEventUnitWidget.cs.meta} | 2 +- .../Widgets/TriggerPinballEventUnitWidget.cs | 30 +++++++++++++++++++ .../TriggerPinballEventUnitWidget.cs.meta | 11 +++++++ Runtime/Nodes/Event/PinballEventUnit.cs | 12 ++++---- .../Nodes/Event/TriggerPinballEventUnit.cs | 23 +++++--------- 6 files changed, 57 insertions(+), 25 deletions(-) rename Editor/Widgets/{CustomEventUnitWidget.cs => PinballEventUnitWidget.cs} (82%) rename Editor/Widgets/{CustomEventUnitWidget.cs.meta => PinballEventUnitWidget.cs.meta} (83%) create mode 100644 Editor/Widgets/TriggerPinballEventUnitWidget.cs create mode 100644 Editor/Widgets/TriggerPinballEventUnitWidget.cs.meta diff --git a/Editor/Widgets/CustomEventUnitWidget.cs b/Editor/Widgets/PinballEventUnitWidget.cs similarity index 82% rename from Editor/Widgets/CustomEventUnitWidget.cs rename to Editor/Widgets/PinballEventUnitWidget.cs index d861d2f..b3b1c71 100644 --- a/Editor/Widgets/CustomEventUnitWidget.cs +++ b/Editor/Widgets/PinballEventUnitWidget.cs @@ -25,9 +25,9 @@ namespace VisualPinball.Unity.VisualScripting.Editor { [Widget(typeof(PinballEventUnit))] - public sealed class CustomEventUnitWidget : UnitWidget + public sealed class PinballEventUnitWidget : GleUnitWidget { - public CustomEventUnitWidget(FlowCanvas canvas, PinballEventUnit unit) : base(canvas, unit) + public PinballEventUnitWidget(FlowCanvas canvas, PinballEventUnit unit) : base(canvas, unit) { } } diff --git a/Editor/Widgets/CustomEventUnitWidget.cs.meta b/Editor/Widgets/PinballEventUnitWidget.cs.meta similarity index 83% rename from Editor/Widgets/CustomEventUnitWidget.cs.meta rename to Editor/Widgets/PinballEventUnitWidget.cs.meta index f9e22e4..f04edb4 100644 --- a/Editor/Widgets/CustomEventUnitWidget.cs.meta +++ b/Editor/Widgets/PinballEventUnitWidget.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 43ffe3ce77e8c3244aaa6f17725d1974 +guid: 37132c71449ce5846bc0c2b2937c4700 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Widgets/TriggerPinballEventUnitWidget.cs b/Editor/Widgets/TriggerPinballEventUnitWidget.cs new file mode 100644 index 0000000..7345001 --- /dev/null +++ b/Editor/Widgets/TriggerPinballEventUnitWidget.cs @@ -0,0 +1,30 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(TriggerPinballEventUnit))] + public sealed class TriggerPinballEventUnitWidget : GleUnitWidget + { + public TriggerPinballEventUnitWidget(FlowCanvas canvas, TriggerPinballEventUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/TriggerPinballEventUnitWidget.cs.meta b/Editor/Widgets/TriggerPinballEventUnitWidget.cs.meta new file mode 100644 index 0000000..4175209 --- /dev/null +++ b/Editor/Widgets/TriggerPinballEventUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bcc0505d85dfff748885fc1f0087c178 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Event/PinballEventUnit.cs b/Runtime/Nodes/Event/PinballEventUnit.cs index c5f315f..d72287e 100644 --- a/Runtime/Nodes/Event/PinballEventUnit.cs +++ b/Runtime/Nodes/Event/PinballEventUnit.cs @@ -28,14 +28,11 @@ namespace VisualPinball.Unity.VisualScripting /// [UnitTitle("On Pinball Event")] [UnitCategory("Events/Visual Pinball")] - public class PinballEventUnit : GameObjectEventUnit + public class PinballEventUnit : GleEventUnit { [Serialize, Inspectable, UnitHeaderInspectable] public EventDefinition Event { get; set; } - public override Type MessageListenerType => null; - protected override string hookName => VisualScriptingEventNames.PinballEvent; - [SerializeAs(nameof(argumentCount))] private int _argumentCount; @@ -50,6 +47,9 @@ public int argumentCount [DoNotSerialize] public List argumentPorts { get; } = new List(); + protected override bool register => true; + public override EventHook GetHook(GraphReference reference) => new(VisualScriptingEventNames.PinballEvent); + protected override void Definition() { base.Definition(); @@ -71,9 +71,9 @@ protected override void AssignArguments(Flow flow, PinballEventArgs args) } } - public static void Trigger(GameObject target, string name, params object[] args) + public static void Trigger(GameObject target, string id, params object[] args) { - EventBus.Trigger(VisualScriptingEventNames.PinballEvent, target, new PinballEventArgs(name, args)); + EventBus.Trigger(VisualScriptingEventNames.PinballEvent, target, new PinballEventArgs(id, args)); } } diff --git a/Runtime/Nodes/Event/TriggerPinballEventUnit.cs b/Runtime/Nodes/Event/TriggerPinballEventUnit.cs index c259a43..db2d617 100644 --- a/Runtime/Nodes/Event/TriggerPinballEventUnit.cs +++ b/Runtime/Nodes/Event/TriggerPinballEventUnit.cs @@ -31,7 +31,7 @@ namespace VisualPinball.Unity.VisualScripting [UnitShortTitle("Trigger")] [TypeIcon(typeof(CustomEvent))] [UnitCategory("Events/Visual Pinball")] - public sealed class TriggerPinballEventUnit : Unit + public sealed class TriggerPinballEventUnit : GleUnit { [Serialize, Inspectable, UnitHeaderInspectable] public EventDefinition Event { get; set; } @@ -57,39 +57,30 @@ public int argumentCount { [PortLabelHidden] public ControlOutput OutputTrigger { get; private set; } - /// - /// The target of the event. - /// - [DoNotSerialize] - [PortLabelHidden] - [NullMeansSelf] - public ValueInput target { get; private set; } - protected override void Definition() { InputTrigger = ControlInput(nameof(InputTrigger), Trigger); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - - target = ValueInput(nameof(target), null).NullMeansSelf(); Arguments = new List(); - for (var i = 0; i < argumentCount; i++) { var argument = ValueInput("argument_" + i); Arguments.Add(argument); Requirement(argument, InputTrigger); } - Requirement(target, InputTrigger); Succession(InputTrigger, OutputTrigger); } private ControlOutput Trigger(Flow flow) { - var t = flow.GetValue(this.target); - var args = Arguments.Select(flow.GetConvertedValue).ToArray(); + if (!AssertVsGle(flow)) { + Debug.LogError("Cannot find GLE."); + return OutputTrigger; + } - PinballEventUnit.Trigger(t, Event.Id, args); + var args = Arguments.Select(flow.GetConvertedValue).ToArray(); + PinballEventUnit.Trigger(VsGle.gameObject, Event.Id, args); return OutputTrigger; } From 186da107d30fea034353bffcb0b1c9ad8bad0980 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 27 Feb 2022 00:19:04 +0100 Subject: [PATCH 49/54] Remove target from pinball event. --- Runtime/Nodes/Event/PinballEventUnit.cs | 4 ++-- Runtime/Nodes/Event/TriggerPinballEventUnit.cs | 7 +------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Runtime/Nodes/Event/PinballEventUnit.cs b/Runtime/Nodes/Event/PinballEventUnit.cs index d72287e..ac299c4 100644 --- a/Runtime/Nodes/Event/PinballEventUnit.cs +++ b/Runtime/Nodes/Event/PinballEventUnit.cs @@ -71,9 +71,9 @@ protected override void AssignArguments(Flow flow, PinballEventArgs args) } } - public static void Trigger(GameObject target, string id, params object[] args) + public static void Trigger(string id, params object[] args) { - EventBus.Trigger(VisualScriptingEventNames.PinballEvent, target, new PinballEventArgs(id, args)); + EventBus.Trigger(VisualScriptingEventNames.PinballEvent, new PinballEventArgs(id, args)); } } diff --git a/Runtime/Nodes/Event/TriggerPinballEventUnit.cs b/Runtime/Nodes/Event/TriggerPinballEventUnit.cs index db2d617..c53ef1a 100644 --- a/Runtime/Nodes/Event/TriggerPinballEventUnit.cs +++ b/Runtime/Nodes/Event/TriggerPinballEventUnit.cs @@ -74,13 +74,8 @@ protected override void Definition() private ControlOutput Trigger(Flow flow) { - if (!AssertVsGle(flow)) { - Debug.LogError("Cannot find GLE."); - return OutputTrigger; - } - var args = Arguments.Select(flow.GetConvertedValue).ToArray(); - PinballEventUnit.Trigger(VsGle.gameObject, Event.Id, args); + PinballEventUnit.Trigger(Event.Id, args); return OutputTrigger; } From 9a3b0e84cab9a730b59987785acb4fe5e43534d7 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Wed, 2 Mar 2022 18:46:13 -0500 Subject: [PATCH 50/54] unit: update switch lamp unit to work more like set lamp unit --- Runtime/Nodes/Lamps/SwitchLampUnit.cs | 72 +++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/Runtime/Nodes/Lamps/SwitchLampUnit.cs b/Runtime/Nodes/Lamps/SwitchLampUnit.cs index ed80cad..f97f55f 100644 --- a/Runtime/Nodes/Lamps/SwitchLampUnit.cs +++ b/Runtime/Nodes/Lamps/SwitchLampUnit.cs @@ -14,10 +14,12 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using Unity.VisualScripting; using UnityEngine; +using VisualPinball.Engine.Game.Engines; namespace VisualPinball.Unity.VisualScripting { @@ -27,8 +29,11 @@ namespace VisualPinball.Unity.VisualScripting [UnitCategory("Visual Pinball")] public class SwitchLampUnit : GleUnit, IMultiInputUnit { - [SerializeAs(nameof(inputCount))] - private int _inputCount = 1; + [Serialize, Inspectable, UnitHeaderInspectable("Match")] + public LampDataType MatchDataType { get; set; } + + [Serialize, Inspectable, UnitHeaderInspectable("Non Match")] + public LampDataType NonMatchDataType { get; set; } [DoNotSerialize] [Inspectable, UnitHeaderInspectable("Lamp IDs")] @@ -46,10 +51,19 @@ public int inputCount [PortLabelHidden] public ControlOutput OutputTrigger; + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + [DoNotSerialize] [PortLabel("Source Value")] public ValueInput SourceValue { get; private set; } + [DoNotSerialize] + public ValueInput Match { get; private set; } + + [DoNotSerialize] + public ValueInput NonMatch { get; private set; } + [DoNotSerialize] public ReadOnlyCollection multiInputs { get; private set; } @@ -62,19 +76,33 @@ protected override void Definition() SourceValue = ValueInput(nameof(SourceValue)); - var _multiInputs = new List(); - - multiInputs = _multiInputs.AsReadOnly(); + var mi = new List(); + multiInputs = mi.AsReadOnly(); for (var i = 0; i < inputCount; i++) { var input = ValueInput(i.ToString(), LampIdValue.Empty.ToJson()); - _multiInputs.Add(input); - + mi.Add(input); Requirement(input, InputTrigger); } _lampIdValueCache.Clear(); + Match = MatchDataType switch { + LampDataType.OnOff => ValueInput(nameof(Match), false), + LampDataType.Status => ValueInput(nameof(Match), LampStatus.Off), + LampDataType.Intensity => ValueInput(nameof(Match), 0f), + LampDataType.Color => ValueInput(nameof(Match), UnityEngine.Color.white), + _ => throw new ArgumentOutOfRangeException() + }; + + NonMatch = NonMatchDataType switch { + LampDataType.OnOff => ValueInput(nameof(NonMatch), false), + LampDataType.Status => ValueInput(nameof(NonMatch), LampStatus.Off), + LampDataType.Intensity => ValueInput(nameof(NonMatch), 0f), + LampDataType.Color => ValueInput(nameof(NonMatch), UnityEngine.Color.white), + _ => throw new ArgumentOutOfRangeException() + }; + Succession(InputTrigger, OutputTrigger); } @@ -84,8 +112,13 @@ private ControlOutput Process(Flow flow) Debug.LogError("Cannot find GLE."); return OutputTrigger; } - - var value = flow.GetValue(SourceValue); + + if (!AssertPlayer(flow)) { + Debug.LogError("Cannot find player."); + return OutputTrigger; + } + + var sourceValue = flow.GetValue(SourceValue); foreach (var input in multiInputs) { var json = flow.GetValue(input); @@ -95,7 +128,26 @@ private ControlOutput Process(Flow flow) } var lampIdValue = _lampIdValueCache[json.GetHashCode()]; - Gle.SetLamp(lampIdValue.id, lampIdValue.value == value ? 255f : 0f); + + var dataType = lampIdValue.value == sourceValue ? MatchDataType : NonMatchDataType; + var value = lampIdValue.value == sourceValue ? Match : NonMatch; + + switch (dataType) { + case LampDataType.OnOff: + Player.SetLamp(lampIdValue.id, flow.GetValue(value) ? LampStatus.On : LampStatus.Off); + break; + case LampDataType.Status: + Player.SetLamp(lampIdValue.id, flow.GetValue(value)); + break; + case LampDataType.Intensity: + Player.SetLamp(lampIdValue.id, flow.GetValue(value)); + break; + case LampDataType.Color: + Player.SetLamp(lampIdValue.id, flow.GetValue(value).ToEngineColor()); + break; + default: + throw new ArgumentOutOfRangeException(); + } } return OutputTrigger; From 9b651cd43adbc1051c296856b0d54e5e303ec229 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 28 Feb 2022 23:00:07 +0100 Subject: [PATCH 51/54] Multiply intensity by 255 if mapping is set to RGB. --- Runtime/Nodes/Lamps/SetLampUnit.cs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Runtime/Nodes/Lamps/SetLampUnit.cs b/Runtime/Nodes/Lamps/SetLampUnit.cs index baa69f8..576bad1 100644 --- a/Runtime/Nodes/Lamps/SetLampUnit.cs +++ b/Runtime/Nodes/Lamps/SetLampUnit.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using Unity.VisualScripting; using UnityEngine; using VisualPinball.Engine.Game.Engines; @@ -58,6 +59,9 @@ public int inputCount [DoNotSerialize] public ValueInput Value { get; private set; } + [DoNotSerialize] + private readonly Dictionary _intensityMultipliers = new(); + protected override void Definition() { InputTrigger = ControlInput(nameof(InputTrigger), Process); @@ -105,7 +109,7 @@ private ControlOutput Process(Flow flow) Player.SetLamp(lampId, flow.GetValue(Value)); break; case LampDataType.Intensity: - Player.SetLamp(lampId, flow.GetValue(Value)); + Player.SetLamp(lampId, flow.GetValue(Value) * GetIntensityMultiplier(lampId)); break; case LampDataType.Color: Player.SetLamp(lampId, flow.GetValue(Value).ToEngineColor()); @@ -117,5 +121,22 @@ private ControlOutput Process(Flow flow) return OutputTrigger; } + + private float GetIntensityMultiplier(string id) + { + if (_intensityMultipliers.ContainsKey(id)) { + return _intensityMultipliers[id]; + } + + var mapping = Player.LampMapping.FirstOrDefault(l => l.Id == id); + if (mapping == null) { + Debug.LogError($"Unknown lamp ID {id}."); + _intensityMultipliers[id] = 1; + return 1; + } + + _intensityMultipliers[id] = mapping.Type == LampType.Rgb ? 255 : 1; + return _intensityMultipliers[id]; + } } } From c02055bf7096ac766c4012cd11ab10e15dd64cce Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Thu, 3 Mar 2022 17:52:16 -0500 Subject: [PATCH 52/54] unit: rework LampSequenceUnit to use mappings --- Runtime/Nodes/Lamps/LampSequenceUnit.cs | 174 ++++++++++++++++++------ Runtime/Nodes/Lamps/SwitchLampUnit.cs | 26 +++- 2 files changed, 153 insertions(+), 47 deletions(-) diff --git a/Runtime/Nodes/Lamps/LampSequenceUnit.cs b/Runtime/Nodes/Lamps/LampSequenceUnit.cs index 67a00eb..789d633 100644 --- a/Runtime/Nodes/Lamps/LampSequenceUnit.cs +++ b/Runtime/Nodes/Lamps/LampSequenceUnit.cs @@ -14,18 +14,44 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using Unity.VisualScripting; using UnityEngine; +using VisualPinball.Engine.Game.Engines; +using Color = VisualPinball.Engine.Math.Color; namespace VisualPinball.Unity.VisualScripting { + public struct LightComponentMapping + { + public LightComponent lightComponent; + public string id; + + public bool IsValid() => !lightComponent.IsUnityNull(); + } + [UnitTitle("Lamp Sequence")] [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Visual Pinball")] public class LampSequenceUnit : GleUnit, IMultiInputUnit { + [Serialize, Inspectable, UnitHeaderInspectable("Value")] + public LampDataType ValueDataType { get; set; } + + [Serialize, Inspectable, UnitHeaderInspectable("Non Step Value")] + public LampDataType NonStepValueDataType { get; set; } + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Lamp IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } + [DoNotSerialize] [PortLabelHidden] public ControlInput InputTrigger; @@ -38,55 +64,66 @@ public class LampSequenceUnit : GleUnit, IMultiInputUnit private int _inputCount = 1; [DoNotSerialize] - [Inspectable, UnitHeaderInspectable("Lamp IDs")] - public int inputCount - { - get => _inputCount; - set => _inputCount = Mathf.Clamp(value, 1, 10); - } + public ReadOnlyCollection multiInputs { get; private set; } [DoNotSerialize] - public ReadOnlyCollection multiInputs { get; private set; } + [PortLabel("Step")] + public ValueInput Step; [DoNotSerialize] - [PortLabel("Value")] public ValueInput Value { get; private set; } [DoNotSerialize] - [PortLabel("Step")] - public ValueInput Step; + public ValueInput NonStepValue { get; private set; } + + [DoNotSerialize] + private readonly Dictionary _intensityMultipliers = new(); + private List _lightComponentCache = new(); private int _currentIndex; - private List _lightComponentCache = null; protected override void Definition() { InputTrigger = ControlInput(nameof(InputTrigger), Process); OutputTrigger = ControlOutput(nameof(OutputTrigger)); - var _multiInputs = new List(); - - multiInputs = _multiInputs.AsReadOnly(); + var mi = new List(); + multiInputs = mi.AsReadOnly(); for (var i = 0; i < inputCount; i++) { var input = ValueInput(i.ToString(), string.Empty); - _multiInputs.Add(input); - + mi.Add(input); Requirement(input, InputTrigger); } - Value = ValueInput(nameof(Value), 0f); Step = ValueInput(nameof(Step), 1); + Value = ValueDataType switch + { + LampDataType.OnOff => ValueInput(nameof(Value), false), + LampDataType.Status => ValueInput(nameof(Value), LampStatus.Off), + LampDataType.Intensity => ValueInput(nameof(Value), 0f), + LampDataType.Color => ValueInput(nameof(Value), UnityEngine.Color.white), + _ => throw new ArgumentOutOfRangeException() + }; + + NonStepValue = NonStepValueDataType switch + { + LampDataType.OnOff => ValueInput(nameof(NonStepValue), false), + LampDataType.Status => ValueInput(nameof(NonStepValue), LampStatus.Off), + LampDataType.Intensity => ValueInput(nameof(NonStepValue), 0f), + LampDataType.Color => ValueInput(nameof(NonStepValue), UnityEngine.Color.white), + _ => throw new ArgumentOutOfRangeException() + }; + Succession(InputTrigger, OutputTrigger); - _lightComponentCache = null; + _lightComponentCache.Clear(); } private ControlOutput Process(Flow flow) { - if (!AssertGle(flow)) - { + if (!AssertGle(flow)) { Debug.LogError("Cannot find GLE."); return OutputTrigger; } @@ -96,52 +133,99 @@ private ControlOutput Process(Flow flow) return OutputTrigger; } - var value = flow.GetValue(Value); - var stepRaw = flow.GetValue(Step); - - if (_lightComponentCache != null) { - foreach (var component in _lightComponentCache) { - if (component.IsUnityNull()) { - _lightComponentCache = null; - break; - } + foreach (var mapping in _lightComponentCache) { + if (!mapping.IsValid()) { + _lightComponentCache.Clear(); + break; } } - if (_lightComponentCache == null) { - _lightComponentCache = new List(); - + if (_lightComponentCache.Count == 0) { foreach (var input in multiInputs) { var lampId = flow.GetValue(input); - _lightComponentCache.AddRange(Flatten(Player.LampDevice(lampId))); + + var mapping = Player.LampMapping.FirstOrDefault(l => l.Id == lampId); + if (mapping != null) { + UpdateLightComponentCache(mapping.Device, lampId); + } + else { + Debug.LogError($"Unknown lamp ID {lampId}."); + _lightComponentCache.Clear(); + + break; + } } } + var stepRaw = flow.GetValue(Step); + + LampDataType dataType; + ValueInput value; + for (var index = 0; index < _lightComponentCache.Count; index++) { - ; + if (index >= _currentIndex * stepRaw && index < (_currentIndex + 1) * stepRaw) { + dataType = ValueDataType; + value = Value; + } + else { + dataType = NonStepValueDataType; + value = NonStepValue; + } + + var lampApi = Player.Lamp(_lightComponentCache[index].lightComponent); + + switch (dataType) { + case LampDataType.OnOff: + lampApi.OnLamp(flow.GetValue(value) ? LampStatus.On : LampStatus.Off); + break; + case LampDataType.Status: + lampApi.OnLamp(flow.GetValue(value)); + break; + case LampDataType.Intensity: + lampApi.OnLamp(flow.GetValue(value) * GetIntensityMultiplier(_lightComponentCache[index].id)); + break; + case LampDataType.Color: + lampApi.OnLamp(flow.GetValue(value)); + break; + default: + throw new ArgumentOutOfRangeException(); + } } if (++_currentIndex >= _lightComponentCache.Count / stepRaw) { _currentIndex = 0; } - + return OutputTrigger; } - private List Flatten(List lampDeviceList) + private float GetIntensityMultiplier(string id) { - List lights = new List(); + if (_intensityMultipliers.ContainsKey(id)) { + return _intensityMultipliers[id]; + } - foreach (ILampDeviceComponent device in lampDeviceList) { - if (device is LightComponent) { - lights.Add(device as LightComponent); - } - else if (device is LightGroupComponent) { - lights.AddRange(Flatten(((LightGroupComponent)device).Lights)); - } + var mapping = Player.LampMapping.FirstOrDefault(l => l.Id == id); + if (mapping == null) { + Debug.LogError($"Unknown lamp ID {id}."); + _intensityMultipliers[id] = 1; + return 1; } - return lights; + _intensityMultipliers[id] = mapping.Type == LampType.Rgb ? 255 : 1; + return _intensityMultipliers[id]; + } + + private void UpdateLightComponentCache(ILampDeviceComponent device, string id) + { + if (device is LightComponent) { + _lightComponentCache.Add(new LightComponentMapping { lightComponent = device as LightComponent, id = id }); + } + else if (device is LightGroupComponent) { + foreach (var light in (device as LightGroupComponent).Lights) { + UpdateLightComponentCache(light, id); + } + } } } } diff --git a/Runtime/Nodes/Lamps/SwitchLampUnit.cs b/Runtime/Nodes/Lamps/SwitchLampUnit.cs index f97f55f..3a24a60 100644 --- a/Runtime/Nodes/Lamps/SwitchLampUnit.cs +++ b/Runtime/Nodes/Lamps/SwitchLampUnit.cs @@ -17,9 +17,11 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using Unity.VisualScripting; using UnityEngine; using VisualPinball.Engine.Game.Engines; +using Color = VisualPinball.Engine.Math.Color; namespace VisualPinball.Unity.VisualScripting { @@ -54,6 +56,9 @@ public int inputCount [SerializeAs(nameof(inputCount))] private int _inputCount = 1; + [DoNotSerialize] + public ReadOnlyCollection multiInputs { get; private set; } + [DoNotSerialize] [PortLabel("Source Value")] public ValueInput SourceValue { get; private set; } @@ -65,7 +70,7 @@ public int inputCount public ValueInput NonMatch { get; private set; } [DoNotSerialize] - public ReadOnlyCollection multiInputs { get; private set; } + private readonly Dictionary _intensityMultipliers = new(); private Dictionary _lampIdValueCache = new Dictionary(); @@ -140,7 +145,7 @@ private ControlOutput Process(Flow flow) Player.SetLamp(lampIdValue.id, flow.GetValue(value)); break; case LampDataType.Intensity: - Player.SetLamp(lampIdValue.id, flow.GetValue(value)); + Player.SetLamp(lampIdValue.id, flow.GetValue(value) * GetIntensityMultiplier(lampIdValue.id)); break; case LampDataType.Color: Player.SetLamp(lampIdValue.id, flow.GetValue(value).ToEngineColor()); @@ -152,5 +157,22 @@ private ControlOutput Process(Flow flow) return OutputTrigger; } + + private float GetIntensityMultiplier(string id) + { + if (_intensityMultipliers.ContainsKey(id)) { + return _intensityMultipliers[id]; + } + + var mapping = Player.LampMapping.FirstOrDefault(l => l.Id == id); + if (mapping == null) { + Debug.LogError($"Unknown lamp ID {id}."); + _intensityMultipliers[id] = 1; + return 1; + } + + _intensityMultipliers[id] = mapping.Type == LampType.Rgb ? 255 : 1; + return _intensityMultipliers[id]; + } } } From 5fb47c6d0dc5b217739def4ae939fa4fe30eb2e4 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Fri, 4 Mar 2022 07:17:17 -0500 Subject: [PATCH 53/54] misc: update lamp sequence to find all lights in a mapping --- Runtime/Nodes/Lamps/LampSequenceUnit.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Runtime/Nodes/Lamps/LampSequenceUnit.cs b/Runtime/Nodes/Lamps/LampSequenceUnit.cs index 789d633..3a5c967 100644 --- a/Runtime/Nodes/Lamps/LampSequenceUnit.cs +++ b/Runtime/Nodes/Lamps/LampSequenceUnit.cs @@ -144,9 +144,11 @@ private ControlOutput Process(Flow flow) foreach (var input in multiInputs) { var lampId = flow.GetValue(input); - var mapping = Player.LampMapping.FirstOrDefault(l => l.Id == lampId); - if (mapping != null) { - UpdateLightComponentCache(mapping.Device, lampId); + var mappingList = Player.LampMapping.Where(l => l.Id == lampId); + if (mappingList.Any()) { + foreach (var mapping in mappingList) { + UpdateLightComponentCache(mapping.Device, lampId); + } } else { Debug.LogError($"Unknown lamp ID {lampId}."); From a21524c606aff7dae32b3a50a861cd45213aa14b Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Tue, 8 Mar 2022 15:26:12 -0500 Subject: [PATCH 54/54] units: added coil units to mirror what we have for switches --- .../AllCoilsEnabledEventUnitDescriptor.cs | 32 +++++++ ...AllCoilsEnabledEventUnitDescriptor.cs.meta | 11 +++ .../CoilEnabledEventUnitDescriptor.cs | 49 +++++++++++ .../CoilEnabledEventUnitDescriptor.cs.meta | 11 +++ Editor/Descriptors/CoilEventUnitDescriptor.cs | 52 +++++++++++ .../CoilEventUnitDescriptor.cs.meta | 11 +++ Editor/Descriptors/GetCoilUnitDescriptor.cs | 53 ++++++++++++ .../Descriptors/GetCoilUnitDescriptor.cs.meta | 11 +++ .../Widgets/AllCoilsEnabledEventUnitWidget.cs | 16 ++++ .../AllCoilsEnabledEventUnitWidget.cs.meta | 11 +++ .../AllSwitchesEnabledEventUnitWidget.cs | 1 + Editor/Widgets/CoilEnabledEventUnitWidget.cs | 34 ++++++++ .../CoilEnabledEventUnitWidget.cs.meta | 11 +++ Editor/Widgets/CoilEventUnitWidget.cs | 34 ++++++++ Editor/Widgets/CoilEventUnitWidget.cs.meta | 11 +++ Editor/Widgets/GetCoilUnitWidget.cs | 55 ++++++++++++ Editor/Widgets/GetCoilUnitWidget.cs.meta | 11 +++ Editor/Widgets/GetSwitchUnitWidget.cs | 3 +- Editor/Widgets/SwitchEventUnitWidget.cs | 1 + .../Nodes/Coils/AllCoilsEnabledEventUnit.cs | 81 +++++++++++++++++ .../Coils/AllCoilsEnabledEventUnit.cs.meta | 11 +++ Runtime/Nodes/Coils/CoilEnabledEventUnit.cs | 73 ++++++++++++++++ .../Nodes/Coils/CoilEnabledEventUnit.cs.meta | 11 +++ Runtime/Nodes/Coils/CoilEventUnit.cs | 86 +++++++++++++++++++ Runtime/Nodes/Coils/CoilEventUnit.cs.meta | 11 +++ Runtime/Nodes/Coils/GetCoilUnit.cs | 51 +++++++++++ Runtime/Nodes/Coils/GetCoilUnit.cs.meta | 11 +++ 27 files changed, 751 insertions(+), 2 deletions(-) create mode 100644 Editor/Descriptors/AllCoilsEnabledEventUnitDescriptor.cs create mode 100644 Editor/Descriptors/AllCoilsEnabledEventUnitDescriptor.cs.meta create mode 100644 Editor/Descriptors/CoilEnabledEventUnitDescriptor.cs create mode 100644 Editor/Descriptors/CoilEnabledEventUnitDescriptor.cs.meta create mode 100644 Editor/Descriptors/CoilEventUnitDescriptor.cs create mode 100644 Editor/Descriptors/CoilEventUnitDescriptor.cs.meta create mode 100644 Editor/Descriptors/GetCoilUnitDescriptor.cs create mode 100644 Editor/Descriptors/GetCoilUnitDescriptor.cs.meta create mode 100644 Editor/Widgets/AllCoilsEnabledEventUnitWidget.cs create mode 100644 Editor/Widgets/AllCoilsEnabledEventUnitWidget.cs.meta create mode 100644 Editor/Widgets/CoilEnabledEventUnitWidget.cs create mode 100644 Editor/Widgets/CoilEnabledEventUnitWidget.cs.meta create mode 100644 Editor/Widgets/CoilEventUnitWidget.cs create mode 100644 Editor/Widgets/CoilEventUnitWidget.cs.meta create mode 100644 Editor/Widgets/GetCoilUnitWidget.cs create mode 100644 Editor/Widgets/GetCoilUnitWidget.cs.meta create mode 100644 Runtime/Nodes/Coils/AllCoilsEnabledEventUnit.cs create mode 100644 Runtime/Nodes/Coils/AllCoilsEnabledEventUnit.cs.meta create mode 100644 Runtime/Nodes/Coils/CoilEnabledEventUnit.cs create mode 100644 Runtime/Nodes/Coils/CoilEnabledEventUnit.cs.meta create mode 100644 Runtime/Nodes/Coils/CoilEventUnit.cs create mode 100644 Runtime/Nodes/Coils/CoilEventUnit.cs.meta create mode 100644 Runtime/Nodes/Coils/GetCoilUnit.cs create mode 100644 Runtime/Nodes/Coils/GetCoilUnit.cs.meta diff --git a/Editor/Descriptors/AllCoilsEnabledEventUnitDescriptor.cs b/Editor/Descriptors/AllCoilsEnabledEventUnitDescriptor.cs new file mode 100644 index 0000000..6bd4ad4 --- /dev/null +++ b/Editor/Descriptors/AllCoilsEnabledEventUnitDescriptor.cs @@ -0,0 +1,32 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(AllCoilsEnabledEventUnit))] + public class AllCoilsEnabledEventUnitDescriptor : MultiUnitDescriptor + { + public AllCoilsEnabledEventUnitDescriptor(AllCoilsEnabledEventUnit target) : base(target) { } + protected override string ItemLabel(int id) => $"Coil ID {id}"; + protected override string ItemDescription(int id) => $"Coil ID {id} to look for enabled status."; + protected override string DefinedSummary() => "This node triggers an event when the last coil in the list gets enabled."; + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.CoilEvent); + } +} diff --git a/Editor/Descriptors/AllCoilsEnabledEventUnitDescriptor.cs.meta b/Editor/Descriptors/AllCoilsEnabledEventUnitDescriptor.cs.meta new file mode 100644 index 0000000..92e11a4 --- /dev/null +++ b/Editor/Descriptors/AllCoilsEnabledEventUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c90e18403ab74304aa29615cd8ac11b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Descriptors/CoilEnabledEventUnitDescriptor.cs b/Editor/Descriptors/CoilEnabledEventUnitDescriptor.cs new file mode 100644 index 0000000..28c305f --- /dev/null +++ b/Editor/Descriptors/CoilEnabledEventUnitDescriptor.cs @@ -0,0 +1,49 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(CoilEnabledEventUnit))] + public class CoilEnabledEventUnitDescriptor : UnitDescriptor + { + public CoilEnabledEventUnitDescriptor(CoilEnabledEventUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node triggers an event when a coil in the list of given ID is enabled."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.CoilEvent); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + if (int.TryParse(port.key, out int id)) { + id += 1; + + desc.label = $"Coil ID {id}"; + desc.summary = $"Coil ID {id} to look for enabled status."; + } + } + } +} diff --git a/Editor/Descriptors/CoilEnabledEventUnitDescriptor.cs.meta b/Editor/Descriptors/CoilEnabledEventUnitDescriptor.cs.meta new file mode 100644 index 0000000..554b7ca --- /dev/null +++ b/Editor/Descriptors/CoilEnabledEventUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c0c89fb9024c456ab5414fb807087e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Descriptors/CoilEventUnitDescriptor.cs b/Editor/Descriptors/CoilEventUnitDescriptor.cs new file mode 100644 index 0000000..333f22d --- /dev/null +++ b/Editor/Descriptors/CoilEventUnitDescriptor.cs @@ -0,0 +1,52 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(CoilEventUnit))] + public class CoilEventUnitDescriptor : UnitDescriptor + { + public CoilEventUnitDescriptor(CoilEventUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node triggers an event when a coil with a given ID changes."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.CoilEvent); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + if (port.key == nameof(CoilEventUnit.IsEnabled)) { + desc.summary = "The new value of the coil, true if enabled, false otherwise."; + } + else if (int.TryParse(port.key, out int id)) { + id += 1; + + desc.label = $"Coil ID {id}"; + desc.summary = $"Coil ID {id} to look for a change status."; + } + } + } +} diff --git a/Editor/Descriptors/CoilEventUnitDescriptor.cs.meta b/Editor/Descriptors/CoilEventUnitDescriptor.cs.meta new file mode 100644 index 0000000..d9ef1f8 --- /dev/null +++ b/Editor/Descriptors/CoilEventUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df01ed8be8c054d5c93bc9d392dc2d55 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Descriptors/GetCoilUnitDescriptor.cs b/Editor/Descriptors/GetCoilUnitDescriptor.cs new file mode 100644 index 0000000..5968731 --- /dev/null +++ b/Editor/Descriptors/GetCoilUnitDescriptor.cs @@ -0,0 +1,53 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using Unity.VisualScripting; +using VisualPinball.Unity.Editor; +using IconSize = VisualPinball.Unity.Editor.IconSize; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Descriptor(typeof(GetCoilUnit))] + public class GetCoilUnitDescriptor : UnitDescriptor + { + public GetCoilUnitDescriptor(GetCoilUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node retrieves the current status of the coil."; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Coil(IconSize.Large, IconColor.Orange)); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + case nameof(GetCoilUnit.Id): + desc.summary = "Coil ID to check if enabled."; + break; + case nameof(GetCoilUnit.IsEnabled): + desc.summary = "Whether the coil is enabled."; + break; + } + } + } +} diff --git a/Editor/Descriptors/GetCoilUnitDescriptor.cs.meta b/Editor/Descriptors/GetCoilUnitDescriptor.cs.meta new file mode 100644 index 0000000..ac5382c --- /dev/null +++ b/Editor/Descriptors/GetCoilUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5bff9c66ee0334b939db93256176fd40 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/AllCoilsEnabledEventUnitWidget.cs b/Editor/Widgets/AllCoilsEnabledEventUnitWidget.cs new file mode 100644 index 0000000..7c2ea40 --- /dev/null +++ b/Editor/Widgets/AllCoilsEnabledEventUnitWidget.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(AllCoilsEnabledEventUnit))] + public sealed class AllCoilsEnabledEventUnitWidget : GleMultiUnitWidget + { + public AllCoilsEnabledEventUnitWidget(FlowCanvas canvas, AllCoilsEnabledEventUnit unit) : base(canvas, unit) + { + } + + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedCoils.Select(coil => coil.Id); + } +} diff --git a/Editor/Widgets/AllCoilsEnabledEventUnitWidget.cs.meta b/Editor/Widgets/AllCoilsEnabledEventUnitWidget.cs.meta new file mode 100644 index 0000000..d66e2c9 --- /dev/null +++ b/Editor/Widgets/AllCoilsEnabledEventUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf621aacfaf6b4110bcc52feafa48776 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/AllSwitchesEnabledEventUnitWidget.cs b/Editor/Widgets/AllSwitchesEnabledEventUnitWidget.cs index 5fb459a..3bd4bb5 100644 --- a/Editor/Widgets/AllSwitchesEnabledEventUnitWidget.cs +++ b/Editor/Widgets/AllSwitchesEnabledEventUnitWidget.cs @@ -10,6 +10,7 @@ public sealed class AllSwitchesEnabledEventUnitWidget : GleMultiUnitWidget IdSuggestions(IGamelogicEngine gle) => gle.RequestedSwitches.Select(sw => sw.Id); } } diff --git a/Editor/Widgets/CoilEnabledEventUnitWidget.cs b/Editor/Widgets/CoilEnabledEventUnitWidget.cs new file mode 100644 index 0000000..378d20d --- /dev/null +++ b/Editor/Widgets/CoilEnabledEventUnitWidget.cs @@ -0,0 +1,34 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(CoilEnabledEventUnit))] + public sealed class CoilEnabledEventUnitWidget : GleMultiUnitWidget + { + public CoilEnabledEventUnitWidget(FlowCanvas canvas, CoilEnabledEventUnit unit) : base(canvas, unit) + { + } + + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedCoils.Select(coil => coil.Id); + } +} diff --git a/Editor/Widgets/CoilEnabledEventUnitWidget.cs.meta b/Editor/Widgets/CoilEnabledEventUnitWidget.cs.meta new file mode 100644 index 0000000..bbd55f0 --- /dev/null +++ b/Editor/Widgets/CoilEnabledEventUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6538db966e0994d1ebd1721fd65a9383 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/CoilEventUnitWidget.cs b/Editor/Widgets/CoilEventUnitWidget.cs new file mode 100644 index 0000000..2736b3b --- /dev/null +++ b/Editor/Widgets/CoilEventUnitWidget.cs @@ -0,0 +1,34 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(CoilEventUnit))] + public sealed class CoilEventUnitWidget : GleMultiUnitWidget + { + public CoilEventUnitWidget(FlowCanvas canvas, CoilEventUnit unit) : base(canvas, unit) + { + } + + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedCoils.Select(coil => coil.Id); + } +} diff --git a/Editor/Widgets/CoilEventUnitWidget.cs.meta b/Editor/Widgets/CoilEventUnitWidget.cs.meta new file mode 100644 index 0000000..f9bd8a0 --- /dev/null +++ b/Editor/Widgets/CoilEventUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3ef4988f2d47743e295807077993a949 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/GetCoilUnitWidget.cs b/Editor/Widgets/GetCoilUnitWidget.cs new file mode 100644 index 0000000..787212e --- /dev/null +++ b/Editor/Widgets/GetCoilUnitWidget.cs @@ -0,0 +1,55 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable UnusedType.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.VisualScripting; + +namespace VisualPinball.Unity.VisualScripting.Editor +{ + [Widget(typeof(GetCoilUnit))] + public sealed class GetCoilUnitWidget : GleUnitWidget + { + public GetCoilUnitWidget(FlowCanvas canvas, GetCoilUnit unit) : base(canvas, unit) + { + _coilIdInspectorConstructor = meta => new VariableNameInspector(meta, GetNameSuggestions); + } + + private VariableNameInspector _coilIdInspector; + private readonly Func _coilIdInspectorConstructor; + + public override Inspector GetPortInspector(IUnitPort port, Metadata meta) + { + if (port == unit.Id) { + InspectorProvider.instance.Renew(ref _coilIdInspector, meta, _coilIdInspectorConstructor); + + return _coilIdInspector; + } + + return base.GetPortInspector(port, meta); + } + + private IEnumerable GetNameSuggestions() + { + return !GleAvailable + ? new List() + : Gle.RequestedCoils.Select(coil => coil.Id).ToList(); + } + } +} diff --git a/Editor/Widgets/GetCoilUnitWidget.cs.meta b/Editor/Widgets/GetCoilUnitWidget.cs.meta new file mode 100644 index 0000000..6e41f12 --- /dev/null +++ b/Editor/Widgets/GetCoilUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c1bfda7a60fc04ad79ac234b8458fdeb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/GetSwitchUnitWidget.cs b/Editor/Widgets/GetSwitchUnitWidget.cs index b468469..e570448 100644 --- a/Editor/Widgets/GetSwitchUnitWidget.cs +++ b/Editor/Widgets/GetSwitchUnitWidget.cs @@ -36,8 +36,7 @@ public GetSwitchUnitWidget(FlowCanvas canvas, GetSwitchUnit unit) : base(canvas, public override Inspector GetPortInspector(IUnitPort port, Metadata meta) { - if (port == unit.Id) - { + if (port == unit.Id) { InspectorProvider.instance.Renew(ref _switchIdInspector, meta, _switchIdInspectorConstructor); return _switchIdInspector; diff --git a/Editor/Widgets/SwitchEventUnitWidget.cs b/Editor/Widgets/SwitchEventUnitWidget.cs index 79d5d23..6c59efd 100644 --- a/Editor/Widgets/SwitchEventUnitWidget.cs +++ b/Editor/Widgets/SwitchEventUnitWidget.cs @@ -28,6 +28,7 @@ public sealed class SwitchEventUnitWidget : GleMultiUnitWidget public SwitchEventUnitWidget(FlowCanvas canvas, SwitchEventUnit unit) : base(canvas, unit) { } + protected override IEnumerable IdSuggestions(IGamelogicEngine gle) => gle.RequestedSwitches.Select(sw => sw.Id); } } diff --git a/Runtime/Nodes/Coils/AllCoilsEnabledEventUnit.cs b/Runtime/Nodes/Coils/AllCoilsEnabledEventUnit.cs new file mode 100644 index 0000000..0d083d1 --- /dev/null +++ b/Runtime/Nodes/Coils/AllCoilsEnabledEventUnit.cs @@ -0,0 +1,81 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("On All Coils Enabled")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Events\\Visual Pinball")] + public class AllCoilsEnabledEventUnit : GleEventUnit, IMultiInputUnit + { + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Coil IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } + + [DoNotSerialize] + public ReadOnlyCollection multiInputs { get; private set; } + + [DoNotSerialize] + protected override bool register => true; + + public override EventHook GetHook(GraphReference reference) => new EventHook(VisualScriptingEventNames.CoilEvent); + + protected override void Definition() + { + base.Definition(); + + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); + + for (var i = 0; i < inputCount; i++) { + _multiInputs.Add(ValueInput(i.ToString(), string.Empty)); + } + } + + protected override bool ShouldTrigger(Flow flow, CoilEventArgs args) + { + if (!AssertGle(flow)) { + Debug.LogError("Cannot find GLE."); + return false; + } + + var validCoil = false; + foreach(var input in multiInputs) { + var coilId = flow.GetValue(input); + if (coilId == args.Id) { + validCoil = true; + } + if (!Gle.GetCoil(coilId)) { + return false; + } + } + return validCoil; + } + } +} diff --git a/Runtime/Nodes/Coils/AllCoilsEnabledEventUnit.cs.meta b/Runtime/Nodes/Coils/AllCoilsEnabledEventUnit.cs.meta new file mode 100644 index 0000000..fa6ab1a --- /dev/null +++ b/Runtime/Nodes/Coils/AllCoilsEnabledEventUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ccc99a11751b4d1b949c5e916689974 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Coils/CoilEnabledEventUnit.cs b/Runtime/Nodes/Coils/CoilEnabledEventUnit.cs new file mode 100644 index 0000000..e64fee0 --- /dev/null +++ b/Runtime/Nodes/Coils/CoilEnabledEventUnit.cs @@ -0,0 +1,73 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("On Coil Enabled")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Events\\Visual Pinball")] + public class CoilEnabledEventUnit : GleEventUnit, IMultiInputUnit + { + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Coil IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } + + [DoNotSerialize] + public ReadOnlyCollection multiInputs { get; private set; } + + [DoNotSerialize] + protected override bool register => true; + + // Adding an EventHook with the name of the event to the list of visual scripting events. + public override EventHook GetHook(GraphReference reference) => new EventHook(VisualScriptingEventNames.CoilEvent); + + protected override void Definition() + { + base.Definition(); + + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); + + for (var i = 0; i < inputCount; i++) { + _multiInputs.Add(ValueInput(i.ToString(), string.Empty)); + } + } + + protected override bool ShouldTrigger(Flow flow, CoilEventArgs args) + { + foreach(var input in multiInputs) { + if (flow.GetValue(input) == args.Id && args.IsEnabled) { + return true; + } + } + + return false; + } + } +} diff --git a/Runtime/Nodes/Coils/CoilEnabledEventUnit.cs.meta b/Runtime/Nodes/Coils/CoilEnabledEventUnit.cs.meta new file mode 100644 index 0000000..375a126 --- /dev/null +++ b/Runtime/Nodes/Coils/CoilEnabledEventUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 36a430294a936419187f5dd803769fbf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Coils/CoilEventUnit.cs b/Runtime/Nodes/Coils/CoilEventUnit.cs new file mode 100644 index 0000000..fb1361f --- /dev/null +++ b/Runtime/Nodes/Coils/CoilEventUnit.cs @@ -0,0 +1,86 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("On Coil Changed")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Events\\Visual Pinball")] + public class CoilEventUnit : GleEventUnit, IMultiInputUnit + { + [SerializeAs(nameof(inputCount))] + private int _inputCount = 1; + + [DoNotSerialize] + [Inspectable, UnitHeaderInspectable("Coil IDs")] + public int inputCount + { + get => _inputCount; + set => _inputCount = Mathf.Clamp(value, 1, 10); + } + + [DoNotSerialize] + public ReadOnlyCollection multiInputs { get; private set; } + + [DoNotSerialize] + [PortLabel("Is Enabled")] + public ValueOutput IsEnabled { get; private set; } + + protected override bool register => true; + + // Adding an EventHook with the name of the event to the list of visual scripting events. + public override EventHook GetHook(GraphReference reference) + { + return new EventHook(VisualScriptingEventNames.CoilEvent); + } + + protected override void Definition() + { + base.Definition(); + + var _multiInputs = new List(); + + multiInputs = _multiInputs.AsReadOnly(); + + for (var i = 0; i < inputCount; i++) { + _multiInputs.Add(ValueInput(i.ToString(), string.Empty)); + } + + IsEnabled = ValueOutput(nameof(IsEnabled)); + } + + protected override bool ShouldTrigger(Flow flow, CoilEventArgs args) + { + foreach (var input in multiInputs) { + if (flow.GetValue(input) == args.Id) { + return true; + } + } + + return false; + } + + protected override void AssignArguments(Flow flow, CoilEventArgs args) + { + flow.SetValue(IsEnabled, args.IsEnabled); + } + } +} diff --git a/Runtime/Nodes/Coils/CoilEventUnit.cs.meta b/Runtime/Nodes/Coils/CoilEventUnit.cs.meta new file mode 100644 index 0000000..1f6c98c --- /dev/null +++ b/Runtime/Nodes/Coils/CoilEventUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1741df536aa73483da12f445f839ccc4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/Coils/GetCoilUnit.cs b/Runtime/Nodes/Coils/GetCoilUnit.cs new file mode 100644 index 0000000..5dd27b7 --- /dev/null +++ b/Runtime/Nodes/Coils/GetCoilUnit.cs @@ -0,0 +1,51 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitTitle("Get Coil Value")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Visual Pinball")] + public class GetCoilUnit : GleUnit + { + [DoNotSerialize] + [PortLabel("Coil ID")] + public ValueInput Id { get; private set; } + + [DoNotSerialize] + [PortLabel("Is Enabled")] + public ValueOutput IsEnabled { get; private set; } + + protected override void Definition() + { + Id = ValueInput(nameof(Id), string.Empty); + IsEnabled = ValueOutput(nameof(IsEnabled), GetEnabled); + } + + private bool GetEnabled(Flow flow) + { + if (!AssertGle(flow)) { + Debug.LogError("Cannot find GLE."); + return false; + } + + return Gle.GetCoil(flow.GetValue(Id)); + } + } +} diff --git a/Runtime/Nodes/Coils/GetCoilUnit.cs.meta b/Runtime/Nodes/Coils/GetCoilUnit.cs.meta new file mode 100644 index 0000000..7752012 --- /dev/null +++ b/Runtime/Nodes/Coils/GetCoilUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b17b98dde58b4401a778eb1a28dbfce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: