@@ -54,50 +54,81 @@ struct InitListPlaceholder
5454// expanded. Pretty critical for tracking down extraneous commas, etc.
5555
5656// Property definitions, and JSON keys
57- #define DECLARE_ARGS (type, name, jsonKey, required, ...) \
57+ #define DECLARE_ARGS (type, name, jsonKey, required, tag, ...) \
5858 static constexpr std::string_view name##Key{ jsonKey }; \
5959 ACTION_ARG (type, name, ##__VA_ARGS__);
6060
6161// Parameters to the non-default ctor
62- #define CTOR_PARAMS (type, name, jsonKey, required, ...) \
62+ #define CTOR_PARAMS (type, name, jsonKey, required, tag, ...) \
6363 const type &name##Param,
6464
6565// initializers in the ctor
66- #define CTOR_INIT (type, name, jsonKey, required, ...) \
66+ #define CTOR_INIT (type, name, jsonKey, required, tag, ...) \
6767 _##name{ name##Param },
6868
69+ // append this argument's description to the internal vector
70+ #define APPEND_ARG_DESCRIPTION (type, name, jsonKey, required, tag, ...) \
71+ _argDescriptions.push_back({ L## #name, L## #type, std::wstring_view (L## #required) != L" false" , tag });
72+
6973// check each property in the Equals() method. You'll note there's a stray
7074// `true` in the definition of Equals() below, that's to deal with trailing
7175// commas
72- #define EQUALS_ARGS (type, name, jsonKey, required, ...) \
76+ #define EQUALS_ARGS (type, name, jsonKey, required, tag, ...) \
7377 &&(otherAsUs->_##name == _##name)
7478
79+ // getter and setter for each property by index
80+ #define GET_ARG_BY_INDEX (type, name, jsonKey, required, tag, ...) \
81+ if (index == curIndex++) \
82+ { \
83+ if (_##name.has_value ()) \
84+ { \
85+ return winrt::box_value (_##name.value ()); \
86+ } \
87+ else \
88+ { \
89+ return winrt::box_value (static_cast <type>(__VA_ARGS__)); \
90+ } \
91+ }
92+
93+ #define SET_ARG_BY_INDEX (type, name, jsonKey, required, tag, ...) \
94+ if (index == curIndex++) \
95+ { \
96+ if (value) \
97+ { \
98+ _##name = winrt::unbox_value<type>(value); \
99+ } \
100+ else \
101+ { \
102+ _##name = std::nullopt ; \
103+ } \
104+ }
105+
75106// JSON deserialization. If the parameter is required to pass any validation,
76107// add that as the `required` parameter here, as the body of a conditional
77108// EX: For the RESIZE_PANE_ARGS
78109// X(Model::ResizeDirection, ResizeDirection, "direction", args->ResizeDirection() == ResizeDirection::None, Model::ResizeDirection::None)
79110// the bit
80111// args->ResizeDirection() == ResizeDirection::None
81112// is used as the conditional for the validation here.
82- #define FROM_JSON_ARGS (type, name, jsonKey, required, ...) \
83- JsonUtils::GetValueForKey (json, jsonKey, args->_##name); \
84- if (required) \
85- { \
86- return { nullptr , { SettingsLoadWarnings::MissingRequiredParameter } }; \
113+ #define FROM_JSON_ARGS (type, name, jsonKey, required, tag, ...) \
114+ JsonUtils::GetValueForKey (json, jsonKey, args->_##name); \
115+ if (required) \
116+ { \
117+ return { nullptr , { SettingsLoadWarnings::MissingRequiredParameter } }; \
87118 }
88119
89120// JSON serialization
90- #define TO_JSON_ARGS (type, name, jsonKey, required, ...) \
121+ #define TO_JSON_ARGS (type, name, jsonKey, required, tag, ...) \
91122 JsonUtils::SetValueForKey (json, jsonKey, args->_##name);
92123
93124// Copy each property in the Copy() method
94- #define COPY_ARGS (type, name, jsonKey, required, ...) \
125+ #define COPY_ARGS (type, name, jsonKey, required, tag, ...) \
95126 copy->_##name = _##name;
96127
97128// hash each property in Hash(). You'll note there's a stray `0` in the
98129// definition of Hash() below, that's to deal with trailing commas (or in this
99130// case, leading.)
100- #define HASH_ARGS (type, name, jsonKey, required, ...) \
131+ #define HASH_ARGS (type, name, jsonKey, required, tag, ...) \
101132 h.write(name());
102133
103134// Use ACTION_ARGS_STRUCT when you've got no other customizing to do.
@@ -111,53 +142,110 @@ struct InitListPlaceholder
111142// * NewTerminalArgs has a ToCommandline method it needs to additionally declare.
112143// * GlobalSummonArgs has the QuakeModeFromJson helper
113144
114- #define ACTION_ARG_BODY (className, argsMacro ) \
115- className () = default; \
116- className ( \
117- argsMacro (CTOR_PARAMS) InitListPlaceholder = {}) : \
118- argsMacro(CTOR_INIT) _placeholder{} {}; \
119- argsMacro (DECLARE_ARGS); \
120- \
121- private: \
122- InitListPlaceholder _placeholder; \
123- \
124- public: \
125- hstring GenerateName () const ; \
126- bool Equals (const IActionArgs& other) \
127- { \
128- auto otherAsUs = other.try_as <className>(); \
129- if (otherAsUs) \
130- { \
131- return true argsMacro (EQUALS_ARGS); \
132- } \
133- return false ; \
134- }; \
135- static FromJsonResult FromJson (const Json::Value& json) \
136- { \
137- auto args = winrt::make_self<className>(); \
138- argsMacro (FROM_JSON_ARGS); \
139- return { *args, {} }; \
140- } \
141- static Json::Value ToJson (const IActionArgs& val) \
142- { \
143- if (!val) \
144- { \
145- return {}; \
146- } \
147- Json::Value json{ Json::ValueType::objectValue }; \
148- const auto args{ get_self<className>(val) }; \
149- argsMacro (TO_JSON_ARGS); \
150- return json; \
151- } \
152- IActionArgs Copy () const \
153- { \
154- auto copy{ winrt::make_self<className>() }; \
155- argsMacro (COPY_ARGS); \
156- return *copy; \
157- } \
158- size_t Hash () const \
159- { \
160- til::hasher h; \
161- argsMacro (HASH_ARGS); \
162- return h.finalize (); \
145+ #define ACTION_ARG_BODY (className, argsMacro ) \
146+ className () { argsMacro (APPEND_ARG_DESCRIPTION) }; \
147+ className ( \
148+ argsMacro (CTOR_PARAMS) InitListPlaceholder = {}) : \
149+ argsMacro(CTOR_INIT) _placeholder{} { \
150+ argsMacro (APPEND_ARG_DESCRIPTION) \
151+ }; \
152+ argsMacro (DECLARE_ARGS); \
153+ \
154+ private: \
155+ InitListPlaceholder _placeholder; \
156+ std::vector<ArgDescription> _argDescriptions; \
157+ \
158+ public: \
159+ hstring GenerateName () const ; \
160+ bool Equals (const IActionArgs& other) \
161+ { \
162+ auto otherAsUs = other.try_as <className>(); \
163+ if (otherAsUs) \
164+ { \
165+ return true argsMacro (EQUALS_ARGS); \
166+ } \
167+ return false ; \
168+ }; \
169+ static FromJsonResult FromJson (const Json::Value& json) \
170+ { \
171+ auto args = winrt::make_self<className>(); \
172+ argsMacro (FROM_JSON_ARGS); \
173+ return { *args, {} }; \
174+ } \
175+ static Json::Value ToJson (const IActionArgs& val) \
176+ { \
177+ if (!val) \
178+ { \
179+ return {}; \
180+ } \
181+ Json::Value json{ Json::ValueType::objectValue }; \
182+ const auto args{ get_self<className>(val) }; \
183+ argsMacro (TO_JSON_ARGS); \
184+ return json; \
185+ } \
186+ IActionArgs Copy () const \
187+ { \
188+ auto copy{ winrt::make_self<className>() }; \
189+ argsMacro (COPY_ARGS); \
190+ copy->_argDescriptions = _argDescriptions; \
191+ return *copy; \
192+ } \
193+ size_t Hash () const \
194+ { \
195+ til::hasher h; \
196+ argsMacro (HASH_ARGS); \
197+ return h.finalize (); \
198+ } \
199+ uint32_t GetArgCount () const \
200+ { \
201+ return gsl::narrow<uint32_t >(_argDescriptions.size ()); \
202+ } \
203+ ArgDescription GetArgDescriptionAt (uint32_t index) const \
204+ { \
205+ return _argDescriptions.at (index); \
206+ } \
207+ IInspectable GetArgAt (uint32_t index) const \
208+ { \
209+ uint32_t curIndex{ 0 }; \
210+ argsMacro (GET_ARG_BY_INDEX) \
211+ return nullptr ; \
212+ } \
213+ void SetArgAt (uint32_t index, IInspectable value) \
214+ { \
215+ uint32_t curIndex{ 0 }; \
216+ argsMacro (SET_ARG_BY_INDEX) \
217+ }
218+
219+ #define PARTIAL_ACTION_ARG_BODY (className, argsMacro ) \
220+ className (){ argsMacro (APPEND_ARG_DESCRIPTION) }; \
221+ className ( \
222+ argsMacro (CTOR_PARAMS) InitListPlaceholder = {}) : \
223+ argsMacro(CTOR_INIT) _placeholder{} { \
224+ argsMacro (APPEND_ARG_DESCRIPTION) \
225+ }; \
226+ argsMacro (DECLARE_ARGS); \
227+ \
228+ private: \
229+ InitListPlaceholder _placeholder; \
230+ std::vector<ArgDescription> _argDescriptions; \
231+ \
232+ public: \
233+ uint32_t GetArgCount () const \
234+ { \
235+ return gsl::narrow<uint32_t >(_argDescriptions.size ()); \
236+ } \
237+ ArgDescription GetArgDescriptionAt (uint32_t index) const \
238+ { \
239+ return _argDescriptions.at (index); \
240+ } \
241+ IInspectable GetArgAt (uint32_t index) const \
242+ { \
243+ uint32_t curIndex{ 0 }; \
244+ argsMacro (GET_ARG_BY_INDEX) \
245+ return nullptr ; \
246+ } \
247+ void SetArgAt (uint32_t index, IInspectable value) \
248+ { \
249+ uint32_t curIndex{ 0 }; \
250+ argsMacro (SET_ARG_BY_INDEX) \
163251 }
0 commit comments