4 #include "devicemanager.h"
20 static inline void GetDeviceProc(T
**func
, ALCdevice
*device
, const char *name
)
21 { *func
= reinterpret_cast<T
*>(alcGetProcAddress(device
, name
)); }
24 ALCboolean (ALC_APIENTRY
*DeviceManagerImpl::SetThreadContext
)(ALCcontext
*);
26 DeviceManagerImpl
&DeviceManagerImpl::get()
28 static DeviceManagerImpl singleton
;
32 DeviceManagerImpl::DeviceManagerImpl()
34 if(alcIsExtensionPresent(0, "ALC_EXT_thread_local_context"))
35 GetDeviceProc(&SetThreadContext
, 0, "alcSetThreadContext");
38 DeviceManagerImpl::~DeviceManagerImpl()
43 bool DeviceManagerImpl::queryExtension(const char *name
) const
45 return alcIsExtensionPresent(nullptr, name
);
48 Vector
<String
> DeviceManagerImpl::enumerate(DeviceEnumeration type
) const
51 if(type
== DeviceEnumeration::Full
&& !alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT"))
52 type
= DeviceEnumeration::Basic
;
53 const ALCchar
*names
= alcGetString(nullptr, (ALenum
)type
);
54 while(names
&& *names
)
56 list
.emplace_back(names
);
57 names
+= strlen(names
)+1;
62 String
DeviceManagerImpl::defaultDeviceName(DefaultDeviceType type
) const
64 if(type
== DefaultDeviceType::Full
&& !alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT"))
65 type
= DefaultDeviceType::Basic
;
66 const ALCchar
*name
= alcGetString(nullptr, (ALenum
)type
);
67 return name
? String(name
) : String();
71 Device
DeviceManagerImpl::openPlayback(const char *name
)
73 ALCdevice
*dev
= alcOpenDevice(name
);
77 throw std::runtime_error("Failed to open default device");
78 throw std::runtime_error(StringView("Failed to open device \"")+name
+"\"");
80 mDevices
.emplace_back(MakeUnique
<DeviceImpl
>(dev
));
81 return Device(mDevices
.back().get());
84 Device
DeviceManagerImpl::openPlayback(const char *name
, const std::nothrow_t
&)
86 ALCdevice
*dev
= alcOpenDevice(name
);
87 if(!dev
) return Device();
88 mDevices
.emplace_back(MakeUnique
<DeviceImpl
>(dev
));
89 return Device(mDevices
.back().get());
92 void DeviceManagerImpl::removeDevice(DeviceImpl
*dev
)
94 auto iter
= std::find_if(mDevices
.begin(), mDevices
.end(),
95 [dev
](const UniquePtr
<DeviceImpl
> &entry
) -> bool
96 { return entry
.get() == dev
; }
98 if(iter
!= mDevices
.end()) mDevices
.erase(iter
);
102 DeviceManager
DeviceManager::get()
103 { return DeviceManager(&DeviceManagerImpl::get()); }
104 DECL_THUNK1(bool, DeviceManager
, queryExtension
, const, const char*)
105 bool DeviceManager::queryExtension(const String
&name
) const
106 { return pImpl
->queryExtension(name
.c_str()); }
107 DECL_THUNK1(Vector
<String
>, DeviceManager
, enumerate
, const, DeviceEnumeration
)
108 DECL_THUNK1(String
, DeviceManager
, defaultDeviceName
, const, DefaultDeviceType
)
109 DECL_THUNK1(Device
, DeviceManager
, openPlayback
,, const char*)
110 Device
DeviceManager::openPlayback(const String
&name
)
111 { return pImpl
->openPlayback(name
.c_str()); }
112 DECL_THUNK2(Device
, DeviceManager
, openPlayback
,, const char*, const std::nothrow_t
&)
113 Device
DeviceManager::openPlayback(const String
&name
, const std::nothrow_t
&nt
)
114 { return pImpl
->openPlayback(name
.c_str(), nt
); }
115 Device
DeviceManager::openPlayback(const std::nothrow_t
&)
116 { return pImpl
->openPlayback(nullptr, std::nothrow
); }