From 2740810a79ea5a4bcebb18b8202fcb8bc2119998 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Sat, 18 Jun 2022 07:44:12 -0400 Subject: [PATCH 1/6] em: Start to implement EMAddPointsUnit --- .../Descriptors/EMAddPointsUnitDescriptor.cs | 45 ++++++++ .../EMAddPointsUnitDescriptor.cs.meta | 11 ++ Editor/Widgets/EMAddPointsUnitWidget.cs | 33 ++++++ Editor/Widgets/EMAddPointsUnitWidget.cs.meta | 11 ++ Runtime/Nodes/EM.meta | 8 ++ Runtime/Nodes/EM/EMAddPointsUnit.cs | 104 ++++++++++++++++++ Runtime/Nodes/EM/EMAddPointsUnit.cs.meta | 11 ++ 7 files changed, 223 insertions(+) create mode 100644 Editor/Descriptors/EMAddPointsUnitDescriptor.cs create mode 100644 Editor/Descriptors/EMAddPointsUnitDescriptor.cs.meta create mode 100644 Editor/Widgets/EMAddPointsUnitWidget.cs create mode 100644 Editor/Widgets/EMAddPointsUnitWidget.cs.meta create mode 100644 Runtime/Nodes/EM.meta create mode 100644 Runtime/Nodes/EM/EMAddPointsUnit.cs create mode 100644 Runtime/Nodes/EM/EMAddPointsUnit.cs.meta diff --git a/Editor/Descriptors/EMAddPointsUnitDescriptor.cs b/Editor/Descriptors/EMAddPointsUnitDescriptor.cs new file mode 100644 index 0000000..f7b73f2 --- /dev/null +++ b/Editor/Descriptors/EMAddPointsUnitDescriptor.cs @@ -0,0 +1,45 @@ +// 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(EMAddPointsUnit))] + public class EMAddPointsUnitDescriptor : UnitDescriptor + { + public EMAddPointsUnitDescriptor(EMAddPointsUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node adds points for EMs."; + } + + 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) { + } + } + } +} diff --git a/Editor/Descriptors/EMAddPointsUnitDescriptor.cs.meta b/Editor/Descriptors/EMAddPointsUnitDescriptor.cs.meta new file mode 100644 index 0000000..dad0342 --- /dev/null +++ b/Editor/Descriptors/EMAddPointsUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88349127e95cc4b64bb76e45f82a88e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/EMAddPointsUnitWidget.cs b/Editor/Widgets/EMAddPointsUnitWidget.cs new file mode 100644 index 0000000..4c2acc2 --- /dev/null +++ b/Editor/Widgets/EMAddPointsUnitWidget.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(EMAddPointsUnit))] + public sealed class EMAddPointsUnitWidget : GleUnitWidget + { + public EMAddPointsUnitWidget(FlowCanvas canvas, EMAddPointsUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/EMAddPointsUnitWidget.cs.meta b/Editor/Widgets/EMAddPointsUnitWidget.cs.meta new file mode 100644 index 0000000..9f0f456 --- /dev/null +++ b/Editor/Widgets/EMAddPointsUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6659f99df4fbf4ce59b36703a7385e0f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/EM.meta b/Runtime/Nodes/EM.meta new file mode 100644 index 0000000..adb6d56 --- /dev/null +++ b/Runtime/Nodes/EM.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c0f219f0a0a654b79862bd68d18a2228 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/EM/EMAddPointsUnit.cs b/Runtime/Nodes/EM/EMAddPointsUnit.cs new file mode 100644 index 0000000..bbb19ae --- /dev/null +++ b/Runtime/Nodes/EM/EMAddPointsUnit.cs @@ -0,0 +1,104 @@ +// 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; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + /* + * Well, I think the node should be an "EM Add Points" node that would accept a "Point Value" + * and a "Score Motor Value". It would send a signal directly to the point value's score reel + * "coil" if the "Score Motor Value" was set to 0. If the "Score Motor Value" was 1-5 then + * the "Point Value" along with the "Score Motor Value" would be sent to the Score Motor. + * The score motor would then send series of pulsed signals to the "point value's" score reel + * coil equal to the "Score Motor Value." The reels would have to be set up with a 9's + * carry over ability (ie 00190 sent a pulse to the 10's coil would have to pulse the + * 100's coil once to get to 200) If the score motor is in motion then all scores that occur + * during this window need to not be scored (per @bord observations today). + */ + + [UnitShortTitle("EM Add Points")] + [UnitTitle("EM Add Points")] + [UnitSurtitle("Gamelogic Engine")] + [UnitCategory("Visual Pinball")] + public class EMAddPointsUnit : GleUnit + { + [Serialize, Inspectable, UnitHeaderInspectable("ID")] + public DisplayDefinition Display { get; private set; } + + [DoNotSerialize] + public ControlInput InputTrigger; + + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + + [DoNotSerialize] + public ControlOutput tick { get; private set; } + + [DoNotSerialize] + public ValueInput scoreMotor { get; private set; } + + [DoNotSerialize] + public ValueInput pointValue { get; private set; } + + [DoNotSerialize] + public ValueInput duration { get; private set; } + + protected override void Definition() + { + InputTrigger = ControlInputCoroutine(nameof(InputTrigger), Process); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + + tick = ControlOutput(nameof(tick)); + + pointValue = ValueInput(nameof(pointValue), 0); + scoreMotor = ValueInput(nameof(scoreMotor), 0); + + duration = ValueInput(nameof(duration), 0f); + } + + private IEnumerator Process(Flow flow) + { + if (!AssertGle(flow)) + { + Debug.LogError("Cannot find GLE."); + yield return OutputTrigger; + } + + if (!AssertPlayer(flow)) + { + Debug.LogError("Cannot find player."); + yield return OutputTrigger; + } + + var seconds = flow.GetValue(this.duration); + + for (int loop = 0; loop < 5; loop++) + { + yield return new WaitForSeconds(seconds); + + yield return tick; + + Debug.Log($"ITERATION LOOP {loop}"); + } + + yield return OutputTrigger; + } + } +} diff --git a/Runtime/Nodes/EM/EMAddPointsUnit.cs.meta b/Runtime/Nodes/EM/EMAddPointsUnit.cs.meta new file mode 100644 index 0000000..a82bb67 --- /dev/null +++ b/Runtime/Nodes/EM/EMAddPointsUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d673fe77022c74cdf8426b744e12cf9b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 6484e3c57ce3d29cffffc62052848109e21fb328 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Tue, 21 Jun 2022 12:10:50 -0400 Subject: [PATCH 2/6] units: complete em add points unit --- Runtime/Nodes/EM/EMAddPointsUnit.cs | 110 ++++++++++++++++++++-------- 1 file changed, 80 insertions(+), 30 deletions(-) diff --git a/Runtime/Nodes/EM/EMAddPointsUnit.cs b/Runtime/Nodes/EM/EMAddPointsUnit.cs index bbb19ae..2f2f3df 100644 --- a/Runtime/Nodes/EM/EMAddPointsUnit.cs +++ b/Runtime/Nodes/EM/EMAddPointsUnit.cs @@ -37,68 +37,118 @@ namespace VisualPinball.Unity.VisualScripting [UnitSurtitle("Gamelogic Engine")] [UnitCategory("Visual Pinball")] public class EMAddPointsUnit : GleUnit - { - [Serialize, Inspectable, UnitHeaderInspectable("ID")] - public DisplayDefinition Display { get; private set; } + { + private Bool running = false; [DoNotSerialize] + [PortLabelHidden] public ControlInput InputTrigger; [DoNotSerialize] - [PortLabelHidden] - public ControlOutput OutputTrigger; - + public ValueInput duration { get; private set; } + [DoNotSerialize] - public ControlOutput tick { get; private set; } + [PortLabel("Unscaled")] + public ValueInput unscaledTime { get; private set; } [DoNotSerialize] - public ValueInput scoreMotor { get; private set; } + public ControlOutput started; [DoNotSerialize] - public ValueInput pointValue { get; private set; } + public ControlOutput stopped; [DoNotSerialize] - public ValueInput duration { get; private set; } + public ControlOutput pulse { get; private set; } + + [DoNotSerialize] + public ValueInput pointValue { get; private set; } + + [DoNotSerialize, PortLabel("Point Value"), Inspectable] + public ValueOutput OutputPointValue { get; private set; } protected override void Definition() { InputTrigger = ControlInputCoroutine(nameof(InputTrigger), Process); - OutputTrigger = ControlOutput(nameof(OutputTrigger)); - - tick = ControlOutput(nameof(tick)); pointValue = ValueInput(nameof(pointValue), 0); - scoreMotor = ValueInput(nameof(scoreMotor), 0); - duration = ValueInput(nameof(duration), 0f); + duration = ValueInput(nameof(duration), .750f); + unscaledTime = ValueInput(nameof(unscaledTime), false); + + started = ControlOutput(nameof(started)); + stopped = ControlOutput(nameof(stopped)); + + pulse = ControlOutput(nameof(pulse)); + + OutputPointValue = ValueOutput(nameof(OutputPointValue)); } private IEnumerator Process(Flow flow) { - if (!AssertGle(flow)) - { + if (!AssertGle(flow)) { Debug.LogError("Cannot find GLE."); - yield return OutputTrigger; - } - if (!AssertPlayer(flow)) - { + yield return null; + } + else if (!AssertPlayer(flow)) { Debug.LogError("Cannot find player."); - yield return OutputTrigger; + + yield return null; } + else if (running) { + var points = flow.GetValue(pointValue); - var seconds = flow.GetValue(this.duration); + Debug.Log($"Score motor is already running. Ignoring {points} point(s)."); - for (int loop = 0; loop < 5; loop++) - { - yield return new WaitForSeconds(seconds); + yield return null; + } + else { + Debug.Log("Starting score motor"); - yield return tick; + yield return started; - Debug.Log($"ITERATION LOOP {loop}"); - } + running = true; + + var points = flow.GetValue(pointValue); + + var pulses = + (points % 100000 == 0) ? points / 100000 : + (points % 10000 == 0) ? points / 10000 : + (points % 1000 == 0) ? points / 1000 : + (points % 100 == 0) ? points / 100 : + (points % 10 == 0) ? points / 10 : + points; + + var pointsPerPulse = points / pulses; + + flow.SetValue(OutputPointValue, pointsPerPulse); + + var seconds = flow.GetValue(duration) / 6; + var realtime = flow.GetValue(unscaledTime); + + for (int loop = 0; loop < 6; loop++) { + Debug.Log($"Waiting {seconds}s. ({loop + 1} of 6)"); + + if (realtime) { + yield return new WaitForSecondsRealtime(seconds); + } + else { + yield return new WaitForSeconds(seconds); + } + + if (loop < pulses) { + Debug.Log($"Performing {pointsPerPulse} point(s) pulse. ({loop + 1} of {pulses})"); + + yield return pulse; + } + } + + Debug.Log("Stopping score motor"); - yield return OutputTrigger; + running = false; + + yield return stopped; + } } } } From 858f5788f87dabd01dc04160e2e8d83147feb08c Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Tue, 28 Jun 2022 19:25:36 -0400 Subject: [PATCH 3/6] em: Add ResetPoints Unit --- .../Descriptors/EMAddPointsUnitDescriptor.cs | 5 +- .../EMResetPointsUnitDescriptor.cs | 46 +++++ .../EMResetPointsUnitDescriptor.cs.meta | 11 ++ Editor/Widgets/EMAddPointsUnitWidget.cs | 3 - Editor/Widgets/EMResetPointsUnitWidget.cs | 30 ++++ .../Widgets/EMResetPointsUnitWidget.cs.meta | 11 ++ Runtime/Nodes/EM/EMAddPointsUnit.cs | 44 ++--- Runtime/Nodes/EM/EMResetPointsUnit.cs | 163 ++++++++++++++++++ Runtime/Nodes/EM/EMResetPointsUnit.cs.meta | 11 ++ 9 files changed, 285 insertions(+), 39 deletions(-) create mode 100644 Editor/Descriptors/EMResetPointsUnitDescriptor.cs create mode 100644 Editor/Descriptors/EMResetPointsUnitDescriptor.cs.meta create mode 100644 Editor/Widgets/EMResetPointsUnitWidget.cs create mode 100644 Editor/Widgets/EMResetPointsUnitWidget.cs.meta create mode 100644 Runtime/Nodes/EM/EMResetPointsUnit.cs create mode 100644 Runtime/Nodes/EM/EMResetPointsUnit.cs.meta diff --git a/Editor/Descriptors/EMAddPointsUnitDescriptor.cs b/Editor/Descriptors/EMAddPointsUnitDescriptor.cs index f7b73f2..fa52a58 100644 --- a/Editor/Descriptors/EMAddPointsUnitDescriptor.cs +++ b/Editor/Descriptors/EMAddPointsUnitDescriptor.cs @@ -29,10 +29,11 @@ public EMAddPointsUnitDescriptor(EMAddPointsUnit target) : base(target) protected override string DefinedSummary() { - return "This node adds points for EMs."; + return "This node takes an incoming point value and pulses values to that can be used to simulate adding points to a score reel. " + + "For example, an incoming point value of 500 will provide 5 pulses of 100."; } - protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.PlayerVariable); + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Mech(Unity.Editor.IconSize.Large, Unity.Editor.IconColor.Orange)); protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) { diff --git a/Editor/Descriptors/EMResetPointsUnitDescriptor.cs b/Editor/Descriptors/EMResetPointsUnitDescriptor.cs new file mode 100644 index 0000000..7b49eea --- /dev/null +++ b/Editor/Descriptors/EMResetPointsUnitDescriptor.cs @@ -0,0 +1,46 @@ +// 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(EMResetPointsUnit))] + public class EMResetPointsUnitDescriptor : UnitDescriptor + { + public EMResetPointsUnitDescriptor(EMResetPointsUnit target) : base(target) + { + } + + protected override string DefinedSummary() + { + return "This node takes an incoming point value and pulses values to that can be used to simulate the resetting of a score reel. " + + "For example, an incoming point value of 2041 will provide the following pulses: 3052, 4063, 5074, 6085, 7096, 8007, 9008, 0009, 0000"; + } + + protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Mech(Unity.Editor.IconSize.Large, Unity.Editor.IconColor.Orange)); + + protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) + { + base.DefinedPort(port, desc); + + switch (port.key) { + } + } + } +} diff --git a/Editor/Descriptors/EMResetPointsUnitDescriptor.cs.meta b/Editor/Descriptors/EMResetPointsUnitDescriptor.cs.meta new file mode 100644 index 0000000..58f710d --- /dev/null +++ b/Editor/Descriptors/EMResetPointsUnitDescriptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e5a9f36c94e9543139b6f68c1b0faf5e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Widgets/EMAddPointsUnitWidget.cs b/Editor/Widgets/EMAddPointsUnitWidget.cs index 4c2acc2..7dc60bd 100644 --- a/Editor/Widgets/EMAddPointsUnitWidget.cs +++ b/Editor/Widgets/EMAddPointsUnitWidget.cs @@ -16,9 +16,6 @@ // ReSharper disable UnusedType.Global -using System; -using System.Collections.Generic; -using System.Linq; using Unity.VisualScripting; namespace VisualPinball.Unity.VisualScripting.Editor diff --git a/Editor/Widgets/EMResetPointsUnitWidget.cs b/Editor/Widgets/EMResetPointsUnitWidget.cs new file mode 100644 index 0000000..9462d10 --- /dev/null +++ b/Editor/Widgets/EMResetPointsUnitWidget.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(EMResetPointsUnit))] + public sealed class EMResetPointsUnitWidget : GleUnitWidget + { + public EMResetPointsUnitWidget(FlowCanvas canvas, EMResetPointsUnit unit) : base(canvas, unit) + { + } + } +} diff --git a/Editor/Widgets/EMResetPointsUnitWidget.cs.meta b/Editor/Widgets/EMResetPointsUnitWidget.cs.meta new file mode 100644 index 0000000..a366979 --- /dev/null +++ b/Editor/Widgets/EMResetPointsUnitWidget.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 71cb8e09a554f4b1aa91d7d87bea76ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Nodes/EM/EMAddPointsUnit.cs b/Runtime/Nodes/EM/EMAddPointsUnit.cs index 2f2f3df..cd63fdf 100644 --- a/Runtime/Nodes/EM/EMAddPointsUnit.cs +++ b/Runtime/Nodes/EM/EMAddPointsUnit.cs @@ -20,26 +20,12 @@ namespace VisualPinball.Unity.VisualScripting { - /* - * Well, I think the node should be an "EM Add Points" node that would accept a "Point Value" - * and a "Score Motor Value". It would send a signal directly to the point value's score reel - * "coil" if the "Score Motor Value" was set to 0. If the "Score Motor Value" was 1-5 then - * the "Point Value" along with the "Score Motor Value" would be sent to the Score Motor. - * The score motor would then send series of pulsed signals to the "point value's" score reel - * coil equal to the "Score Motor Value." The reels would have to be set up with a 9's - * carry over ability (ie 00190 sent a pulse to the 10's coil would have to pulse the - * 100's coil once to get to 200) If the score motor is in motion then all scores that occur - * during this window need to not be scored (per @bord observations today). - */ - [UnitShortTitle("EM Add Points")] [UnitTitle("EM Add Points")] - [UnitSurtitle("Gamelogic Engine")] - [UnitCategory("Visual Pinball")] + [UnitSurtitle("EM")] + [UnitCategory("Visual Pinball/EM")] public class EMAddPointsUnit : GleUnit { - private Bool running = false; - [DoNotSerialize] [PortLabelHidden] public ControlInput InputTrigger; @@ -66,6 +52,8 @@ public class EMAddPointsUnit : GleUnit [DoNotSerialize, PortLabel("Point Value"), Inspectable] public ValueOutput OutputPointValue { get; private set; } + private Bool running = false; + protected override void Definition() { InputTrigger = ControlInputCoroutine(nameof(InputTrigger), Process); @@ -85,17 +73,7 @@ protected override void Definition() private IEnumerator Process(Flow flow) { - if (!AssertGle(flow)) { - Debug.LogError("Cannot find GLE."); - - yield return null; - } - else if (!AssertPlayer(flow)) { - Debug.LogError("Cannot find player."); - - yield return null; - } - else if (running) { + if (running) { var points = flow.GetValue(pointValue); Debug.Log($"Score motor is already running. Ignoring {points} point(s)."); @@ -121,13 +99,13 @@ private IEnumerator Process(Flow flow) var pointsPerPulse = points / pulses; - flow.SetValue(OutputPointValue, pointsPerPulse); - var seconds = flow.GetValue(duration) / 6; var realtime = flow.GetValue(unscaledTime); for (int loop = 0; loop < 6; loop++) { - Debug.Log($"Waiting {seconds}s. ({loop + 1} of 6)"); + var outputPoints = loop < pulses ? pointsPerPulse : 0; + + Debug.Log($"Pulse {loop + 1} of 6 - waiting {seconds} and triggering with {outputPoints} points"); if (realtime) { yield return new WaitForSecondsRealtime(seconds); @@ -136,11 +114,9 @@ private IEnumerator Process(Flow flow) yield return new WaitForSeconds(seconds); } - if (loop < pulses) { - Debug.Log($"Performing {pointsPerPulse} point(s) pulse. ({loop + 1} of {pulses})"); + flow.SetValue(OutputPointValue, outputPoints); - yield return pulse; - } + yield return pulse; } Debug.Log("Stopping score motor"); diff --git a/Runtime/Nodes/EM/EMResetPointsUnit.cs b/Runtime/Nodes/EM/EMResetPointsUnit.cs new file mode 100644 index 0000000..4cd07f6 --- /dev/null +++ b/Runtime/Nodes/EM/EMResetPointsUnit.cs @@ -0,0 +1,163 @@ +// 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; +using Unity.VisualScripting; +using UnityEngine; + +namespace VisualPinball.Unity.VisualScripting +{ + [UnitShortTitle("EM Reset Points")] + [UnitTitle("EM Reset Points")] + [UnitSurtitle("EM")] + [UnitCategory("Visual Pinball/EM")] + public class EMResetPointsUnit : GleUnit + { + [DoNotSerialize] + [PortLabelHidden] + public ControlInput InputTrigger; + + [DoNotSerialize] + public ValueInput duration { get; private set; } + + [DoNotSerialize] + [PortLabel("Unscaled")] + public ValueInput unscaledTime { get; private set; } + + [DoNotSerialize] + public ControlOutput started; + + [DoNotSerialize] + public ControlOutput stopped; + + [DoNotSerialize] + public ControlOutput pulse { get; private set; } + + [DoNotSerialize] + public ValueInput pointValue { get; private set; } + + [DoNotSerialize, PortLabel("Point Value"), Inspectable] + public ValueOutput OutputPointValue { get; private set; } + + private Bool running = false; + + protected override void Definition() + { + InputTrigger = ControlInputCoroutine(nameof(InputTrigger), Process); + + pointValue = ValueInput(nameof(pointValue), 0); + + duration = ValueInput(nameof(duration), .750f); + unscaledTime = ValueInput(nameof(unscaledTime), false); + + started = ControlOutput(nameof(started)); + stopped = ControlOutput(nameof(stopped)); + + pulse = ControlOutput(nameof(pulse)); + + OutputPointValue = ValueOutput(nameof(OutputPointValue)); + } + + private IEnumerator Process(Flow flow) + { + if (running) { + var points = flow.GetValue(pointValue); + + Debug.Log($"Score motor is already running. Ignoring {points} point(s)."); + + yield return null; + } + else { + Debug.Log("Starting score motor"); + + yield return started; + + running = true; + + var points = flow.GetValue(pointValue); + + var seconds = flow.GetValue(duration) / 6; + var realtime = flow.GetValue(unscaledTime); + + while (points > 0) { + for (int loop = 0; loop < 6; loop++) { + points = AdvancePoints(points); + + Debug.Log($"Pulse {loop + 1} of 6 - waiting {seconds} and triggering with {points} points"); + + if (realtime) { + yield return new WaitForSecondsRealtime(seconds); + } + else { + yield return new WaitForSeconds(seconds); + } + + flow.SetValue(OutputPointValue, points); + + yield return pulse; + } + } + + Debug.Log("Stopping score motor"); + + running = false; + + yield return stopped; + } + } + + private static int NumDigits(int n) + { + if (n < 0) + { + n = n == int.MinValue ? int.MaxValue : -n; + } + return n switch + { + < 10 => 1, + < 100 => 2, + < 1000 => 3, + < 10000 => 4, + < 100000 => 5, + < 1000000 => 6, + < 10000000 => 7, + < 100000000 => 8, + < 1000000000 => 9, + _ => 10 + }; + } + + private static int[] DigitArr(int n) + { + var result = new int[NumDigits(n)]; + for (var i = result.Length - 1; i >= 0; i--) { + result[i] = n % 10; + n /= 10; + } + return result; + } + + private static int AdvancePoints(int points) { + var value = 0; + + foreach (var i in DigitArr(points)) { + value = (value * 10) + ((i > 0 && i < 9) ? (i + 1) : 0); + } + + return value; + } + } +} diff --git a/Runtime/Nodes/EM/EMResetPointsUnit.cs.meta b/Runtime/Nodes/EM/EMResetPointsUnit.cs.meta new file mode 100644 index 0000000..dc8aca3 --- /dev/null +++ b/Runtime/Nodes/EM/EMResetPointsUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 37d591d7c9d694b89a42a1ff9ce2545f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 944eb6ecc70956887bdc18439208416fb7135431 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Tue, 28 Jun 2022 22:13:31 -0400 Subject: [PATCH 4/6] misc: clean up unit descriptors for new EM units --- .../Descriptors/EMAddPointsUnitDescriptor.cs | 25 ++++++++++++++++++- .../EMResetPointsUnitDescriptor.cs | 25 ++++++++++++++++++- Runtime/Nodes/EM/EMAddPointsUnit.cs | 3 ++- Runtime/Nodes/EM/EMResetPointsUnit.cs | 3 ++- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/Editor/Descriptors/EMAddPointsUnitDescriptor.cs b/Editor/Descriptors/EMAddPointsUnitDescriptor.cs index fa52a58..363bf0f 100644 --- a/Editor/Descriptors/EMAddPointsUnitDescriptor.cs +++ b/Editor/Descriptors/EMAddPointsUnitDescriptor.cs @@ -30,7 +30,7 @@ public EMAddPointsUnitDescriptor(EMAddPointsUnit target) : base(target) protected override string DefinedSummary() { return "This node takes an incoming point value and pulses values to that can be used to simulate adding points to a score reel. " - + "For example, an incoming point value of 500 will provide 5 pulses of 100."; + + "\n\nFor example, an incoming point value of 500 will provide 5 pulses of 100."; } protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Mech(Unity.Editor.IconSize.Large, Unity.Editor.IconColor.Orange)); @@ -40,6 +40,29 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { + case nameof(EMAddPointsUnit.pointValue): + desc.summary = "The total amount of points to add."; + break; + + case nameof(EMAddPointsUnit.duration): + desc.summary = "The amount of time (in ms) the score motor runs."; + break; + + case nameof(EMAddPointsUnit.started): + desc.summary = "Triggered when score motor starts."; + break; + + case nameof(EMAddPointsUnit.stopped): + desc.summary = "Triggered when score motor finishes."; + break; + + case nameof(EMAddPointsUnit.pulse): + desc.summary = "Triggered during each pulse of the score motor."; + break; + + case nameof(EMAddPointsUnit.OutputPointValue): + desc.summary = "The current pulses calculated points value that can be used to increment a score value and update a score reel."; + break; } } } diff --git a/Editor/Descriptors/EMResetPointsUnitDescriptor.cs b/Editor/Descriptors/EMResetPointsUnitDescriptor.cs index 7b49eea..73bf48e 100644 --- a/Editor/Descriptors/EMResetPointsUnitDescriptor.cs +++ b/Editor/Descriptors/EMResetPointsUnitDescriptor.cs @@ -30,7 +30,7 @@ public EMResetPointsUnitDescriptor(EMResetPointsUnit target) : base(target) protected override string DefinedSummary() { return "This node takes an incoming point value and pulses values to that can be used to simulate the resetting of a score reel. " - + "For example, an incoming point value of 2041 will provide the following pulses: 3052, 4063, 5074, 6085, 7096, 8007, 9008, 0009, 0000"; + + "\n\nFor example, an incoming point value of 2041 will provide the following pulses: 3052, 4063, 5074, 6085, 7096, 8007, 9008, 0009, 0000"; } protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Mech(Unity.Editor.IconSize.Large, Unity.Editor.IconColor.Orange)); @@ -40,6 +40,29 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) base.DefinedPort(port, desc); switch (port.key) { + case nameof(EMResetPointsUnit.pointValue): + desc.summary = "The starting points value used to seed the reset sequence."; + break; + + case nameof(EMResetPointsUnit.duration): + desc.summary = "The amount of time (in ms) the score motor runs."; + break; + + case nameof(EMResetPointsUnit.started): + desc.summary = "Triggered when score motor starts."; + break; + + case nameof(EMResetPointsUnit.stopped): + desc.summary = "Triggered when score motor finishes."; + break; + + case nameof(EMResetPointsUnit.pulse): + desc.summary = "Triggered during each pulse of the score motor."; + break; + + case nameof(EMResetPointsUnit.OutputPointValue): + desc.summary = "The current pulses calculated points value that can be used to update a score reel."; + break; } } } diff --git a/Runtime/Nodes/EM/EMAddPointsUnit.cs b/Runtime/Nodes/EM/EMAddPointsUnit.cs index cd63fdf..80c8e30 100644 --- a/Runtime/Nodes/EM/EMAddPointsUnit.cs +++ b/Runtime/Nodes/EM/EMAddPointsUnit.cs @@ -49,7 +49,8 @@ public class EMAddPointsUnit : GleUnit [DoNotSerialize] public ValueInput pointValue { get; private set; } - [DoNotSerialize, PortLabel("Point Value"), Inspectable] + [DoNotSerialize] + [PortLabel("Point Value")] public ValueOutput OutputPointValue { get; private set; } private Bool running = false; diff --git a/Runtime/Nodes/EM/EMResetPointsUnit.cs b/Runtime/Nodes/EM/EMResetPointsUnit.cs index 4cd07f6..b1c9971 100644 --- a/Runtime/Nodes/EM/EMResetPointsUnit.cs +++ b/Runtime/Nodes/EM/EMResetPointsUnit.cs @@ -49,7 +49,8 @@ public class EMResetPointsUnit : GleUnit [DoNotSerialize] public ValueInput pointValue { get; private set; } - [DoNotSerialize, PortLabel("Point Value"), Inspectable] + [DoNotSerialize] + [PortLabel("Point Value")] public ValueOutput OutputPointValue { get; private set; } private Bool running = false; From 59d9d1085cd0993e9348708665c2a6d84d9ec5eb Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Thu, 30 Jun 2022 22:54:02 -0400 Subject: [PATCH 5/6] em: add block, positions, and global score motor running --- .../Descriptors/EMAddPointsUnitDescriptor.cs | 8 ++ Runtime/Nodes/EM/EMAddPointsUnit.cs | 96 ++++++++++++------- 2 files changed, 72 insertions(+), 32 deletions(-) diff --git a/Editor/Descriptors/EMAddPointsUnitDescriptor.cs b/Editor/Descriptors/EMAddPointsUnitDescriptor.cs index 363bf0f..66d23e7 100644 --- a/Editor/Descriptors/EMAddPointsUnitDescriptor.cs +++ b/Editor/Descriptors/EMAddPointsUnitDescriptor.cs @@ -44,6 +44,14 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) desc.summary = "The total amount of points to add."; break; + case nameof(EMAddPointsUnit.blockPoints): + desc.summary = "Block single pulse points when score motor running."; + break; + + case nameof(EMAddPointsUnit.positions): + desc.summary = "Score motor positions."; + break; + case nameof(EMAddPointsUnit.duration): desc.summary = "The amount of time (in ms) the score motor runs."; break; diff --git a/Runtime/Nodes/EM/EMAddPointsUnit.cs b/Runtime/Nodes/EM/EMAddPointsUnit.cs index 80c8e30..a63192c 100644 --- a/Runtime/Nodes/EM/EMAddPointsUnit.cs +++ b/Runtime/Nodes/EM/EMAddPointsUnit.cs @@ -30,6 +30,12 @@ public class EMAddPointsUnit : GleUnit [PortLabelHidden] public ControlInput InputTrigger; + [DoNotSerialize] + public ValueInput blockPoints { get; private set; } + + [DoNotSerialize] + public ValueInput positions { get; private set; } + [DoNotSerialize] public ValueInput duration { get; private set; } @@ -37,6 +43,10 @@ public class EMAddPointsUnit : GleUnit [PortLabel("Unscaled")] public ValueInput unscaledTime { get; private set; } + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + [DoNotSerialize] public ControlOutput started; @@ -53,7 +63,7 @@ public class EMAddPointsUnit : GleUnit [PortLabel("Point Value")] public ValueOutput OutputPointValue { get; private set; } - private Bool running = false; + private static string VARIABLE_EM_SCORE_MOTOR = "EM_SCORE_MOTOR"; protected override void Definition() { @@ -61,9 +71,13 @@ protected override void Definition() pointValue = ValueInput(nameof(pointValue), 0); - duration = ValueInput(nameof(duration), .750f); + blockPoints = ValueInput(nameof(blockPoints), true); + positions = ValueInput(nameof(positions), 6); + duration = ValueInput(nameof(duration), 750); unscaledTime = ValueInput(nameof(unscaledTime), false); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + started = ControlOutput(nameof(started)); stopped = ControlOutput(nameof(stopped)); @@ -74,22 +88,17 @@ protected override void Definition() private IEnumerator Process(Flow flow) { - if (running) { - var points = flow.GetValue(pointValue); + var running = false; - Debug.Log($"Score motor is already running. Ignoring {points} point(s)."); - - yield return null; + if (Variables.Application.IsDefined(VARIABLE_EM_SCORE_MOTOR)) { + running = Variables.Application.Get(VARIABLE_EM_SCORE_MOTOR); } - else { - Debug.Log("Starting score motor"); - - yield return started; - running = true; + yield return OutputTrigger; - var points = flow.GetValue(pointValue); + var points = flow.GetValue(pointValue); + if (points > 0) { var pulses = (points % 100000 == 0) ? points / 100000 : (points % 10000 == 0) ? points / 10000 : @@ -98,34 +107,57 @@ private IEnumerator Process(Flow flow) (points % 10 == 0) ? points / 10 : points; - var pointsPerPulse = points / pulses; + if (pulses == 1) { + if (!running || (running && !flow.GetValue(blockPoints))) { + Debug.Log($"Single pulse triggering with {points} points"); - var seconds = flow.GetValue(duration) / 6; - var realtime = flow.GetValue(unscaledTime); + flow.SetValue(OutputPointValue, points); - for (int loop = 0; loop < 6; loop++) { - var outputPoints = loop < pulses ? pointsPerPulse : 0; + yield return pulse; + } + } + else if (running) + { + Debug.Log($"Score motor is already running."); + } + else { + Debug.Log("Starting score motor"); - Debug.Log($"Pulse {loop + 1} of 6 - waiting {seconds} and triggering with {outputPoints} points"); + Variables.Application.Set(VARIABLE_EM_SCORE_MOTOR, true); + + yield return started; - if (realtime) { - yield return new WaitForSecondsRealtime(seconds); - } - else { - yield return new WaitForSeconds(seconds); - } + var motorPositions = flow.GetValue(positions); + + var delay = (flow.GetValue(duration) / 1000f) / motorPositions; + var realtime = flow.GetValue(unscaledTime); + + var pointsPerPulse = points / pulses; - flow.SetValue(OutputPointValue, outputPoints); + for (int loop = 0; loop < motorPositions; loop++) { + var outputPoints = loop < pulses ? pointsPerPulse : 0; - yield return pulse; - } + Debug.Log($"Pulse {loop + 1} of {motorPositions} - waiting {delay}ms and triggering with {outputPoints} points"); + + if (realtime) { + yield return new WaitForSecondsRealtime(delay); + } + else { + yield return new WaitForSeconds(delay); + } + + flow.SetValue(OutputPointValue, outputPoints); + + yield return pulse; + } - Debug.Log("Stopping score motor"); + Debug.Log("Stopping score motor"); - running = false; + Variables.Application.Set(VARIABLE_EM_SCORE_MOTOR, false); - yield return stopped; - } + yield return stopped; + } + } } } } From bcfb0a382939b90b551ef5a2d766afb2376943ba Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Fri, 1 Jul 2022 07:44:34 -0400 Subject: [PATCH 6/6] misc: misc clean up. Use dynamic table variable for Score Motor status. --- .../Descriptors/EMAddPointsUnitDescriptor.cs | 3 +- .../EMResetPointsUnitDescriptor.cs | 4 + Runtime/Gamelogic/State.cs | 2 + Runtime/Nodes/EM/EMAddPointsUnit.cs | 105 ++++++++++-------- Runtime/Nodes/EM/EMResetPointsUnit.cs | 91 +++++++++------ 5 files changed, 122 insertions(+), 83 deletions(-) diff --git a/Editor/Descriptors/EMAddPointsUnitDescriptor.cs b/Editor/Descriptors/EMAddPointsUnitDescriptor.cs index 66d23e7..9d4966b 100644 --- a/Editor/Descriptors/EMAddPointsUnitDescriptor.cs +++ b/Editor/Descriptors/EMAddPointsUnitDescriptor.cs @@ -30,7 +30,8 @@ public EMAddPointsUnitDescriptor(EMAddPointsUnit target) : base(target) protected override string DefinedSummary() { return "This node takes an incoming point value and pulses values to that can be used to simulate adding points to a score reel. " - + "\n\nFor example, an incoming point value of 500 will provide 5 pulses of 100."; + + "\n\nFor example, an incoming point value of 500 will provide 5 pulses of 100. " + + "\n\nSingle pulse points (1, 10, 100, 1000, 10000) will be blocked if the score motor is running and Block Points is enabled."; } protected override EditorTexture DefinedIcon() => EditorTexture.Single(Unity.Editor.Icons.Mech(Unity.Editor.IconSize.Large, Unity.Editor.IconColor.Orange)); diff --git a/Editor/Descriptors/EMResetPointsUnitDescriptor.cs b/Editor/Descriptors/EMResetPointsUnitDescriptor.cs index 73bf48e..c62cee2 100644 --- a/Editor/Descriptors/EMResetPointsUnitDescriptor.cs +++ b/Editor/Descriptors/EMResetPointsUnitDescriptor.cs @@ -48,6 +48,10 @@ protected override void DefinedPort(IUnitPort port, UnitPortDescription desc) desc.summary = "The amount of time (in ms) the score motor runs."; break; + case nameof(EMAddPointsUnit.positions): + desc.summary = "Score motor positions."; + break; + case nameof(EMResetPointsUnit.started): desc.summary = "Triggered when score motor starts."; break; diff --git a/Runtime/Gamelogic/State.cs b/Runtime/Gamelogic/State.cs index 3663421..df7084d 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 bool IsDefined(string variableId) => _variables.ContainsKey(variableId); + public StateVariable GetVariable(string variableId) => _variables[variableId]; public object Get(string variableId) diff --git a/Runtime/Nodes/EM/EMAddPointsUnit.cs b/Runtime/Nodes/EM/EMAddPointsUnit.cs index a63192c..5ad1395 100644 --- a/Runtime/Nodes/EM/EMAddPointsUnit.cs +++ b/Runtime/Nodes/EM/EMAddPointsUnit.cs @@ -63,6 +63,7 @@ public class EMAddPointsUnit : GleUnit [PortLabel("Point Value")] public ValueOutput OutputPointValue { get; private set; } + private State State => VsGle.TableState; private static string VARIABLE_EM_SCORE_MOTOR = "EM_SCORE_MOTOR"; protected override void Definition() @@ -88,75 +89,81 @@ protected override void Definition() private IEnumerator Process(Flow flow) { - var running = false; - - if (Variables.Application.IsDefined(VARIABLE_EM_SCORE_MOTOR)) { - running = Variables.Application.Get(VARIABLE_EM_SCORE_MOTOR); + if (!AssertVsGle(flow)) { + yield return OutputTrigger; } + else { + var running = false; - yield return OutputTrigger; - - var points = flow.GetValue(pointValue); + if (State.IsDefined(VARIABLE_EM_SCORE_MOTOR)) { + running = State.Get(VARIABLE_EM_SCORE_MOTOR); + } + else { + State.AddProperty(new StateVariable(VARIABLE_EM_SCORE_MOTOR, "", false)); + } + + var points = flow.GetValue(pointValue); - if (points > 0) { - var pulses = - (points % 100000 == 0) ? points / 100000 : - (points % 10000 == 0) ? points / 10000 : - (points % 1000 == 0) ? points / 1000 : - (points % 100 == 0) ? points / 100 : - (points % 10 == 0) ? points / 10 : - points; + if (points > 0) { + var pulses = + (points % 100000 == 0) ? points / 100000 : + (points % 10000 == 0) ? points / 10000 : + (points % 1000 == 0) ? points / 1000 : + (points % 100 == 0) ? points / 100 : + (points % 10 == 0) ? points / 10 : + points; - if (pulses == 1) { - if (!running || (running && !flow.GetValue(blockPoints))) { - Debug.Log($"Single pulse triggering with {points} points"); + if (pulses == 1) { + if (!running || (running && !flow.GetValue(blockPoints))) { + Debug.Log($"Single pulse triggering with {points} points"); - flow.SetValue(OutputPointValue, points); + flow.SetValue(OutputPointValue, points); - yield return pulse; + yield return pulse; + } } - } - else if (running) - { - Debug.Log($"Score motor is already running."); - } - else { - Debug.Log("Starting score motor"); + else if (running) { + Debug.Log($"Score motor is already running."); + } + else { + Debug.Log("Starting score motor"); - Variables.Application.Set(VARIABLE_EM_SCORE_MOTOR, true); - - yield return started; + State.Set(VARIABLE_EM_SCORE_MOTOR, true); - var motorPositions = flow.GetValue(positions); + yield return started; - var delay = (flow.GetValue(duration) / 1000f) / motorPositions; - var realtime = flow.GetValue(unscaledTime); + var motorPositions = flow.GetValue(positions); - var pointsPerPulse = points / pulses; + var delay = (flow.GetValue(duration) / 1000f) / motorPositions; + var realtime = flow.GetValue(unscaledTime); - for (int loop = 0; loop < motorPositions; loop++) { - var outputPoints = loop < pulses ? pointsPerPulse : 0; + var pointsPerPulse = points / pulses; - Debug.Log($"Pulse {loop + 1} of {motorPositions} - waiting {delay}ms and triggering with {outputPoints} points"); + for (int loop = 0; loop < motorPositions; loop++) { + var outputPoints = loop < pulses ? pointsPerPulse : 0; - if (realtime) { - yield return new WaitForSecondsRealtime(delay); - } - else { - yield return new WaitForSeconds(delay); - } + Debug.Log($"Pulse {loop + 1} of {motorPositions} - waiting {delay}ms and triggering with {outputPoints} points"); - flow.SetValue(OutputPointValue, outputPoints); + if (realtime) { + yield return new WaitForSecondsRealtime(delay); + } + else { + yield return new WaitForSeconds(delay); + } - yield return pulse; - } + flow.SetValue(OutputPointValue, outputPoints); + + yield return pulse; + } - Debug.Log("Stopping score motor"); + Debug.Log("Stopping score motor"); - Variables.Application.Set(VARIABLE_EM_SCORE_MOTOR, false); + State.Set(VARIABLE_EM_SCORE_MOTOR, false); - yield return stopped; + yield return stopped; + } } + } } } diff --git a/Runtime/Nodes/EM/EMResetPointsUnit.cs b/Runtime/Nodes/EM/EMResetPointsUnit.cs index b1c9971..f150c88 100644 --- a/Runtime/Nodes/EM/EMResetPointsUnit.cs +++ b/Runtime/Nodes/EM/EMResetPointsUnit.cs @@ -33,10 +33,17 @@ public class EMResetPointsUnit : GleUnit [DoNotSerialize] public ValueInput duration { get; private set; } + [DoNotSerialize] + public ValueInput positions { get; private set; } + [DoNotSerialize] [PortLabel("Unscaled")] public ValueInput unscaledTime { get; private set; } + [DoNotSerialize] + [PortLabelHidden] + public ControlOutput OutputTrigger; + [DoNotSerialize] public ControlOutput started; @@ -53,7 +60,8 @@ public class EMResetPointsUnit : GleUnit [PortLabel("Point Value")] public ValueOutput OutputPointValue { get; private set; } - private Bool running = false; + private State State => VsGle.TableState; + private static string VARIABLE_EM_SCORE_MOTOR = "EM_SCORE_MOTOR"; protected override void Definition() { @@ -61,9 +69,12 @@ protected override void Definition() pointValue = ValueInput(nameof(pointValue), 0); - duration = ValueInput(nameof(duration), .750f); + positions = ValueInput(nameof(positions), 6); + duration = ValueInput(nameof(duration), 750); unscaledTime = ValueInput(nameof(unscaledTime), false); + OutputTrigger = ControlOutput(nameof(OutputTrigger)); + started = ControlOutput(nameof(started)); stopped = ControlOutput(nameof(stopped)); @@ -74,49 +85,63 @@ protected override void Definition() private IEnumerator Process(Flow flow) { - if (running) { - var points = flow.GetValue(pointValue); - - Debug.Log($"Score motor is already running. Ignoring {points} point(s)."); - - yield return null; + if (!AssertVsGle(flow)) { + yield return OutputTrigger; } else { - Debug.Log("Starting score motor"); + yield return OutputTrigger; + + var running = false; - yield return started; + if (State.IsDefined(VARIABLE_EM_SCORE_MOTOR)) { + running = State.Get(VARIABLE_EM_SCORE_MOTOR); + } + else { + State.AddProperty(new StateVariable(VARIABLE_EM_SCORE_MOTOR, "", false)); + } - running = true; + if (running) { + Debug.Log($"Score motor is already running."); + } + else { + Debug.Log("Starting score motor"); - var points = flow.GetValue(pointValue); + State.Set(VARIABLE_EM_SCORE_MOTOR, true); - var seconds = flow.GetValue(duration) / 6; - var realtime = flow.GetValue(unscaledTime); + yield return started; - while (points > 0) { - for (int loop = 0; loop < 6; loop++) { - points = AdvancePoints(points); + var motorPositions = flow.GetValue(positions); - Debug.Log($"Pulse {loop + 1} of 6 - waiting {seconds} and triggering with {points} points"); + var delay = (flow.GetValue(duration) / 1000f) / motorPositions; + var realtime = flow.GetValue(unscaledTime); - if (realtime) { - yield return new WaitForSecondsRealtime(seconds); - } - else { - yield return new WaitForSeconds(seconds); - } + var points = flow.GetValue(pointValue); - flow.SetValue(OutputPointValue, points); + while (points > 0) { + for (int loop = 0; loop < motorPositions; loop++) { + points = AdvancePoints(points); - yield return pulse; - } + Debug.Log($"Pulse {loop + 1} of {motorPositions} - waiting {delay}ms and triggering with {points} points"); + + if (realtime) { + yield return new WaitForSecondsRealtime(delay); + } + else { + yield return new WaitForSeconds(delay); + } + + flow.SetValue(OutputPointValue, points); + + yield return pulse; + } + } + + Debug.Log("Stopping score motor"); + + State.Set(VARIABLE_EM_SCORE_MOTOR, false); + + yield return stopped; } - - Debug.Log("Stopping score motor"); - - running = false; - - yield return stopped; } }