Skip to content

decoupling request IDs for pre-connect api calls #131

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 8 commits into from
Jan 28, 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
1 change: 1 addition & 0 deletions reference/async_reference/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ cc_library(
deps = [
"//:async",
"//:core",
"//reference/async_reference/request_id_factory",
"//reference/async_reference/callbacks:async_callbacks",
"//reference/async_reference/callbacks:execution_callbacks",
"//reference/async_reference/detail/c_execution_options",
Expand Down
63 changes: 49 additions & 14 deletions reference/async_reference/async.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,75 @@

#include "ecsact/runtime/async.h"
#include "async_reference.hh"
#include "callbacks/async_callbacks.hh"
#include "request_id_factory/request_id_factory.hh"

namespace async {
std::optional<async_reference> reference;
}
using namespace ecsact::async_reference;

// NOTE: These are the singletons for managing the reference library state.
// This file should be small. Declare a few variables and call a few
// functions in the C function bodies. Keep the logic minimal.
static auto async_callbacks = detail::async_callbacks{};
static auto request_id_factory = detail::request_id_factory{};
static auto reference = std::optional<detail::async_reference>{};

ecsact_async_request_id ecsact_async_connect(const char* connection_string) {
async::reference.emplace();
return async::reference->connect(connection_string);
auto req_id = request_id_factory.next_id();
reference.emplace(async_callbacks);
reference->connect(req_id, connection_string);
return req_id;
}

void ecsact_async_disconnect() {
if(async::reference) {
async::reference->disconnect();
async::reference.reset();
if(reference) {
reference->disconnect();
reference.reset();
}
}

void ecsact_async_flush_events(
const ecsact_execution_events_collector* execution_events,
const ecsact_async_events_collector* async_events
const ecsact_execution_events_collector* execution_evc,
const ecsact_async_events_collector* async_evc
) {
async::reference->flush_events(execution_events, async_events);
async_callbacks.invoke(async_evc);
if(reference) {
reference->invoke_execution_events(execution_evc);
}
}

ecsact_async_request_id ecsact_async_create_entity() {
return async::reference->create_entity_request();
auto req_id = request_id_factory.next_id();
if(!reference) {
async_callbacks.add(detail::types::async_error{
.error = ECSACT_ASYNC_ERR_PERMISSION_DENIED,
.request_ids = {req_id},
});
return req_id;
}

reference->create_entity_request(req_id);
return req_id;
}

ecsact_async_request_id ecsact_async_enqueue_execution_options(
const ecsact_execution_options options
) {
return async::reference->enqueue_execution_options(options);
auto req_id = request_id_factory.next_id();
if(!reference) {
async_callbacks.add(detail::types::async_error{
.error = ECSACT_ASYNC_ERR_PERMISSION_DENIED,
.request_ids = {req_id},
});
return req_id;
}

reference->enqueue_execution_options(req_id, options);
return req_id;
}

int32_t ecsact_async_get_current_tick() {
return async::reference->get_current_tick();
if(reference) {
return reference->get_current_tick();
}
return 0;
}
43 changes: 16 additions & 27 deletions reference/async_reference/async_reference.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include "async_reference.hh"

using namespace ecsact::async_reference::detail;

struct parsed_connection_string {
std::string host;
std::map<std::string, std::string> options;
Expand Down Expand Up @@ -54,10 +56,10 @@ static auto parse_connection_string(std::string_view str)
return result;
}

ecsact_async_request_id async_reference::connect(const char* connection_string
void async_reference::connect(
ecsact_async_request_id req_id,
const char* connection_string
) {
auto req_id = next_request_id();

std::string connect_str(connection_string);

auto result = parse_connection_string(connect_str);
Expand All @@ -74,7 +76,7 @@ ecsact_async_request_id async_reference::connect(const char* connection_string
if(result.host != "good") {
is_connected = false;
is_connected_notified = false;
return req_id;
return;
}

if(tick_rate.count() == 0) {
Expand All @@ -84,21 +86,18 @@ ecsact_async_request_id async_reference::connect(const char* connection_string
};

async_callbacks.add(async_err);
return req_id;
return;
}

registry_id = ecsact_create_registry("async_reference_impl_reg");
is_connected = true;
execute_systems();

return req_id;
}

ecsact_async_request_id async_reference::enqueue_execution_options(
void async_reference::enqueue_execution_options(
ecsact_async_request_id req_id,
const ecsact_execution_options& options
) {
auto req_id = next_request_id();

if(is_connected == false && is_connected_notified == false) {
types::async_error async_err{
.error = ECSACT_ASYNC_ERR_PERMISSION_DENIED,
Expand All @@ -107,7 +106,7 @@ ecsact_async_request_id async_reference::enqueue_execution_options(

is_connected_notified = true;
async_callbacks.add(async_err);
return req_id;
return;
}

auto cpp_options = util::c_to_cpp_execution_options(options);
Expand All @@ -118,7 +117,7 @@ ecsact_async_request_id async_reference::enqueue_execution_options(
};

tick_manager.add_pending_options(pending_options);
return req_id;
return;
}

void async_reference::execute_systems() {
Expand Down Expand Up @@ -189,18 +188,15 @@ void async_reference::execute_systems() {
});
}

void async_reference::flush_events(
const ecsact_execution_events_collector* execution_events,
const ecsact_async_events_collector* async_events
void async_reference::invoke_execution_events(
const ecsact_execution_events_collector* execution_evc
) {
async_callbacks.invoke(async_events);
if(registry_id) {
exec_callbacks.invoke(execution_events, *registry_id);
exec_callbacks.invoke(execution_evc, *registry_id);
}
}

ecsact_async_request_id async_reference::create_entity_request() {
auto req_id = next_request_id();
void async_reference::create_entity_request(ecsact_async_request_id req_id) {
if(is_connected == false && is_connected_notified == false) {
types::async_error async_err{
.error = ECSACT_ASYNC_ERR_PERMISSION_DENIED,
Expand All @@ -210,11 +206,10 @@ ecsact_async_request_id async_reference::create_entity_request() {
async_callbacks.add(async_err);
is_connected_notified = true;

return req_id;
return;
}

entity_manager.request_entity(req_id);
return req_id;
}

int32_t async_reference::get_current_tick() {
Expand All @@ -227,9 +222,3 @@ void async_reference::disconnect() {
execution_thread.join();
}
}

ecsact_async_request_id async_reference::next_request_id() {
return static_cast<ecsact_async_request_id>(
_last_request_id.fetch_add(1, std::memory_order_relaxed)
);
}
33 changes: 20 additions & 13 deletions reference/async_reference/async_reference.hh
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,33 @@
#include "reference/async_reference/callbacks/execution_callbacks.hh"
#include "reference/async_reference/callbacks/async_callbacks.hh"
#include "reference/async_reference/entity_manager/entity_manager.hh"
#include "request_id_factory/request_id_factory.hh"

namespace ecsact::async_reference::detail {
class async_reference {
public:
ecsact_async_request_id enqueue_execution_options(
inline async_reference(async_callbacks& async_callbacks)
: async_callbacks(async_callbacks) {
}

inline ~async_reference() {
}

void enqueue_execution_options(
ecsact_async_request_id req_id,
const ecsact_execution_options& options
);

void execute_systems();

void flush_events(
const ecsact_execution_events_collector* execution_events,
const ecsact_async_events_collector* async_events
void invoke_execution_events(
const ecsact_execution_events_collector* execution_evc
);

ecsact_async_request_id create_entity_request();

int32_t get_current_tick();

ecsact_async_request_id connect(const char* connection_string);
void create_entity_request(ecsact_async_request_id req_id);
void connect(ecsact_async_request_id req_id, const char* connection_string);

void disconnect();

Expand All @@ -46,10 +54,10 @@ private:

std::optional<ecsact_registry_id> registry_id;

tick_manager tick_manager;
execution_callbacks exec_callbacks;
async_callbacks async_callbacks;
entity_manager entity_manager;
tick_manager tick_manager;
execution_callbacks exec_callbacks;
entity_manager entity_manager;
detail::async_callbacks& async_callbacks;

std::thread execution_thread;
std::mutex execution_m;
Expand All @@ -58,6 +66,5 @@ private:
std::atomic_bool is_connected_notified = false;

std::chrono::milliseconds tick_rate = {};

ecsact_async_request_id next_request_id();
};
}; // namespace ecsact::async_reference::detail
2 changes: 2 additions & 0 deletions reference/async_reference/callbacks/async_callbacks.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "async_callbacks.hh"

using namespace ecsact::async_reference::detail;

void async_callbacks::add(const types::async_requests type) {
std::unique_lock lk(async_m);
requests.push_back(type);
Expand Down
4 changes: 4 additions & 0 deletions reference/async_reference/callbacks/async_callbacks.hh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "reference/async_reference/util/types.hh"
#include "reference/async_reference/util/util.hh"

namespace ecsact::async_reference::detail {

class async_callbacks {
public:
void invoke(const ecsact_async_events_collector* async_events);
Expand All @@ -18,3 +20,5 @@ private:

std::mutex async_m;
};

} // namespace ecsact::async_reference::detail
6 changes: 4 additions & 2 deletions reference/async_reference/callbacks/execution_callbacks.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "execution_callbacks.hh"

using namespace ecsact::async_reference::detail;

execution_callbacks::execution_callbacks() {
collector.init_callback = &execution_callbacks::init_callback;
collector.update_callback = &execution_callbacks::update_callback;
Expand Down Expand Up @@ -158,7 +160,7 @@ void execution_callbacks::init_callback(
}
}

auto info = types::callback_info{};
auto info = detail::types::callback_info{};

info.event = event;
info.entity_id = entity_id;
Expand All @@ -175,7 +177,7 @@ void execution_callbacks::update_callback(
) {
auto self = static_cast<execution_callbacks*>(callback_user_data);

auto info = types::callback_info{};
auto info = detail::types::callback_info{};

info.event = event;
info.entity_id = entity_id;
Expand Down
2 changes: 2 additions & 0 deletions reference/async_reference/callbacks/execution_callbacks.hh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "ecsact/runtime/serialize.hh"
#include "reference/async_reference/util/types.hh"

namespace ecsact::async_reference::detail {
class execution_callbacks {
public:
execution_callbacks();
Expand Down Expand Up @@ -59,3 +60,4 @@ private:
void* callback_user_data
);
};
} // namespace ecsact::async_reference::detail
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "c_execution_options.hh"

ecsact_execution_options detail::c_execution_options::c() {
using namespace ecsact::async_reference::detail;

ecsact_execution_options c_execution_options::c() {
for(auto& action_info : actions_info) {
ecsact_action action;
action.action_data = action_info.data.data();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "ecsact/runtime/core.h"
#include "ecsact/runtime/async.h"

namespace detail {
namespace ecsact::async_reference::detail {

template<typename T>
struct data_info {
Expand Down Expand Up @@ -37,4 +37,5 @@ private:
std::vector<ecsact_component> adds;
std::vector<ecsact_component> updates;
};
} // namespace detail

} // namespace ecsact::async_reference::detail
2 changes: 2 additions & 0 deletions reference/async_reference/entity_manager/entity_manager.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "entity_manager.hh"

using namespace ecsact::async_reference::detail;

void entity_manager::process_entities(
async_callbacks& callbacks,
const ecsact_registry_id& registry_id
Expand Down
2 changes: 2 additions & 0 deletions reference/async_reference/entity_manager/entity_manager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "reference/async_reference/callbacks/async_callbacks.hh"
#include "reference/async_reference/util/types.hh"

namespace ecsact::async_reference::detail {
class entity_manager {
public:
void process_entities(
Expand All @@ -21,3 +22,4 @@ private:

std::vector<ecsact_async_request_id> pending_entity_requests;
};
} // namespace ecsact::async_reference::detail
Loading