events.cpp 2.8 KB

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