keyboard.cpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright 2017 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <atomic>
  5. #include <list>
  6. #include <mutex>
  7. #include <utility>
  8. #include "input_common/keyboard.h"
  9. namespace InputCommon {
  10. class KeyButton final : public Input::ButtonDevice {
  11. public:
  12. explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_)
  13. : key_button_list(std::move(key_button_list_)) {}
  14. ~KeyButton() override;
  15. bool GetStatus() const override {
  16. return status.load();
  17. }
  18. friend class KeyButtonList;
  19. private:
  20. std::shared_ptr<KeyButtonList> key_button_list;
  21. std::atomic<bool> status{false};
  22. };
  23. struct KeyButtonPair {
  24. int key_code;
  25. KeyButton* key_button;
  26. };
  27. class KeyButtonList {
  28. public:
  29. void AddKeyButton(int key_code, KeyButton* key_button) {
  30. std::lock_guard<std::mutex> guard(mutex);
  31. list.push_back(KeyButtonPair{key_code, key_button});
  32. }
  33. void RemoveKeyButton(const KeyButton* key_button) {
  34. std::lock_guard<std::mutex> guard(mutex);
  35. list.remove_if(
  36. [key_button](const KeyButtonPair& pair) { return pair.key_button == key_button; });
  37. }
  38. void ChangeKeyStatus(int key_code, bool pressed) {
  39. std::lock_guard<std::mutex> guard(mutex);
  40. for (const KeyButtonPair& pair : list) {
  41. if (pair.key_code == key_code)
  42. pair.key_button->status.store(pressed);
  43. }
  44. }
  45. void ChangeAllKeyStatus(bool pressed) {
  46. std::lock_guard<std::mutex> guard(mutex);
  47. for (const KeyButtonPair& pair : list) {
  48. pair.key_button->status.store(pressed);
  49. }
  50. }
  51. private:
  52. std::mutex mutex;
  53. std::list<KeyButtonPair> list;
  54. };
  55. Keyboard::Keyboard() : key_button_list{std::make_shared<KeyButtonList>()} {}
  56. KeyButton::~KeyButton() {
  57. key_button_list->RemoveKeyButton(this);
  58. }
  59. std::unique_ptr<Input::ButtonDevice> Keyboard::Create(const Common::ParamPackage& params) {
  60. int key_code = params.Get("code", 0);
  61. std::unique_ptr<KeyButton> button = std::make_unique<KeyButton>(key_button_list);
  62. key_button_list->AddKeyButton(key_code, button.get());
  63. return std::move(button);
  64. }
  65. void Keyboard::PressKey(int key_code) {
  66. key_button_list->ChangeKeyStatus(key_code, true);
  67. }
  68. void Keyboard::ReleaseKey(int key_code) {
  69. key_button_list->ChangeKeyStatus(key_code, false);
  70. }
  71. void Keyboard::ReleaseAllKeys() {
  72. key_button_list->ChangeAllKeyStatus(false);
  73. }
  74. } // namespace InputCommon