InputCommon: add Keyboard

This commit is contained in:
wwylele 2017-01-21 11:53:03 +02:00
parent 70420272ca
commit 38e800f70d
17 changed files with 254 additions and 85 deletions

View file

@ -0,0 +1,15 @@
set(SRCS
keyboard.cpp
main.cpp
)
set(HEADERS
keyboard.h
main.h
)
create_directory_groups(${SRCS} ${HEADERS})
add_library(input_common STATIC ${SRCS} ${HEADERS})
target_link_libraries(input_common common core)

View file

@ -0,0 +1,82 @@
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <atomic>
#include <list>
#include <mutex>
#include "input_common/keyboard.h"
namespace InputCommon {
class KeyButton final : public Input::ButtonDevice {
public:
explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_)
: key_button_list(key_button_list_) {}
~KeyButton();
bool GetStatus() const override {
return status.load();
}
friend class KeyButtonList;
private:
std::shared_ptr<KeyButtonList> key_button_list;
std::atomic<bool> status{false};
};
struct KeyButtonPair {
int key_code;
KeyButton* key_button;
};
class KeyButtonList {
public:
void AddKeyButton(int key_code, KeyButton* key_button) {
std::lock_guard<std::mutex> guard(mutex);
list.push_back(KeyButtonPair{key_code, key_button});
}
void RemoveKeyButton(const KeyButton* key_button) {
std::lock_guard<std::mutex> guard(mutex);
list.remove_if(
[key_button](const KeyButtonPair& pair) { return pair.key_button == key_button; });
}
void ChangeKeyStatus(int key_code, bool pressed) {
std::lock_guard<std::mutex> guard(mutex);
for (const KeyButtonPair& pair : list) {
if (pair.key_code == key_code)
pair.key_button->status.store(pressed);
}
}
private:
std::mutex mutex;
std::list<KeyButtonPair> list;
};
Keyboard::Keyboard() : key_button_list{std::make_shared<KeyButtonList>()} {}
KeyButton::~KeyButton() {
key_button_list->RemoveKeyButton(this);
}
std::unique_ptr<Input::ButtonDevice> Keyboard::Create(const Common::ParamPackage& params) {
int key_code = params.Get("code", 0);
std::unique_ptr<KeyButton> button = std::make_unique<KeyButton>(key_button_list);
key_button_list->AddKeyButton(key_code, button.get());
return std::move(button);
}
void Keyboard::PressKey(int key_code) {
key_button_list->ChangeKeyStatus(key_code, true);
}
void Keyboard::ReleaseKey(int key_code) {
key_button_list->ChangeKeyStatus(key_code, false);
}
} // namespace InputCommon

View file

@ -0,0 +1,45 @@
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include "core/frontend/input.h"
namespace InputCommon {
class KeyButtonList;
/**
* A button device factory representing a keyboard. It receives keyboard events and forward them
* to all button devices it created.
*/
class Keyboard final : public Input::Factory<Input::ButtonDevice> {
public:
Keyboard();
/**
* Creates a button device from a keyboard key
* @param params contains parameters for creating the device:
* - "code": the code of the key to bind with the button
*/
std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override;
/**
* Sets the status of all buttons bound with the key to pressed
* @param key_code the code of the key to press
*/
void PressKey(int key_code);
/**
* Sets the status of all buttons bound with the key to released
* @param key_code the code of the key to release
*/
void ReleaseKey(int key_code);
private:
std::shared_ptr<KeyButtonList> key_button_list;
};
} // namespace InputCommon

35
src/input_common/main.cpp Normal file
View file

@ -0,0 +1,35 @@
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <memory>
#include "common/param_package.h"
#include "input_common/keyboard.h"
#include "input_common/main.h"
namespace InputCommon {
static std::shared_ptr<Keyboard> keyboard;
void Init() {
keyboard = std::make_shared<InputCommon::Keyboard>();
Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard);
}
void Shutdown() {
Input::UnregisterFactory<Input::ButtonDevice>("keyboard");
keyboard.reset();
}
Keyboard* GetKeyboard() {
return keyboard.get();
}
std::string GenerateKeyboardParam(int key_code) {
Common::ParamPackage param{
{"engine", "keyboard"}, {"code", std::to_string(key_code)},
};
return param.Serialize();
}
} // namespace InputCommon

25
src/input_common/main.h Normal file
View file

@ -0,0 +1,25 @@
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <string>
namespace InputCommon {
/// Initializes and registers all built-in input device factories.
void Init();
/// Unresisters all build-in input device factories and shut them down.
void Shutdown();
class Keyboard;
/// Gets the keyboard button device factory.
Keyboard* GetKeyboard();
/// Generates a serialized param package for creating a keyboard button device
std::string GenerateKeyboardParam(int key_code);
} // namespace InputCommon