Skip to content

Commit bc3fe60

Browse files
authored
Added execution_options wrapper (#136)
1 parent 94b3c74 commit bc3fe60

File tree

2 files changed

+165
-43
lines changed

2 files changed

+165
-43
lines changed

ecsact/runtime/core.hh

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#pragma once
22

33
#include <type_traits>
4+
#include <vector>
5+
#include <functional>
46
#include "ecsact/runtime/core.h"
57

68
namespace ecsact::core {
@@ -91,4 +93,137 @@ public:
9193
}
9294
};
9395

96+
class builder_entity {
97+
public:
98+
template<typename C>
99+
inline builder_entity& add_component(C* component) {
100+
components.push_back(ecsact_component{
101+
.component_id = C::id,
102+
.component_data = component,
103+
});
104+
return *this;
105+
}
106+
107+
friend class execution_options;
108+
109+
private:
110+
std::vector<ecsact_component> components;
111+
};
112+
113+
class execution_options {
114+
public:
115+
/**
116+
* The lifetime of @p `component` must be maintained until the
117+
* `ecsact::core::execution_options` destructor occurs or `clear()` occurs.
118+
*/
119+
template<typename C>
120+
void add_component(ecsact_entity_id entity, C* component) {
121+
add_components_container.push_back(
122+
ecsact_component{.component_id = C::id, .component_data = component}
123+
);
124+
add_entities_container.push_back(entity);
125+
}
126+
127+
/**
128+
* The lifetime of @p `component` must be maintained until the
129+
* `ecsact::core::execution_options` destructor occurs or `clear()` occurs.
130+
*/
131+
template<typename C>
132+
void update_component(ecsact_entity_id entity, C* component) {
133+
update_components_container.push_back(
134+
ecsact_component{.component_id = C::id, .component_data = component}
135+
);
136+
update_entities_container.push_back(entity);
137+
}
138+
139+
template<typename C>
140+
inline void remove_component(ecsact_entity_id entity_id) {
141+
remove_component_ids_container.push_back(C::id);
142+
remove_entities_container.push_back(entity_id);
143+
}
144+
145+
inline void remove_component(
146+
ecsact_entity_id entity_id,
147+
ecsact_component_id component_id
148+
) {
149+
remove_component_ids_container.push_back(component_id);
150+
remove_entities_container.push_back(entity_id);
151+
}
152+
153+
inline builder_entity& create_entity() {
154+
auto& builder = create_entities.emplace_back(builder_entity{});
155+
return builder;
156+
}
157+
158+
inline void destroy_entity(const ecsact_entity_id& entity_id) {
159+
destroy_entities.push_back(entity_id);
160+
}
161+
162+
inline void clear() {
163+
options = {};
164+
165+
add_entities_container.clear();
166+
add_components_container.clear();
167+
168+
update_entities_container.clear();
169+
update_components_container.clear();
170+
171+
remove_entities_container.clear();
172+
remove_component_ids_container.clear();
173+
174+
entities_components.clear();
175+
entities_component_lengths.clear();
176+
177+
create_entities.clear();
178+
destroy_entities.clear();
179+
}
180+
181+
inline ecsact_execution_options c() {
182+
options.add_components_length = add_components_container.size();
183+
options.add_components_entities = add_entities_container.data();
184+
options.add_components = add_components_container.data();
185+
186+
options.update_components_length = update_components_container.size();
187+
options.update_components_entities = update_entities_container.data();
188+
options.update_components = update_components_container.data();
189+
190+
options.remove_components_length = remove_component_ids_container.size();
191+
options.remove_components_entities = remove_entities_container.data();
192+
options.remove_components = remove_component_ids_container.data();
193+
194+
for(auto& built_entity : create_entities) {
195+
entities_component_lengths.push_back(built_entity.components.size());
196+
entities_components.push_back(built_entity.components.data());
197+
}
198+
199+
options.create_entities_components = entities_components.data();
200+
options.create_entities_length = create_entities.size();
201+
options.create_entities_components_length =
202+
entities_component_lengths.data();
203+
204+
options.destroy_entities = destroy_entities.data();
205+
options.destroy_entities_length = destroy_entities.size();
206+
207+
return options;
208+
}
209+
210+
private:
211+
std::vector<ecsact_entity_id> add_entities_container;
212+
std::vector<ecsact_component> add_components_container;
213+
214+
std::vector<ecsact_entity_id> update_entities_container;
215+
std::vector<ecsact_component> update_components_container;
216+
217+
std::vector<ecsact_entity_id> remove_entities_container;
218+
std::vector<ecsact_component_id> remove_component_ids_container;
219+
220+
std::vector<builder_entity> create_entities;
221+
std::vector<ecsact_entity_id> destroy_entities;
222+
223+
std::vector<int> entities_component_lengths;
224+
std::vector<ecsact_component*> entities_components;
225+
226+
ecsact_execution_options options;
227+
};
228+
94229
} // namespace ecsact::core

tests/async/async_ref_test.cc

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "async_test.ecsact.systems.hh"
1010
#include "ecsact/runtime/async.h"
1111
#include "ecsact/runtime/dynamic.h"
12+
#include "ecsact/runtime/core.hh"
1213

1314
using namespace std::chrono_literals;
1415
using std::chrono::duration_cast;
@@ -159,10 +160,19 @@ TEST(AsyncRef, AddUpdateAndRemove) {
159160
cb_info.entity = entity_id;
160161
};
161162

163+
// Declare core execution options
164+
auto options = ecsact::core::execution_options{};
165+
162166
ecsact_async_events_collector entity_async_evc{};
163167
entity_async_evc.async_entity_callback = entity_cb;
164168
entity_async_evc.async_entity_callback_user_data = &cb_info;
165169

170+
auto my_needed_component = async_test::NeededComponent{};
171+
172+
options.create_entity().add_component(&my_needed_component);
173+
174+
ecsact_async_enqueue_execution_options(options.c());
175+
166176
auto start_tick = ecsact_async_get_current_tick();
167177
while(cb_info.wait != true) {
168178
ecsact_async_flush_events(nullptr, &entity_async_evc);
@@ -171,40 +181,18 @@ TEST(AsyncRef, AddUpdateAndRemove) {
171181
ASSERT_LT(tick_diff, 10);
172182
}
173183

184+
options.clear();
185+
174186
// Preparing add component data
175-
auto my_needed_component = async_test::NeededComponent{};
187+
// auto my_needed_component = async_test::NeededComponent{};
176188
auto my_update_component = async_test::ComponentUpdate{.value_to_update = 1};
177189

178-
std::array add_components{
179-
ecsact_component{
180-
.component_id = async_test::NeededComponent::id,
181-
.component_data = &my_needed_component,
182-
},
183-
ecsact_component{
184-
.component_id = async_test::ComponentUpdate::id,
185-
.component_data = &my_update_component,
186-
},
187-
};
188-
auto add_components_entities = std::array{cb_info.entity, cb_info.entity};
189-
190-
ASSERT_EQ(add_components_entities.size(), add_components.size());
190+
// options.add_component(cb_info.entity, &my_needed_component);
191+
options.add_component(cb_info.entity, &my_update_component);
191192

192193
// Adding components
193-
auto add_options = ecsact_execution_options{};
194-
add_options.add_components_length = add_components.size();
195-
add_options.add_components_entities = add_components_entities.data();
196-
add_options.add_components = add_components.data();
197-
ecsact_async_enqueue_execution_options(add_options);
198-
199-
// Prepare update component data
200-
my_update_component.value_to_update += 5;
201-
auto update_components = std::array{
202-
ecsact_component{
203-
.component_id = async_test::ComponentUpdate::id,
204-
.component_data = &my_update_component,
205-
},
206-
};
207-
auto component_update_entities = std::array{cb_info.entity};
194+
ecsact_async_enqueue_execution_options(options.c());
195+
options.clear();
208196

209197
// Prepare the events collector for the flush to make sure we got all the
210198
// events we expected.
@@ -259,12 +247,16 @@ TEST(AsyncRef, AddUpdateAndRemove) {
259247
ASSERT_EQ(comp->value_to_update, 6);
260248
};
261249

250+
// Prepare update component data
251+
my_update_component.value_to_update += 5;
252+
262253
// Update components
263-
ecsact_execution_options update_options{};
264-
update_options.update_components_length = update_components.size();
265-
update_options.update_components_entities = component_update_entities.data();
266-
update_options.update_components = update_components.data();
267-
ecsact_async_enqueue_execution_options(update_options);
254+
options.update_component<async_test::ComponentUpdate>(
255+
cb_info.entity,
256+
&my_update_component
257+
);
258+
ecsact_async_enqueue_execution_options(options.c());
259+
options.clear();
268260

269261
start_tick = ecsact_async_get_current_tick();
270262
while(!cb_info.update_happened) {
@@ -277,16 +269,11 @@ TEST(AsyncRef, AddUpdateAndRemove) {
277269
evc.update_callback = {};
278270
evc.update_callback_user_data = nullptr;
279271

280-
// Prepare remove component data
281-
auto remove_components = std::array{async_test::ComponentUpdate::id};
282-
auto components_remove_entities = std::array{cb_info.entity};
283-
284272
// Remove component
285-
auto remove_options = ecsact_execution_options{};
286-
remove_options.remove_components_length = remove_components.size();
287-
remove_options.remove_components_entities = components_remove_entities.data();
288-
remove_options.remove_components = remove_components.data();
289-
ecsact_async_enqueue_execution_options(remove_options);
273+
options.remove_component<async_test::ComponentUpdate>(cb_info.entity);
274+
275+
ecsact_async_enqueue_execution_options(options.c());
276+
options.clear();
290277

291278
evc.remove_callback_user_data = &cb_info;
292279
evc.remove_callback = //

0 commit comments

Comments
 (0)