4 #include "devicemanager.h"
18 std::string
alc_category::message(int condition
) const
22 case ALC_NO_ERROR
: return "No error";
23 case ALC_INVALID_ENUM
: return "Invalid enum";
24 case ALC_INVALID_VALUE
: return "Invalid value";
25 case ALC_INVALID_DEVICE
: return "Invalid device";
26 case ALC_INVALID_CONTEXT
: return "Invalid context";
27 case ALC_OUT_OF_MEMORY
: return "Out of memory";
29 return "Unknown ALC error "+std::to_string(condition
);
32 std::string
al_category::message(int condition
) const
36 case AL_NO_ERROR
: return "No error";
37 case AL_INVALID_NAME
: return "Invalid name";
38 case AL_INVALID_ENUM
: return "Invalid enum";
39 case AL_INVALID_VALUE
: return "Invalid value";
40 case AL_INVALID_OPERATION
: return "Invalid operation";
41 case AL_OUT_OF_MEMORY
: return "Out of memory";
43 return "Unknown AL error "+std::to_string(condition
);
46 alc_category
alc_category::sSingleton
;
47 al_category
al_category::sSingleton
;
51 static inline void GetDeviceProc(T
*&func
, ALCdevice
*device
, const char *name
)
52 { func
= reinterpret_cast<T
*>(alcGetProcAddress(device
, name
)); }
55 WeakPtr
<DeviceManagerImpl
> DeviceManagerImpl::sInstance
;
56 ALCboolean (ALC_APIENTRY
*DeviceManagerImpl::SetThreadContext
)(ALCcontext
*);
58 DeviceManager::DeviceManager(SharedPtr
<DeviceManagerImpl
>&& impl
) noexcept
59 : pImpl(std::move(impl
))
62 DeviceManager::~DeviceManager() { }
64 DeviceManager
DeviceManager::getInstance()
65 { return DeviceManager(DeviceManagerImpl::getInstance()); }
66 SharedPtr
<DeviceManagerImpl
> DeviceManagerImpl::getInstance()
68 SharedPtr
<DeviceManagerImpl
> ret
= sInstance
.lock();
71 ret
= MakeShared
<DeviceManagerImpl
>();
78 DeviceManagerImpl::DeviceManagerImpl()
80 if(alcIsExtensionPresent(nullptr, "ALC_EXT_thread_local_context"))
81 GetDeviceProc(SetThreadContext
, nullptr, "alcSetThreadContext");
84 DeviceManagerImpl::~DeviceManagerImpl()
89 bool DeviceManager::queryExtension(const String
&name
) const
90 { return queryExtension(name
.c_str()); }
91 DECL_THUNK1(bool, DeviceManager
, queryExtension
, const, const char*)
92 bool DeviceManagerImpl::queryExtension(const char *name
) const
94 return static_cast<bool>(alcIsExtensionPresent(nullptr, name
));
97 DECL_THUNK1(Vector
<String
>, DeviceManager
, enumerate
, const, DeviceEnumeration
)
98 Vector
<String
> DeviceManagerImpl::enumerate(DeviceEnumeration type
) const
101 if(type
== DeviceEnumeration::Full
&& !alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT"))
102 type
= DeviceEnumeration::Basic
;
103 const ALCchar
*names
= alcGetString(nullptr, (ALenum
)type
);
104 while(names
&& *names
)
106 list
.emplace_back(names
);
107 names
+= strlen(names
)+1;
112 DECL_THUNK1(String
, DeviceManager
, defaultDeviceName
, const, DefaultDeviceType
)
113 String
DeviceManagerImpl::defaultDeviceName(DefaultDeviceType type
) const
115 if(type
== DefaultDeviceType::Full
&& !alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT"))
116 type
= DefaultDeviceType::Basic
;
117 const ALCchar
*name
= alcGetString(nullptr, (ALenum
)type
);
118 return name
? String(name
) : String();
122 Device
DeviceManager::openPlayback(const String
&name
)
123 { return openPlayback(name
.c_str()); }
124 DECL_THUNK1(Device
, DeviceManager
, openPlayback
,, const char*)
125 Device
DeviceManagerImpl::openPlayback(const char *name
)
127 mDevices
.emplace_back(MakeUnique
<DeviceImpl
>(name
));
128 return Device(mDevices
.back().get());
131 Device
DeviceManager::openPlayback(const String
&name
, const std::nothrow_t
&nt
) noexcept
132 { return openPlayback(name
.c_str(), nt
); }
133 Device
DeviceManager::openPlayback(const std::nothrow_t
&) noexcept
134 { return openPlayback(nullptr, std::nothrow
); }
135 DECL_THUNK2(Device
, DeviceManager
, openPlayback
, noexcept
, const char*, const std::nothrow_t
&)
136 Device
DeviceManagerImpl::openPlayback(const char *name
, const std::nothrow_t
&) noexcept
139 return openPlayback(name
);
146 void DeviceManagerImpl::removeDevice(DeviceImpl
*dev
)
148 auto iter
= std::find_if(mDevices
.begin(), mDevices
.end(),
149 [dev
](const UniquePtr
<DeviceImpl
> &entry
) -> bool
150 { return entry
.get() == dev
; }
152 if(iter
!= mDevices
.end()) mDevices
.erase(iter
);