aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--al/extension.cpp12
-rw-r--r--al/state.cpp2
-rw-r--r--alc/context.cpp166
-rw-r--r--alc/context.h7
4 files changed, 85 insertions, 102 deletions
diff --git a/al/extension.cpp b/al/extension.cpp
index 3ead0af8..dbaf4d5f 100644
--- a/al/extension.cpp
+++ b/al/extension.cpp
@@ -46,18 +46,10 @@ START_API_FUNC
}
size_t len{strlen(extName)};
- const char *ptr{context->mExtensionList};
- while(ptr && *ptr)
+ for(std::string_view ext : context->mExtensions)
{
- if(al::strncasecmp(ptr, extName, len) == 0 && (ptr[len] == '\0' || isspace(ptr[len])))
+ if(len == ext.length() && al::strncasecmp(ext.data(), extName, len) == 0)
return AL_TRUE;
-
- if((ptr=strchr(ptr, ' ')) != nullptr)
- {
- do {
- ++ptr;
- } while(isspace(*ptr));
- }
}
return AL_FALSE;
diff --git a/al/state.cpp b/al/state.cpp
index fb3186c7..cb2afd6c 100644
--- a/al/state.cpp
+++ b/al/state.cpp
@@ -560,7 +560,7 @@ START_API_FUNC
break;
case AL_EXTENSIONS:
- value = context->mExtensionList;
+ value = context->mExtensionsString.c_str();
break;
case AL_NO_ERROR:
diff --git a/alc/context.cpp b/alc/context.cpp
index 2fbf67af..d920d4b6 100644
--- a/alc/context.cpp
+++ b/alc/context.cpp
@@ -11,6 +11,7 @@
#include <numeric>
#include <stddef.h>
#include <stdexcept>
+#include <string_view>
#include <utility>
#include "AL/efx.h"
@@ -48,48 +49,52 @@ using namespace std::placeholders;
using voidp = void*;
/* Default context extensions */
-constexpr ALchar alExtList[] =
- "AL_EXT_ALAW "
- "AL_EXT_BFORMAT "
- "AL_EXTX_debug "
- "AL_EXT_DOUBLE "
- "AL_EXT_EXPONENT_DISTANCE "
- "AL_EXT_FLOAT32 "
- "AL_EXT_IMA4 "
- "AL_EXT_LINEAR_DISTANCE "
- "AL_EXT_MCFORMATS "
- "AL_EXT_MULAW "
- "AL_EXT_MULAW_BFORMAT "
- "AL_EXT_MULAW_MCFORMATS "
- "AL_EXT_OFFSET "
- "AL_EXT_source_distance_model "
- "AL_EXT_SOURCE_RADIUS "
- "AL_EXT_STATIC_BUFFER "
- "AL_EXT_STEREO_ANGLES "
- "AL_LOKI_quadriphonic "
- "AL_SOFT_bformat_ex "
- "AL_SOFTX_bformat_hoa "
- "AL_SOFT_block_alignment "
- "AL_SOFT_buffer_length_query "
- "AL_SOFT_callback_buffer "
- "AL_SOFTX_convolution_reverb "
- "AL_SOFT_deferred_updates "
- "AL_SOFT_direct_channels "
- "AL_SOFT_direct_channels_remix "
- "AL_SOFT_effect_target "
- "AL_SOFT_events "
- "AL_SOFT_gain_clamp_ex "
- "AL_SOFTX_hold_on_disconnect "
- "AL_SOFT_loop_points "
- "AL_SOFTX_map_buffer "
- "AL_SOFT_MSADPCM "
- "AL_SOFT_source_latency "
- "AL_SOFT_source_length "
- "AL_SOFT_source_resampler "
- "AL_SOFT_source_spatialize "
- "AL_SOFT_source_start_delay "
- "AL_SOFT_UHJ "
- "AL_SOFT_UHJ_ex";
+std::vector<std::string_view> getContextExtensions() noexcept
+{
+ return std::vector<std::string_view>{
+ "AL_EXT_ALAW",
+ "AL_EXT_BFORMAT",
+ "AL_EXTX_debug",
+ "AL_EXT_DOUBLE",
+ "AL_EXT_EXPONENT_DISTANCE",
+ "AL_EXT_FLOAT32",
+ "AL_EXT_IMA4",
+ "AL_EXT_LINEAR_DISTANCE",
+ "AL_EXT_MCFORMATS",
+ "AL_EXT_MULAW",
+ "AL_EXT_MULAW_BFORMAT",
+ "AL_EXT_MULAW_MCFORMATS",
+ "AL_EXT_OFFSET",
+ "AL_EXT_source_distance_model",
+ "AL_EXT_SOURCE_RADIUS",
+ "AL_EXT_STATIC_BUFFER",
+ "AL_EXT_STEREO_ANGLES",
+ "AL_LOKI_quadriphonic",
+ "AL_SOFT_bformat_ex",
+ "AL_SOFTX_bformat_hoa",
+ "AL_SOFT_block_alignment",
+ "AL_SOFT_buffer_length_query",
+ "AL_SOFT_callback_buffer",
+ "AL_SOFTX_convolution_reverb",
+ "AL_SOFT_deferred_updates",
+ "AL_SOFT_direct_channels",
+ "AL_SOFT_direct_channels_remix",
+ "AL_SOFT_effect_target",
+ "AL_SOFT_events",
+ "AL_SOFT_gain_clamp_ex",
+ "AL_SOFTX_hold_on_disconnect",
+ "AL_SOFT_loop_points",
+ "AL_SOFTX_map_buffer",
+ "AL_SOFT_MSADPCM",
+ "AL_SOFT_source_latency",
+ "AL_SOFT_source_length",
+ "AL_SOFT_source_resampler",
+ "AL_SOFT_source_spatialize",
+ "AL_SOFT_source_start_delay",
+ "AL_SOFT_UHJ",
+ "AL_SOFT_UHJ_ex",
+ };
+}
} // namespace
@@ -179,26 +184,41 @@ void ALCcontext::init()
mCurrentVoiceChange.store(cur, std::memory_order_relaxed);
}
- mExtensionList = alExtList;
+ mExtensions = getContextExtensions();
if(sBufferSubDataCompat)
{
- std::string extlist{mExtensionList};
-
- const auto pos = extlist.find("AL_EXT_SOURCE_RADIUS ");
- if(pos != std::string::npos)
- extlist.replace(pos, 20, "AL_SOFT_buffer_sub_data");
- else
- extlist += " AL_SOFT_buffer_sub_data";
-
- mExtensionListOverride = std::move(extlist);
- mExtensionList = mExtensionListOverride.c_str();
+ auto iter = std::find(mExtensions.begin(), mExtensions.end(), "AL_EXT_SOURCE_RADIUS");
+ if(iter != mExtensions.end()) mExtensions.erase(iter);
+ /* TODO: Would be nice to sort this alphabetically. Needs case-
+ * insensitive searching.
+ */
+ mExtensions.emplace_back("AL_SOFT_buffer_sub_data");
}
#ifdef ALSOFT_EAX
eax_initialize_extensions();
#endif // ALSOFT_EAX
+ if(!mExtensions.empty())
+ {
+ const size_t len{std::accumulate(mExtensions.cbegin()+1, mExtensions.cend(),
+ mExtensions.front().length(),
+ [](size_t current, std::string_view ext) noexcept
+ { return current + ext.length() + 1; })};
+
+ std::string extensions;
+ extensions.reserve(len);
+ extensions += mExtensions.front();
+ for(std::string_view ext : al::span{mExtensions}.subspan<1>())
+ {
+ extensions += ' ';
+ extensions += ext;
+ }
+
+ mExtensionsString = std::move(extensions);
+ }
+
mParams.Position = alu::Vector{0.0f, 0.0f, 0.0f, 1.0f};
mParams.Matrix = alu::Matrix::Identity();
mParams.Velocity = alu::Vector{};
@@ -457,43 +477,15 @@ void ALCcontext::eax_initialize_extensions()
if(!eax_g_is_enabled)
return;
- const auto string_max_capacity =
- std::strlen(mExtensionList) + 1 +
- std::strlen(eax1_ext_name) + 1 +
- std::strlen(eax2_ext_name) + 1 +
- std::strlen(eax3_ext_name) + 1 +
- std::strlen(eax4_ext_name) + 1 +
- std::strlen(eax5_ext_name) + 1 +
- std::strlen(eax_x_ram_ext_name) + 1;
-
- std::string extlist;
- extlist.reserve(string_max_capacity);
-
+ mExtensions.emplace(mExtensions.begin(), eax_x_ram_ext_name);
if(eaxIsCapable())
{
- extlist += eax1_ext_name;
- extlist += ' ';
-
- extlist += eax2_ext_name;
- extlist += ' ';
-
- extlist += eax3_ext_name;
- extlist += ' ';
-
- extlist += eax4_ext_name;
- extlist += ' ';
-
- extlist += eax5_ext_name;
- extlist += ' ';
+ mExtensions.emplace(mExtensions.begin(), eax5_ext_name);
+ mExtensions.emplace(mExtensions.begin(), eax4_ext_name);
+ mExtensions.emplace(mExtensions.begin(), eax3_ext_name);
+ mExtensions.emplace(mExtensions.begin(), eax2_ext_name);
+ mExtensions.emplace(mExtensions.begin(), eax1_ext_name);
}
-
- extlist += eax_x_ram_ext_name;
- extlist += ' ';
-
- extlist += mExtensionList;
-
- mExtensionListOverride = std::move(extlist);
- mExtensionList = mExtensionListOverride.c_str();
}
void ALCcontext::eax_initialize()
diff --git a/alc/context.h b/alc/context.h
index 402794eb..acbb3788 100644
--- a/alc/context.h
+++ b/alc/context.h
@@ -7,7 +7,7 @@
#include <mutex>
#include <stdint.h>
#include <string>
-#include <unordered_map>
+#include <string_view>
#include <utility>
#include "AL/al.h"
@@ -143,9 +143,8 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext>, ContextBase {
/* Default effect slot */
std::unique_ptr<ALeffectslot> mDefaultSlot;
- const char *mExtensionList{nullptr};
-
- std::string mExtensionListOverride{};
+ std::vector<std::string_view> mExtensions;
+ std::string mExtensionsString{};
ALCcontext(al::intrusive_ptr<ALCdevice> device, ContextFlagBitset flags);