|
3 | 3 | using System.Collections.Generic;
|
4 | 4 | using System.Linq;
|
5 | 5 | using Unity.Collections;
|
| 6 | +using Unity.Profiling; |
6 | 7 | using UnityEngine.InputSystem.Utilities;
|
7 | 8 |
|
8 | 9 | ////REVIEW: given we have the global ActionPerformed callback, do we really need the per-map callback?
|
@@ -313,6 +314,11 @@ public event Action<InputAction.CallbackContext> actionTriggered
|
313 | 314 | remove => m_ActionCallbacks.RemoveCallback(value);
|
314 | 315 | }
|
315 | 316 |
|
| 317 | + /// <summary> |
| 318 | + /// ProfilerMarker to measure how long it takes to resolve bindings. |
| 319 | + /// </summary> |
| 320 | + static readonly ProfilerMarker k_ResolveBindingsProfilerMarker = new ProfilerMarker("InputActionMap.ResolveBindings"); |
| 321 | + |
316 | 322 | /// <summary>
|
317 | 323 | /// Construct an action map with default values.
|
318 | 324 | /// </summary>
|
@@ -1299,100 +1305,104 @@ internal bool ResolveBindingsIfNecessary()
|
1299 | 1305 | /// </remarks>
|
1300 | 1306 | internal void ResolveBindings()
|
1301 | 1307 | {
|
1302 |
| - // Make sure that if we trigger callbacks as part of disabling and re-enabling actions, |
1303 |
| - // we don't trigger a re-resolve while we're already resolving bindings. |
1304 |
| - using (InputActionRebindingExtensions.DeferBindingResolution()) |
| 1308 | + using (k_ResolveBindingsProfilerMarker.Auto()) |
1305 | 1309 | {
|
1306 |
| - // In case we have actions that are currently enabled, we temporarily retain the |
1307 |
| - // UnmanagedMemory of our InputActionState so that we can sync action states after |
1308 |
| - // we have re-resolved bindings. |
1309 |
| - var oldMemory = new InputActionState.UnmanagedMemory(); |
1310 |
| - try |
| 1310 | + // Make sure that if we trigger callbacks as part of disabling and re-enabling actions, |
| 1311 | + // we don't trigger a re-resolve while we're already resolving bindings. |
| 1312 | + using (InputActionRebindingExtensions.DeferBindingResolution()) |
1311 | 1313 | {
|
1312 |
| - OneOrMore<InputActionMap, ReadOnlyArray<InputActionMap>> actionMaps; |
| 1314 | + // In case we have actions that are currently enabled, we temporarily retain the |
| 1315 | + // UnmanagedMemory of our InputActionState so that we can sync action states after |
| 1316 | + // we have re-resolved bindings. |
| 1317 | + var oldMemory = new InputActionState.UnmanagedMemory(); |
| 1318 | + try |
| 1319 | + { |
| 1320 | + OneOrMore<InputActionMap, ReadOnlyArray<InputActionMap>> actionMaps; |
1313 | 1321 |
|
1314 |
| - // Start resolving. |
1315 |
| - var resolver = new InputBindingResolver(); |
| 1322 | + // Start resolving. |
| 1323 | + var resolver = new InputBindingResolver(); |
1316 | 1324 |
|
1317 |
| - // If we're part of an asset, we share state and thus binding resolution with |
1318 |
| - // all maps in the asset. |
1319 |
| - var needFullResolve = m_State == null; |
1320 |
| - if (m_Asset != null) |
1321 |
| - { |
1322 |
| - actionMaps = m_Asset.actionMaps; |
1323 |
| - Debug.Assert(actionMaps.Count > 0, "Asset referred to by action map does not have action maps"); |
| 1325 | + // If we're part of an asset, we share state and thus binding resolution with |
| 1326 | + // all maps in the asset. |
| 1327 | + var needFullResolve = m_State == null; |
| 1328 | + if (m_Asset != null) |
| 1329 | + { |
| 1330 | + actionMaps = m_Asset.actionMaps; |
| 1331 | + Debug.Assert(actionMaps.Count > 0, "Asset referred to by action map does not have action maps"); |
1324 | 1332 |
|
1325 |
| - // If there's a binding mask set on the asset, apply it. |
1326 |
| - resolver.bindingMask = m_Asset.m_BindingMask; |
| 1333 | + // If there's a binding mask set on the asset, apply it. |
| 1334 | + resolver.bindingMask = m_Asset.m_BindingMask; |
1327 | 1335 |
|
1328 |
| - foreach (var map in actionMaps) |
| 1336 | + foreach (var map in actionMaps) |
| 1337 | + { |
| 1338 | + needFullResolve |= map.bindingResolutionNeedsFullReResolve; |
| 1339 | + map.needToResolveBindings = false; |
| 1340 | + map.bindingResolutionNeedsFullReResolve = false; |
| 1341 | + map.controlsForEachActionInitialized = false; |
| 1342 | + } |
| 1343 | + } |
| 1344 | + else |
1329 | 1345 | {
|
1330 |
| - needFullResolve |= map.bindingResolutionNeedsFullReResolve; |
1331 |
| - map.needToResolveBindings = false; |
1332 |
| - map.bindingResolutionNeedsFullReResolve = false; |
1333 |
| - map.controlsForEachActionInitialized = false; |
| 1346 | + // Standalone action map (possibly a hidden one created for a singleton action). |
| 1347 | + // Gets its own private state. |
| 1348 | + |
| 1349 | + actionMaps = this; |
| 1350 | + needFullResolve |= bindingResolutionNeedsFullReResolve; |
| 1351 | + needToResolveBindings = false; |
| 1352 | + bindingResolutionNeedsFullReResolve = false; |
| 1353 | + controlsForEachActionInitialized = false; |
1334 | 1354 | }
|
1335 |
| - } |
1336 |
| - else |
1337 |
| - { |
1338 |
| - // Standalone action map (possibly a hidden one created for a singleton action). |
1339 |
| - // Gets its own private state. |
1340 |
| - |
1341 |
| - actionMaps = this; |
1342 |
| - needFullResolve |= bindingResolutionNeedsFullReResolve; |
1343 |
| - needToResolveBindings = false; |
1344 |
| - bindingResolutionNeedsFullReResolve = false; |
1345 |
| - controlsForEachActionInitialized = false; |
1346 |
| - } |
1347 | 1355 |
|
1348 |
| - // If we already have a state, re-use the arrays we have already allocated. |
1349 |
| - // NOTE: We will install the arrays on the very same InputActionState instance below. In the |
1350 |
| - // case where we didn't have to grow the arrays, we should end up with zero GC allocations |
1351 |
| - // here. |
1352 |
| - var hasEnabledActions = false; |
1353 |
| - InputControlList<InputControl> activeControls = default; |
1354 |
| - if (m_State != null) |
1355 |
| - { |
1356 |
| - // Grab a clone of the current memory. We clone because disabling all the actions |
1357 |
| - // in the map will alter the memory state and we want the state before we start |
1358 |
| - // touching it. |
1359 |
| - oldMemory = m_State.memory.Clone(); |
| 1356 | + // If we already have a state, re-use the arrays we have already allocated. |
| 1357 | + // NOTE: We will install the arrays on the very same InputActionState instance below. In the |
| 1358 | + // case where we didn't have to grow the arrays, we should end up with zero GC allocations |
| 1359 | + // here. |
| 1360 | + var hasEnabledActions = false; |
| 1361 | + InputControlList<InputControl> activeControls = default; |
| 1362 | + if (m_State != null) |
| 1363 | + { |
| 1364 | + // Grab a clone of the current memory. We clone because disabling all the actions |
| 1365 | + // in the map will alter the memory state and we want the state before we start |
| 1366 | + // touching it. |
| 1367 | + oldMemory = m_State.memory.Clone(); |
1360 | 1368 |
|
1361 |
| - m_State.PrepareForBindingReResolution(needFullResolve, ref activeControls, ref hasEnabledActions); |
| 1369 | + m_State.PrepareForBindingReResolution(needFullResolve, ref activeControls, ref hasEnabledActions); |
1362 | 1370 |
|
1363 |
| - // Reuse the arrays we have so that we can avoid managed memory allocations, if possible. |
1364 |
| - resolver.StartWithPreviousResolve(m_State, isFullResolve: needFullResolve); |
| 1371 | + // Reuse the arrays we have so that we can avoid managed memory allocations, if possible. |
| 1372 | + resolver.StartWithPreviousResolve(m_State, isFullResolve: needFullResolve); |
1365 | 1373 |
|
1366 |
| - // Throw away old memory. |
1367 |
| - m_State.memory.Dispose(); |
1368 |
| - } |
| 1374 | + // Throw away old memory. |
| 1375 | + m_State.memory.Dispose(); |
| 1376 | + } |
1369 | 1377 |
|
1370 |
| - // Resolve all maps in the asset. |
1371 |
| - foreach (var map in actionMaps) |
1372 |
| - resolver.AddActionMap(map); |
| 1378 | + // Resolve all maps in the asset. |
| 1379 | + foreach (var map in actionMaps) |
| 1380 | + resolver.AddActionMap(map); |
1373 | 1381 |
|
1374 |
| - // Install state. |
1375 |
| - if (m_State == null) |
1376 |
| - { |
1377 |
| - m_State = new InputActionState(); |
1378 |
| - m_State.Initialize(resolver); |
1379 |
| - } |
1380 |
| - else |
1381 |
| - { |
1382 |
| - m_State.ClaimDataFrom(resolver); |
| 1382 | + // Install state. |
| 1383 | + if (m_State == null) |
| 1384 | + { |
| 1385 | + m_State = new InputActionState(); |
| 1386 | + m_State.Initialize(resolver); |
| 1387 | + } |
| 1388 | + else |
| 1389 | + { |
| 1390 | + m_State.ClaimDataFrom(resolver); |
| 1391 | + } |
| 1392 | + |
| 1393 | + if (m_Asset != null) |
| 1394 | + { |
| 1395 | + foreach (var map in actionMaps) |
| 1396 | + map.m_State = m_State; |
| 1397 | + m_Asset.m_SharedStateForAllMaps = m_State; |
| 1398 | + } |
| 1399 | + |
| 1400 | + m_State.FinishBindingResolution(hasEnabledActions, oldMemory, activeControls, isFullResolve: needFullResolve); |
1383 | 1401 | }
|
1384 |
| - if (m_Asset != null) |
| 1402 | + finally |
1385 | 1403 | {
|
1386 |
| - foreach (var map in actionMaps) |
1387 |
| - map.m_State = m_State; |
1388 |
| - m_Asset.m_SharedStateForAllMaps = m_State; |
| 1404 | + oldMemory.Dispose(); |
1389 | 1405 | }
|
1390 |
| - |
1391 |
| - m_State.FinishBindingResolution(hasEnabledActions, oldMemory, activeControls, isFullResolve: needFullResolve); |
1392 |
| - } |
1393 |
| - finally |
1394 |
| - { |
1395 |
| - oldMemory.Dispose(); |
1396 | 1406 | }
|
1397 | 1407 | }
|
1398 | 1408 | }
|
|
0 commit comments