From 10a8f305ac10634e1882eceebe8dddee2436912e Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 24 May 2024 18:59:32 -0700 Subject: [PATCH] Use a variant to select between temp source handle storage --- al/source.cpp | 149 +++++++++++++++++++++++++++------------------------------- 1 file changed, 69 insertions(+), 80 deletions(-) diff --git a/al/source.cpp b/al/source.cpp index 25d2a47b..b59ade72 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -87,6 +87,10 @@ namespace { using SubListAllocator = al::allocator>; using std::chrono::nanoseconds; using seconds_d = std::chrono::duration; +using source_store_array = std::array; +using source_store_vector = std::vector; +using source_store_variant = std::variant; + Voice *GetSourceVoice(ALsource *source, ALCcontext *context) { @@ -3204,25 +3208,22 @@ try { if(n <= 0) UNLIKELY return; al::span sids{sources, static_cast(n)}; - std::vector extra_sources; - std::array source_storage; - al::span srchandles; - if(sids.size() <= source_storage.size()) LIKELY - srchandles = al::span{source_storage}.first(sids.size()); - else + source_store_variant source_store; + const auto srchandles = [&source_store](size_t count) -> al::span { - extra_sources.resize(sids.size()); - srchandles = extra_sources; - } + if(count > std::tuple_size_v) + return al::span{source_store.emplace(count)}; + return al::span{source_store.emplace()}.first(count); + }(sids.size()); std::lock_guard sourcelock{context->mSourceLock}; - std::transform(sids.cbegin(), sids.cend(), srchandles.begin(), - [context](const ALuint sid) -> ALsource* - { - if(ALsource *src{LookupSource(context, sid)}) - return src; - throw al::context_error{AL_INVALID_NAME, "Invalid source ID %u", sid}; - }); + auto lookup_src = [context](const ALuint sid) -> ALsource* + { + if(ALsource *src{LookupSource(context, sid)}) + return src; + throw al::context_error{AL_INVALID_NAME, "Invalid source ID %u", sid}; + }; + std::transform(sids.cbegin(), sids.cend(), srchandles.begin(), lookup_src); StartSources(context, srchandles); } @@ -3242,25 +3243,22 @@ try { throw al::context_error{AL_INVALID_VALUE, "Invalid time point %" PRId64, start_time}; al::span sids{sources, static_cast(n)}; - std::vector extra_sources; - std::array source_storage; - al::span srchandles; - if(sids.size() <= source_storage.size()) LIKELY - srchandles = al::span{source_storage}.first(sids.size()); - else + source_store_variant source_store; + const auto srchandles = [&source_store](size_t count) -> al::span { - extra_sources.resize(sids.size()); - srchandles = extra_sources; - } + if(count > std::tuple_size_v) + return al::span{source_store.emplace(count)}; + return al::span{source_store.emplace()}.first(count); + }(sids.size()); std::lock_guard sourcelock{context->mSourceLock}; - std::transform(sids.cbegin(), sids.cend(), srchandles.begin(), - [context](const ALuint sid) -> ALsource* - { - if(ALsource *src{LookupSource(context, sid)}) - return src; - throw al::context_error{AL_INVALID_NAME, "Invalid source ID %u", sid}; - }); + auto lookup_src = [context](const ALuint sid) -> ALsource* + { + if(ALsource *src{LookupSource(context, sid)}) + return src; + throw al::context_error{AL_INVALID_NAME, "Invalid source ID %u", sid}; + }; + std::transform(sids.cbegin(), sids.cend(), srchandles.begin(), lookup_src); StartSources(context, srchandles, nanoseconds{start_time}); } @@ -3282,25 +3280,22 @@ try { if(n <= 0) UNLIKELY return; al::span sids{sources, static_cast(n)}; - std::vector extra_sources; - std::array source_storage; - al::span srchandles; - if(sids.size() <= source_storage.size()) LIKELY - srchandles = al::span{source_storage}.first(sids.size()); - else + source_store_variant source_store; + const auto srchandles = [&source_store](size_t count) -> al::span { - extra_sources.resize(sids.size()); - srchandles = extra_sources; - } + if(count > std::tuple_size_v) + return al::span{source_store.emplace(count)}; + return al::span{source_store.emplace()}.first(count); + }(sids.size()); std::lock_guard sourcelock{context->mSourceLock}; - std::transform(sids.cbegin(), sids.cend(), srchandles.begin(), - [context](const ALuint sid) -> ALsource* - { - if(ALsource *src{LookupSource(context, sid)}) - return src; - throw al::context_error{AL_INVALID_NAME, "Invalid source ID %u", sid}; - }); + auto lookup_src = [context](const ALuint sid) -> ALsource* + { + if(ALsource *src{LookupSource(context, sid)}) + return src; + throw al::context_error{AL_INVALID_NAME, "Invalid source ID %u", sid}; + }; + std::transform(sids.cbegin(), sids.cend(), srchandles.begin(), lookup_src); /* Pausing has to be done in two steps. First, for each source that's * detected to be playing, chamge the voice (asynchronously) to @@ -3358,25 +3353,22 @@ try { if(n <= 0) UNLIKELY return; al::span sids{sources, static_cast(n)}; - std::vector extra_sources; - std::array source_storage; - al::span srchandles; - if(sids.size() <= source_storage.size()) LIKELY - srchandles = al::span{source_storage}.first(sids.size()); - else + source_store_variant source_store; + const auto srchandles = [&source_store](size_t count) -> al::span { - extra_sources.resize(sids.size()); - srchandles = extra_sources; - } + if(count > std::tuple_size_v) + return al::span{source_store.emplace(count)}; + return al::span{source_store.emplace()}.first(count); + }(sids.size()); std::lock_guard sourcelock{context->mSourceLock}; - std::transform(sids.cbegin(), sids.cend(), srchandles.begin(), - [context](const ALuint sid) -> ALsource* - { - if(ALsource *src{LookupSource(context, sid)}) - return src; - throw al::context_error{AL_INVALID_NAME, "Invalid source ID %u", sid}; - }); + auto lookup_src = [context](const ALuint sid) -> ALsource* + { + if(ALsource *src{LookupSource(context, sid)}) + return src; + throw al::context_error{AL_INVALID_NAME, "Invalid source ID %u", sid}; + }; + std::transform(sids.cbegin(), sids.cend(), srchandles.begin(), lookup_src); VoiceChange *tail{}, *cur{}; for(ALsource *source : srchandles) @@ -3421,25 +3413,22 @@ try { if(n <= 0) UNLIKELY return; al::span sids{sources, static_cast(n)}; - std::vector extra_sources; - std::array source_storage; - al::span srchandles; - if(sids.size() <= source_storage.size()) LIKELY - srchandles = al::span{source_storage}.first(sids.size()); - else + source_store_variant source_store; + const auto srchandles = [&source_store](size_t count) -> al::span { - extra_sources.resize(sids.size()); - srchandles = extra_sources; - } + if(count > std::tuple_size_v) + return al::span{source_store.emplace(count)}; + return al::span{source_store.emplace()}.first(count); + }(sids.size()); std::lock_guard sourcelock{context->mSourceLock}; - std::transform(sids.cbegin(), sids.cend(), srchandles.begin(), - [context](const ALuint sid) -> ALsource* - { - if(ALsource *src{LookupSource(context, sid)}) - return src; - throw al::context_error{AL_INVALID_NAME, "Invalid source ID %u", sid}; - }); + auto lookup_src = [context](const ALuint sid) -> ALsource* + { + if(ALsource *src{LookupSource(context, sid)}) + return src; + throw al::context_error{AL_INVALID_NAME, "Invalid source ID %u", sid}; + }; + std::transform(sids.cbegin(), sids.cend(), srchandles.begin(), lookup_src); VoiceChange *tail{}, *cur{}; for(ALsource *source : srchandles) -- 2.11.4.GIT