Ejemplo n.º 1
0
        protected void Update()
        {
            model.CheckPluginsHaveChanged();

            if (model.IsRecording)
            {
                model.RecordUpdate();
            }

            // If no keys are pressed then just exit out
            if (!InputWrapper.AnyKeyOrAxis())
            {
                if (model.IsRecording)
                {
                    model.RecordFinish();
                }

                foreach (var noLongerPressed in _activeBindings)
                {
                    // axis commands really benefit from a final "reset to 0" command run -- so do that
                    if (noLongerPressed.KeyChord.HasAxis)
                    {
                        model.EnqueueAction(
                            new BindingEvent {
                            EventName = BindingEvent.ON_BINDING_REPEAT,
                            Command   = noLongerPressed.Command,
                            Binding   = noLongerPressed,
                            Args      = new CommandExecuteEventArgs
                            {
                                KeyBinding = noLongerPressed,
                                Data       = 0,
                                IsRepeat   = true
                            }
                        }
                            );
                    }
                }
                _activeBindings.Clear();

                return;
            }

            if (model.IsRecording)
            {
                return;
            }

            // If we are typing somewhere else, don't listen for keybindings
            var focusedObject = EventSystem.current.currentSelectedGameObject;

            if (focusedObject != null && focusedObject.GetComponent <UnityEngine.UI.InputField>() != null)
            {
                return;
            }

            // get all bindings that match the keys being pressed ordered by the most specific ones first
            var matches = model.KeyBindings
                          .Where((b) => b.KeyChord.IsBeingPressed())
                          .OrderByDescending((b) => b.KeyChord.Length)
                          .ToList();

            // nothing being pressed
            if (matches.Count == 0)
            {
                _activeBindings.Clear();
                return;
            }

            // see if anything used to be pressed but is not anymore
            foreach (var noLongerPressed in _activeBindings.Where((b) => !matches.Contains(b)))
            {
                // axis commands really benefit from a final "reset to 0" command run -- so do that
                if (noLongerPressed.KeyChord.HasAxis)
                {
                    model.EnqueueAction(
                        new BindingEvent {
                        EventName = BindingEvent.ON_BINDING_UP,
                        Command   = noLongerPressed.Command,
                        Binding   = noLongerPressed,
                        Args      = new CommandExecuteEventArgs
                        {
                            KeyBinding = noLongerPressed,
                            Data       = 0,
                            IsRepeat   = true
                        }
                    }
                        );
                }
            }
            // remove only the inactive bindings
            _activeBindings.RemoveWhere((b) => !matches.Contains(b));

            foreach (var binding in matches)
            {
                var chord  = binding.KeyChord;
                var action = binding.Action;

                // did another binding get triggered that is a superset of us?
                // (or are we a subset of an action that was just triggered)
                if (_activeBindings.Any((b) => chord.IsProperSubsetOf(b.KeyChord)))
                {
                    // .. then consider us already tiggered
                    continue;
                }

                if (chord.IsBeingRepeated())
                {
                    // Check repeat if still holding down last key
                    if (_activeBindings.Any((b) => b.Equals(binding)))
                    {
                        // Still holding down the key... is it time for a repeat?
                        if (Time.unscaledTime >= _chordRepeatTimestamp)
                        {
                            _chordRepeatTimestamp = Time.unscaledTime + binding.Command.RepeatSpeed;
                            model.EnqueueAction(
                                new BindingEvent {
                                EventName = BindingEvent.ON_BINDING_REPEAT,
                                Command   = binding.Command,
                                Binding   = binding,
                                Args      = new CommandExecuteEventArgs
                                {
                                    KeyBinding = binding,
                                    Data       = binding.KeyChord.GetPressedValue(),
                                    IsRepeat   = true
                                }
                            }
                                );
                        }
                    }
                    else
                    {
                        _activeBindings.Add(binding);
                        _chordRepeatTimestamp = Time.unscaledTime + binding.Command.RepeatDelay;
                    }
                }
                else
                {
                    // Handle the keypress and set the repeat delay timer
                    model.EnqueueAction(
                        new BindingEvent {
                        EventName = BindingEvent.ON_BINDING_DOWN,
                        Command   = binding.Command,
                        Binding   = binding,
                        Args      = new CommandExecuteEventArgs
                        {
                            KeyBinding = binding,
                            Data       = binding.KeyChord.GetPressedValue(),
                            IsRepeat   = false
                        }
                    }
                        );

                    _chordRepeatTimestamp = Time.unscaledTime + binding.Command.RepeatDelay;
                    _activeBindings.Add(binding);
                }
            }

            // run any queue commands for this phase
            foreach (var e in model.DequeueActionForUpdate())
            {
                var result = e.Execute();
            }
        }