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