예제 #1
0
            private unsafe void OnEvent(InputEventPtr eventPtr)
            {
                // Ignore if not a state event.
                if (!eventPtr.IsA <StateEvent>() && !eventPtr.IsA <DeltaStateEvent>())
                {
                    return;
                }

                // Fetch device.
                var device = InputSystem.GetDeviceById(eventPtr.deviceId);

                if (device == null)
                {
                    return;
                }

                // Go through controls and see if there's anything interesting in the event.
                var controls              = device.allControls;
                var controlCount          = controls.Count;
                var haveChangedCandidates = false;

                for (var i = 0; i < controlCount; ++i)
                {
                    var control = controls[i];

                    // Skip controls that have no state in the event.
                    var statePtr = control.GetStatePtrFromStateEvent(eventPtr);
                    if (statePtr == null)
                    {
                        continue;
                    }

                    // If the control that cancels has been actuated, abort the operation now.
                    if (!string.IsNullOrEmpty(m_CancelBinding) && InputControlPath.Matches(m_CancelBinding, control) &&
                        !control.CheckStateIsAtDefault(statePtr) && control.HasValueChangeInState(statePtr))
                    {
                        OnCancel();
                        break;
                    }

                    // Skip noisy controls.
                    if (control.noisy && (m_Flags & Flags.DontIgnoreNoisyControls) == 0)
                    {
                        continue;
                    }

                    // If controls have to match a certain path, check if this one does.
                    if (m_IncludePathCount > 0 && !HavePathMatch(control, m_IncludePaths, m_IncludePathCount))
                    {
                        continue;
                    }

                    // If controls must not match certain path, make sure the control doesn't.
                    if (m_ExcludePathCount > 0 && HavePathMatch(control, m_ExcludePaths, m_ExcludePathCount))
                    {
                        continue;
                    }

                    // If we're expecting controls of a certain type, skip if control isn't of
                    // the right type.
                    if (m_ControlType != null && !m_ControlType.IsInstanceOfType(control))
                    {
                        continue;
                    }

                    // If we're expecting controls to be based on a specific layout, skip if control
                    // isn't based on that layout.
                    if (!m_ExpectedLayout.IsEmpty() &&
                        m_ExpectedLayout != control.m_Layout &&
                        !InputControlLayout.s_Layouts.IsBasedOn(m_ExpectedLayout, control.m_Layout))
                    {
                        continue;
                    }

                    // Skip controls that are in their default state.
                    // NOTE: This is the cheapest check with respect to looking at actual state. So
                    //       do this first before looking further at the state.
                    if (control.CheckStateIsAtDefault(statePtr))
                    {
                        continue;
                    }

                    // Skip controls that have no effective value change.
                    // NOTE: This will run the full processor stack and is move involved.
                    if (!control.HasValueChangeInState(statePtr))
                    {
                        continue;
                    }

                    // If we have a magnitude threshold, see if control passes it.
                    var magnitude = -1f;
                    if (m_MagnitudeThreshold >= 0f)
                    {
                        magnitude = control.EvaluateMagnitude(statePtr);
                        if (magnitude >= 0 && magnitude < m_MagnitudeThreshold)
                        {
                            continue; // No, so skip.
                        }
                    }

                    // Compute score.
                    float score;
                    if (m_OnComputeScore != null)
                    {
                        score = m_OnComputeScore(control, eventPtr);
                    }
                    else
                    {
                        score = magnitude;

                        // We don't want synthetic controls to not be bindable at all but they should
                        // generally cede priority to controls that aren't synthetic. So we bump all
                        // scores of controls that aren't synthetic.
                        if (!control.synthetic)
                        {
                            score += 1f;
                        }
                    }

                    // Control is a candidate.
                    // See if we already singled the control out as a potential candidate.
                    var candidateIndex = m_Candidates.IndexOf(control);
                    if (candidateIndex != -1)
                    {
                        // Yes, we did. So just check whether it became a better candidate than before.
                        if (m_Scores[candidateIndex] < score)
                        {
                            haveChangedCandidates    = true;
                            m_Scores[candidateIndex] = score;

                            if (m_WaitSecondsAfterMatch > 0)
                            {
                                m_LastMatchTime = InputRuntime.s_Instance.currentTime;
                            }
                        }
                    }
                    else
                    {
                        // No, so add it.
                        var candidateCount = m_Candidates.Count;
                        m_Candidates.Add(control);
                        ArrayHelpers.AppendWithCapacity(ref m_Scores, ref candidateCount, score);
                        haveChangedCandidates = true;

                        if (m_WaitSecondsAfterMatch > 0)
                        {
                            m_LastMatchTime = InputRuntime.s_Instance.currentTime;
                        }
                    }
                }

                if (haveChangedCandidates && !cancelled)
                {
                    // If we have a callback that wants to control matching, leave it to the callback to decide
                    // whether the rebind is complete or not. Otherwise, just complete.
                    if (m_OnPotentialMatch != null)
                    {
                        SortCandidatesByScore();
                        m_OnPotentialMatch(this);
                    }
                    else if (m_WaitSecondsAfterMatch <= 0)
                    {
                        OnComplete();
                    }
                    else
                    {
                        SortCandidatesByScore();
                    }
                }
            }
예제 #2
0
            private void OnEvent(InputEventPtr eventPtr)
            {
                // Ignore if not a state event.
                if (!eventPtr.IsA <StateEvent>() && !eventPtr.IsA <DeltaStateEvent>())
                {
                    return;
                }

                // Fetch device.
                var device = InputSystem.GetDeviceById(eventPtr.deviceId);

                if (device == null)
                {
                    return;
                }

                // Go through controls and see if there's anything interesting in the event.
                var controls     = device.allControls;
                var controlCount = controls.Count;

                for (var i = 0; i < controlCount; ++i)
                {
                    var control = controls[i];

                    ////TODO: skip noisy controls

                    // Skip controls that have no state in the event.
                    var statePtr = control.GetStatePtrFromStateEvent(eventPtr);
                    if (statePtr == IntPtr.Zero)
                    {
                        continue;
                    }

                    // If we're expecting controls of a certain type, skip if control isn't of
                    // the right type.
                    if (m_ControlType != null && !m_ControlType.IsInstanceOfType(control))
                    {
                        continue;
                    }

                    // If we're expecting controls to be based on a specific layout, skip if control
                    // isn't based on that layout.
                    if (!m_ExpectedLayout.IsEmpty() &&
                        InputControlLayout.s_Layouts.IsBasedOn(m_ExpectedLayout, control.m_Layout))
                    {
                        continue;
                    }

                    // Skip controls that are in their default state.
                    // NOTE: This is the cheapest check with respect to looking at actual state. So
                    //       do this first before looking further at the state.
                    if (control.CheckStateIsAtDefault(statePtr))
                    {
                        continue;
                    }

                    // Skip controls that have no effective value change.
                    // NOTE: This will run the full processor stack and is move involved.
                    if (!control.HasValueChangeIn(statePtr))
                    {
                        continue;
                    }

                    // If it's the control that cancels, abort the operation now.
                    if (!string.IsNullOrEmpty(m_CancelBinding) && InputControlPath.Matches(m_CancelBinding, control))
                    {
                        OnCancel();
                        break;
                    }

                    m_Candidates.Add(control);
                    OnComplete();
                    break;
                }
            }