Avoid a stateful unique_ptr deleter
[openal-soft.git] / alc / device.h
blobdaade87ac65c2e97d39eb3234a93982eb918714f
1 #ifndef ALC_DEVICE_H
2 #define ALC_DEVICE_H
4 #include <atomic>
5 #include <memory>
6 #include <mutex>
7 #include <stdint.h>
8 #include <string>
9 #include <utility>
11 #include "AL/alc.h"
12 #include "AL/alext.h"
14 #include "alconfig.h"
15 #include "almalloc.h"
16 #include "alnumeric.h"
17 #include "core/device.h"
18 #include "intrusive_ptr.h"
19 #include "vector.h"
21 #ifdef ALSOFT_EAX
22 #include "al/eax_x_ram.h"
23 #endif // ALSOFT_EAX
25 struct ALbuffer;
26 struct ALeffect;
27 struct ALfilter;
28 struct BackendBase;
30 using uint = unsigned int;
33 struct BufferSubList {
34 uint64_t FreeMask{~0_u64};
35 ALbuffer *Buffers{nullptr}; /* 64 */
37 BufferSubList() noexcept = default;
38 BufferSubList(const BufferSubList&) = delete;
39 BufferSubList(BufferSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Buffers{rhs.Buffers}
40 { rhs.FreeMask = ~0_u64; rhs.Buffers = nullptr; }
41 ~BufferSubList();
43 BufferSubList& operator=(const BufferSubList&) = delete;
44 BufferSubList& operator=(BufferSubList&& rhs) noexcept
45 { std::swap(FreeMask, rhs.FreeMask); std::swap(Buffers, rhs.Buffers); return *this; }
48 struct EffectSubList {
49 uint64_t FreeMask{~0_u64};
50 ALeffect *Effects{nullptr}; /* 64 */
52 EffectSubList() noexcept = default;
53 EffectSubList(const EffectSubList&) = delete;
54 EffectSubList(EffectSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Effects{rhs.Effects}
55 { rhs.FreeMask = ~0_u64; rhs.Effects = nullptr; }
56 ~EffectSubList();
58 EffectSubList& operator=(const EffectSubList&) = delete;
59 EffectSubList& operator=(EffectSubList&& rhs) noexcept
60 { std::swap(FreeMask, rhs.FreeMask); std::swap(Effects, rhs.Effects); return *this; }
63 struct FilterSubList {
64 uint64_t FreeMask{~0_u64};
65 ALfilter *Filters{nullptr}; /* 64 */
67 FilterSubList() noexcept = default;
68 FilterSubList(const FilterSubList&) = delete;
69 FilterSubList(FilterSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Filters{rhs.Filters}
70 { rhs.FreeMask = ~0_u64; rhs.Filters = nullptr; }
71 ~FilterSubList();
73 FilterSubList& operator=(const FilterSubList&) = delete;
74 FilterSubList& operator=(FilterSubList&& rhs) noexcept
75 { std::swap(FreeMask, rhs.FreeMask); std::swap(Filters, rhs.Filters); return *this; }
79 struct ALCdevice : public al::intrusive_ref<ALCdevice>, DeviceBase {
80 /* This lock protects the device state (format, update size, etc) from
81 * being from being changed in multiple threads, or being accessed while
82 * being changed. It's also used to serialize calls to the backend.
84 std::mutex StateLock;
85 std::unique_ptr<BackendBase> Backend;
87 ALCuint NumMonoSources{};
88 ALCuint NumStereoSources{};
90 // Maximum number of sources that can be created
91 uint SourcesMax{};
92 // Maximum number of slots that can be created
93 uint AuxiliaryEffectSlotMax{};
95 std::string mHrtfName;
96 al::vector<std::string> mHrtfList;
97 ALCenum mHrtfStatus{ALC_FALSE};
99 std::atomic<ALCenum> LastError{ALC_NO_ERROR};
101 // Map of Buffers for this device
102 std::mutex BufferLock;
103 al::vector<BufferSubList> BufferList;
105 // Map of Effects for this device
106 std::mutex EffectLock;
107 al::vector<EffectSubList> EffectList;
109 // Map of Filters for this device
110 std::mutex FilterLock;
111 al::vector<FilterSubList> FilterList;
113 #ifdef ALSOFT_EAX
114 ALsizei eax_x_ram_free_size{eax_x_ram_max_size};
115 #endif // ALSOFT_EAX
118 ALCdevice(DeviceType type);
119 ~ALCdevice();
121 void enumerateHrtfs();
123 bool getConfigValueBool(const char *block, const char *key, int def)
124 { return GetConfigValueBool(DeviceName.c_str(), block, key, def); }
126 template<typename T>
127 al::optional<T> configValue(const char *block, const char *key) = delete;
129 DEF_NEWDEL(ALCdevice)
132 template<>
133 inline al::optional<std::string> ALCdevice::configValue(const char *block, const char *key)
134 { return ConfigValueStr(DeviceName.c_str(), block, key); }
135 template<>
136 inline al::optional<int> ALCdevice::configValue(const char *block, const char *key)
137 { return ConfigValueInt(DeviceName.c_str(), block, key); }
138 template<>
139 inline al::optional<uint> ALCdevice::configValue(const char *block, const char *key)
140 { return ConfigValueUInt(DeviceName.c_str(), block, key); }
141 template<>
142 inline al::optional<float> ALCdevice::configValue(const char *block, const char *key)
143 { return ConfigValueFloat(DeviceName.c_str(), block, key); }
144 template<>
145 inline al::optional<bool> ALCdevice::configValue(const char *block, const char *key)
146 { return ConfigValueBool(DeviceName.c_str(), block, key); }
148 #endif