Sunday, 3 July 2011

Input & Hotkey Management

Input management is one of those things I never really paid a lot of attention to, using simple if-statements inside an Update() or HandleInput() function worked fine is most cases, until recently. Recently I started to notice my input handling got scattered throughout my code-base and a lot of coupling was required to make sure it was handled properly.

To prevent hotkey-clutter (especially when modifiers (ctrl, shift, alt) get involved) I started working on a HotkeyManager that handles groups of Hotkeys in an easily maintanable way. Initially it was supposed to assign a HotkeyGroup to one or more 'editor-states', like 'only-use-this-hotkey-while-in-editmeshmode', I soon realized this wasn't going to be very helpful and I would have to continuously add new states to keep it up to this was scrapped and replaced by a simpler, but more powerful feature - Predicate<T>. Using predicates enables the manager/hotkey to activate only if a predefined condition is met (i.e. if gizmo.IsActive == true -> execute the hotkey-function) it can contain more than one statement such as gizmo.IsActive == true && Camera.IsMoving == false for example...if both conditions are met, the hotkey may execute with the associated Action (the method assigned to the hotkey) The code-snippet below should be able to illustrate its use.

You may have noticed the above code refers to the GizmoComponent class. SetSelectionPool(IEnumerable<ISelectable> selectables) is a new function I've added to more easily support custom collections and to assign new collections at runtime, in my case this is used to switch between vertex- and object-selection more easily. I will add this along with many other improvements to the open-source gizmocomponent at codeplex at some point.

Back to the hotkeys...within InitializeHotkeys() there is a HotkeyGroup class, this class holds a collection of hotkeys that belong to the same component or share similar functionality. These groups are passed to the manager and will be updated automatically.  The Hotkey class is the main class and has several parameters including key (supports all Keys, MouseButtons and GamepadButtons) a KeyPressState (press, release, hold) a KeyModifier (control, shift, alt or a combination - not illustrated in img), the parent  (used by the Predicate to verify the conditions) and the Action to execute after the key is pressed and all conditions are met.

A quick search revealed there are no suitable Input/Hotkey managers (I didn't like any of the libraries available on Codeplex) so I might turn this into an open-source component/library if enough people are interested in such a library.

Actions and Vertex manipulations are also still WIP, I made some progress on both these tasks and should have some something new to blog about soon enough.

No comments:

Post a Comment