    ////WIP

# Input Events

The input system is event-driven. All input is delivered as events and custom input can be generated by injecting events. Also, by listening in on the events flowing through the system, all source input can be observed.

Input events are a low-level mechanism. Events are stored in unmanaged memory buffers and not converted to C# heap objects. Wrapper APIs are provided but for more involved event manipulations, unsafe code is required.

Note that there is no routing mechanism. Events are delivered from the runtime straight to the input system where they are incorporated directly into device state.

Each event has a set of properties common to all events:

* `type`: FourCC code that indicates what type of event it is.
* `id`: Unique numeric of the event.
* `time`: Timestamp of when the event was generated.
* `deviceId`: ID of the device that the event is targeted at.
* `sizeInBytes`: Total size of the event in bytes.

## Types of Events

### State Events

A state event contains input state for a device. These events are what gets new input into the system.

There are two types of state events:

* `StateEvent`
* `DeltaStateEvent`

`StateEvent` contains a full snapshot of the entire state of a device in the format specific to the device.

### Device Events

Device events indicate a change that is relevant to a device as a whole.

* `DeviceRemovedEvent`
* `DeviceConfigurationEvent`

`DeviceRemovedEvent` indicates that a device has been removed/disconnected.

`DeviceConfigurationEvent` indicates that the configuration of a device has changed. This can have a wide ...

### Text Events

* `TextEvent`
* `IMECompositionEvent`

## Working With Events

### Monitoring Events

### Reading State Events

State events contain raw memory snapshots for devices. As such, interpreting the data in the event requires knowledge about where and how individual state is stored for a given device.

The easiest way to access state contained in a state event is to rely on the device the state is meant for. Any control can be asked to read its value from a given event rather than from its own internally stored state.

For example, the following code demonstrates how to read a value for `Gamepad.leftStick` from a state event targeted at a `Gamepad`.

```
InputSystem.onEvent +=
    eventPtr =>
    {
        // Ignore anything that isn't a state event.
        if (!eventPtr.IsA<StateEvent>() && !eventPtr.IsA<DeltaStateEvent>())
            return;

        var gamepad = InputSystem.GetDeviceById(eventPtr.deviceId) as Gamepad;
        if (gamepad == null)
        {
            // Event isn't for a gamepad or device ID is no longer valid.
            return;
        }

        var leftStickValue = gamepad.leftStick.ReadValueFromEvent(eventPtr);
    };
```

### Creating Events

New input events can be created and queued by anyone and against any existing device. Queueing an input event is thread-safe meaning that event generation can happen in background threads.

>NOTE: Memory allocated to events coming from background threads is limited. If too many events are produced by background threads, queueing an event from a thread will block the thread until the main thread has flushed out the background event queue.

Note that queuing an event will not immediately consume the event. Processing of events happens on the next update (depending `InputSettings.updateMode`, either manually triggered via `InputSystem.Update` or triggered automatically as part of the player loop).

#### Sending State Events

The easiest way to create a state event is directly from the device.

```
// `StateEvent.From` creates a temporary buffer in unmanaged memory holding
// a state event large enough for the given device and containing a memory
// copy of the device's current state.
InputEventPtr eventPtr;
using (StateEvent.From(myDevice, out eventPtr))
{
    ((AxisControl) myDevice["myControl"]).WriteValueIntoEvent(0.5f, eventPtr);
    InputSystem.QueueEvent(eventPtr);
}
```

Another way for sending state is to send events for individual controls.

```
// Send event to update leftStick on the gamepad.
InputSystem.QueueDeltaStateEvent(Gamepad.current.leftStick,
    new Vector2(0.123f, 0.234f);
```

Note that delta state events only work for controls that are both byte-aligned and a multiple of 8 bits in size in memory. It is not supported to, for example, send a delta state event for a button control that is stored as a single bit.

### Capturing Events

### Defining New Types of Events
