diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.h b/src/cascadia/TerminalSettingsModel/ActionArgs.h index 4f70bc2f9d..f5bb64e1b0 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.h +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.h @@ -394,8 +394,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation public: NewTerminalArgs(int32_t& profileIndex) : - _ProfileIndex{ profileIndex }, - _argDescriptors(INIT_ARG_DESCRIPTORS(NEW_TERMINAL_ARGS)) {}; + _ProfileIndex{ profileIndex } {}; hstring GenerateName() const { return GenerateName(GetLibraryResourceLoader().ResourceContext()); } hstring GenerateName(const winrt::Windows::ApplicationModel::Resources::Core::ResourceContext&) const; hstring ToCommandline() const; @@ -637,7 +636,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation h.write(ContentArgs()); return h.finalize(); } - uint32_t GetArgCount() const + uint32_t GetArgCount() { if (_ContentArgs) { @@ -648,42 +647,57 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation } return 0; } - Model::ArgDescriptor GetArgDescriptorAt(uint32_t index) const + winrt::Windows::Foundation::Collections::IVectorView GetArgDescriptors() { - return _ContentArgs.as()->GetArgDescriptorAt(index); + if (_ContentArgs) + { + if (const auto newTermArgs = _ContentArgs.try_as()) + { + return newTermArgs->GetArgDescriptors(); + } + } + return {}; } IInspectable GetArgAt(uint32_t index) const { - return _ContentArgs.as()->GetArgAt(index); + if (_ContentArgs) + { + if (const auto newTermArgs = _ContentArgs.try_as()) + { + return newTermArgs->GetArgAt(index); + } + } + return nullptr; } void SetArgAt(uint32_t index, IInspectable value) { - _ContentArgs.as()->SetArgAt(index, value); + if (_ContentArgs) + { + if (const auto newTermArgs = _ContentArgs.try_as()) + { + newTermArgs->SetArgAt(index, value); + } + } } }; struct SplitPaneArgs : public SplitPaneArgsT { - SplitPaneArgs() : - _argDescriptors(INIT_ARG_DESCRIPTORS(SPLIT_PANE_ARGS)) {}; + SplitPaneArgs() = default; SplitPaneArgs(SplitType splitMode, SplitDirection direction, float size, const Model::INewContentArgs& terminalArgs) : _SplitMode{ splitMode }, _SplitDirection{ direction }, _SplitSize{ size }, - _ContentArgs{ terminalArgs }, - _argDescriptors(INIT_ARG_DESCRIPTORS(SPLIT_PANE_ARGS)) {}; + _ContentArgs{ terminalArgs } {}; SplitPaneArgs(SplitDirection direction, float size, const Model::INewContentArgs& terminalArgs) : _SplitDirection{ direction }, _SplitSize{ size }, - _ContentArgs{ terminalArgs }, - _argDescriptors(INIT_ARG_DESCRIPTORS(SPLIT_PANE_ARGS)) {}; + _ContentArgs{ terminalArgs } {}; SplitPaneArgs(SplitDirection direction, const Model::INewContentArgs& terminalArgs) : _SplitDirection{ direction }, - _ContentArgs{ terminalArgs }, - _argDescriptors(INIT_ARG_DESCRIPTORS(SPLIT_PANE_ARGS)) {}; + _ContentArgs{ terminalArgs } {}; SplitPaneArgs(SplitType splitMode) : - _SplitMode{ splitMode }, - _argDescriptors(INIT_ARG_DESCRIPTORS(SPLIT_PANE_ARGS)) {}; + _SplitMode{ splitMode } {}; SPLIT_PANE_ARGS(DECLARE_ARGS); WINRT_PROPERTY(Model::INewContentArgs, ContentArgs, Model::NewTerminalArgs{}); @@ -752,35 +766,43 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation h.write(SplitSize()); return h.finalize(); } - uint32_t GetArgCount() const + uint32_t GetArgCount() { if (_ContentArgs) { if (const auto newTermArgs = _ContentArgs.try_as()) { - return newTermArgs->GetArgCount() + gsl::narrow(_argDescriptors.size()); + return newTermArgs->GetArgCount() + gsl::narrow(GetArgDescriptors().Size()); } } - return gsl::narrow(_argDescriptors.size()); + return gsl::narrow(GetArgDescriptors().Size()); } - Model::ArgDescriptor GetArgDescriptorAt(uint32_t index) const + winrt::Windows::Foundation::Collections::IVectorView GetArgDescriptors() { - const auto additionalArgCount = gsl::narrow(_argDescriptors.size()); + static const auto thisArgs = INIT_ARG_DESCRIPTORS(SPLIT_PANE_ARGS); + auto contentArgs = _ContentArgs.as()->GetArgDescriptors(); + + // Merge into a new vector + std::vector merged; + merged.reserve(thisArgs.Size() + contentArgs.Size()); + + for (const auto desc : thisArgs) + { + merged.push_back(desc); + } + for (const auto desc : contentArgs) + { + merged.push_back(desc); + } + + return winrt::single_threaded_vector(std::move(merged)).GetView(); + } + IInspectable GetArgAt(uint32_t index) + { + const auto additionalArgCount = gsl::narrow(GetArgDescriptors().Size()); if (index < additionalArgCount) { - return _argDescriptors.at(index); - } - else - { - return _ContentArgs.as()->GetArgDescriptorAt(index - additionalArgCount); - } - } - IInspectable GetArgAt(uint32_t index) const - { - const auto additionalArgCount = gsl::narrow(_argDescriptors.size()); - if (index < additionalArgCount) - { - uint32_t curIndex{ 0 }; + X_MACRO_INDEX_BASE(); SPLIT_PANE_ARGS(GET_ARG_BY_INDEX); } else @@ -791,10 +813,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation } void SetArgAt(uint32_t index, IInspectable value) { - const auto additionalArgCount = gsl::narrow(_argDescriptors.size()); + const auto additionalArgCount = gsl::narrow(GetArgDescriptors().Size()); if (index < additionalArgCount) { - uint32_t curIndex{ 0 }; + X_MACRO_INDEX_BASE(); SPLIT_PANE_ARGS(SET_ARG_BY_INDEX); } else @@ -802,9 +824,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation _ContentArgs.as()->SetArgAt(index - additionalArgCount, value); } } - - private: - const std::vector _argDescriptors; }; struct NewWindowArgs : public NewWindowArgsT @@ -856,7 +875,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation h.write(ContentArgs()); return h.finalize(); } - uint32_t GetArgCount() const + uint32_t GetArgCount() { if (_ContentArgs) { @@ -867,9 +886,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation } return 0; } - Model::ArgDescriptor GetArgDescriptorAt(uint32_t index) const + winrt::Windows::Foundation::Collections::IVectorView GetArgDescriptors() { - return _ContentArgs.as()->GetArgDescriptorAt(index); + return _ContentArgs.as()->GetArgDescriptors(); } IInspectable GetArgAt(uint32_t index) const { @@ -1019,11 +1038,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation h.write(winrt::get_abi(_Actions)); return h.finalize(); } - uint32_t GetArgCount() const + uint32_t GetArgCount() { return _Actions.Size(); } - Model::ArgDescriptor GetArgDescriptorAt(uint32_t /*index*/) const + winrt::Windows::Foundation::Collections::IVectorView GetArgDescriptors() { return {}; } diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.idl b/src/cascadia/TerminalSettingsModel/ActionArgs.idl index 1864559102..7012343199 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.idl +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.idl @@ -24,7 +24,7 @@ namespace Microsoft.Terminal.Settings.Model interface IActionArgsDescriptorAccess { UInt32 GetArgCount(); - ArgDescriptor GetArgDescriptorAt(UInt32 index); + Windows.Foundation.Collections.IVectorView GetArgDescriptors(); IInspectable GetArgAt(UInt32 index); void SetArgAt(UInt32 index, Object value); }; diff --git a/src/cascadia/TerminalSettingsModel/ActionArgsMagic.h b/src/cascadia/TerminalSettingsModel/ActionArgsMagic.h index ff2e1bcf00..06718afc37 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgsMagic.h +++ b/src/cascadia/TerminalSettingsModel/ActionArgsMagic.h @@ -76,10 +76,10 @@ struct InitListPlaceholder #define APPEND_ARG_DESCRIPTION(type, name, jsonKey, required, typeHint, ...) \ temp.push_back({ RS_(LOCALIZED_NAME(name)), L## #type, std::wstring_view(L## #required) != L"false", typeHint }); -#define INIT_ARG_DESCRIPTORS(argsMacro) \ - ([&]() { \ - std::vector temp; \ - argsMacro(APPEND_ARG_DESCRIPTION) return temp; \ +#define INIT_ARG_DESCRIPTORS(argsMacro) \ + ([]() -> winrt::Windows::Foundation::Collections::IVectorView { \ + std::vector temp; \ + argsMacro(APPEND_ARG_DESCRIPTION) return winrt::single_threaded_vector(std::move(temp)).GetView(); \ }()) // check each property in the Equals() method. You'll note there's a stray @@ -88,22 +88,28 @@ struct InitListPlaceholder #define EQUALS_ARGS(type, name, jsonKey, required, typeHint, ...) \ &&(otherAsUs->_##name == _##name) +#define X_MACRO_INDEX_BASE() \ + constexpr auto X_MACRO_INDEXED_BASE__ = __COUNTER__ - 1 + +#define X_MACRO_INDEX() \ + (__COUNTER__ - X_MACRO_INDEXED_BASE__) + // getter and setter for each property by index -#define GET_ARG_BY_INDEX(type, name, jsonKey, required, typeHint, ...) \ - if (index == curIndex++) \ - { \ - if (_##name.has_value()) \ - { \ - return winrt::box_value(_##name.value()); \ - } \ - else \ - { \ - return winrt::box_value(static_cast(__VA_ARGS__)); \ - } \ +#define GET_ARG_BY_INDEX(type, name, jsonKey, required, typeHint, ...) \ + if (index == X_MACRO_INDEX()) \ + { \ + if (_##name.has_value()) \ + { \ + return winrt::box_value(_##name.value()); \ + } \ + else \ + { \ + return winrt::box_value(static_cast(__VA_ARGS__)); \ + } \ } #define SET_ARG_BY_INDEX(type, name, jsonKey, required, typeHint, ...) \ - if (index == curIndex++) \ + if (index == X_MACRO_INDEX()) \ { \ if (value) \ { \ @@ -155,18 +161,15 @@ struct InitListPlaceholder // * GlobalSummonArgs has the QuakeModeFromJson helper #define ACTION_ARG_BODY(className, argsMacro) \ - className() : _argDescriptors(INIT_ARG_DESCRIPTORS(argsMacro)) {}; \ - \ + className() = default; \ className( \ argsMacro(CTOR_PARAMS) InitListPlaceholder = {}) : \ argsMacro(CTOR_INIT) \ - _placeholder{}, \ - _argDescriptors(INIT_ARG_DESCRIPTORS(argsMacro)) {}; \ + _placeholder{} {}; \ argsMacro(DECLARE_ARGS); \ \ private: \ InitListPlaceholder _placeholder; \ - const std::vector _argDescriptors; \ \ public: \ hstring GenerateName() const \ @@ -214,56 +217,54 @@ public: argsMacro(HASH_ARGS); \ return h.finalize(); \ } \ - uint32_t GetArgCount() const \ + uint32_t GetArgCount() \ { \ - return gsl::narrow(_argDescriptors.size()); \ + return gsl::narrow(GetArgDescriptors().Size()); \ } \ - ArgDescriptor GetArgDescriptorAt(uint32_t index) const \ + winrt::Windows::Foundation::Collections::IVectorView GetArgDescriptors() \ { \ - return _argDescriptors.at(index); \ + static const auto descriptors = INIT_ARG_DESCRIPTORS(argsMacro); \ + return descriptors; \ } \ IInspectable GetArgAt(uint32_t index) const \ { \ - uint32_t curIndex{ 0 }; \ + X_MACRO_INDEX_BASE(); \ argsMacro(GET_ARG_BY_INDEX) return nullptr; \ } \ void SetArgAt(uint32_t index, IInspectable value) \ { \ - uint32_t curIndex{ 0 }; \ + X_MACRO_INDEX_BASE(); \ argsMacro(SET_ARG_BY_INDEX) \ } -#define PARTIAL_ACTION_ARG_BODY(className, argsMacro) \ - className() : \ - _argDescriptors(INIT_ARG_DESCRIPTORS(argsMacro)) {}; \ - \ - className( \ - argsMacro(CTOR_PARAMS) InitListPlaceholder = {}) : \ - argsMacro(CTOR_INIT) \ - _placeholder{}, \ - _argDescriptors(INIT_ARG_DESCRIPTORS(argsMacro)) {}; \ - argsMacro(DECLARE_ARGS); \ - \ -private: \ - InitListPlaceholder _placeholder; \ - const std::vector _argDescriptors; \ - \ -public: \ - uint32_t GetArgCount() const \ - { \ - return gsl::narrow(_argDescriptors.size()); \ - } \ - ArgDescriptor GetArgDescriptorAt(uint32_t index) const \ - { \ - return _argDescriptors.at(index); \ - } \ - IInspectable GetArgAt(uint32_t index) const \ - { \ - uint32_t curIndex{ 0 }; \ - argsMacro(GET_ARG_BY_INDEX) return nullptr; \ - } \ - void SetArgAt(uint32_t index, IInspectable value) \ - { \ - uint32_t curIndex{ 0 }; \ - argsMacro(SET_ARG_BY_INDEX) \ +#define PARTIAL_ACTION_ARG_BODY(className, argsMacro) \ + className() = default; \ + className( \ + argsMacro(CTOR_PARAMS) InitListPlaceholder = {}) : \ + argsMacro(CTOR_INIT) \ + _placeholder{} {}; \ + argsMacro(DECLARE_ARGS); \ + \ +private: \ + InitListPlaceholder _placeholder; \ + \ +public: \ + uint32_t GetArgCount() \ + { \ + return gsl::narrow(GetArgDescriptors().Size()); \ + } \ + winrt::Windows::Foundation::Collections::IVectorView GetArgDescriptors() \ + { \ + static const auto descriptors = INIT_ARG_DESCRIPTORS(argsMacro); \ + return descriptors; \ + } \ + IInspectable GetArgAt(uint32_t index) const \ + { \ + X_MACRO_INDEX_BASE(); \ + argsMacro(GET_ARG_BY_INDEX) return nullptr; \ + } \ + void SetArgAt(uint32_t index, IInspectable value) \ + { \ + X_MACRO_INDEX_BASE(); \ + argsMacro(SET_ARG_BY_INDEX) \ }