Skip to content

Commit ce3b1d6

Browse files
committed
Parial cleanup of action layers.
1 parent 5f7e367 commit ce3b1d6

File tree

12 files changed

+176
-75
lines changed

12 files changed

+176
-75
lines changed

source/code/core/core/public/ice/error_codes.hxx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace ice
1616
static constexpr ice::ErrorCode E_InvalidArgument{ "E.0002:General:Invalid argument provided" };
1717
static constexpr ice::ErrorCode E_OutOfRange{ "E.0003:General:Accessing value out of range" };
1818
static constexpr ice::ErrorCode E_NotImplemented{ "E.0004:General:Function or method is not implemented" };
19+
static constexpr ice::ErrorCode E_NullPointerData{ "E.0005:General:Passed 'Data{nullptr}' object to function expecting valid data." };
20+
static constexpr ice::ErrorCode E_NullPointerMemory{ "E.0006:General:Passed 'Memory{nullptr}' object to function expecting valid memory." };
1921
static constexpr ice::ErrorCode E_TaskCanceled{ "E.1001:Tasks:Task canceled" };
2022

2123
// Aliases are comparable

source/code/systems/input_action_system/private/input_action_dsl_layer_builder.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ namespace ice
3232
void InputActionDSLLayerBuilder::visit(arctic::SyntaxNode<ice::syntax::Layer> node) noexcept
3333
{
3434
ICE_LOG(LogSeverity::Info, LogTag::Engine, "Layer: {}", node.data().name);
35+
_builder->set_name(node.data().name);
3536

3637
arctic::SyntaxNode<> child = node.child();
3738
while(child != false)

source/code/systems/input_action_system/private/input_action_internal_types.hxx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@
55
namespace ice
66
{
77

8+
//! \brief Header-like structure for binarized version of an InputActionLayer.
9+
//! \note This structure will be used for storing input actions in binary format for release builds.
10+
struct InputActionLayerInfoHeader
11+
{
12+
ice::u16 size_name;
13+
ice::u16 count_sources;
14+
ice::u16 count_actions;
15+
ice::u16 count_conditions;
16+
ice::u16 count_steps;
17+
ice::u16 count_modifiers;
18+
ice::u32 offset_strings;
19+
};
20+
821
struct InputActionIndex
922
{
1023
static constexpr ice::u16 SelfIndex = 8191;

source/code/systems/input_action_system/private/input_action_layer.cxx

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
namespace ice
1818
{
1919

20-
struct StandardInputActionLayerParams
20+
struct InputActionLayerInfo
2121
{
22+
ice::String name;
2223
ice::Span<ice::InputActionSourceInputInfo const> sources;
2324
ice::Span<ice::InputActionInfo const> actions;
2425
ice::Span<ice::InputActionConditionData const> conditions;
@@ -27,30 +28,37 @@ namespace ice
2728
ice::String strings;
2829
};
2930

30-
auto params_from_data(ice::Data memory) noexcept -> ice::Expected<ice::StandardInputActionLayerParams>
31+
template<typename T>
32+
auto load_field_from_data(ice::Span<T const>& out_span, ice::Data data, ice::usize offset, ice::ucount count) noexcept
3133
{
32-
ice::InputActionLayerInfo const* layer_info = reinterpret_cast<ice::InputActionLayerInfo const*>(memory.location);
33-
if (layer_info == nullptr)
34+
out_span = ice::span::from_data<T>(data, count, offset);
35+
return ice::span::data_view(out_span).size;
36+
}
37+
38+
auto load_from_data(ice::Data data) noexcept -> ice::Expected<ice::InputActionLayerInfo>
39+
{
40+
if (data.location == nullptr)
3441
{
35-
return E_Fail;
42+
return E_NullPointerData;
3643
}
3744

38-
ice::usize offset = ice::size_of<ice::InputActionLayerInfo>;
39-
ice::StandardInputActionLayerParams result{};
40-
41-
result.sources = ice::span::from_data<ice::InputActionSourceInputInfo>(memory, layer_info->count_sources, offset);
42-
offset += ice::span::data_view(result.sources).size;
43-
result.actions = ice::span::from_data<ice::InputActionInfo>(memory, layer_info->count_actions, offset);
44-
offset += ice::span::data_view(result.actions).size;
45-
result.conditions = ice::span::from_data<ice::InputActionConditionData>(memory, layer_info->count_conditions, offset);
46-
offset += ice::span::data_view(result.conditions).size;
47-
result.steps = ice::span::from_data<ice::InputActionStepData>(memory, layer_info->count_steps, offset);
48-
offset += ice::span::data_view(result.steps).size;
49-
result.modifiers = ice::span::from_data<ice::InputActionModifierData>(memory, layer_info->count_modifiers, offset);
50-
offset += ice::span::data_view(result.modifiers).size;
51-
52-
ICE_ASSERT_CORE(offset == ice::usize{ layer_info->offset_strings });
53-
result.strings = ice::string::from_data(memory, { layer_info->offset_strings }, ice::ucount(memory.size.value - layer_info->offset_strings));
45+
ice::InputActionLayerInfoHeader const& header = *reinterpret_cast<ice::InputActionLayerInfoHeader const*>(data.location);
46+
ice::usize offset = ice::size_of<ice::InputActionLayerInfoHeader>;
47+
48+
ice::InputActionLayerInfo result{};
49+
offset += load_field_from_data(result.sources, data, offset, header.count_sources);
50+
offset += load_field_from_data(result.actions, data, offset, header.count_actions);
51+
offset += load_field_from_data(result.conditions, data, offset, header.count_conditions);
52+
offset += load_field_from_data(result.steps, data, offset, header.count_steps);
53+
offset += load_field_from_data(result.modifiers, data, offset, header.count_modifiers);
54+
55+
ICE_ASSERT_CORE(offset == ice::usize{ header.offset_strings });
56+
result.strings = ice::string::from_data(
57+
data,
58+
ice::usize{ header.offset_strings },
59+
ice::ucount( data.size.value - header.offset_strings )
60+
);
61+
result.name = ice::string::substr(result.strings, 0, header.size_name);
5462
return result;
5563
}
5664

@@ -60,21 +68,18 @@ namespace ice
6068
StandardInputActionLayer(
6169
ice::Allocator& alloc,
6270
ice::Memory memory,
63-
ice::StandardInputActionLayerParams const& params
71+
ice::InputActionLayerInfo const& info
6472
) noexcept
6573
: _allocator{ alloc }
6674
, _rawdata{ memory }
67-
, _sources{ params.sources }
68-
, _actions{ params.actions }
69-
, _conditions{ params.conditions }
70-
, _steps{ params.steps }
71-
, _modifiers{ params.modifiers }
72-
, _strings{ params.strings }
73-
, _runtime_sources{ alloc }
74-
{
75-
ice::array::resize(_runtime_sources, ice::count(_sources));
76-
ice::array::memset(_runtime_sources, 0);
77-
}
75+
, _name{ info.name }
76+
, _sources{ info.sources }
77+
, _actions{ info.actions }
78+
, _conditions{ info.conditions }
79+
, _steps{ info.steps }
80+
, _modifiers{ info.modifiers }
81+
, _strings{ info.strings }
82+
{ }
7883

7984
~StandardInputActionLayer() noexcept override
8085
{
@@ -83,7 +88,7 @@ namespace ice
8388

8489
auto name() const noexcept -> ice::String override
8590
{
86-
return "Default";
91+
return _name;
8792
}
8893

8994
auto sources() const noexcept -> ice::Span<ice::InputActionSourceInputInfo const> override
@@ -106,14 +111,15 @@ namespace ice
106111
return ice::string::substr(_strings, action.name);
107112
}
108113

109-
bool process_inputs(
110-
ice::Span<ice::input::InputEvent const> input_events,
114+
auto process_inputs(
115+
ice::Span<ice::input::InputEvent> input_events,
111116
ice::Span<ice::InputActionSource* const> source_values
112-
) const noexcept override
117+
) const noexcept -> ice::ucount override
113118
{
114119
IPT_ZONE_SCOPED;
115120

116121
ice::ucount event_index = 0;
122+
ice::ucount processed_count = 0;
117123
ice::ucount const event_count = ice::count(input_events);
118124

119125
while(event_index < event_count)
@@ -170,20 +176,15 @@ namespace ice
170176
};
171177
}
172178

173-
// ICE_LOG(LogSeverity::Debug, LogTag::Engine, "SRC: '{}', VAL = {}", ice::string::substr(_strings, src.name_offset, src.name_length), value.value);
174-
175-
// Remove the processed input
176-
// if (ice::exchange(removed, true) == false)
177-
// {
178-
// ice::array::remove_at(inputs, index);
179-
// count -= 1;
180-
// }
179+
// Clear the processed event
180+
input_events[event_index] = ice::input::InputEvent{};
181+
processed_count += 1;
181182
}
182183

183184
event_index += 1;
184185
}
185186

186-
return event_count != ice::count(input_events);
187+
return processed_count;
187188
}
188189

189190
bool update_actions(
@@ -366,14 +367,13 @@ namespace ice
366367
ice::Allocator& _allocator;
367368
ice::Memory _rawdata;
368369

370+
ice::String _name;
369371
ice::Span<ice::InputActionSourceInputInfo const> _sources;
370372
ice::Span<ice::InputActionInfo const> _actions;
371373
ice::Span<ice::InputActionConditionData const> _conditions;
372374
ice::Span<ice::InputActionStepData const> _steps;
373375
ice::Span<ice::InputActionModifierData const> _modifiers;
374376
ice::String _strings;
375-
376-
ice::Array<ice::InputActionSource> _runtime_sources;
377377
};
378378

379379
auto create_input_action_layer(
@@ -384,7 +384,7 @@ namespace ice
384384
ice::Memory const data_copy = alloc.allocate({ layer_data.size, layer_data.alignment });
385385
ice::memcpy(data_copy, layer_data);
386386

387-
ice::Expected<ice::StandardInputActionLayerParams> params = ice::params_from_data(ice::data_view(data_copy));
387+
ice::Expected<ice::InputActionLayerInfo> params = ice::load_from_data(ice::data_view(data_copy));
388388
if (params.succeeded() == false)
389389
{
390390
return {};
@@ -398,7 +398,7 @@ namespace ice
398398
ice::Memory layer_data
399399
) noexcept -> ice::UniquePtr<ice::InputActionLayer>
400400
{
401-
ice::Expected<ice::StandardInputActionLayerParams> params = ice::params_from_data(ice::data_view(layer_data));
401+
ice::Expected<ice::InputActionLayerInfo> params = ice::load_from_data(ice::data_view(layer_data));
402402
if (params.succeeded() == false)
403403
{
404404
return {};
@@ -412,7 +412,7 @@ namespace ice
412412
ice::String definition
413413
) noexcept -> ice::UniquePtr<ice::InputActionLayer>
414414
{
415-
InputActionDSLLayerBuilder dsl_builder{ ice::create_input_action_layer_builder(alloc) };
415+
InputActionDSLLayerBuilder dsl_builder{ ice::create_input_action_layer_builder(alloc, "") };
416416
if (ice::parse_action_input_definition(definition, dsl_builder))
417417
{
418418
return dsl_builder.finalize(alloc);

source/code/systems/input_action_system/private/input_action_layer_builder.cxx

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,27 @@ namespace ice
107107
class SimpleInputActionLayerBuilder : public ice::InputActionLayerBuilder
108108
{
109109
public:
110-
SimpleInputActionLayerBuilder(ice::Allocator& alloc) noexcept
110+
SimpleInputActionLayerBuilder(
111+
ice::Allocator& alloc,
112+
ice::String name
113+
) noexcept
111114
: _allocator{ alloc }
112115
, _sources{ alloc }
113116
, _actions{ alloc }
117+
, _name{ alloc, name }
114118
{
115119
ice::hashmap::reserve(_sources, 16);
116120
ice::hashmap::reserve(_actions, 10);
117121
}
118122

123+
auto set_name(
124+
ice::String name
125+
) noexcept -> ice::InputActionLayerBuilder& override
126+
{
127+
_name = name;
128+
return *this;
129+
}
130+
119131
auto define_source(ice::String name, ice::InputActionSourceType type) noexcept -> SourceBuilder override
120132
{
121133
ice::hashmap::set(_sources, ice::hash(name), {_allocator, name, type});
@@ -142,6 +154,10 @@ namespace ice
142154
ice::Array<ice::InputActionModifierData> final_modifiers{ _allocator };
143155
ice::Array<ice::InputActionInfo> final_actions{ _allocator };
144156

157+
// Insert layer name as the first string
158+
ice::string::push_back(strings, _name);
159+
ice::string::push_back(strings, '\0');
160+
145161
// Prepare data of all sources
146162
for (SourceBuilder::Internal const& source : _sources)
147163
{
@@ -307,7 +323,8 @@ namespace ice
307323
condition_offset += ice::exchange(condition_count, ice::u16_0);
308324
}
309325

310-
ice::InputActionLayerInfo final_info{
326+
ice::InputActionLayerInfoHeader final_info{
327+
.size_name = ice::u16(ice::size(_name)),
311328
.count_sources = ice::u16(ice::count(final_sources)),
312329
.count_actions = ice::u16(ice::count(final_actions)),
313330
.count_conditions = ice::u16(ice::count(final_conditions)),
@@ -317,7 +334,7 @@ namespace ice
317334
};
318335

319336
// Allocate memory and copy all data
320-
ice::meminfo minfo_layer = ice::meminfo_of<ice::InputActionLayerInfo>;
337+
ice::meminfo minfo_layer = ice::meminfo_of<ice::InputActionLayerInfoHeader>;
321338
ice::usize const offset_sources = minfo_layer += ice::array::meminfo(final_sources);
322339
ice::usize const offset_actions = minfo_layer += ice::array::meminfo(final_actions);
323340
ice::usize const offset_conditions = minfo_layer += ice::array::meminfo(final_conditions);
@@ -341,6 +358,7 @@ namespace ice
341358
ice::Allocator& _allocator;
342359
ice::HashMap<SourceBuilder::Internal> _sources;
343360
ice::HashMap<ActionBuilder::Internal> _actions;
361+
ice::HeapString<> _name;
344362
};
345363

346364

@@ -550,9 +568,12 @@ namespace ice
550568
return *this;
551569
}
552570

553-
auto create_input_action_layer_builder(ice::Allocator& alloc) noexcept -> ice::UniquePtr<ice::InputActionLayerBuilder>
571+
auto create_input_action_layer_builder(
572+
ice::Allocator& alloc,
573+
ice::String name
574+
) noexcept -> ice::UniquePtr<ice::InputActionLayerBuilder>
554575
{
555-
return ice::make_unique<SimpleInputActionLayerBuilder>(alloc, alloc);
576+
return ice::make_unique<SimpleInputActionLayerBuilder>(alloc, alloc, name);
556577
}
557578

558579
} // namespace ice

source/code/systems/input_action_system/private/input_action_stack.cxx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ namespace ice
278278
{
279279
IPT_ZONE_SCOPED;
280280

281+
ice::ucount remaining_events = ice::count(events);
281282
ice::Array<ice::input::InputEvent> events_copy{ _allocator, events };
282283
ice::Array<ice::InputActionSource*> source_values{ _allocator };
283284

@@ -295,7 +296,15 @@ namespace ice
295296
ice::array::push_back(source_values, ice::addressof(_sources_values[offset]));
296297
}
297298

298-
layer.layer->process_inputs(events_copy, source_values);
299+
ice::ucount const processed_events = layer.layer->process_inputs(events_copy, source_values);
300+
ICE_ASSERT_CORE(processed_events <= remaining_events);
301+
remaining_events -= processed_events;
302+
303+
// TODO: further cleanup.
304+
if (remaining_events == 0)
305+
{
306+
break;
307+
}
299308
}
300309

301310
ice::InputActionExecutor ex{};

source/code/systems/input_action_system/public/ice/input_action_definitions.hxx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@ namespace ice
6161
//! \brief Developer defined "input source" for activating actions and processing their values.
6262
//! \details A source represents a single device input event. This can be a Button, Axis, Trigger, Key, Position on
6363
//! any input device like a mouse, keyboard, controller or anything else.
64+
//!
6465
//! \note When represeting an axis, only a single component is set each source.
6566
//! So for a 2d axis you will need to define two sources.
67+
//! \todo Try to remove the 23bit padding.
6668
struct InputActionSource
6769
{
6870
//! \brief The type of the event that triggered a value change for this source.
@@ -73,6 +75,8 @@ namespace ice
7375
//! \note Since multiple events can trigger a value change, we want to act only once for multiple buttons.
7476
bool changed;
7577

78+
// 2 bytes of padding (23 bits in reality due to unused bool bits, 7 + 16)
79+
7680
//! \brief The value of the input source.
7781
//! \details See \see InputActionSourceInfo::type for details.
7882
ice::f32 value;

source/code/systems/input_action_system/public/ice/input_action_executor.hxx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,31 @@ namespace ice
4343
ice::f32 param
4444
) const noexcept;
4545

46+
//! \brief Executes a step over the current actions runtime object, this is generally called for '.activate', '.toggle' and
47+
//! simmilar actions.
48+
//! \param[in] step Action step to be executed.
49+
//! \param[out] runtime Object to be modifed from the action step taken.
4650
void execute_step(
4751
ice::InputActionStep step,
4852
ice::InputActionRuntime& runtime
4953
) const noexcept;
5054

55+
//! \brief Executes a step by taking a value from an input source and storing it at a specific input action value.
56+
//! \param[in] step Action step to be executed.
57+
//! \param[in] source_value Input source from which we want to take the new value.
58+
//! \param[out] destination_value Destination value where we want to store the value from the input source.
5159
void execute_step(
5260
ice::InputActionStep step,
5361
ice::InputActionSource const& source_value,
5462
ice::f32& destination_value
5563
) const noexcept;
5664

65+
//! \brief Executes an modifier with a user provided parameter over an action value.
66+
//! \param modifier Modifier to be executed on the given value.
67+
//! \param action_value The value to be modified (if necessary).
68+
//! \param param User parameter that may be used by the selected modifier.
5769
void execute_modifier(
58-
ice::InputActionModifier step,
70+
ice::InputActionModifier modifier,
5971
ice::f32& action_value,
6072
ice::f32 param
6173
) const noexcept;

0 commit comments

Comments
 (0)