--- /dev/null
+#ifndef MSP_INPUT_BINDINGS_H_
+#define MSP_INPUT_BINDINGS_H_
+
+#include <msp/datafile/objectloader.h>
+#include <msp/strings/lexicalcast.h>
+#include "control.h"
+#include "device.h"
+#include "keys.h"
+
+namespace Msp {
+namespace Input {
+
+class ControlScheme;
+
+class Bindings
+{
+public:
+ class Loader: public DataFile::ObjectLoader<Bindings>
+ {
+ private:
+ static ActionMap shared_actions;
+
+ public:
+ Loader(Bindings &);
+
+ private:
+ virtual void init_actions();
+
+ void binding(const std::string &);
+ void device_type(DeviceType);
+ void device_name(const std::string &);
+ };
+
+ struct DeviceRef
+ {
+ DeviceType type = UNSPECIFIED;
+ std::string name;
+ };
+
+private:
+ enum AxisSide
+ {
+ POSITIVE,
+ NEGATIVE
+ };
+
+ friend void operator>>(const LexicalConverter &, AxisSide &);
+ friend void operator<<(LexicalConverter &, AxisSide);
+
+public:
+ struct Binding
+ {
+ class Loader: public DataFile::ObjectLoader<Binding>
+ {
+ private:
+ static ActionMap shared_actions;
+
+ public:
+ Loader(Binding &);
+
+ private:
+ virtual void init_actions();
+
+ void axis(unsigned, AxisSide);
+ void button(unsigned);
+ void key(Key k) { button(k); }
+ };
+
+ std::string control;
+ unsigned device;
+ ControlSrcType type;
+ unsigned index;
+ };
+
+private:
+ std::vector<DeviceRef> devices;
+ std::vector<Binding> bindings;
+
+public:
+ const std::vector<DeviceRef> &get_devices() const { return devices; }
+ std::vector<Device *> resolve_devices(Device &) const;
+ bool is_compatible(Device &) const;
+ const std::vector<Binding> &get_bindings() const { return bindings; }
+
+ bool apply_to(ControlScheme &, Device &);
+};
+
+} // namespace Input
+} // namespace Msp
+
+#endif