mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	Input: add device and factory template
This commit is contained in:
		@@ -71,6 +71,7 @@ namespace Log {
 | 
			
		||||
    CLS(Audio)                                                                                     \
 | 
			
		||||
    SUB(Audio, DSP)                                                                                \
 | 
			
		||||
    SUB(Audio, Sink)                                                                               \
 | 
			
		||||
    CLS(Input)                                                                                     \
 | 
			
		||||
    CLS(Loader)
 | 
			
		||||
 | 
			
		||||
// GetClassName is a macro defined by Windows.h, grrr...
 | 
			
		||||
 
 | 
			
		||||
@@ -89,6 +89,7 @@ enum class Class : ClassType {
 | 
			
		||||
    Audio_DSP,         ///< The HLE implementation of the DSP
 | 
			
		||||
    Audio_Sink,        ///< Emulator audio output backend
 | 
			
		||||
    Loader,            ///< ROM loader
 | 
			
		||||
    Input,             ///< Input emulation
 | 
			
		||||
    Count              ///< Total number of logging classes
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -218,6 +218,7 @@ set(HEADERS
 | 
			
		||||
            frontend/camera/factory.h
 | 
			
		||||
            frontend/camera/interface.h
 | 
			
		||||
            frontend/emu_window.h
 | 
			
		||||
            frontend/input.h
 | 
			
		||||
            frontend/key_map.h
 | 
			
		||||
            frontend/motion_emu.h
 | 
			
		||||
            gdbstub/gdbstub.h
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										97
									
								
								src/core/frontend/input.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								src/core/frontend/input.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
// Copyright 2017 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <tuple>
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "common/param_package.h"
 | 
			
		||||
 | 
			
		||||
namespace Input {
 | 
			
		||||
 | 
			
		||||
/// An abstract class template for an input device (a button, an analog input, etc.).
 | 
			
		||||
template <typename StatusType>
 | 
			
		||||
class InputDevice {
 | 
			
		||||
public:
 | 
			
		||||
    virtual ~InputDevice() = default;
 | 
			
		||||
    virtual StatusType GetStatus() const {
 | 
			
		||||
        return {};
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// An abstract class template for a factory that can create input devices.
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
} // namespace Impl
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Registers an input device factory.
 | 
			
		||||
 * @tparam InputDeviceType the type of input devices the factory can create
 | 
			
		||||
 * @param name the name of the factory. Will be used to match the "engine" parameter when creating
 | 
			
		||||
 *     a device
 | 
			
		||||
 * @param factory the factory object to register
 | 
			
		||||
 */
 | 
			
		||||
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 %s already registered", name.c_str());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Unregisters an input device factory.
 | 
			
		||||
 * @tparam InputDeviceType the type of input devices the factory can create
 | 
			
		||||
 * @param name the name of the factory to unregister
 | 
			
		||||
 */
 | 
			
		||||
template <typename InputDeviceType>
 | 
			
		||||
void UnregisterFactory(const std::string& name) {
 | 
			
		||||
    if (Impl::FactoryList<InputDeviceType>::list.erase(name) == 0) {
 | 
			
		||||
        LOG_ERROR(Input, "Factory %s not registered", name.c_str());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create an input device from given paramters.
 | 
			
		||||
 * @tparam InputDeviceType the type of input devices to create
 | 
			
		||||
 * @param params a serialized ParamPackage string contains all parameters for creating the device
 | 
			
		||||
 */
 | 
			
		||||
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: %s", engine.c_str());
 | 
			
		||||
        }
 | 
			
		||||
        return std::make_unique<InputDeviceType>();
 | 
			
		||||
    }
 | 
			
		||||
    return pair->second->Create(package);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Input
 | 
			
		||||
		Reference in New Issue
	
	Block a user