@@ -61,7 +61,8 @@ namespace ice
6161 }
6262
6363 ice::InputActionBuilder::Source source = _builder->define_source (node.data ().name , type);
64- if (arctic::SyntaxNode const binding = node.child <ice::syntax::LayerInputBinding>(); binding)
64+ arctic::SyntaxNode binding = node.child <ice::syntax::LayerInputBinding>();
65+ while (binding)
6566 {
6667 using ice::input::DeviceType;
6768 using ice::input::KeyboardKey;
@@ -103,6 +104,9 @@ namespace ice
103104 source.add_button (mouseinput);
104105 }
105106 }
107+
108+ // TODO: We need to fix building layers with sources having multiple inputs, before enabling this.
109+ binding = binding.sibling <ice::syntax::LayerInputBinding>();
106110 }
107111
108112 ICE_LOG (LogSeverity::Info, LogTag::Engine, " Source: {}" , node.data ().name );
@@ -135,17 +139,8 @@ namespace ice
135139 {
136140 if (child.type () == ice::syntax::SyntaxEntity_LayerActionCondition)
137141 {
138- visit_cond (action, child.to <ice::syntax::LayerActionWhen>());
139-
140- arctic::SyntaxNode<> steps = child.child ();
141- while (steps != false )
142- {
143- if (steps.type () == ice::syntax::SyntaxEntity_LayerActionStep)
144- {
145- visit_step (action, steps.to <ice::syntax::LayerActionStep>());
146- }
147- steps = steps.sibling ();
148- }
142+ // Returns the final node of the series. The next sibling is either a: modifier, condition_series or action
143+ child = visit_cond (action.add_condition_series (), child.to <ice::syntax::LayerActionWhen>());
149144 }
150145 else if (child.type () == ice::syntax::SyntaxEntity_LayerActionModifier)
151146 {
@@ -155,72 +150,98 @@ namespace ice
155150 }
156151 }
157152
158- void InputActionDSLLayerBuilder::visit_cond (
159- ice::InputActionBuilder::Action& action ,
153+ auto InputActionDSLLayerBuilder::visit_cond (
154+ ice::InputActionBuilder::ConditionSeries series ,
160155 arctic::SyntaxNode<ice::syntax::LayerActionWhen> node
161- ) noexcept
156+ ) noexcept -> arctic::SyntaxNode<>
162157 {
163158 using enum ice::InputActionCondition;
164159
165- ice::syntax::LayerActionWhen const & cond = node.to <ice::syntax::LayerActionWhen>().data ();
166- ICE_LOG (LogSeverity::Debug, LogTag::Tool, " - {} {}.{} {} {}" , cond.type .value , cond.source_type .value , cond.source_name , cond.condition .value , cond.param .value );
167-
168- bool const from_action = cond.source_type .type == grammar::UCT_Action
169- || (cond.source_type .type == arctic::TokenType::Invalid && cond.source_name .empty ()); // "self"
170- ice::InputActionCondition const condition = detail::condition_from_dsl (cond.condition , from_action);
171- ice::InputActionConditionFlags flags = InputActionConditionFlags::None;
160+ arctic::SyntaxNode<ice::syntax::LayerActionWhen> cond_node = node;
161+ ICE_ASSERT_CORE (cond_node.data ().type .type == grammar::UCT_When);
172162
173- // No siblings or next sibling: "when" == "final" condition.
174- if (auto sib = node.sibling <ice::syntax::LayerActionWhen>(); !sib || sib.data ().type .type == grammar::UCT_When)
175- {
176- flags |= InputActionConditionFlags::Final;
177- }
178- if (node.child <syntax::LayerActionStep>()) // Only steps can introduce children.
179- {
180- flags |= InputActionConditionFlags::RunSteps;
181- }
182- if (cond.flag_series )
183- {
184- flags |= InputActionConditionFlags::SeriesCheck;
185- }
186- if (cond.type .type == grammar::UCT_WhenAnd) // Only steps can introduce children.
187- {
188- flags |= InputActionConditionFlags::SeriesAnd;
189- }
190- else // if (cond.type.type == grammar::UCT_WhenOr) // Only steps can introduce children.
163+ ICE_LOG (LogSeverity::Debug, LogTag::Tool, " New condition series" );
164+ do
191165 {
192- flags |= InputActionConditionFlags::SeriesOr;
193- }
166+ node = cond_node; // Set the node to the current cond_node, necessary to return a valid node
167+ ice::syntax::LayerActionWhen const & cond = cond_node.data ();
168+ ICE_LOG (LogSeverity::Debug, LogTag::Tool, " - {} {}.{} {} {}" , cond.type .value , cond.source_type .value , cond.source_name , cond.condition .value , cond.param .value );
169+
170+ bool const from_action = cond.source_type .type == grammar::UCT_Action
171+ || (cond.source_type .type == arctic::TokenType::Invalid && cond.source_name .empty ()); // "self"
172+ ice::InputActionCondition const condition = detail::condition_from_dsl (cond.condition , from_action);
173+
174+ ice::InputActionConditionFlags flags = InputActionConditionFlags::None;
175+ if (cond_node.child <syntax::LayerActionStep>())
176+ {
177+ flags |= InputActionConditionFlags::RunSteps;
178+ }
179+ if (cond.flag_series )
180+ {
181+ flags |= InputActionConditionFlags::SeriesCheck;
182+ }
194183
195- // TODO: SeriesCheck
196- // TODO: non-Final
184+ if (cond.type .type == grammar::UCT_WhenAnd)
185+ {
186+ flags |= InputActionConditionFlags::SeriesAnd;
187+ }
188+ // If we are When or WhenOr, we default to 'SeriesOr'
189+ else
190+ {
191+ flags |= InputActionConditionFlags::SeriesOr;
192+ }
197193
198- ice::f32 param = 0 .0f ;
199- bool const is_param_condition = condition == Equal || condition == NotEqual
200- || condition == Greater || condition == GreaterOrEqual
201- || condition == Lower || condition == LowerOrEqual;
202- if (is_param_condition)
194+ ice::f32 param = 0 .0f ;
195+ bool const is_param_condition = condition == Equal || condition == NotEqual
196+ || condition == Greater || condition == GreaterOrEqual
197+ || condition == Lower || condition == LowerOrEqual;
198+ if (is_param_condition)
199+ {
200+ ice::from_chars (cond.param .value , param);
201+ }
202+
203+ // Adds the new condition
204+ series.add_condition (
205+ cond.source_name , condition, flags, param, from_action
206+ );
207+
208+ // Move over all steps defined for this condition
209+ arctic::SyntaxNode<> steps = cond_node.child ();
210+ while (steps != false )
211+ {
212+ if (steps.type () == ice::syntax::SyntaxEntity_LayerActionStep)
213+ {
214+ visit_step (series, steps.to <ice::syntax::LayerActionStep>());
215+ }
216+ steps = steps.sibling ();
217+ }
218+
219+ cond_node = cond_node.sibling <ice::syntax::LayerActionWhen>();
220+ } while (cond_node && cond_node.data ().type .type != grammar::UCT_When);
221+
222+ // TODO: Check for '.continue' flag to skip setting 'Final' flag here
223+ // if (/* DOES NOT HAVE '.continue' flag */)
203224 {
204- ice::from_chars (cond. param . value , param );
225+ series. set_finished ( );
205226 }
206227
207- action. add_condition (cond. source_name , condition, flags, param, from_action) ;
228+ return node ;
208229 }
209230
210231 void InputActionDSLLayerBuilder::visit_step (
211- ice::InputActionBuilder::Action& action ,
232+ ice::InputActionBuilder::ConditionSeries& condition_series ,
212233 arctic::SyntaxNode<ice::syntax::LayerActionStep> node
213234 ) noexcept
214235 {
215236 ice::syntax::LayerActionStep const & info = node.data ();
216237 ice::InputActionStep const step = detail::step_from_dsl (info.step );
217238 if (step == InputActionStep::Set || step == InputActionStep::Add || step == InputActionStep::Sub)
218239 {
219- action .add_step (info.source , step, info.destination );
240+ condition_series .add_step (info.source , step, info.destination );
220241 }
221242 else
222243 {
223- action .add_step (step);
244+ condition_series .add_step (step);
224245 }
225246 }
226247
@@ -275,19 +296,19 @@ namespace ice
275296 {
276297 result = KeyboardKey::Space;
277298 }
278- else if (value == " up" )
299+ else if (ice::compare ( value, " up" ) == CompareResult::Equal )
279300 {
280301 result = KeyboardKey::Up;
281302 }
282- else if (value == " down" )
303+ else if (ice::compare ( value, " down" ) == CompareResult::Equal )
283304 {
284305 result = KeyboardKey::Down;
285306 }
286- else if (value == " left" )
307+ else if (ice::compare ( value, " left" ) == CompareResult::Equal )
287308 {
288309 result = KeyboardKey::Left;
289310 }
290- else if (value == " right" )
311+ else if (ice::compare ( value, " right" ) == CompareResult::Equal )
291312 {
292313 result = KeyboardKey::Right;
293314 }
@@ -328,57 +349,6 @@ namespace ice
328349 return result;
329350 }
330351
331- #if 0
332- auto detail::mod_from_dsl(arctic::String value) noexcept -> ice::input::KeyboardMod
333- {
334- using ice::input::KeyboardMod;
335-
336- if (strnicmp(value.data(), "mode", 4) == 0)
337- {
338- return KeyboardMod::Mode;
339- }
340- else if (strnicmp(value.data(), "numlock", 4) == 0)
341- {
342- return KeyboardMod::NumLock;
343- }
344- else if (strnicmp(value.data(), "capslock", 4) == 0)
345- {
346- return KeyboardMod::CapsLock;
347- }
348-
349- // If left == 2, if right == 1, else 0
350- KeyboardMod result = KeyboardMod::None;
351- ICE_ASSERT_CORE(value.size() >= 3);
352-
353- ice::u8 const mod_side = (value[0] == 'l' ? 2 : (value[0] == 'r' ? 1 : 0));
354- value = value.substr(ice::u32(mod_side != 0)); // We remove the prefix ('l' or 'r') from the remaining value.
355-
356- switch (value[0])
357- {
358- case 's':
359- case 'S':
360- result = static_cast<KeyboardMod>(3 ^ mod_side);
361- break;
362- case 'c':
363- case 'C':
364- result = static_cast<KeyboardMod>((3 ^ mod_side) << 2);
365- break;
366- case 'a':
367- case 'A':
368- result = static_cast<KeyboardMod>((3 ^ mod_side) << 4);
369- break;
370- case 'g':
371- case 'G':
372- result = static_cast<KeyboardMod>((3 ^ mod_side) << 8);
373- break;
374- default:
375- break;
376- }
377-
378- return result;
379- }
380- #endif
381-
382352 auto detail::mouse_from_dsl (arctic::String value) noexcept -> ice::input::MouseInput
383353 {
384354 using ice::input::MouseInput;
0 commit comments