Rename AL* implementation classes to *Impl
[alure.git] / src / devicemanager.cpp
blob023ac4c54b26af01c088fd8c80cbc58d776af489
2 #include "config.h"
4 #include "devicemanager.h"
5 #include "device.h"
7 #include <string.h>
9 #include <algorithm>
10 #include <stdexcept>
12 #include "alc.h"
13 #include "al.h"
15 namespace alure
18 template<typename T>
19 static inline void GetDeviceProc(T **func, ALCdevice *device, const char *name)
20 { *func = reinterpret_cast<T*>(alcGetProcAddress(device, name)); }
23 ALCboolean (ALC_APIENTRY*DeviceManagerImpl::SetThreadContext)(ALCcontext*);
25 DeviceManagerImpl &DeviceManagerImpl::get()
27 static DeviceManagerImpl singleton;
28 return singleton;
31 DeviceManagerImpl::DeviceManagerImpl()
33 if(alcIsExtensionPresent(0, "ALC_EXT_thread_local_context"))
34 GetDeviceProc(&SetThreadContext, 0, "alcSetThreadContext");
37 DeviceManagerImpl::~DeviceManagerImpl()
42 bool DeviceManagerImpl::queryExtension(const String &name) const
44 return alcIsExtensionPresent(nullptr, name.c_str());
47 Vector<String> DeviceManagerImpl::enumerate(DeviceEnumeration type) const
49 Vector<String> list;
50 if(type == DeviceEnumeration::Full && !alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT"))
51 type = DeviceEnumeration::Basic;
52 const ALCchar *names = alcGetString(nullptr, (ALenum)type);
53 while(names && *names)
55 list.emplace_back(names);
56 names += strlen(names)+1;
58 return list;
61 String DeviceManagerImpl::defaultDeviceName(DefaultDeviceType type) const
63 if(type == DefaultDeviceType::Full && !alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT"))
64 type = DefaultDeviceType::Basic;
65 const ALCchar *name = alcGetString(nullptr, (ALenum)type);
66 return name ? String(name) : String();
70 Device DeviceManagerImpl::openPlayback(const String &name)
72 ALCdevice *dev = alcOpenDevice(name.c_str());
73 if(!dev)
75 if(name.empty())
76 throw std::runtime_error("Failed to open default device");
77 throw std::runtime_error("Failed to open device \""+name+"\"");
79 mDevices.emplace_back(MakeUnique<DeviceImpl>(dev));
80 return Device(mDevices.back().get());
83 Device DeviceManagerImpl::openPlayback(const String &name, const std::nothrow_t&)
85 ALCdevice *dev = alcOpenDevice(name.c_str());
86 if(!dev) return Device();
87 mDevices.emplace_back(MakeUnique<DeviceImpl>(dev));
88 return Device(mDevices.back().get());
91 void DeviceManagerImpl::removeDevice(DeviceImpl *dev)
93 auto iter = std::find_if(mDevices.begin(), mDevices.end(),
94 [dev](const UniquePtr<DeviceImpl> &entry) -> bool
95 { return entry.get() == dev; }
97 if(iter != mDevices.end()) mDevices.erase(iter);
101 DeviceManager DeviceManager::get()
102 { return DeviceManager(&DeviceManagerImpl::get()); }
103 DECL_THUNK1(bool, DeviceManager, queryExtension, const, const String&)
104 DECL_THUNK1(Vector<String>, DeviceManager, enumerate, const, DeviceEnumeration)
105 DECL_THUNK1(String, DeviceManager, defaultDeviceName, const, DefaultDeviceType)
106 DECL_THUNK1(Device, DeviceManager, openPlayback,, const String&)
107 DECL_THUNK2(Device, DeviceManager, openPlayback,, const String&, const std::nothrow_t&)
108 Device DeviceManager::openPlayback(const std::nothrow_t&)
109 { return openPlayback(String(), std::nothrow); }