From bdf44322f8c9fc1abf3fc26f0f14826d2efd59f8 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 14 Jul 2025 17:43:48 -0500 Subject: [PATCH] Expose a library's Resource Loader, allow a user to "subset" it (#19131) This pull request elevates ScopedResourceLoader to the API surface of LibraryResources, which will allow any library resource consumer to directly interact with its resource loader. One of those new interactions is to make a sub-context with a specific narrowed-down qualifier. Like this: ```c++ auto englishOnlyLoader = GetLibraryResourceLoader().WithQualifier(L"language", L"en-us"); /* auto foo = */ englishOnlyLoader.GetLocalizedString(USES_RESOURCE(L"AppName")); ``` --- src/cascadia/WinRTUtils/LibraryResources.cpp | 10 ++++------ src/cascadia/WinRTUtils/ScopedResourceLoader.cpp | 11 +++++++++++ src/cascadia/WinRTUtils/inc/LibraryResources.h | 3 +++ src/cascadia/WinRTUtils/inc/ScopedResourceLoader.h | 3 +++ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/cascadia/WinRTUtils/LibraryResources.cpp b/src/cascadia/WinRTUtils/LibraryResources.cpp index 82c4acbc9f..66984a4d63 100644 --- a/src/cascadia/WinRTUtils/LibraryResources.cpp +++ b/src/cascadia/WinRTUtils/LibraryResources.cpp @@ -76,10 +76,10 @@ static void EnsureAllResourcesArePresent(const ScopedResourceLoader& loader) #endif -static ScopedResourceLoader GetLibraryResourceLoader() +const ScopedResourceLoader& GetLibraryResourceLoader() try { - ScopedResourceLoader loader{ g_WinRTUtilsLibraryResourceScope }; + static ScopedResourceLoader loader{ g_WinRTUtilsLibraryResourceScope }; #ifdef _DEBUG EnsureAllResourcesArePresent(loader); #endif @@ -90,15 +90,13 @@ CATCH_FAIL_FAST() winrt::hstring GetLibraryResourceString(const std::wstring_view key) try { - static auto loader{ GetLibraryResourceLoader() }; - return loader.GetLocalizedString(key); + return GetLibraryResourceLoader().GetLocalizedString(key); } CATCH_FAIL_FAST() bool HasLibraryResourceWithName(const std::wstring_view key) try { - static auto loader{ GetLibraryResourceLoader() }; - return loader.HasResourceWithName(key); + return GetLibraryResourceLoader().HasResourceWithName(key); } CATCH_FAIL_FAST() diff --git a/src/cascadia/WinRTUtils/ScopedResourceLoader.cpp b/src/cascadia/WinRTUtils/ScopedResourceLoader.cpp index e872a2d42b..4ad6482008 100644 --- a/src/cascadia/WinRTUtils/ScopedResourceLoader.cpp +++ b/src/cascadia/WinRTUtils/ScopedResourceLoader.cpp @@ -46,3 +46,14 @@ bool ScopedResourceLoader::HasResourceWithName(const std::wstring_view resourceN { return _resourceMap.HasKey(resourceName); } + +ScopedResourceLoader::ScopedResourceLoader(winrt::Windows::ApplicationModel::Resources::Core::ResourceMap map, winrt::Windows::ApplicationModel::Resources::Core::ResourceContext context) noexcept : + _resourceMap{ std::move(map) }, _resourceContext{ std::move(context) } {} + +ScopedResourceLoader ScopedResourceLoader::WithQualifier(const wil::zwstring_view qualifierName, const wil::zwstring_view qualifierValue) const +{ + auto newContext = _resourceContext.Clone(); + auto qualifierValues = newContext.QualifierValues(); + qualifierValues.Insert(qualifierName, qualifierValue); // mutable! + return ScopedResourceLoader{ _resourceMap, std::move(newContext) }; +} diff --git a/src/cascadia/WinRTUtils/inc/LibraryResources.h b/src/cascadia/WinRTUtils/inc/LibraryResources.h index 56a0b1b5e1..92d9563a8e 100644 --- a/src/cascadia/WinRTUtils/inc/LibraryResources.h +++ b/src/cascadia/WinRTUtils/inc/LibraryResources.h @@ -67,6 +67,9 @@ namespace Microsoft::Console::Utils __pragma(warning(suppress : 26485)); \ __declspec(selectany) extern const wchar_t* g_WinRTUtilsLibraryResourceScope{ (x) }; +class ScopedResourceLoader; + +const ScopedResourceLoader& GetLibraryResourceLoader(); winrt::hstring GetLibraryResourceString(const std::wstring_view key); bool HasLibraryResourceWithName(const std::wstring_view key); diff --git a/src/cascadia/WinRTUtils/inc/ScopedResourceLoader.h b/src/cascadia/WinRTUtils/inc/ScopedResourceLoader.h index f7664115e4..6ae1fb6820 100644 --- a/src/cascadia/WinRTUtils/inc/ScopedResourceLoader.h +++ b/src/cascadia/WinRTUtils/inc/ScopedResourceLoader.h @@ -11,7 +11,10 @@ public: winrt::hstring GetLocalizedString(const std::wstring_view resourceName) const; bool HasResourceWithName(const std::wstring_view resourceName) const; + ScopedResourceLoader WithQualifier(const wil::zwstring_view qualifierName, const wil::zwstring_view qualifierValue) const; + private: + ScopedResourceLoader(winrt::Windows::ApplicationModel::Resources::Core::ResourceMap map, winrt::Windows::ApplicationModel::Resources::Core::ResourceContext context) noexcept; winrt::Windows::ApplicationModel::Resources::Core::ResourceMap _resourceMap; winrt::Windows::ApplicationModel::Resources::Core::ResourceContext _resourceContext; };