@@ -112,7 +112,26 @@ internal unsafe class InputActionState : IInputStateChangeMonitor, ICloneable, I
112112 public BindingState * bindingStates => memory . bindingStates ;
113113 public InteractionState * interactionStates => memory . interactionStates ;
114114 public int * controlIndexToBindingIndex => memory . controlIndexToBindingIndex ;
115- public ushort * controlGroupingAndPriority => memory . controlGroupingAndPriority ;
115+ private ushort * controlGroupingAndPriority => memory . controlGroupingAndPriority ;
116+
117+ /// <summary>
118+ /// Layout of <see cref="UnmanagedMemory.controlGroupingAndPriority"/>: interleaved ushort pairs (group id, binding priority) per control slot.
119+ /// </summary>
120+ internal static class ControlGroupingTable
121+ {
122+ public const int Stride = 2 ;
123+
124+ public static int GroupElementIndex ( int controlIndex ) => controlIndex * Stride ;
125+
126+ public static int PriorityElementIndex ( int controlIndex ) => controlIndex * Stride + 1 ;
127+ }
128+
129+ private uint GetControlMonitorGroupIndex ( int controlIndex ) =>
130+ controlGroupingAndPriority [ ControlGroupingTable . GroupElementIndex ( controlIndex ) ] ;
131+
132+ private int GetControlBindingPriority ( int controlIndex ) =>
133+ controlGroupingAndPriority [ ControlGroupingTable . PriorityElementIndex ( controlIndex ) ] ;
134+
116135 public float * controlMagnitudes => memory . controlMagnitudes ;
117136 public uint * enabledControls => ( uint * ) memory . enabledControls ;
118137
@@ -160,10 +179,10 @@ private void ComputeControlGroupingIfNecessary()
160179
161180 var priority = Math . Clamp ( action != null ? action . Priority : 0 , 0 , 65535 ) ;
162181
163- controlGroupingAndPriority [ i * 2 + 1 ] = ( ushort ) priority ;
182+ controlGroupingAndPriority [ ControlGroupingTable . PriorityElementIndex ( i ) ] = ( ushort ) priority ;
164183
165184 // Compute grouping. If already set, skip.
166- if ( controlGroupingAndPriority [ i * 2 ] == 0 )
185+ if ( controlGroupingAndPriority [ ControlGroupingTable . GroupElementIndex ( i ) ] == 0 )
167186 {
168187 for ( var n = 0 ; n < totalControlCount ; ++ n )
169188 {
@@ -176,10 +195,10 @@ private void ComputeControlGroupingIfNecessary()
176195 if ( control != otherControl )
177196 continue ;
178197
179- controlGroupingAndPriority [ n * 2 ] = ( ushort ) currentGroup ;
198+ controlGroupingAndPriority [ ControlGroupingTable . GroupElementIndex ( n ) ] = ( ushort ) currentGroup ;
180199 }
181200
182- controlGroupingAndPriority [ i * 2 ] = ( ushort ) currentGroup ;
201+ controlGroupingAndPriority [ ControlGroupingTable . GroupElementIndex ( i ) ] = ( ushort ) currentGroup ;
183202
184203 ++ currentGroup ;
185204 }
@@ -1150,7 +1169,8 @@ private void EnableControls(int mapIndex, int controlStartIndex, int numControls
11501169 var bindingStatePtr = & bindingStates [ bindingIndex ] ;
11511170 if ( bindingStatePtr ->wantsInitialStateCheck )
11521171 SetInitialStateCheckPending ( bindingStatePtr , true ) ;
1153- manager . AddStateChangeMonitor ( controls [ controlIndex ] , this , mapControlAndBindingIndex , controlGroupingAndPriority [ controlIndex * 2 ] ) ;
1172+ manager . AddStateChangeMonitor ( controls [ controlIndex ] , this , mapControlAndBindingIndex ,
1173+ GetControlMonitorGroupIndex ( controlIndex ) ) ;
11541174
11551175 SetControlEnabled ( controlIndex , true ) ;
11561176 }
@@ -1344,19 +1364,21 @@ void IInputStateChangeMonitor.NotifyControlStateChanged(InputControl control, do
13441364 return ;
13451365 #endif
13461366
1347- SplitUpMapAndControlAndBindingIndex ( mapControlAndBindingIndex , out var mapIndex , out var controlIndex , out var bindingIndex ) ;
1348- ProcessControlStateChange ( mapIndex , controlIndex , bindingIndex , time , eventPtr ) ;
1367+ var monitorIndex = InputActionStateMonitorIndex . FromPacked ( mapControlAndBindingIndex ) ;
1368+ ProcessControlStateChange ( monitorIndex . MapIndex , monitorIndex . ControlIndex , monitorIndex . BindingIndex , time ,
1369+ eventPtr ) ;
13491370 }
13501371
13511372 void IInputStateChangeMonitor . NotifyTimerExpired ( InputControl control , double time ,
13521373 long mapControlAndBindingIndex , int interactionIndex )
13531374 {
1354- SplitUpMapAndControlAndBindingIndex ( mapControlAndBindingIndex , out var mapIndex , out var controlIndex , out var bindingIndex ) ;
1355- ProcessTimeout ( time , mapIndex , controlIndex , bindingIndex , interactionIndex ) ;
1375+ var monitorIndex = InputActionStateMonitorIndex . FromPacked ( mapControlAndBindingIndex ) ;
1376+ ProcessTimeout ( time , monitorIndex . MapIndex , monitorIndex . ControlIndex , monitorIndex . BindingIndex ,
1377+ interactionIndex ) ;
13561378 }
13571379
13581380 /// <summary>
1359- /// Bit pack the mapIndex, controlIndex, bindingIndex and complexity components into a single long monitor index value.
1381+ /// Bit pack the mapIndex, controlIndex, bindingIndex and binding-priority components into a single long monitor index value.
13601382 /// </summary>
13611383 /// <param name="mapIndex">The mapIndex value to pack.</param>
13621384 /// <param name="controlIndex">The controlIndex value to pack.</param>
@@ -1366,42 +1388,14 @@ void IInputStateChangeMonitor.NotifyTimerExpired(InputControl control, double ti
13661388 /// monitors. While we could look up map and binding indices from control indices, keeping
13671389 /// all the information together avoids having to unnecessarily jump around in memory to grab
13681390 /// the various pieces of data.
1369- /// The complexity component is implicitly derived and does not need to be passed as an argument .
1391+ /// Priority is read from <see cref="ControlGroupingTable"/> data for <paramref name="controlIndex"/> .
13701392 /// </remarks>
13711393 private long ToCombinedMapAndControlAndBindingIndex ( int mapIndex , int controlIndex , int bindingIndex )
13721394 {
13731395 // We have limits on the numbers of maps, controls, and bindings we allow in any single
13741396 // action state (see TriggerState.kMaxNumXXX).
1375- var complexity = controlGroupingAndPriority [ controlIndex * 2 + 1 ] ;
1376- var result = ( long ) controlIndex ;
1377- result |= ( long ) bindingIndex << 24 ;
1378- result |= ( long ) mapIndex << 40 ;
1379- result |= ( long ) complexity << 48 ;
1380- return result ;
1381- }
1382-
1383- /// <summary>
1384- /// Extract the mapIndex, controlIndex and bindingIndex components from the provided bit packed argument (monitor index).
1385- /// </summary>
1386- /// <param name="mapControlAndBindingIndex">Represents a monitor index, which is a bit packed field containing multiple components.</param>
1387- /// <param name="mapIndex">Will hold the extracted mapIndex value after the function completes.</param>
1388- /// <param name="controlIndex">Will hold the extracted controlIndex value after the function completes.</param>
1389- /// <param name="bindingIndex">Will hold the extracted bindingIndex value after the function completes.</param>
1390- private void SplitUpMapAndControlAndBindingIndex ( long mapControlAndBindingIndex , out int mapIndex ,
1391- out int controlIndex , out int bindingIndex )
1392- {
1393- controlIndex = ( int ) ( mapControlAndBindingIndex & 0x00ffffff ) ;
1394- bindingIndex = ( int ) ( ( mapControlAndBindingIndex >> 24 ) & 0xffff ) ;
1395- mapIndex = ( int ) ( ( mapControlAndBindingIndex >> 40 ) & 0xff ) ;
1396- }
1397-
1398- /// <summary>
1399- /// Extract the 'complexity' component from the provided bit packed argument (monitor index).
1400- /// </summary>
1401- /// <param name="mapControlAndBindingIndex">Represents a monitor index, which is a bit packed field containing multiple components.</param>
1402- internal static int GetPriorityFromMonitorIndex ( long mapControlAndBindingIndex )
1403- {
1404- return ( int ) ( ( mapControlAndBindingIndex >> 48 ) & 0xff ) ;
1397+ return InputActionStateMonitorIndex . Create ( mapIndex , controlIndex , bindingIndex ,
1398+ GetControlBindingPriority ( controlIndex ) ) . Packed ;
14051399 }
14061400
14071401 /// <summary>
@@ -2462,7 +2456,7 @@ private void ChangePhaseOfActionInternal(int actionIndex, TriggerState* actionSt
24622456 // When we perform an action, we mark the event handled such that FireStateChangeNotifications()
24632457 // can then reset state monitors in the same group (strictly lower binding priority only).
24642458 // NOTE: We don't consume for controls at binding priority 0. Those we fire in unison.
2465- if ( controlGroupingAndPriority [ trigger . controlIndex * 2 + 1 ] > 0 &&
2459+ if ( GetControlBindingPriority ( trigger . controlIndex ) > 0 &&
24662460 // we can end up switching to performed state from an interaction with a timeout, at which point
24672461 // the original event will probably have been removed from memory, so make sure to check
24682462 // we still have one
0 commit comments