1717// ReSharper disable InconsistentNaming
1818
1919using System ;
20+ using System . Collections . Generic ;
21+ using System . Linq ;
2022using NLog ;
2123using PinMame ;
2224using UnityEngine ;
25+ using VisualPinball . Engine . Game . Engines ;
2326using VisualPinball . Unity ;
2427using Logger = NLog . Logger ;
2528
2629namespace VisualPinball . Engine . PinMAME
2730{
2831 [ AddComponentMenu ( "Visual Pinball/PinMAME/PinMAME Mech Handler" ) ]
29- public class PinMameMechComponent : MonoBehaviour , IMechHandler
32+ public class PinMameMechComponent : MonoBehaviour , IMechHandler , ISwitchDeviceComponent , ISerializationCallbackReceiver
3033 {
3134 #region Data
3235
@@ -61,7 +64,7 @@ public class PinMameMechComponent : MonoBehaviour, IMechHandler
6164 public int Steps ;
6265
6366 [ Tooltip ( "Define your switch marks here." ) ]
64- public PinMameMechSwitchMark [ ] Marks ;
67+ public MechMark [ ] Marks ;
6568
6669 [ Unit ( "ms" ) ]
6770 [ Min ( 0 ) ]
@@ -78,66 +81,67 @@ public class PinMameMechComponent : MonoBehaviour, IMechHandler
7881
7982 public event EventHandler < MechEventArgs > OnMechUpdate ;
8083
81- public PinMameMechConfig Config
84+ public PinMameMechConfig Config ( List < SwitchMapping > switchMappings )
8285 {
83- get {
84- var type = 0u ;
85- type |= Type switch {
86- PinMameMechType . OneSolenoid => ( uint ) PinMameMechFlag . OneSol ,
87- PinMameMechType . OneDirectionalSolenoid => ( uint ) PinMameMechFlag . OneDirSol ,
88- PinMameMechType . TwoDirectionalSolenoids => ( uint ) PinMameMechFlag . TwoDirSol ,
89- PinMameMechType . TwoStepperSolenoids => ( uint ) PinMameMechFlag . TwoStepSol ,
90- PinMameMechType . FourStepperSolenoids => ( uint ) PinMameMechFlag . FourStepSol ,
91- _ => throw new ArgumentOutOfRangeException ( )
92- } ;
93-
94- type |= Repeat switch {
95- PinMameRepeat . Circle => ( uint ) PinMameMechFlag . Circle ,
96- PinMameRepeat . Reverse => ( uint ) PinMameMechFlag . Reverse ,
97- PinMameRepeat . StopAtEnd => ( uint ) PinMameMechFlag . StopEnd ,
98- _ => throw new ArgumentOutOfRangeException ( )
99- } ;
100-
101- type |= LinearMovement ? ( uint ) PinMameMechFlag . Linear : ( uint ) PinMameMechFlag . NonLinear ;
102- type |= FastUpdates ? ( uint ) PinMameMechFlag . Fast : ( uint ) PinMameMechFlag . Slow ;
103- type |= ResultByLength ? ( uint ) PinMameMechFlag . LengthSw : ( uint ) PinMameMechFlag . StepSw ;
104-
105- var mechConfig = new PinMameMechConfig (
106- type ,
107- Solenoid1 ,
108- Solenoid2 ,
109- Length ,
110- Steps ,
111- 0 ,
112- Acceleration ,
113- Retardation
114- ) ;
115-
116- foreach ( var mark in Marks ) {
117- switch ( mark . Type ) {
118- case PinMameMechSwitchMarkType . Switch :
119- mechConfig . AddSwitch ( new PinMameMechSwitchConfig ( mark . SwitchId , mark . StepBeginning , mark . StepEnd ) ) ;
120- break ;
121- case PinMameMechSwitchMarkType . PulseSwitch :
122- mechConfig . AddSwitch ( new PinMameMechSwitchConfig ( mark . SwitchId , mark . StepBeginning , mark . StepPulseDuration , 1 ) ) ;
123- break ;
124- case PinMameMechSwitchMarkType . PulseSwitchNew :
125- mechConfig . AddSwitch ( new PinMameMechSwitchConfig ( mark . SwitchId , mark . StepBeginning , mark . StepEnd , mark . StepPulseDuration ) ) ;
126- break ;
127- default :
128- throw new ArgumentOutOfRangeException ( ) ;
129- }
86+ var type = 0u ;
87+ type |= Type switch {
88+ PinMameMechType . OneSolenoid => ( uint ) PinMameMechFlag . OneSol ,
89+ PinMameMechType . OneDirectionalSolenoid => ( uint ) PinMameMechFlag . OneDirSol ,
90+ PinMameMechType . TwoDirectionalSolenoids => ( uint ) PinMameMechFlag . TwoDirSol ,
91+ PinMameMechType . TwoStepperSolenoids => ( uint ) PinMameMechFlag . TwoStepSol ,
92+ PinMameMechType . FourStepperSolenoids => ( uint ) PinMameMechFlag . FourStepSol ,
93+ _ => throw new ArgumentOutOfRangeException ( )
94+ } ;
95+
96+ type |= Repeat switch {
97+ PinMameRepeat . Circle => ( uint ) PinMameMechFlag . Circle ,
98+ PinMameRepeat . Reverse => ( uint ) PinMameMechFlag . Reverse ,
99+ PinMameRepeat . StopAtEnd => ( uint ) PinMameMechFlag . StopEnd ,
100+ _ => throw new ArgumentOutOfRangeException ( )
101+ } ;
102+
103+ type |= LinearMovement ? ( uint ) PinMameMechFlag . Linear : ( uint ) PinMameMechFlag . NonLinear ;
104+ type |= FastUpdates ? ( uint ) PinMameMechFlag . Fast : ( uint ) PinMameMechFlag . Slow ;
105+ type |= ResultByLength ? ( uint ) PinMameMechFlag . LengthSw : ( uint ) PinMameMechFlag . StepSw ;
106+
107+ var mechConfig = new PinMameMechConfig (
108+ type ,
109+ Solenoid1 ,
110+ Solenoid2 ,
111+ Length ,
112+ Steps ,
113+ 0 ,
114+ Acceleration ,
115+ Retardation
116+ ) ;
117+
118+ foreach ( var mark in Marks ) {
119+ var switchMapping = switchMappings . FirstOrDefault ( sm => sm . Device == this && sm . DeviceItem == mark . SwitchId ) ;
120+ if ( switchMapping == null ) {
121+ Logger . Error ( $ "Switch \" { mark . Description } \" for mech { name } is not mapped in the switch manager, ignoring.") ;
122+ continue ;
130123 }
131-
132- return mechConfig ;
124+ mechConfig . AddSwitch ( new PinMameMechSwitchConfig ( switchMapping . InternalId , mark . StepBeginning , mark . StepEnd , mark . Pulse ) ) ;
133125 }
134126
127+ return mechConfig ;
128+
135129 }
136130
137131 private static readonly Logger Logger = LogManager . GetCurrentClassLogger ( ) ;
138132
139133 #endregion
140134
135+ #region Wiring
136+
137+ public IEnumerable < GamelogicEngineSwitch > AvailableSwitches => Marks . Select ( m => m . Switch ) ;
138+
139+ public SwitchDefault SwitchDefault => SwitchDefault . NormallyOpen ;
140+
141+ IEnumerable < GamelogicEngineSwitch > IDeviceComponent < GamelogicEngineSwitch > . AvailableDeviceItems => AvailableSwitches ;
142+
143+ #endregion
144+
141145 #region Runtime
142146
143147 private PinMameGamelogicEngine _gle ;
@@ -157,6 +161,27 @@ public void UpdateMech(PinMameMechInfo data)
157161
158162 #endregion
159163
164+ #region ISerializationCallbackReceiver
165+
166+ public void OnBeforeSerialize ( )
167+ {
168+ #if UNITY_EDITOR
169+
170+ var switchIds = new HashSet < string > ( ) ;
171+ foreach ( var mark in Marks ) {
172+ if ( ! mark . HasId || switchIds . Contains ( mark . SwitchId ) ) {
173+ mark . GenerateId ( ) ;
174+ }
175+ switchIds . Add ( mark . SwitchId ) ;
176+ }
177+ #endif
178+ }
179+
180+ public void OnAfterDeserialize ( )
181+ {
182+ }
183+
184+ #endregion
160185 }
161186
162187 [ Serializable ]
0 commit comments