| |
| |
| |
|
|
| #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>>; |
|
|
| } |
|
|