# Device Source Manager

> Learn about managing input devices with the Device Source Manager.

Source: https://doc.babylonjs.com/features/featuresDeepDive/input/deviceSourceManager

## Introduction

The [DeviceSourceManager](https://doc.babylonjs.com/typedoc/classes/babylon.devicesourcemanager) is a class that manages connections for various user input devices and provides methods for querying those devices for their current state.  
This class supports several methods of input:

- **Keyboard** _(DeviceType: BABYLON.DeviceType.Keyboard, Inputs: number)_
- **Mouse** _(DeviceType: BABYLON.DeviceType.Mouse, Inputs: BABYLON.PointerInput)_
- **Touch** _(DeviceType: BABYLON.DeviceType.Pointer, Inputs: BABYLON.PointerInput)_
- **DualShock Gamepad** _(DeviceType: BABYLON.DeviceType.DualShock, Inputs: BABYLON.DualShockInput)_
- **Xbox Gamepad, One or 360** _(DeviceType: BABYLON.DeviceType.Xbox, Inputs: BABYLON.XboxInput)_
- **Switch Gamepad, L+R JoyCon Grip or Pro Controller** _(DeviceType: BABYLON.DeviceType.Switch, Inputs: BABYLON.SwitchInput)_
- **Generic/Other Gamepad** _(DeviceType: BABYLON.DeviceType.Generic, Inputs: number)_

Here's an example of the DeviceSourceManager in use.
- [Playground: DeviceSourceManager Example](https://playground.babylonjs.com/#C7PM2B#18) - Simple example showing how to use the DeviceSourceManager in your scene.

To use the DeviceSourceManager, first create an instance of it. You will need to provide an engine object.

```javascript
const deviceSourceManager = new BABYLON.DeviceSourceManager(scene.getEngine());
```

Within your scene's render/game loop, you can query the DeviceSourceManager for the current state of a specific input. First, you will need to get the DeviceSource object. With this object, you can then query for a specific input's status.

```javascript
// If the device has been registered in the DeviceSourceManager
if (deviceSourceManager.getDeviceSource(BABYLON.DeviceType.Xbox)) {
  // And the A button was pressed
  if (deviceSourceManager.getDeviceSource(BABYLON.DeviceType.Xbox).getInput(BABYLON.XboxInput.A) === 1) {
    // Do something
  }
}
```

You can also use optional chaining to fit the checks into a single line.

```javascript
if (deviceSourceManager.getDeviceSource(BABYLON.DeviceType.Xbox)?.getInput(BABYLON.XboxInput.A) === 1) {
  // Do something
}
```

## Events and Observables

You can use the following Observables to work with a given device's identifiers.

```javascript
// When a device is registered in the DeviceSourceManager
onDeviceConnectedObservable.add((device) => {
  // You can get the device type by using device.deviceType
  // You can also get the device slot by using device.deviceSlot (default is 0 for keyboard and 1 for mouse)
  // "device" is of Type DeviceSource do you can also access the getInput function or add an observable for onInputChangedObservable
});

// When a device is unregistered in the DeviceSourceManager
onDeviceDisconnectedObservable.add((device) => {
  // You can get the device type by using device.deviceType
  // You can also get the device slot by using device.deviceSlot (default is 0 for keyboard and 1 for mouse)
  // "device" is of Type DeviceSource
});
```

Here's a demonstration of how these Observables work.
- [Playground: Basic DeviceSourceManager Demo](https://playground.babylonjs.com/#Y4YWCD#1) - Simple demonstration of how the DeviceSourceManager observables work

For keyboards and pointers, you can use an event-based system to get the current and previous input when an input is activated.

```javascript
deviceSourceManager.getDeviceSource(BABYLON.DeviceType.Keyboard).onInputChangedObservable.add((eventData) => {
  // eventData will contain the event data that you'd find in something like a PointerEvent or KeyboardEvent
  // eventData also has an additional value inputIndex
});
```
