terminal/src/cascadia/WinRTUtils/LibraryResources.cpp
Mike Griese aa1ed0a19c
Add support for the Command Palette (#6635)
## Summary of the Pull Request

![command-palette-001](https://user-images.githubusercontent.com/18356694/85313480-b6dbef00-b47d-11ea-8a8f-a802d26c2f9b.gif)


This adds a first iteration on the command palette. Notable missing features are:
* Commandline mode: This will be a follow-up PR, following the merge of #6537
* nested and iterable commands: These will additionally be a follow-up PR.

This is also additionally based off the addenda in #6532. 

This does not bind a key for the palette by default. That will be done when the above follow-ups are completed.

## References
* #2046 - The original command palette thread
* #5400 - This is the megathread for all command palette issues, which is tracking a bunch of additional follow up work 
* #5674 and #6532 - specs
* #6537 - related

## PR Checklist
* [x] Closes #2046
  - incidentally also closes #6645
* [x] I work here
* [x] Tests added/passed
* [ ] Requires documentation to be updated - delaying this until it's more polished.


## Detailed Description of the Pull Request / Additional comments

* There's a lot of code for autogenerating command names. That's all in `ActionArgs.cpp`, because each case is so _not_ boilerplate, unlike the rest of the code in `ActionArgs.h`.

## Validation Steps Performed

* I've been playing with this for months.
* Tests
* Selfhost with the team
2020-06-26 20:38:02 +00:00

105 lines
3.1 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "ScopedResourceLoader.h"
#include "LibraryResources.h"
/*
CHECKED RESOURCES
This is the support infrastructure for "checked resources", a system that lets
us immediately failfast (on launch) when a library makes a static reference to
a resource that doesn't exist at runtime.
Resource checking relies on diligent use of USES_RESOURCE() and RS_() (which
uses USES_RESOURCE), but can make sure we don't ship something that'll blow up
at runtime.
It works like this:
** IN DEBUG MODE **
- All resource names referenced through USES_RESOURCE() are emitted alongside
their referencing filenames and line numbers into a static section of the
binary.
That section is named .util$res$m.
- We emit two sentinel values into two different sections, .util$res$a and
.util$res$z.
- The linker sorts all sections alphabetically before crushing them together
into the final binary.
- When we first construct our library's scoped resource loader, we iterate over
every resource reference between $a and $z and check residency.
** IN RELEASE MODE **
- All checked resource code is compiled out.
*/
extern const wchar_t* g_WinRTUtilsLibraryResourceScope;
#ifdef _DEBUG
#pragma detect_mismatch("winrt_utils_debug", "1")
#pragma section(".util$res$a", read)
#pragma section(".util$res$z", read)
__declspec(allocate(".util$res$a")) static const ::Microsoft::Console::Utils::StaticResource* debugResFirst{ nullptr };
__declspec(allocate(".util$res$z")) static const ::Microsoft::Console::Utils::StaticResource* debugResLast{ nullptr };
static void EnsureAllResourcesArePresent(const ScopedResourceLoader& loader)
{
for (auto resp = &debugResFirst; resp != &debugResLast; ++resp)
{
if (*resp)
{
const auto& res = **resp;
if (!loader.HasResourceWithName(res.resourceKey))
{
auto filename = wcsrchr(res.filename, L'\\');
if (!filename)
{
filename = res.filename;
}
else
{
filename++; // skip the '\'
}
FAIL_FAST_MSG("Resource %ls not found in scope %ls (%ls:%u)", res.resourceKey, g_WinRTUtilsLibraryResourceScope, filename, res.line);
}
}
}
}
#else // _DEBUG
#pragma detect_mismatch("winrt_utils_debug", "0")
#endif
static ScopedResourceLoader GetLibraryResourceLoader()
try
{
ScopedResourceLoader loader{ g_WinRTUtilsLibraryResourceScope };
#ifdef _DEBUG
EnsureAllResourcesArePresent(loader);
#endif
return loader;
}
CATCH_FAIL_FAST()
winrt::hstring GetLibraryResourceString(const std::wstring_view key)
try
{
static auto loader{ GetLibraryResourceLoader() };
return loader.GetLocalizedString(key);
}
CATCH_FAIL_FAST()
bool HasLibraryResourceWithName(const std::wstring_view key)
try
{
static auto loader{ GetLibraryResourceLoader() };
return loader.HasResourceWithName(key);
}
CATCH_FAIL_FAST()