| | |
| | |
| | |
| |
|
| | #pragma once |
| |
|
| | #include <memory> |
| | #include <string> |
| | #include <tuple> |
| | #include <unordered_map> |
| | #include <utility> |
| | #include "common/logging/log.h" |
| | #include "common/param_package.h" |
| | #include "common/vector_math.h" |
| |
|
| | namespace Input { |
| |
|
| | |
| | template <typename StatusType> |
| | class InputDevice { |
| | public: |
| | virtual ~InputDevice() = default; |
| | virtual StatusType GetStatus() const { |
| | return {}; |
| | } |
| | }; |
| |
|
| | |
| | template <typename InputDeviceType> |
| | class Factory { |
| | public: |
| | virtual ~Factory() = default; |
| | virtual std::unique_ptr<InputDeviceType> Create(const Common::ParamPackage&) = 0; |
| | }; |
| |
|
| | namespace Impl { |
| |
|
| | template <typename InputDeviceType> |
| | using FactoryListType = std::unordered_map<std::string, std::shared_ptr<Factory<InputDeviceType>>>; |
| |
|
| | template <typename InputDeviceType> |
| | struct FactoryList { |
| | static FactoryListType<InputDeviceType> list; |
| | }; |
| |
|
| | template <typename InputDeviceType> |
| | FactoryListType<InputDeviceType> FactoryList<InputDeviceType>::list; |
| |
|
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <typename InputDeviceType> |
| | void RegisterFactory(const std::string& name, std::shared_ptr<Factory<InputDeviceType>> factory) { |
| | auto pair = std::make_pair(name, std::move(factory)); |
| | if (!Impl::FactoryList<InputDeviceType>::list.insert(std::move(pair)).second) { |
| | LOG_ERROR(Input, "Factory {} already registered", name); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | template <typename InputDeviceType> |
| | void UnregisterFactory(const std::string& name) { |
| | if (Impl::FactoryList<InputDeviceType>::list.erase(name) == 0) { |
| | LOG_ERROR(Input, "Factory {} not registered", name); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | template <typename InputDeviceType> |
| | std::unique_ptr<InputDeviceType> CreateDevice(const std::string& params) { |
| | const Common::ParamPackage package(params); |
| | const std::string engine = package.Get("engine", "null"); |
| | const auto& factory_list = Impl::FactoryList<InputDeviceType>::list; |
| | const auto pair = factory_list.find(engine); |
| | if (pair == factory_list.end()) { |
| | if (engine != "null") { |
| | LOG_ERROR(Input, "Unknown engine name: {}", engine); |
| | } |
| | return std::make_unique<InputDeviceType>(); |
| | } |
| | return pair->second->Create(package); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | using ButtonDevice = InputDevice<bool>; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | using AnalogDevice = InputDevice<std::tuple<float, float>>; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | using MotionDevice = InputDevice<std::tuple<Common::Vec3<float>, Common::Vec3<float>>>; |
| |
|
| | |
| | |
| | |
| | |
| | using TouchDevice = InputDevice<std::tuple<float, float, bool>>; |
| |
|
| | } |
| |
|