Mark the nothrow methods explicitly noexcept
[alure.git] / src / devicemanager.cpp
blob1442d30eab8119d4c39abff7877e167070e9f36f
2 #include "config.h"
4 #include "devicemanager.h"
5 #include "device.h"
7 #include <string.h>
9 #include <algorithm>
10 #include <stdexcept>
11 #include <iostream>
13 #include "alc.h"
14 #include "al.h"
16 namespace alure
19 template<typename T>
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 DeviceManager DeviceManager::get()
27 { return DeviceManager(&DeviceManagerImpl::get()); }
28 DeviceManagerImpl &DeviceManagerImpl::get()
30 static DeviceManagerImpl singleton;
31 return singleton;
35 DeviceManagerImpl::DeviceManagerImpl()
37 if(alcIsExtensionPresent(0, "ALC_EXT_thread_local_context"))
38 GetDeviceProc(&SetThreadContext, 0, "alcSetThreadContext");
41 DeviceManagerImpl::~DeviceManagerImpl()
46 bool DeviceManager::queryExtension(const String &name) const
47 { return pImpl->queryExtension(name.c_str()); }
48 DECL_THUNK1(bool, DeviceManager, queryExtension, const, const char*)
49 bool DeviceManagerImpl::queryExtension(const char *name) const
51 return alcIsExtensionPresent(nullptr, name);
54 DECL_THUNK1(Vector<String>, DeviceManager, enumerate, const, DeviceEnumeration)
55 Vector<String> DeviceManagerImpl::enumerate(DeviceEnumeration type) const
57 Vector<String> list;
58 if(type == DeviceEnumeration::Full && !alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT"))
59 type = DeviceEnumeration::Basic;
60 const ALCchar *names = alcGetString(nullptr, (ALenum)type);
61 while(names && *names)
63 list.emplace_back(names);
64 names += strlen(names)+1;
66 return list;
69 DECL_THUNK1(String, DeviceManager, defaultDeviceName, const, DefaultDeviceType)
70 String DeviceManagerImpl::defaultDeviceName(DefaultDeviceType type) const
72 if(type == DefaultDeviceType::Full && !alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT"))
73 type = DefaultDeviceType::Basic;
74 const ALCchar *name = alcGetString(nullptr, (ALenum)type);
75 return name ? String(name) : String();
79 Device DeviceManager::openPlayback(const String &name)
80 { return pImpl->openPlayback(name.c_str()); }
81 DECL_THUNK1(Device, DeviceManager, openPlayback,, const char*)
82 Device DeviceManagerImpl::openPlayback(const char *name)
84 ALCdevice *dev = alcOpenDevice(name);
85 if(dev)
87 try {
88 mDevices.emplace_back(MakeUnique<DeviceImpl>(dev));
89 return Device(mDevices.back().get());
91 catch(...) {
92 alcCloseDevice(dev);
93 throw;
96 if(!name || !name[0])
97 throw std::runtime_error("Failed to open default device");
98 throw std::runtime_error(StringView("Failed to open device \"")+name+"\"");
101 Device DeviceManager::openPlayback(const String &name, const std::nothrow_t &nt) noexcept
102 { return pImpl->openPlayback(name.c_str(), nt); }
103 Device DeviceManager::openPlayback(const std::nothrow_t&) noexcept
104 { return pImpl->openPlayback(nullptr, std::nothrow); }
105 DECL_THUNK2(Device, DeviceManager, openPlayback, noexcept, const char*, const std::nothrow_t&)
106 Device DeviceManagerImpl::openPlayback(const char *name, const std::nothrow_t&) noexcept
108 try {
109 openPlayback(name);
111 catch(...) {
113 return Device();
116 void DeviceManagerImpl::removeDevice(DeviceImpl *dev)
118 auto iter = std::find_if(mDevices.begin(), mDevices.end(),
119 [dev](const UniquePtr<DeviceImpl> &entry) -> bool
120 { return entry.get() == dev; }
122 if(iter != mDevices.end()) mDevices.erase(iter);