events.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "config.h"
  2. #include "events.h"
  3. #include "alspan.h"
  4. #include "core/logging.h"
  5. #include "device.h"
  6. namespace {
  7. ALCenum EnumFromEventType(const alc::EventType type)
  8. {
  9. switch(type)
  10. {
  11. case alc::EventType::DefaultDeviceChanged: return ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT;
  12. case alc::EventType::DeviceAdded: return ALC_EVENT_TYPE_DEVICE_ADDED_SOFT;
  13. case alc::EventType::DeviceRemoved: return ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT;
  14. case alc::EventType::Count: break;
  15. }
  16. throw std::runtime_error{"Invalid EventType: "+std::to_string(al::to_underlying(type))};
  17. }
  18. } // namespace
  19. namespace alc {
  20. std::optional<alc::EventType> GetEventType(ALCenum type)
  21. {
  22. switch(type)
  23. {
  24. case ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT: return alc::EventType::DefaultDeviceChanged;
  25. case ALC_EVENT_TYPE_DEVICE_ADDED_SOFT: return alc::EventType::DeviceAdded;
  26. case ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT: return alc::EventType::DeviceRemoved;
  27. }
  28. return std::nullopt;
  29. }
  30. void Event(EventType eventType, DeviceType deviceType, ALCdevice *device, std::string_view message) noexcept
  31. {
  32. auto eventlock = std::unique_lock{EventMutex};
  33. if(EventCallback && EventsEnabled.test(al::to_underlying(eventType)))
  34. EventCallback(EnumFromEventType(eventType), al::to_underlying(deviceType), device,
  35. static_cast<ALCsizei>(message.length()), message.data(), EventUserPtr);
  36. }
  37. } // namespace alc
  38. FORCE_ALIGN ALCboolean ALC_APIENTRY alcEventControlSOFT(ALCsizei count, const ALCenum *events,
  39. ALCboolean enable) noexcept
  40. {
  41. if(enable != ALC_FALSE && enable != ALC_TRUE)
  42. {
  43. alcSetError(nullptr, ALC_INVALID_ENUM);
  44. return ALC_FALSE;
  45. }
  46. if(count < 0)
  47. {
  48. alcSetError(nullptr, ALC_INVALID_VALUE);
  49. return ALC_FALSE;
  50. }
  51. if(count == 0)
  52. return ALC_TRUE;
  53. if(!events)
  54. {
  55. alcSetError(nullptr, ALC_INVALID_VALUE);
  56. return ALC_FALSE;
  57. }
  58. alc::EventBitSet eventSet{0};
  59. for(ALCenum type : al::span{events, static_cast<ALCuint>(count)})
  60. {
  61. auto etype = alc::GetEventType(type);
  62. if(!etype)
  63. {
  64. WARN("Invalid event type: 0x%04x\n", type);
  65. alcSetError(nullptr, ALC_INVALID_ENUM);
  66. return ALC_FALSE;
  67. }
  68. eventSet.set(al::to_underlying(*etype));
  69. }
  70. auto eventlock = std::unique_lock{alc::EventMutex};
  71. if(enable) alc::EventsEnabled |= eventSet;
  72. else alc::EventsEnabled &= ~eventSet;
  73. return ALC_TRUE;
  74. }
  75. FORCE_ALIGN void ALC_APIENTRY alcEventCallbackSOFT(ALCEVENTPROCTYPESOFT callback, void *userParam) noexcept
  76. {
  77. auto eventlock = std::unique_lock{alc::EventMutex};
  78. alc::EventCallback = callback;
  79. alc::EventUserPtr = userParam;
  80. }