Use rvalue or const lvalue references for some parameters
[alure.git] / src / devicemanager.cpp
blobe01aa2f3966942bb1f558b6f1adf6763adae12a2
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 DeviceManagerImpl &DeviceManagerImpl::get()
28 static DeviceManagerImpl singleton;
29 return 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
50 Vector<String> list;
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;
59 return list;
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);
74 if(!dev)
76 if(!name || !name[0])
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); }