public void AddActionMap(InputActionMap actionMap) { ////TODO: throw if added to another manager if (actionMap == null) { throw new ArgumentNullException("actionMap"); } if (actionMap.enabled) { throw new InvalidOperationException( string.Format("Cannot add action map '{0}' to manager while it is enabled", actionMap)); } // Get rid of action map state that may already be on the map. if (actionMap.m_State != null) { // Ignore if action map has already been added to this manager. if (actionMap.m_State == m_State) { return; } actionMap.m_State.Destroy(); Debug.Assert(actionMap.m_State == null); } ////TODO: defer resolution until we have all the maps; we really want the ability to set //// an InputActionMapState on a map without having to resolve yet // Add the map to our state. var resolver = new InputBindingResolver(); if (m_State != null) { resolver.ContinueWithDataFrom(m_State); } else { m_State = new InputActionMapState(); } resolver.AddActionMap(actionMap); m_State.Initialize(resolver); actionMap.m_State = m_State; // Listen for actions trigger on the map. actionMap.AddActionCallbackReceiver(this); // If it's the first map added to us, also hook into the input system to automatically // flush our recorded data between updates. if (m_State.totalMapCount == 1) { InputSystem.onUpdate += OnBeforeInputSystemUpdate; } }
////TODO: when re-resolving, we need to preserve InteractionStates and not just reset them // Resolve all bindings to their controls and also add any action interactions // from the bindings. The best way is for this to happen once for each action // set at the beginning of the game and to then enable and disable the sets // as needed. However, the system will also re-resolve bindings if the control // setup in the system changes (i.e. if devices are added or removed or if // layouts in the system are changed). internal void ResolveBindings() { Debug.Assert(m_State == null); // Resolve all source paths. var resolver = new InputBindingResolver(); resolver.AddActionMap(this); // Transfer final arrays into state. m_State = new InputActionMapState(); m_State.Initialize(resolver); }
/// <summary> /// Resolve all bindings to their controls and also add any action interactions /// from the bindings. /// </summary> /// <remarks> /// The best way is for this to happen once for each action map at the beginning of the game /// and to then enable and disable the maps as needed. However, the system will also re-resolve /// bindings if the control setup in the system changes (i.e. if devices are added or removed /// or if layouts in the system are changed). /// </remarks> internal void ResolveBindings() { // If we're part of an asset, we share state and thus binding resolution with // all maps in the asset. if (m_Asset) { var actionMaps = m_Asset.m_ActionMaps; Debug.Assert(actionMaps != null); // Should have at least us in the array. var actionMapCount = actionMaps.Length; // Start resolving. var resolver = new InputBindingResolver(); // If there's a binding mask set on the asset, apply it. resolver.bindingMask = m_Asset.m_BindingMask; // Resolve all maps in the asset. for (var i = 0; i < actionMapCount; ++i) { resolver.AddActionMap(actionMaps[i]); } // Install state. if (m_Asset.m_ActionMapState == null) { var state = new InputActionMapState(); for (var i = 0; i < actionMapCount; ++i) { actionMaps[i].m_State = state; } m_Asset.m_ActionMapState = state; m_State.Initialize(resolver); } else { m_State.ClaimDataFrom(resolver); } // Wipe caches. for (var i = 0; i < actionMapCount; ++i) { actionMaps[i].ClearPerActionCachedBindingData(); } } else { // Standalone action map (possibly a hidden one created for a singleton action). // We get our own private state. // Resolve all source paths. var resolver = new InputBindingResolver(); resolver.AddActionMap(this); // Transfer final arrays into state. if (m_State == null) { m_State = new InputActionMapState(); m_State.Initialize(resolver); } else { m_State.ClaimDataFrom(resolver); ClearPerActionCachedBindingData(); } } }
/// <summary> /// Resolve all bindings to their controls and also add any action interactions /// from the bindings. /// </summary> /// <remarks> /// The best way is for this to happen once for each action map at the beginning of the game /// and to then enable and disable the maps as needed. However, the system will also re-resolve /// bindings if the control setup in the system changes (i.e. if devices are added or removed /// or if layouts in the system are changed). /// </remarks> internal void ResolveBindings() { // If we're part of an asset, we share state and thus binding resolution with // all maps in the asset. if (m_Asset != null) { var actionMaps = m_Asset.m_ActionMaps; Debug.Assert(actionMaps != null); // Should have at least us in the array. var actionMapCount = actionMaps.Length; // Start resolving. var resolver = new InputBindingResolver(); // If we already have a state, re-use the arrays we have already allocated. // NOTE: We will install the arrays on the very same InputActionMapState instance below. In the // case where we didn't have to grow the arrays, we should end up with zero GC allocations // here. if (m_State != null) { resolver.StartWithArraysFrom(m_State); } // If there's a binding mask set on the asset, apply it. resolver.bindingMask = m_Asset.m_BindingMask; // Resolve all maps in the asset. for (var i = 0; i < actionMapCount; ++i) { resolver.AddActionMap(actionMaps[i]); } // Install state. if (m_Asset.m_ActionMapState == null) { var state = new InputActionMapState(); for (var i = 0; i < actionMapCount; ++i) { actionMaps[i].m_State = state; } m_Asset.m_ActionMapState = state; m_State.Initialize(resolver); } else { m_State.ClaimDataFrom(resolver); } ////TODO: determine whether we really need to wipe those; keep them if nothing has changed // Wipe caches. for (var i = 0; i < actionMapCount; ++i) { actionMaps[i].ClearPerActionCachedBindingData(); } } else { // Standalone action map (possibly a hidden one created for a singleton action). // We get our own private state. // Resolve all source paths. var resolver = new InputBindingResolver(); if (m_State != null) { resolver.StartWithArraysFrom(m_State); } resolver.AddActionMap(this); // Transfer final arrays into state. if (m_State == null) { m_State = new InputActionMapState(); m_State.Initialize(resolver); } else { m_State.ClaimDataFrom(resolver); ClearPerActionCachedBindingData(); } } }