[+] Aurora Engine wrappers
[*] Unfuck legacy build pipeline dependency, now compiles under our buildchain [-] Partially strip legacy logger [-] Removed TRACE that doesn't compile with our logger [*] Use Aurora Runtime for IO when possible [TODO] Wrap Aurora Runtime streams
This commit is contained in:
parent
7fb6d64ca8
commit
9ddf5419f0
@ -49,7 +49,6 @@ namespace {
|
||||
|
||||
class filter_exception final : public al::base_exception {
|
||||
public:
|
||||
[[gnu::format(printf, 3, 4)]]
|
||||
filter_exception(ALenum code, const char *msg, ...) : base_exception{code}
|
||||
{
|
||||
std::va_list args;
|
||||
|
@ -350,7 +350,7 @@ struct ALCdevice : public al::intrusive_ref<ALCdevice> {
|
||||
void renderSamples(void *outBuffer, const ALuint numSamples, const size_t frameStep);
|
||||
|
||||
/* Caller must lock the device state, and the mixer must not be running. */
|
||||
[[gnu::format(printf,2,3)]] void handleDisconnect(const char *msg, ...);
|
||||
void handleDisconnect(const char *msg, ...);
|
||||
|
||||
DEF_NEWDEL(ALCdevice)
|
||||
};
|
||||
|
169
alc/alconfig.cpp
169
alc/alconfig.cpp
@ -25,13 +25,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
@ -280,162 +274,25 @@ void LoadConfigFromFile(std::istream &f)
|
||||
} // namespace
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
void ReadALConfig()
|
||||
{
|
||||
WCHAR buffer[MAX_PATH];
|
||||
if(SHGetSpecialFolderPathW(nullptr, buffer, CSIDL_APPDATA, FALSE) != FALSE)
|
||||
{
|
||||
std::string filepath{wstr_to_utf8(buffer)};
|
||||
filepath += "\\alsoft.ini";
|
||||
AuString configBuffer;
|
||||
|
||||
TRACE("Loading config %s...\n", filepath.c_str());
|
||||
al::ifstream f{filepath};
|
||||
if(f.is_open())
|
||||
LoadConfigFromFile(f);
|
||||
AuString pathA;
|
||||
Aurora::FS::GetSystemDomain("OpenAL", pathA);
|
||||
pathA += "configuration.ini";
|
||||
|
||||
if (!Aurora::FS::ReadString(pathA, configBuffer))
|
||||
{
|
||||
if (!Aurora::FS::ReadString("openal.ini", configBuffer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ppath{GetProcBinary().path};
|
||||
if(!ppath.empty())
|
||||
{
|
||||
ppath += "\\alsoft.ini";
|
||||
TRACE("Loading config %s...\n", ppath.c_str());
|
||||
al::ifstream f{ppath};
|
||||
if(f.is_open())
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
|
||||
if(auto confpath = al::getenv(L"ALSOFT_CONF"))
|
||||
{
|
||||
TRACE("Loading config %s...\n", wstr_to_utf8(confpath->c_str()).c_str());
|
||||
al::ifstream f{*confpath};
|
||||
if(f.is_open())
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
LoadConfigFromFile(std::istringstream(configBuffer));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void ReadALConfig()
|
||||
{
|
||||
const char *str{"/etc/openal/alsoft.conf"};
|
||||
|
||||
TRACE("Loading config %s...\n", str);
|
||||
al::ifstream f{str};
|
||||
if(f.is_open())
|
||||
LoadConfigFromFile(f);
|
||||
f.close();
|
||||
|
||||
std::string confpaths{al::getenv("XDG_CONFIG_DIRS").value_or("/etc/xdg")};
|
||||
/* Go through the list in reverse, since "the order of base directories
|
||||
* denotes their importance; the first directory listed is the most
|
||||
* important". Ergo, we need to load the settings from the later dirs
|
||||
* first so that the settings in the earlier dirs override them.
|
||||
*/
|
||||
std::string fname;
|
||||
while(!confpaths.empty())
|
||||
{
|
||||
auto next = confpaths.find_last_of(':');
|
||||
if(next < confpaths.length())
|
||||
{
|
||||
fname = confpaths.substr(next+1);
|
||||
confpaths.erase(next);
|
||||
}
|
||||
else
|
||||
{
|
||||
fname = confpaths;
|
||||
confpaths.clear();
|
||||
}
|
||||
|
||||
if(fname.empty() || fname.front() != '/')
|
||||
WARN("Ignoring XDG config dir: %s\n", fname.c_str());
|
||||
else
|
||||
{
|
||||
if(fname.back() != '/') fname += "/alsoft.conf";
|
||||
else fname += "alsoft.conf";
|
||||
|
||||
TRACE("Loading config %s...\n", fname.c_str());
|
||||
f = al::ifstream{fname};
|
||||
if(f.is_open())
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
fname.clear();
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
||||
if(mainBundle)
|
||||
{
|
||||
unsigned char fileName[PATH_MAX];
|
||||
CFURLRef configURL;
|
||||
|
||||
if((configURL=CFBundleCopyResourceURL(mainBundle, CFSTR(".alsoftrc"), CFSTR(""), nullptr)) &&
|
||||
CFURLGetFileSystemRepresentation(configURL, true, fileName, sizeof(fileName)))
|
||||
{
|
||||
f = al::ifstream{reinterpret_cast<char*>(fileName)};
|
||||
if(f.is_open())
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(auto homedir = al::getenv("HOME"))
|
||||
{
|
||||
fname = *homedir;
|
||||
if(fname.back() != '/') fname += "/.alsoftrc";
|
||||
else fname += ".alsoftrc";
|
||||
|
||||
TRACE("Loading config %s...\n", fname.c_str());
|
||||
f = al::ifstream{fname};
|
||||
if(f.is_open())
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
|
||||
if(auto configdir = al::getenv("XDG_CONFIG_HOME"))
|
||||
{
|
||||
fname = *configdir;
|
||||
if(fname.back() != '/') fname += "/alsoft.conf";
|
||||
else fname += "alsoft.conf";
|
||||
}
|
||||
else
|
||||
{
|
||||
fname.clear();
|
||||
if(auto homedir = al::getenv("HOME"))
|
||||
{
|
||||
fname = *homedir;
|
||||
if(fname.back() != '/') fname += "/.config/alsoft.conf";
|
||||
else fname += ".config/alsoft.conf";
|
||||
}
|
||||
}
|
||||
if(!fname.empty())
|
||||
{
|
||||
TRACE("Loading config %s...\n", fname.c_str());
|
||||
f = al::ifstream{fname};
|
||||
if(f.is_open())
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
|
||||
std::string ppath{GetProcBinary().path};
|
||||
if(!ppath.empty())
|
||||
{
|
||||
if(ppath.back() != '/') ppath += "/alsoft.conf";
|
||||
else ppath += "alsoft.conf";
|
||||
|
||||
TRACE("Loading config %s...\n", ppath.c_str());
|
||||
f = al::ifstream{ppath};
|
||||
if(f.is_open())
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
|
||||
if(auto confname = al::getenv("ALSOFT_CONF"))
|
||||
{
|
||||
TRACE("Loading config %s...\n", confname->c_str());
|
||||
f = al::ifstream{*confname};
|
||||
if(f.is_open())
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *GetConfigValue(const char *devName, const char *blockName, const char *keyName, const char *def)
|
||||
{
|
||||
|
@ -221,7 +221,7 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext> {
|
||||
/** Resumes update processing after being deferred. */
|
||||
void processUpdates();
|
||||
|
||||
[[gnu::format(printf,3,4)]] void setError(ALenum errorCode, const char *msg, ...);
|
||||
void setError(ALenum errorCode, const char *msg, ...);
|
||||
|
||||
DEF_NEWDEL(ALCcontext)
|
||||
};
|
||||
|
@ -95,7 +95,6 @@ namespace al {
|
||||
|
||||
class backend_exception final : public base_exception {
|
||||
public:
|
||||
[[gnu::format(printf, 3, 4)]]
|
||||
backend_exception(ALCenum code, const char *msg, ...) : base_exception{code}
|
||||
{
|
||||
std::va_list args;
|
||||
|
@ -161,7 +161,7 @@ BOOL CALLBACK DSoundEnumDevices(GUID *guid, const WCHAR *desc, const WCHAR*, voi
|
||||
HRESULT hr{StringFromCLSID(*guid, &guidstr)};
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
TRACE("Got device \"%s\", GUID \"%ls\"\n", newentry.name.c_str(), guidstr);
|
||||
//TRACE("Got device \"%s\", GUID \"%ls\"\n", newentry.name.c_str(), guidstr);
|
||||
CoTaskMemFree(guidstr);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1 @@
|
||||
#ifndef AL_COMPAT_H
|
||||
#define AL_COMPAT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
struct PathNamePair { std::string path, fname; };
|
||||
const PathNamePair &GetProcBinary(void);
|
||||
|
||||
#endif /* AL_COMPAT_H */
|
||||
|
@ -129,7 +129,6 @@ union EffectProps {
|
||||
|
||||
class effect_exception final : public al::base_exception {
|
||||
public:
|
||||
[[gnu::format(printf, 3, 4)]]
|
||||
effect_exception(ALenum code, const char *msg, ...);
|
||||
};
|
||||
|
||||
|
446
alc/helpers.cpp
446
alc/helpers.cpp
@ -40,46 +40,6 @@
|
||||
#include "vector.h"
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <shlobj.h>
|
||||
|
||||
const PathNamePair &GetProcBinary()
|
||||
{
|
||||
static PathNamePair ret;
|
||||
if(!ret.fname.empty() || !ret.path.empty())
|
||||
return ret;
|
||||
|
||||
auto fullpath = al::vector<WCHAR>(256);
|
||||
DWORD len;
|
||||
while((len=GetModuleFileNameW(nullptr, fullpath.data(), static_cast<DWORD>(fullpath.size()))) == fullpath.size())
|
||||
fullpath.resize(fullpath.size() << 1);
|
||||
if(len == 0)
|
||||
{
|
||||
ERR("Failed to get process name: error %lu\n", GetLastError());
|
||||
return ret;
|
||||
}
|
||||
|
||||
fullpath.resize(len);
|
||||
if(fullpath.back() != 0)
|
||||
fullpath.push_back(0);
|
||||
|
||||
auto sep = std::find(fullpath.rbegin()+1, fullpath.rend(), '\\');
|
||||
sep = std::find(fullpath.rbegin()+1, sep, '/');
|
||||
if(sep != fullpath.rend())
|
||||
{
|
||||
*sep = 0;
|
||||
ret.fname = wstr_to_utf8(&*sep + 1);
|
||||
ret.path = wstr_to_utf8(fullpath.data());
|
||||
}
|
||||
else
|
||||
ret.fname = wstr_to_utf8(fullpath.data());
|
||||
|
||||
TRACE("Got binary: %s, %s\n", ret.path.c_str(), ret.fname.c_str());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void al_print(LogLevel level, FILE *logfile, const char *fmt, ...)
|
||||
{
|
||||
al::vector<char> dynmsg;
|
||||
@ -99,413 +59,11 @@ void al_print(LogLevel level, FILE *logfile, const char *fmt, ...)
|
||||
va_end(args2);
|
||||
va_end(args);
|
||||
|
||||
std::wstring wstr{utf8_to_wstr(str)};
|
||||
if(gLogLevel >= level)
|
||||
{
|
||||
fputws(wstr.c_str(), logfile);
|
||||
fflush(logfile);
|
||||
}
|
||||
OutputDebugStringW(wstr.c_str());
|
||||
Aurora::Console::Logging::LogGame(str);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void DirectorySearch(const char *path, const char *ext, al::vector<std::string> *const results)
|
||||
{
|
||||
std::string pathstr{path};
|
||||
pathstr += "\\*";
|
||||
pathstr += ext;
|
||||
TRACE("Searching %s\n", pathstr.c_str());
|
||||
|
||||
std::wstring wpath{utf8_to_wstr(pathstr.c_str())};
|
||||
WIN32_FIND_DATAW fdata;
|
||||
HANDLE hdl{FindFirstFileW(wpath.c_str(), &fdata)};
|
||||
if(hdl == INVALID_HANDLE_VALUE) return;
|
||||
|
||||
const auto base = results->size();
|
||||
|
||||
do {
|
||||
results->emplace_back();
|
||||
std::string &str = results->back();
|
||||
str = path;
|
||||
str += '\\';
|
||||
str += wstr_to_utf8(fdata.cFileName);
|
||||
} while(FindNextFileW(hdl, &fdata));
|
||||
FindClose(hdl);
|
||||
|
||||
const al::span<std::string> newlist{results->data()+base, results->size()-base};
|
||||
std::sort(newlist.begin(), newlist.end());
|
||||
for(const auto &name : newlist)
|
||||
TRACE(" got %s\n", name.c_str());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
al::vector<std::string> SearchDataFiles(const char *ext, const char *subdir)
|
||||
{
|
||||
auto is_slash = [](int c) noexcept -> int { return (c == '\\' || c == '/'); };
|
||||
|
||||
static std::mutex search_lock;
|
||||
std::lock_guard<std::mutex> _{search_lock};
|
||||
|
||||
/* If the path is absolute, use it directly. */
|
||||
al::vector<std::string> results;
|
||||
if(isalpha(subdir[0]) && subdir[1] == ':' && is_slash(subdir[2]))
|
||||
{
|
||||
std::string path{subdir};
|
||||
std::replace(path.begin(), path.end(), '/', '\\');
|
||||
DirectorySearch(path.c_str(), ext, &results);
|
||||
return results;
|
||||
}
|
||||
if(subdir[0] == '\\' && subdir[1] == '\\' && subdir[2] == '?' && subdir[3] == '\\')
|
||||
{
|
||||
DirectorySearch(subdir, ext, &results);
|
||||
return results;
|
||||
}
|
||||
|
||||
std::string path;
|
||||
|
||||
/* Search the app-local directory. */
|
||||
if(auto localpath = al::getenv(L"ALSOFT_LOCAL_PATH"))
|
||||
{
|
||||
path = wstr_to_utf8(localpath->c_str());
|
||||
if(is_slash(path.back()))
|
||||
path.pop_back();
|
||||
}
|
||||
else if(WCHAR *cwdbuf{_wgetcwd(nullptr, 0)})
|
||||
{
|
||||
path = wstr_to_utf8(cwdbuf);
|
||||
if(is_slash(path.back()))
|
||||
path.pop_back();
|
||||
free(cwdbuf);
|
||||
}
|
||||
else
|
||||
path = ".";
|
||||
std::replace(path.begin(), path.end(), '/', '\\');
|
||||
DirectorySearch(path.c_str(), ext, &results);
|
||||
|
||||
/* Search the local and global data dirs. */
|
||||
static const int ids[2]{ CSIDL_APPDATA, CSIDL_COMMON_APPDATA };
|
||||
for(int id : ids)
|
||||
{
|
||||
WCHAR buffer[MAX_PATH];
|
||||
if(SHGetSpecialFolderPathW(nullptr, buffer, id, FALSE) == FALSE)
|
||||
continue;
|
||||
|
||||
path = wstr_to_utf8(buffer);
|
||||
if(!is_slash(path.back()))
|
||||
path += '\\';
|
||||
path += subdir;
|
||||
std::replace(path.begin(), path.end(), '/', '\\');
|
||||
|
||||
DirectorySearch(path.c_str(), ext, &results);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
void SetRTPriority(void)
|
||||
{
|
||||
if(RTPrioLevel > 0)
|
||||
{
|
||||
if(!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL))
|
||||
ERR("Failed to set priority level for thread\n");
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#ifdef __HAIKU__
|
||||
#include <FindDirectory.h>
|
||||
#endif
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
#ifdef HAVE_PROC_PIDPATH
|
||||
#include <libproc.h>
|
||||
#endif
|
||||
#if defined(HAVE_PTHREAD_SETSCHEDPARAM) && !defined(__OpenBSD__)
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
const PathNamePair &GetProcBinary()
|
||||
{
|
||||
static PathNamePair ret;
|
||||
if(!ret.fname.empty() || !ret.path.empty())
|
||||
return ret;
|
||||
|
||||
al::vector<char> pathname;
|
||||
#ifdef __FreeBSD__
|
||||
size_t pathlen;
|
||||
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
|
||||
if(sysctl(mib, 4, nullptr, &pathlen, nullptr, 0) == -1)
|
||||
WARN("Failed to sysctl kern.proc.pathname: %s\n", strerror(errno));
|
||||
else
|
||||
{
|
||||
pathname.resize(pathlen + 1);
|
||||
sysctl(mib, 4, pathname.data(), &pathlen, nullptr, 0);
|
||||
pathname.resize(pathlen);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_PROC_PIDPATH
|
||||
if(pathname.empty())
|
||||
{
|
||||
char procpath[PROC_PIDPATHINFO_MAXSIZE]{};
|
||||
const pid_t pid{getpid()};
|
||||
if(proc_pidpath(pid, procpath, sizeof(procpath)) < 1)
|
||||
ERR("proc_pidpath(%d, ...) failed: %s\n", pid, strerror(errno));
|
||||
else
|
||||
pathname.insert(pathname.end(), procpath, procpath+strlen(procpath));
|
||||
}
|
||||
#endif
|
||||
#ifdef __HAIKU__
|
||||
char procpath[PATH_MAX];
|
||||
if(find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, NULL, procpath, sizeof(procpath)) == B_OK)
|
||||
{
|
||||
pathname.insert(pathname.end(), procpath, procpath+strlen(procpath));
|
||||
}
|
||||
#endif
|
||||
if(pathname.empty())
|
||||
{
|
||||
static const char SelfLinkNames[][32]{
|
||||
"/proc/self/exe",
|
||||
"/proc/self/file",
|
||||
"/proc/curproc/exe",
|
||||
"/proc/curproc/file"
|
||||
};
|
||||
|
||||
pathname.resize(256);
|
||||
|
||||
const char *selfname{};
|
||||
ssize_t len{};
|
||||
for(const char *name : SelfLinkNames)
|
||||
{
|
||||
selfname = name;
|
||||
len = readlink(selfname, pathname.data(), pathname.size());
|
||||
if(len >= 0 || errno != ENOENT) break;
|
||||
}
|
||||
|
||||
while(len > 0 && static_cast<size_t>(len) == pathname.size())
|
||||
{
|
||||
pathname.resize(pathname.size() << 1);
|
||||
len = readlink(selfname, pathname.data(), pathname.size());
|
||||
}
|
||||
if(len <= 0)
|
||||
{
|
||||
WARN("Failed to readlink %s: %s\n", selfname, strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
|
||||
pathname.resize(static_cast<size_t>(len));
|
||||
}
|
||||
while(!pathname.empty() && pathname.back() == 0)
|
||||
pathname.pop_back();
|
||||
|
||||
auto sep = std::find(pathname.crbegin(), pathname.crend(), '/');
|
||||
if(sep != pathname.crend())
|
||||
{
|
||||
ret.path = std::string(pathname.cbegin(), sep.base()-1);
|
||||
ret.fname = std::string(sep.base(), pathname.cend());
|
||||
}
|
||||
else
|
||||
ret.fname = std::string(pathname.cbegin(), pathname.cend());
|
||||
|
||||
TRACE("Got binary: %s, %s\n", ret.path.c_str(), ret.fname.c_str());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void al_print(LogLevel level, FILE *logfile, const char *fmt, ...)
|
||||
{
|
||||
al::vector<char> dynmsg;
|
||||
char stcmsg[256];
|
||||
char *str{stcmsg};
|
||||
|
||||
va_list args, args2;
|
||||
va_start(args, fmt);
|
||||
va_copy(args2, args);
|
||||
int msglen{std::vsnprintf(str, sizeof(stcmsg), fmt, args)};
|
||||
if UNLIKELY(msglen >= 0 && static_cast<size_t>(msglen) >= sizeof(stcmsg))
|
||||
{
|
||||
dynmsg.resize(static_cast<size_t>(msglen) + 1u);
|
||||
str = dynmsg.data();
|
||||
msglen = std::vsnprintf(str, dynmsg.size(), fmt, args2);
|
||||
}
|
||||
va_end(args2);
|
||||
va_end(args);
|
||||
|
||||
if(gLogLevel >= level)
|
||||
{
|
||||
fputs(str, logfile);
|
||||
fflush(logfile);
|
||||
}
|
||||
#ifdef __ANDROID__
|
||||
auto android_severity = [](LogLevel l) noexcept
|
||||
{
|
||||
switch(l)
|
||||
{
|
||||
case LogLevel::Trace: return ANDROID_LOG_DEBUG;
|
||||
case LogLevel::Warning: return ANDROID_LOG_WARN;
|
||||
case LogLevel::Error: return ANDROID_LOG_ERROR;
|
||||
/* Should not happen. */
|
||||
case LogLevel::Disable:
|
||||
break;
|
||||
}
|
||||
return ANDROID_LOG_ERROR;
|
||||
};
|
||||
__android_log_print(android_severity(level), "openal", "%s", str);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void DirectorySearch(const char *path, const char *ext, al::vector<std::string> *const results)
|
||||
{
|
||||
TRACE("Searching %s for *%s\n", path, ext);
|
||||
DIR *dir{opendir(path)};
|
||||
if(!dir) return;
|
||||
|
||||
const auto base = results->size();
|
||||
const size_t extlen{strlen(ext)};
|
||||
|
||||
while(struct dirent *dirent{readdir(dir)})
|
||||
{
|
||||
if(strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
const size_t len{strlen(dirent->d_name)};
|
||||
if(len <= extlen) continue;
|
||||
if(al::strcasecmp(dirent->d_name+len-extlen, ext) != 0)
|
||||
continue;
|
||||
|
||||
results->emplace_back();
|
||||
std::string &str = results->back();
|
||||
str = path;
|
||||
if(str.back() != '/')
|
||||
str.push_back('/');
|
||||
str += dirent->d_name;
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
const al::span<std::string> newlist{results->data()+base, results->size()-base};
|
||||
std::sort(newlist.begin(), newlist.end());
|
||||
for(const auto &name : newlist)
|
||||
TRACE(" got %s\n", name.c_str());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
al::vector<std::string> SearchDataFiles(const char *ext, const char *subdir)
|
||||
{
|
||||
static std::mutex search_lock;
|
||||
std::lock_guard<std::mutex> _{search_lock};
|
||||
|
||||
al::vector<std::string> results;
|
||||
if(subdir[0] == '/')
|
||||
{
|
||||
DirectorySearch(subdir, ext, &results);
|
||||
return results;
|
||||
}
|
||||
|
||||
/* Search the app-local directory. */
|
||||
if(auto localpath = al::getenv("ALSOFT_LOCAL_PATH"))
|
||||
DirectorySearch(localpath->c_str(), ext, &results);
|
||||
else
|
||||
{
|
||||
al::vector<char> cwdbuf(256);
|
||||
while(!getcwd(cwdbuf.data(), cwdbuf.size()))
|
||||
{
|
||||
if(errno != ERANGE)
|
||||
{
|
||||
cwdbuf.clear();
|
||||
break;
|
||||
}
|
||||
cwdbuf.resize(cwdbuf.size() << 1);
|
||||
}
|
||||
if(cwdbuf.empty())
|
||||
DirectorySearch(".", ext, &results);
|
||||
else
|
||||
{
|
||||
DirectorySearch(cwdbuf.data(), ext, &results);
|
||||
cwdbuf.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Search local data dir
|
||||
if(auto datapath = al::getenv("XDG_DATA_HOME"))
|
||||
{
|
||||
std::string &path = *datapath;
|
||||
if(path.back() != '/')
|
||||
path += '/';
|
||||
path += subdir;
|
||||
DirectorySearch(path.c_str(), ext, &results);
|
||||
}
|
||||
else if(auto homepath = al::getenv("HOME"))
|
||||
{
|
||||
std::string &path = *homepath;
|
||||
if(path.back() == '/')
|
||||
path.pop_back();
|
||||
path += "/.local/share/";
|
||||
path += subdir;
|
||||
DirectorySearch(path.c_str(), ext, &results);
|
||||
}
|
||||
|
||||
// Search global data dirs
|
||||
std::string datadirs{al::getenv("XDG_DATA_DIRS").value_or("/usr/local/share/:/usr/share/")};
|
||||
|
||||
size_t curpos{0u};
|
||||
while(curpos < datadirs.size())
|
||||
{
|
||||
size_t nextpos{datadirs.find(':', curpos)};
|
||||
|
||||
std::string path{(nextpos != std::string::npos) ?
|
||||
datadirs.substr(curpos, nextpos++ - curpos) : datadirs.substr(curpos)};
|
||||
curpos = nextpos;
|
||||
|
||||
if(path.empty()) continue;
|
||||
if(path.back() != '/')
|
||||
path += '/';
|
||||
path += subdir;
|
||||
|
||||
DirectorySearch(path.c_str(), ext, &results);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
void SetRTPriority()
|
||||
{
|
||||
#if defined(HAVE_PTHREAD_SETSCHEDPARAM) && !defined(__OpenBSD__)
|
||||
if(RTPrioLevel > 0)
|
||||
{
|
||||
struct sched_param param{};
|
||||
/* Use the minimum real-time priority possible for now (on Linux this
|
||||
* should be 1 for SCHED_RR).
|
||||
*/
|
||||
param.sched_priority = sched_get_priority_min(SCHED_RR);
|
||||
int err;
|
||||
#ifdef SCHED_RESET_ON_FORK
|
||||
err = pthread_setschedparam(pthread_self(), SCHED_RR|SCHED_RESET_ON_FORK, ¶m);
|
||||
if(err == EINVAL)
|
||||
#endif
|
||||
err = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m);
|
||||
if(err != 0)
|
||||
ERR("Failed to set real-time priority for thread: %s (%d)\n", std::strerror(err), err);
|
||||
}
|
||||
#else
|
||||
/* Real-time priority not available */
|
||||
if(RTPrioLevel > 0)
|
||||
ERR("Cannot set priority level for thread\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
149
alc/hrtf.cpp
149
alc/hrtf.cpp
@ -1121,94 +1121,7 @@ bool checkName(const std::string &name)
|
||||
return std::find_if(enum_names.cbegin(), enum_names.cend(), match_name) != enum_names.cend();
|
||||
}
|
||||
|
||||
void AddFileEntry(const std::string &filename)
|
||||
{
|
||||
/* Check if this file has already been enumerated. */
|
||||
auto enum_iter = std::find_if(EnumeratedHrtfs.cbegin(), EnumeratedHrtfs.cend(),
|
||||
[&filename](const HrtfEntry &entry) -> bool
|
||||
{ return entry.mFilename == filename; });
|
||||
if(enum_iter != EnumeratedHrtfs.cend())
|
||||
{
|
||||
TRACE("Skipping duplicate file entry %s\n", filename.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: Get a human-readable name from the HRTF data (possibly coming in a
|
||||
* format update). */
|
||||
size_t namepos = filename.find_last_of('/')+1;
|
||||
if(!namepos) namepos = filename.find_last_of('\\')+1;
|
||||
|
||||
size_t extpos{filename.find_last_of('.')};
|
||||
if(extpos <= namepos) extpos = std::string::npos;
|
||||
|
||||
const std::string basename{(extpos == std::string::npos) ?
|
||||
filename.substr(namepos) : filename.substr(namepos, extpos-namepos)};
|
||||
std::string newname{basename};
|
||||
int count{1};
|
||||
while(checkName(newname))
|
||||
{
|
||||
newname = basename;
|
||||
newname += " #";
|
||||
newname += std::to_string(++count);
|
||||
}
|
||||
EnumeratedHrtfs.emplace_back(HrtfEntry{newname, filename});
|
||||
const HrtfEntry &entry = EnumeratedHrtfs.back();
|
||||
|
||||
TRACE("Adding file entry \"%s\"\n", entry.mFilename.c_str());
|
||||
}
|
||||
|
||||
/* Unfortunate that we have to duplicate AddFileEntry to take a memory buffer
|
||||
* for input instead of opening the given filename.
|
||||
*/
|
||||
void AddBuiltInEntry(const std::string &dispname, ALuint residx)
|
||||
{
|
||||
const std::string filename{'!'+std::to_string(residx)+'_'+dispname};
|
||||
|
||||
auto enum_iter = std::find_if(EnumeratedHrtfs.cbegin(), EnumeratedHrtfs.cend(),
|
||||
[&filename](const HrtfEntry &entry) -> bool
|
||||
{ return entry.mFilename == filename; });
|
||||
if(enum_iter != EnumeratedHrtfs.cend())
|
||||
{
|
||||
TRACE("Skipping duplicate file entry %s\n", filename.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: Get a human-readable name from the HRTF data (possibly coming in a
|
||||
* format update). */
|
||||
|
||||
std::string newname{dispname};
|
||||
int count{1};
|
||||
while(checkName(newname))
|
||||
{
|
||||
newname = dispname;
|
||||
newname += " #";
|
||||
newname += std::to_string(++count);
|
||||
}
|
||||
EnumeratedHrtfs.emplace_back(HrtfEntry{newname, filename});
|
||||
const HrtfEntry &entry = EnumeratedHrtfs.back();
|
||||
|
||||
TRACE("Adding built-in entry \"%s\"\n", entry.mFilename.c_str());
|
||||
}
|
||||
|
||||
|
||||
#define IDR_DEFAULT_HRTF_MHR 1
|
||||
|
||||
#ifndef ALSOFT_EMBED_HRTF_DATA
|
||||
|
||||
al::span<const char> GetResource(int /*name*/)
|
||||
{ return {}; }
|
||||
|
||||
#else
|
||||
|
||||
#include "hrtf_default.h"
|
||||
|
||||
al::span<const char> GetResource(int name)
|
||||
{
|
||||
if(name == IDR_DEFAULT_HRTF_MHR)
|
||||
return {reinterpret_cast<const char*>(hrtf_default), sizeof(hrtf_default)};
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -1218,50 +1131,23 @@ al::vector<std::string> EnumerateHrtf(const char *devname)
|
||||
std::lock_guard<std::mutex> _{EnumeratedHrtfLock};
|
||||
EnumeratedHrtfs.clear();
|
||||
|
||||
bool usedefaults{true};
|
||||
if(auto pathopt = ConfigValueStr(devname, nullptr, "hrtf-paths"))
|
||||
{
|
||||
const char *pathlist{pathopt->c_str()};
|
||||
while(pathlist && *pathlist)
|
||||
AuString pathA;
|
||||
Aurora::FS::GetSystemDomain("OpenAL", pathA);
|
||||
|
||||
AuList<AuString> files;
|
||||
Aurora::FS::FilesInDirectory(pathA, files);
|
||||
|
||||
for (const auto& file : files)
|
||||
{
|
||||
const char *next, *end;
|
||||
if (!EndsWith(file, ".mhr")) continue;
|
||||
|
||||
auto shortName = file.substr(0, file.size() - 4);
|
||||
|
||||
while(isspace(*pathlist) || *pathlist == ',')
|
||||
pathlist++;
|
||||
if(*pathlist == '\0')
|
||||
continue;
|
||||
|
||||
next = strchr(pathlist, ',');
|
||||
if(next)
|
||||
end = next++;
|
||||
else
|
||||
{
|
||||
end = pathlist + strlen(pathlist);
|
||||
usedefaults = false;
|
||||
}
|
||||
|
||||
while(end != pathlist && isspace(*(end-1)))
|
||||
--end;
|
||||
if(end != pathlist)
|
||||
{
|
||||
const std::string pname{pathlist, end};
|
||||
for(const auto &fname : SearchDataFiles(".mhr", pname.c_str()))
|
||||
AddFileEntry(fname);
|
||||
}
|
||||
|
||||
pathlist = next;
|
||||
EnumeratedHrtfs.emplace_back(HrtfEntry{ shortName, pathA + file });
|
||||
}
|
||||
}
|
||||
|
||||
if(usedefaults)
|
||||
{
|
||||
for(const auto &fname : SearchDataFiles(".mhr", "openal/hrtf"))
|
||||
AddFileEntry(fname);
|
||||
|
||||
if(!GetResource(IDR_DEFAULT_HRTF_MHR).empty())
|
||||
AddBuiltInEntry("Built-In HRTF", IDR_DEFAULT_HRTF_MHR);
|
||||
}
|
||||
|
||||
al::vector<std::string> list;
|
||||
list.reserve(EnumeratedHrtfs.size());
|
||||
for(auto &entry : EnumeratedHrtfs)
|
||||
@ -1307,18 +1193,7 @@ HrtfStorePtr GetLoadedHrtf(const std::string &name, const char *devname, const A
|
||||
std::unique_ptr<std::istream> stream;
|
||||
int residx{};
|
||||
char ch{};
|
||||
if(sscanf(fname.c_str(), "!%d%c", &residx, &ch) == 2 && ch == '_')
|
||||
{
|
||||
TRACE("Loading %s...\n", fname.c_str());
|
||||
al::span<const char> res{GetResource(residx)};
|
||||
if(res.empty())
|
||||
{
|
||||
ERR("Could not get resource %u, %s\n", residx, name.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
stream = std::make_unique<idstream>(res.begin(), res.end());
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
TRACE("Loading %s...\n", fname.c_str());
|
||||
auto fstr = std::make_unique<al::ifstream>(fname.c_str(), std::ios::binary);
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef LOGGING_H
|
||||
#define LOGGING_H
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@ -16,32 +15,12 @@ extern LogLevel gLogLevel;
|
||||
|
||||
extern FILE *gLogFile;
|
||||
|
||||
void al_print(LogLevel level, FILE *logfile, const char *fmt, ...);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__ANDROID__)
|
||||
#define TRACE(...) do { \
|
||||
if UNLIKELY(gLogLevel >= LogLevel::Trace) \
|
||||
fprintf(gLogFile, "[ALSOFT] (II) " __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#define WARN(...) do { \
|
||||
if UNLIKELY(gLogLevel >= LogLevel::Warning) \
|
||||
fprintf(gLogFile, "[ALSOFT] (WW) " __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#define ERR(...) do { \
|
||||
if UNLIKELY(gLogLevel >= LogLevel::Error) \
|
||||
fprintf(gLogFile, "[ALSOFT] (EE) " __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define TRACE(...) Aurora::Console::Logging::LogDbg("[ALSOFT] (II) " __VA_ARGS__)
|
||||
#else
|
||||
|
||||
[[gnu::format(printf,3,4)]] void al_print(LogLevel level, FILE *logfile, const char *fmt, ...);
|
||||
|
||||
#define TRACE(...) al_print(LogLevel::Trace, gLogFile, "[ALSOFT] (II) " __VA_ARGS__)
|
||||
|
||||
#define WARN(...) al_print(LogLevel::Warning, gLogFile, "[ALSOFT] (WW) " __VA_ARGS__)
|
||||
|
||||
#define ERR(...) al_print(LogLevel::Error, gLogFile, "[ALSOFT] (EE) " __VA_ARGS__)
|
||||
#define TRACE(...)
|
||||
#endif
|
||||
|
||||
#endif /* LOGGING_H */
|
||||
#define WARN(...) Aurora::Console::Logging::LogWarn("[ALSOFT] (WW) " __VA_ARGS__)
|
||||
#define ERR(...) Aurora::Console::Logging::LogWarn("[ALSOFT] (EE) " __VA_ARGS__)
|
@ -1,64 +1,21 @@
|
||||
|
||||
/**
|
||||
* Aurora Engine allocation wrapper reimplementation for OpenAL
|
||||
* Copyright (C) Reece Wilson 2021
|
||||
* License: MIT
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include "almalloc.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
|
||||
void *al_malloc(size_t alignment, size_t size)
|
||||
{
|
||||
assert((alignment & (alignment-1)) == 0);
|
||||
alignment = std::max(alignment, alignof(std::max_align_t));
|
||||
|
||||
#if defined(HAVE_STD_ALIGNED_ALLOC)
|
||||
size = (size+(alignment-1))&~(alignment-1);
|
||||
return std::aligned_alloc(alignment, size);
|
||||
#elif defined(HAVE_POSIX_MEMALIGN)
|
||||
void *ret{};
|
||||
if(posix_memalign(&ret, alignment, size) == 0)
|
||||
return ret;
|
||||
return nullptr;
|
||||
#elif defined(HAVE__ALIGNED_MALLOC)
|
||||
return _aligned_malloc(size, alignment);
|
||||
#else
|
||||
size_t total_size{size + alignment-1 + sizeof(void*)};
|
||||
void *base{std::malloc(total_size)};
|
||||
if(base != nullptr)
|
||||
{
|
||||
void *aligned_ptr{static_cast<char*>(base) + sizeof(void*)};
|
||||
total_size -= sizeof(void*);
|
||||
|
||||
std::align(alignment, size, aligned_ptr, total_size);
|
||||
*(static_cast<void**>(aligned_ptr)-1) = base;
|
||||
base = aligned_ptr;
|
||||
}
|
||||
return base;
|
||||
#endif
|
||||
return Aurora::Memory::SAlloc<void*>(size, alignment);
|
||||
}
|
||||
|
||||
void *al_calloc(size_t alignment, size_t size)
|
||||
{
|
||||
void *ret{al_malloc(alignment, size)};
|
||||
if(ret) std::memset(ret, 0, size);
|
||||
return ret;
|
||||
return Aurora::Memory::ZAlloc<void*>(size, alignment);
|
||||
}
|
||||
|
||||
void al_free(void *ptr) noexcept
|
||||
{
|
||||
#if defined(HAVE_STD_ALIGNED_ALLOC) || defined(HAVE_POSIX_MEMALIGN)
|
||||
std::free(ptr);
|
||||
#elif defined(HAVE__ALIGNED_MALLOC)
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
if(ptr != nullptr)
|
||||
std::free(*(static_cast<void**>(ptr) - 1));
|
||||
#endif
|
||||
}
|
||||
Aurora::Memory::Free(ptr);
|
||||
}
|
@ -13,8 +13,8 @@
|
||||
#include "pragmadefs.h"
|
||||
|
||||
|
||||
[[gnu::alloc_align(1), gnu::alloc_size(2)]] void *al_malloc(size_t alignment, size_t size);
|
||||
[[gnu::alloc_align(1), gnu::alloc_size(2)]] void *al_calloc(size_t alignment, size_t size);
|
||||
void *al_malloc(size_t alignment, size_t size);
|
||||
void *al_calloc(size_t alignment, size_t size);
|
||||
void al_free(void *ptr) noexcept;
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ struct allocator {
|
||||
template<typename U, std::size_t N>
|
||||
constexpr allocator(const allocator<U,N>&) noexcept { }
|
||||
|
||||
[[gnu::assume_aligned(alignment), gnu::alloc_size(2)]] T *allocate(std::size_t n)
|
||||
T *allocate(std::size_t n)
|
||||
{
|
||||
if(n > std::numeric_limits<std::size_t>::max()/sizeof(T)) throw std::bad_alloc();
|
||||
if(auto p = static_cast<T*>(al_malloc(alignment, n*sizeof(T)))) return p;
|
||||
@ -102,7 +102,7 @@ template<typename T, std::size_t N, typename U, std::size_t M>
|
||||
bool operator!=(const allocator<T,N>&, const allocator<U,M>&) noexcept { return false; }
|
||||
|
||||
template<size_t alignment, typename T>
|
||||
[[gnu::assume_aligned(alignment)]] inline T* assume_aligned(T *ptr) noexcept { return ptr; }
|
||||
inline T* assume_aligned(T *ptr) noexcept { return ptr; }
|
||||
|
||||
/* At least VS 2015 complains that 'ptr' is unused when the given type's
|
||||
* destructor is trivial (a no-op). So disable that warning for this call.
|
||||
|
@ -1,176 +1,42 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
* Aurora Engine semaphore wrapper reimplementation for OpenAL
|
||||
* Copyright (C) Reece Wilson 2021
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "opthelpers.h"
|
||||
#include "threads.h"
|
||||
|
||||
#include <system_error>
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
void althrd_setname(const char *name)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
#define MS_VC_EXCEPTION 0x406D1388
|
||||
#pragma pack(push,8)
|
||||
struct {
|
||||
DWORD dwType; // Must be 0x1000.
|
||||
LPCSTR szName; // Pointer to name (in user addr space).
|
||||
DWORD dwThreadID; // Thread ID (-1=caller thread).
|
||||
DWORD dwFlags; // Reserved for future use, must be zero.
|
||||
} info;
|
||||
#pragma pack(pop)
|
||||
info.dwType = 0x1000;
|
||||
info.szName = name;
|
||||
info.dwThreadID = ~DWORD{0};
|
||||
info.dwFlags = 0;
|
||||
// NO OP
|
||||
}
|
||||
|
||||
__try {
|
||||
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
|
||||
namespace al
|
||||
{
|
||||
semaphore::semaphore(unsigned int initial)
|
||||
{
|
||||
_semaphore = Aurora::Threading::SemaphoreNew(initial);
|
||||
}
|
||||
__except(EXCEPTION_CONTINUE_EXECUTION) {
|
||||
|
||||
semaphore::~semaphore()
|
||||
{
|
||||
Aurora::Threading::SemaphoreDestroy(_semaphore);
|
||||
}
|
||||
#undef MS_VC_EXCEPTION
|
||||
#else
|
||||
(void)name;
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace al {
|
||||
void semaphore::post()
|
||||
{
|
||||
_semaphore->Unlock(1);
|
||||
}
|
||||
|
||||
semaphore::semaphore(unsigned int initial)
|
||||
{
|
||||
if(initial > static_cast<unsigned int>(std::numeric_limits<int>::max()))
|
||||
throw std::system_error(std::make_error_code(std::errc::value_too_large));
|
||||
mSem = CreateSemaphore(nullptr, initial, std::numeric_limits<int>::max(), nullptr);
|
||||
if(mSem == nullptr)
|
||||
throw std::system_error(std::make_error_code(std::errc::resource_unavailable_try_again));
|
||||
}
|
||||
void semaphore::wait() noexcept
|
||||
{
|
||||
_semaphore->Lock();
|
||||
}
|
||||
|
||||
semaphore::~semaphore()
|
||||
{ CloseHandle(mSem); }
|
||||
|
||||
void semaphore::post()
|
||||
{
|
||||
if UNLIKELY(!ReleaseSemaphore(static_cast<HANDLE>(mSem), 1, nullptr))
|
||||
throw std::system_error(std::make_error_code(std::errc::value_too_large));
|
||||
}
|
||||
|
||||
void semaphore::wait() noexcept
|
||||
{ WaitForSingleObject(static_cast<HANDLE>(mSem), INFINITE); }
|
||||
|
||||
bool semaphore::try_wait() noexcept
|
||||
{ return WaitForSingleObject(static_cast<HANDLE>(mSem), 0) == WAIT_OBJECT_0; }
|
||||
|
||||
} // namespace al
|
||||
|
||||
#else
|
||||
|
||||
#if defined(HAVE_PTHREAD_SETNAME_NP) || defined(HAVE_PTHREAD_SET_NAME_NP)
|
||||
#include <pthread.h>
|
||||
#ifdef HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
void althrd_setname(const char *name)
|
||||
{
|
||||
#if defined(HAVE_PTHREAD_SET_NAME_NP)
|
||||
pthread_set_name_np(pthread_self(), name);
|
||||
#elif defined(PTHREAD_SETNAME_NP_ONE_PARAM)
|
||||
pthread_setname_np(name);
|
||||
#elif defined(PTHREAD_SETNAME_NP_THREE_PARAMS)
|
||||
pthread_setname_np(pthread_self(), "%s", (void*)name);
|
||||
#else
|
||||
pthread_setname_np(pthread_self(), name);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void althrd_setname(const char*) { }
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
namespace al {
|
||||
|
||||
semaphore::semaphore(unsigned int initial)
|
||||
{
|
||||
mSem = dispatch_semaphore_create(initial);
|
||||
if(!mSem)
|
||||
throw std::system_error(std::make_error_code(std::errc::resource_unavailable_try_again));
|
||||
}
|
||||
|
||||
semaphore::~semaphore()
|
||||
{ dispatch_release(mSem); }
|
||||
|
||||
void semaphore::post()
|
||||
{ dispatch_semaphore_signal(mSem); }
|
||||
|
||||
void semaphore::wait() noexcept
|
||||
{ dispatch_semaphore_wait(mSem, DISPATCH_TIME_FOREVER); }
|
||||
|
||||
bool semaphore::try_wait() noexcept
|
||||
{ return dispatch_semaphore_wait(mSem, DISPATCH_TIME_NOW) == 0; }
|
||||
|
||||
} // namespace al
|
||||
|
||||
#else /* !__APPLE__ */
|
||||
|
||||
#include <cerrno>
|
||||
|
||||
namespace al {
|
||||
|
||||
semaphore::semaphore(unsigned int initial)
|
||||
{
|
||||
if(sem_init(&mSem, 0, initial) != 0)
|
||||
throw std::system_error(std::make_error_code(std::errc::resource_unavailable_try_again));
|
||||
}
|
||||
|
||||
semaphore::~semaphore()
|
||||
{ sem_destroy(&mSem); }
|
||||
|
||||
void semaphore::post()
|
||||
{
|
||||
if(sem_post(&mSem) != 0)
|
||||
throw std::system_error(std::make_error_code(std::errc::value_too_large));
|
||||
}
|
||||
|
||||
void semaphore::wait() noexcept
|
||||
{
|
||||
while(sem_wait(&mSem) == -1 && errno == EINTR) {
|
||||
bool semaphore::try_wait() noexcept
|
||||
{
|
||||
return _semaphore->TryLock();
|
||||
}
|
||||
}
|
||||
|
||||
bool semaphore::try_wait() noexcept
|
||||
{ return sem_trywait(&mSem) == 0; }
|
||||
|
||||
} // namespace al
|
||||
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
@ -1,48 +1,28 @@
|
||||
#ifndef AL_THREADS_H
|
||||
#define AL_THREADS_H
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
/* force_align_arg_pointer is required for proper function arguments aligning
|
||||
* when SSE code is used. Some systems (Windows, QNX) do not guarantee our
|
||||
* thread functions will be properly aligned on the stack, even though GCC may
|
||||
* generate code with the assumption that it is. */
|
||||
#define FORCE_ALIGN __attribute__((force_align_arg_pointer))
|
||||
#else
|
||||
#define FORCE_ALIGN
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <dispatch/dispatch.h>
|
||||
#elif !defined(_WIN32)
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
/**
|
||||
* OpenAL semaphore wrapper reimplementation for the Aurora Engine
|
||||
* Copyright (C) Reece Wilson 2021
|
||||
* License: MIT
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
void althrd_setname(const char *name);
|
||||
|
||||
namespace al {
|
||||
namespace al
|
||||
{
|
||||
class semaphore
|
||||
{
|
||||
public:
|
||||
semaphore(unsigned int initial = 0);
|
||||
semaphore(const semaphore&) = delete;
|
||||
~semaphore();
|
||||
|
||||
class semaphore {
|
||||
#ifdef _WIN32
|
||||
using native_type = void*;
|
||||
#elif defined(__APPLE__)
|
||||
using native_type = dispatch_semaphore_t;
|
||||
#else
|
||||
using native_type = sem_t;
|
||||
#endif
|
||||
native_type mSem;
|
||||
semaphore& operator=(const semaphore&) = delete;
|
||||
|
||||
public:
|
||||
semaphore(unsigned int initial=0);
|
||||
semaphore(const semaphore&) = delete;
|
||||
~semaphore();
|
||||
void post();
|
||||
void wait() noexcept;
|
||||
bool try_wait() noexcept;
|
||||
|
||||
semaphore& operator=(const semaphore&) = delete;
|
||||
|
||||
void post();
|
||||
void wait() noexcept;
|
||||
bool try_wait() noexcept;
|
||||
};
|
||||
|
||||
} // namespace al
|
||||
|
||||
#endif /* AL_THREADS_H */
|
||||
private:
|
||||
Aurora::Threading::ISemaphore* _semaphore;
|
||||
};
|
||||
}
|
7
config/config.h
Normal file
7
config/config.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define RESTRICT
|
||||
#define FORCE_ALIGN
|
||||
|
||||
#include <AuroraCommon.hpp>
|
||||
#include <Aurora/Kernel.hpp>
|
4
config/version.h
Normal file
4
config/version.h
Normal file
@ -0,0 +1,4 @@
|
||||
#define ALSOFT_VERSION "1"
|
||||
#define ALSOFT_VERSION_NUM "0"
|
||||
#define ALSOFT_GIT_BRANCH "1"
|
||||
#define ALSOFT_GIT_COMMIT_HASH "AURORA ENGINE"
|
@ -6,19 +6,23 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef AL_API
|
||||
#if defined(AL_LIBTYPE_STATIC)
|
||||
#define AL_API
|
||||
#elif defined(_WIN32)
|
||||
#define AL_API __declspec(dllimport)
|
||||
#else
|
||||
#define AL_API extern
|
||||
#endif
|
||||
#if defined(AL_LIBTYPE_STATIC)
|
||||
#define AL_API
|
||||
#elif defined(_WIN32)
|
||||
#if defined(AURORA_OPENAL)
|
||||
#define AL_API __declspec(dllexport)
|
||||
#else
|
||||
#define AL_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define AL_API extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define AL_APIENTRY __cdecl
|
||||
#define AL_APIENTRY __cdecl
|
||||
#else
|
||||
#define AL_APIENTRY
|
||||
#define AL_APIENTRY
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -6,13 +6,17 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef ALC_API
|
||||
#if defined(AL_LIBTYPE_STATIC)
|
||||
#define ALC_API
|
||||
#elif defined(_WIN32)
|
||||
#define ALC_API __declspec(dllimport)
|
||||
#else
|
||||
#define ALC_API extern
|
||||
#endif
|
||||
#if defined(AL_LIBTYPE_STATIC)
|
||||
#define ALC_API
|
||||
#elif defined(_WIN32)
|
||||
#if defined(AURORA_OPENAL)
|
||||
#define ALC_API __declspec(dllexport)
|
||||
#else
|
||||
#define ALC_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define ALC_API extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
Loading…
Reference in New Issue
Block a user