keyboard.cpp 2.5 KB

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