PistonDevelopers/input — pull request #30 by tomaka (2014-08-22 15:56:19+00:00)
Title: Concept implementation

Here is a summary of the implementation that I'd propose for this crate.

The library contains two main traits: `Device` and `Event`.

# Devices

An implementation of this library (for example `gl-init` or `glfw-rs`) should provide a way to obtain the list of devices available on the system. The exact way is implementation-specific. For example for `glfw`, you could simply add the functions `get_mouses()`, `get_keyboards()` and `get_gamepads()`.

When an object that implements `Device` is also a keyboard, it should also implement the `KeyboardDevice` trait, defined in the `keyboard` mod. When a device is also a mouse, it should also implement the `MouseDevice` trait, defined in the `mouse` mod. Same for other kind of devices (gamepad, touch screen, kinect, etc.).

These "more precise" traits (`KeyboardDevice`, `MouseDevice`, etc.) allows one to get more specific informations: what is the state of a key, what is the position of the cursor on the screen, etc.

*Defect*: there is currently no way to get the type of a device if you don't know it at compile-time. For example if a device can have both keyboards and gamepads, you need to provide `get_keyboards()` and `get_gamepads()` instead of just `get_devices()`. Associated types will solve this.

# Events

An implementation should also provide objects which represent an input event, and which must implement the `Event` trait.
The exact way that events are provided is implementation specific.
For example for `gl-init`, I would return a list of what happened in the last frame, and one of the things that can happen is an input event. For a more complex implementation you could imaging having a per-device `Sender`.

The `Event` trait allows one to retrieve all the raw informations about an event, ie. which device produced it, which element of the device, and what is the new "value" of the element.
But if you want more informations about an event, you can import either the `ToKeyboardEvent` trait or the `ToMouseEvent` trait, which allow you to turn, if possible, the event into a `KeyboardEvent` or a `MouseEvent`.

`KeyboardEvent` and `MouseEvent` are simple enums that are easier to manipulate.

# Modular

This design is modular. If you want to manipulate raw events, you can just get a list of `Device`s, and receive `Event`s.

If you want to use the keyboard, just use the `input::keyboard` module which contains the definitions for `KeyboardDevice`, `KeyboardEvent` and `ToKeyboardEvent`.

For the moment I have only added the `keyboard` and `mouse` modules, but other modules can be added in the future: kinect, touch screen, wiimote, gamepad, etc. One could even implement its own device type outside of the library, if necessary.