Skip to content

Added execution_options wrapper #136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions ecsact/runtime/core.hh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once

#include <type_traits>
#include <vector>
#include <functional>
#include "ecsact/runtime/core.h"

namespace ecsact::core {
Expand Down Expand Up @@ -91,4 +93,137 @@ public:
}
};

class builder_entity {
public:
template<typename C>
inline builder_entity& add_component(C* component) {
components.push_back(ecsact_component{
.component_id = C::id,
.component_data = component,
});
return *this;
}

friend class execution_options;

private:
std::vector<ecsact_component> components;
};

class execution_options {
public:
/**
* The lifetime of @p `component` must be maintained until the
* `ecsact::core::execution_options` destructor occurs or `clear()` occurs.
*/
template<typename C>
void add_component(ecsact_entity_id entity, C* component) {
add_components_container.push_back(
ecsact_component{.component_id = C::id, .component_data = component}
);
add_entities_container.push_back(entity);
}

/**
* The lifetime of @p `component` must be maintained until the
* `ecsact::core::execution_options` destructor occurs or `clear()` occurs.
*/
template<typename C>
void update_component(ecsact_entity_id entity, C* component) {
update_components_container.push_back(
ecsact_component{.component_id = C::id, .component_data = component}
);
update_entities_container.push_back(entity);
}

template<typename C>
inline void remove_component(ecsact_entity_id entity_id) {
remove_component_ids_container.push_back(C::id);
remove_entities_container.push_back(entity_id);
}

inline void remove_component(
ecsact_entity_id entity_id,
ecsact_component_id component_id
) {
remove_component_ids_container.push_back(component_id);
remove_entities_container.push_back(entity_id);
}

inline builder_entity& create_entity() {
auto& builder = create_entities.emplace_back(builder_entity{});
return builder;
}

inline void destroy_entity(const ecsact_entity_id& entity_id) {
destroy_entities.push_back(entity_id);
}

inline void clear() {
options = {};

add_entities_container.clear();
add_components_container.clear();

update_entities_container.clear();
update_components_container.clear();

remove_entities_container.clear();
remove_component_ids_container.clear();

entities_components.clear();
entities_component_lengths.clear();

create_entities.clear();
destroy_entities.clear();
}

inline ecsact_execution_options c() {
options.add_components_length = add_components_container.size();
options.add_components_entities = add_entities_container.data();
options.add_components = add_components_container.data();

options.update_components_length = update_components_container.size();
options.update_components_entities = update_entities_container.data();
options.update_components = update_components_container.data();

options.remove_components_length = remove_component_ids_container.size();
options.remove_components_entities = remove_entities_container.data();
options.remove_components = remove_component_ids_container.data();

for(auto& built_entity : create_entities) {
entities_component_lengths.push_back(built_entity.components.size());
entities_components.push_back(built_entity.components.data());
}

options.create_entities_components = entities_components.data();
options.create_entities_length = create_entities.size();
options.create_entities_components_length =
entities_component_lengths.data();

options.destroy_entities = destroy_entities.data();
options.destroy_entities_length = destroy_entities.size();

return options;
}

private:
std::vector<ecsact_entity_id> add_entities_container;
std::vector<ecsact_component> add_components_container;

std::vector<ecsact_entity_id> update_entities_container;
std::vector<ecsact_component> update_components_container;

std::vector<ecsact_entity_id> remove_entities_container;
std::vector<ecsact_component_id> remove_component_ids_container;

std::vector<builder_entity> create_entities;
std::vector<ecsact_entity_id> destroy_entities;

std::vector<int> entities_component_lengths;
std::vector<ecsact_component*> entities_components;

ecsact_execution_options options;
};

} // namespace ecsact::core
73 changes: 30 additions & 43 deletions tests/async/async_ref_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "async_test.ecsact.systems.hh"
#include "ecsact/runtime/async.h"
#include "ecsact/runtime/dynamic.h"
#include "ecsact/runtime/core.hh"

using namespace std::chrono_literals;
using std::chrono::duration_cast;
Expand Down Expand Up @@ -159,10 +160,19 @@ TEST(AsyncRef, AddUpdateAndRemove) {
cb_info.entity = entity_id;
};

// Declare core execution options
auto options = ecsact::core::execution_options{};

ecsact_async_events_collector entity_async_evc{};
entity_async_evc.async_entity_callback = entity_cb;
entity_async_evc.async_entity_callback_user_data = &cb_info;

auto my_needed_component = async_test::NeededComponent{};

options.create_entity().add_component(&my_needed_component);

ecsact_async_enqueue_execution_options(options.c());

auto start_tick = ecsact_async_get_current_tick();
while(cb_info.wait != true) {
ecsact_async_flush_events(nullptr, &entity_async_evc);
Expand All @@ -171,40 +181,18 @@ TEST(AsyncRef, AddUpdateAndRemove) {
ASSERT_LT(tick_diff, 10);
}

options.clear();

// Preparing add component data
auto my_needed_component = async_test::NeededComponent{};
// auto my_needed_component = async_test::NeededComponent{};
auto my_update_component = async_test::ComponentUpdate{.value_to_update = 1};

std::array add_components{
ecsact_component{
.component_id = async_test::NeededComponent::id,
.component_data = &my_needed_component,
},
ecsact_component{
.component_id = async_test::ComponentUpdate::id,
.component_data = &my_update_component,
},
};
auto add_components_entities = std::array{cb_info.entity, cb_info.entity};

ASSERT_EQ(add_components_entities.size(), add_components.size());
// options.add_component(cb_info.entity, &my_needed_component);
options.add_component(cb_info.entity, &my_update_component);

// Adding components
auto add_options = ecsact_execution_options{};
add_options.add_components_length = add_components.size();
add_options.add_components_entities = add_components_entities.data();
add_options.add_components = add_components.data();
ecsact_async_enqueue_execution_options(add_options);

// Prepare update component data
my_update_component.value_to_update += 5;
auto update_components = std::array{
ecsact_component{
.component_id = async_test::ComponentUpdate::id,
.component_data = &my_update_component,
},
};
auto component_update_entities = std::array{cb_info.entity};
ecsact_async_enqueue_execution_options(options.c());
options.clear();

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

// Prepare update component data
my_update_component.value_to_update += 5;

// Update components
ecsact_execution_options update_options{};
update_options.update_components_length = update_components.size();
update_options.update_components_entities = component_update_entities.data();
update_options.update_components = update_components.data();
ecsact_async_enqueue_execution_options(update_options);
options.update_component<async_test::ComponentUpdate>(
cb_info.entity,
&my_update_component
);
ecsact_async_enqueue_execution_options(options.c());
options.clear();

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

// Prepare remove component data
auto remove_components = std::array{async_test::ComponentUpdate::id};
auto components_remove_entities = std::array{cb_info.entity};

// Remove component
auto remove_options = ecsact_execution_options{};
remove_options.remove_components_length = remove_components.size();
remove_options.remove_components_entities = components_remove_entities.data();
remove_options.remove_components = remove_components.data();
ecsact_async_enqueue_execution_options(remove_options);
options.remove_component<async_test::ComponentUpdate>(cb_info.entity);

ecsact_async_enqueue_execution_options(options.c());
options.clear();

evc.remove_callback_user_data = &cb_info;
evc.remove_callback = //
Expand Down