keyboard.cpp 2.4 KB

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