From 1c002c036d87398e0855657a1cb97a63fb3abeaf Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 25 Nov 2021 00:17:30 +0100 Subject: [PATCH 1/3] fix: Share the same switch status object among multiple switch sources. --- .../VisualPinball.Unity/Game/DeviceSwitch.cs | 4 +-- .../VisualPinball.Unity/Game/SwitchHandler.cs | 8 +++-- .../VisualPinball.Unity/Game/SwitchPlayer.cs | 3 +- .../VPT/Bumper/BumperApi.cs | 2 +- .../VPT/CollisionSwitch/CollisionSwitchApi.cs | 35 +++++++++++++------ .../VPT/Flipper/FlipperApi.cs | 2 +- .../VisualPinball.Unity/VPT/Gate/GateApi.cs | 2 +- .../VPT/HitTarget/DropTargetApi.cs | 2 +- .../VPT/HitTarget/HitTargetApi.cs | 2 +- .../VisualPinball.Unity/VPT/IApi.cs | 3 +- .../VisualPinball.Unity/VPT/ItemApi.cs | 2 +- .../VPT/Kicker/KickerApi.cs | 2 +- .../VPT/Spinner/SpinnerApi.cs | 2 +- .../VPT/Trigger/TriggerApi.cs | 2 +- 14 files changed, 45 insertions(+), 26 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/DeviceSwitch.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/DeviceSwitch.cs index a3a6c47b9..fe241ce1f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/DeviceSwitch.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/DeviceSwitch.cs @@ -59,8 +59,8 @@ public DeviceSwitch(string name, bool isPulseSwitch, SwitchDefault switchDefault _switchHandler = new SwitchHandler(name, player); } - IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig) => - _switchHandler.AddSwitchDest(switchConfig.WithPulse(_isPulseSwitch).WithDefault(_switchDefault)); + IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => + _switchHandler.AddSwitchDest(switchConfig.WithPulse(_isPulseSwitch).WithDefault(_switchDefault), switchStatus); public void AddWireDest(WireDestConfig wireConfig) => _switchHandler.AddWireDest(wireConfig); void IApiSwitch.RemoveWireDest(string destId) => _switchHandler.RemoveWireDest(destId); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs index 3bc557b11..cebfe5d8d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs @@ -36,7 +36,7 @@ public class SwitchHandler /// private List _wires; - private readonly Dictionary _switchStatuses = new Dictionary(); + private readonly Dictionary _switchStatuses = new Dictionary(); private static VisualPinballSimulationSystemGroup SimulationSystemGroup => World.DefaultGameObjectInjectionWorld.GetOrCreateSystem(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); @@ -52,12 +52,14 @@ public SwitchHandler(string name, Player player, bool isEnabled = false) /// Set up this switch to send its status to the gamelogic engine with the given ID. /// /// Config containing gamelogic engine's switch ID and pulse settings - internal IApiSwitchStatus AddSwitchDest(SwitchConfig switchConfig) + /// Since multiple switch destinations can map to a switch, we might already have a status object. + internal IApiSwitchStatus AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) { if (_switches == null) { _switches = new List(); } - var swStatus = new ItemSwitchStatus(switchConfig.IsNormallyClosed) { IsSwitchEnabled = IsEnabled }; + + var swStatus = switchStatus ?? new ItemSwitchStatus(switchConfig.IsNormallyClosed) { IsSwitchEnabled = IsEnabled }; _switches.Add(switchConfig); _switchStatuses[switchConfig.SwitchId] = swStatus; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchPlayer.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchPlayer.cs index d3ebd798c..2405ffe47 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchPlayer.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchPlayer.cs @@ -85,7 +85,8 @@ public void OnStart() var device = _switchDevices[switchMapping.Device]; var deviceSwitch = device.Switch(switchMapping.DeviceItem); if (deviceSwitch != null) { - var switchStatus = deviceSwitch.AddSwitchDest(new SwitchConfig(switchMapping)); + var existingSwitchStatus = SwitchStatuses.ContainsKey(switchMapping.Id) ? SwitchStatuses[switchMapping.Id] : null; + var switchStatus = deviceSwitch.AddSwitchDest(new SwitchConfig(switchMapping), existingSwitchStatus); SwitchStatuses[switchMapping.Id] = switchStatus; } else { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs index 16f6fa261..263dc02b9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs @@ -48,7 +48,7 @@ public BumperApi(GameObject go, Entity entity, Entity parentEntity, Player playe #region Wiring public bool IsSwitchEnabled => SwitchHandler.IsEnabled; - IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig) => AddSwitchDest(switchConfig.WithPulse(true)); + IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => AddSwitchDest(switchConfig.WithPulse(true), switchStatus); IApiSwitch IApiSwitchDevice.Switch(string deviceItem) => this; IApiCoil IApiCoilDevice.Coil(string deviceItem) => this; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchApi.cs index c9b27e0bf..c076f42d5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchApi.cs @@ -1,8 +1,23 @@ +// Visual Pinball Engine +// Copyright (C) 2021 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 Logger = NLog.Logger; using NLog; using UnityEngine; -using Unity.Entities; +using Logger = NLog.Logger; namespace VisualPinball.Unity { @@ -11,20 +26,20 @@ public class CollisionSwitchApi : IApi, IApiSwitch, IApiSwitchDevice private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private readonly CollisionSwitchComponent _collisionSwitchComponent; - private Player _player; + private readonly Player _player; private IApiHittable _hittable; - private protected readonly SwitchHandler SwitchHandler; + private readonly SwitchHandler _switchHandler; public event EventHandler Init; public event EventHandler Switch; - public bool IsSwitchEnabled => SwitchHandler.IsEnabled; - IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig) => SwitchHandler.AddSwitchDest(switchConfig.WithPulse(true)); - void IApiSwitch.AddWireDest(WireDestConfig wireConfig) => SwitchHandler.AddWireDest(wireConfig.WithPulse(true)); - void IApiSwitch.RemoveWireDest(string destId) => SwitchHandler.RemoveWireDest(destId); + public bool IsSwitchEnabled => _switchHandler.IsEnabled; + IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => _switchHandler.AddSwitchDest(switchConfig.WithPulse(true), switchStatus); + void IApiSwitch.AddWireDest(WireDestConfig wireConfig) => _switchHandler.AddWireDest(wireConfig.WithPulse(true)); + void IApiSwitch.RemoveWireDest(string destId) => _switchHandler.RemoveWireDest(destId); IApiSwitch IApiSwitchDevice.Switch(string deviceItem) => this; - public void OnSwitch(bool closed) => SwitchHandler.OnSwitch(closed); + public void OnSwitch(bool closed) => _switchHandler.OnSwitch(closed); public bool IsHittable => _hittable != null; @@ -33,7 +48,7 @@ internal CollisionSwitchApi(GameObject go, Player player) _collisionSwitchComponent = go.GetComponentInChildren(); _player = player; - SwitchHandler = new SwitchHandler(go.name, player); + _switchHandler = new SwitchHandler(go.name, player); } void IApi.OnInit(BallManager ballManager) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs index 2ad824693..1e326b538 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs @@ -181,7 +181,7 @@ private void OnDualWoundCoil(bool enabled, bool isHoldCoil) #region Wiring public bool IsSwitchEnabled => SwitchHandler.IsEnabled; - IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig) => AddSwitchDest(switchConfig); + IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => AddSwitchDest(switchConfig, switchStatus); void IApiSwitch.AddWireDest(WireDestConfig wireConfig) => AddWireDest(wireConfig); void IApiSwitch.RemoveWireDest(string destId) => RemoveWireDest(destId); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs index f1fe9960c..00e3718ec 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs @@ -81,7 +81,7 @@ public GateApi(GameObject go, Entity entity, Entity parentEntity, Player player) #region Wiring public bool IsSwitchEnabled => SwitchHandler.IsEnabled; - IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig) => AddSwitchDest(switchConfig.WithPulse(true)); + IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => AddSwitchDest(switchConfig.WithPulse(true), switchStatus); void IApiSwitch.AddWireDest(WireDestConfig wireConfig) => AddWireDest(wireConfig.WithPulse(true)); void IApiSwitch.RemoveWireDest(string destId) => RemoveWireDest(destId); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs index 2805b2f94..8d0de1dfe 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs @@ -93,7 +93,7 @@ private void SetIsDropped(bool isDropped) #region Wiring public bool IsSwitchEnabled => SwitchHandler.IsEnabled; - IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig) => AddSwitchDest(switchConfig); + IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => AddSwitchDest(switchConfig, switchStatus); IApiSwitch IApiSwitchDevice.Switch(string deviceItem) => this; void IApiSwitch.AddWireDest(WireDestConfig wireConfig) => AddWireDest(wireConfig); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs index 3e26ecde7..a61e34bdd 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs @@ -48,7 +48,7 @@ internal HitTargetApi(GameObject go, Entity entity, Entity parentEntity, Player #region Wiring public bool IsSwitchEnabled => SwitchHandler.IsEnabled; - IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig) => AddSwitchDest(switchConfig.WithPulse(true)); + IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => AddSwitchDest(switchConfig.WithPulse(true), switchStatus); void IApiSwitch.AddWireDest(WireDestConfig wireConfig) => AddWireDest(wireConfig.WithPulse(true)); void IApiSwitch.RemoveWireDest(string destId) => RemoveWireDest(destId); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs index 2ff348d5b..ce608f628 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs @@ -142,7 +142,8 @@ public interface IApiSwitch /// Set up this switch to send its status to the gamelogic engine with the given ID. /// /// Config containing gamelogic engine's switch ID and pulse settings - IApiSwitchStatus AddSwitchDest(SwitchConfig switchConfig); + /// Since multiple switch destinations can map to a switch, we might already have a status object. + IApiSwitchStatus AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus); /// /// Set up this switch to directly trigger another game item (coil or lamp), or diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs index 01e7a4ea0..9da25873b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs @@ -66,7 +66,7 @@ protected void OnInit(BallManager ballManager) private protected DeviceSwitch CreateSwitch(string name, bool isPulseSwitch, SwitchDefault switchDefault = SwitchDefault.Configurable) => new DeviceSwitch(name, isPulseSwitch, switchDefault, _player); - private protected IApiSwitchStatus AddSwitchDest(SwitchConfig switchConfig) => SwitchHandler.AddSwitchDest(switchConfig); + private protected IApiSwitchStatus AddSwitchDest(SwitchConfig switchConfig,IApiSwitchStatus switchStatus) => SwitchHandler.AddSwitchDest(switchConfig, switchStatus); internal void AddWireDest(WireDestConfig wireConfig) => SwitchHandler.AddWireDest(wireConfig); internal void RemoveWireDest(string destId) => SwitchHandler.RemoveWireDest(destId); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs index 7c24308ff..7c1a897a8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs @@ -235,7 +235,7 @@ private void KickXYZ(Entity kickerEntity, float angle, float speed, float inclin } } - IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig) => AddSwitchDest(switchConfig.WithPulse(false)); + IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => AddSwitchDest(switchConfig.WithPulse(false), switchStatus); void IApiSwitch.AddWireDest(WireDestConfig wireConfig) => AddWireDest(wireConfig.WithPulse(false)); void IApiSwitch.RemoveWireDest(string destId) => RemoveWireDest(destId); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs index c03d15df1..b67ee38ba 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs @@ -73,7 +73,7 @@ public SpinnerApi(GameObject go, Entity entity, Entity parentEntity, Player play #region IApiSwitch public bool IsSwitchEnabled => SwitchHandler.IsEnabled; - IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig) => AddSwitchDest(switchConfig.WithPulse(true)); + IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => AddSwitchDest(switchConfig.WithPulse(true), switchStatus); void IApiSwitch.AddWireDest(WireDestConfig wireConfig) => AddWireDest(wireConfig.WithPulse(true)); void IApiSwitch.RemoveWireDest(string destId) => RemoveWireDest(destId); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs index 4a5bfa5b0..48f528215 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs @@ -53,7 +53,7 @@ internal TriggerApi(GameObject go, Entity entity, Entity parentEntity, Player pl #region Wiring public bool IsSwitchEnabled => SwitchHandler.IsEnabled; - IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig) => AddSwitchDest(switchConfig); + IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => AddSwitchDest(switchConfig, switchStatus); void IApiSwitch.AddWireDest(WireDestConfig wireConfig) => AddWireDest(wireConfig); void IApiSwitch.RemoveWireDest(string destId) => RemoveWireDest(destId); From 7159c1c224f10bbf9f8d763c986f913c0eba198a Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 30 Nov 2021 12:33:10 +0100 Subject: [PATCH 2/3] doc: Update CHANGELOG. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0799677d6..cf4d75a47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ Built with Unity 2021.2. - Put game-, mesh-, collision- animation data into separate components ([#227](https://github.com/freezy/VisualPinball.Engine/pull/227), [Documentation](https://docs.visualpinball.org/creators-guide/editor/unity-components.html)). ### Fixed +- Fixed switch status when multiple mappings point to the same ID ([#347](https://github.com/freezy/VisualPinball.Engine/pull/347)). - Lighting setup. It's now usable ([#330](https://github.com/freezy/VisualPinball.Engine/pull/330)). - Ball passing through collider plane and disappearing. - Alpha channel of color values is now correctly written ([#291](https://github.com/freezy/VisualPinball.Engine/pull/291)). From 96d8d934661133f597c8bbdceb32680e81280154 Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 30 Nov 2021 12:43:20 +0100 Subject: [PATCH 3/3] fix: Compilation error. --- .../VisualPinball.Unity/VPT/Surface/SlingshotApi.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotApi.cs index 7ce6302ba..fe6780016 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotApi.cs @@ -36,7 +36,7 @@ public class SlingshotApi : IApi, IApiSwitch, IApiSwitchDevice public event EventHandler Switch; public bool IsSwitchEnabled => _switchHandler.IsEnabled; - IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig) => _switchHandler.AddSwitchDest(switchConfig.WithPulse(true)); + IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => _switchHandler.AddSwitchDest(switchConfig.WithPulse(true), switchStatus); void IApiSwitch.AddWireDest(WireDestConfig wireConfig) => _switchHandler.AddWireDest(wireConfig.WithPulse(true)); void IApiSwitch.RemoveWireDest(string destId) => _switchHandler.RemoveWireDest(destId); IApiSwitch IApiSwitchDevice.Switch(string deviceItem) => this;