Skip to content

Commit 19e3c71

Browse files
authored
feat: implement new async session api (#36)
* also added a blank core reference for future use
1 parent aa9572e commit 19e3c71

22 files changed

+984
-377
lines changed

.bazelversion

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7.3.0
1+
7.5.0

MODULE.bazel

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,29 @@ module(
44
compatibility_level = 1,
55
)
66

7-
bazel_dep(name = "rules_cc", version = "0.0.9")
8-
bazel_dep(name = "ecsact_runtime", version = "0.7.0")
9-
bazel_dep(name = "ecsact_codegen", version = "0.4.3")
10-
bazel_dep(name = "ecsact_lang_cpp", version = "0.4.10")
11-
bazel_dep(name = "rules_ecsact", version = "0.5.8")
12-
bazel_dep(name = "ecsact_cli", version = "0.3.19")
7+
bazel_dep(name = "rules_cc", version = "0.0.17")
8+
bazel_dep(name = "ecsact_runtime", version = "0.8.1")
9+
10+
# NOTE: I don't know why this is necessary. The compatibility error is very unclear.
11+
# Possibly due to this? https://github.com/bazelbuild/bazel/issues/22972
12+
single_version_override(
13+
module_name = "ecsact_runtime",
14+
version = "0.8.1",
15+
)
16+
17+
bazel_dep(name = "ecsact_codegen", version = "0.4.4")
18+
bazel_dep(name = "ecsact_lang_cpp", version = "0.4.11")
19+
bazel_dep(name = "rules_ecsact", version = "0.5.9")
20+
bazel_dep(name = "ecsact_cli", version = "0.3.23")
1321
bazel_dep(name = "bazel_skylib", version = "1.4.2")
1422
bazel_dep(name = "boost.process", version = "1.83.0.bzl.2")
1523
bazel_dep(name = "boost.dll", version = "1.83.0.bzl.2")
1624

1725
bazel_dep(name = "toolchains_llvm", version = "1.0.0", dev_dependency = True)
1826
bazel_dep(name = "hedron_compile_commands", dev_dependency = True)
27+
28+
bazel_dep(name = "docopt.cpp", version = "0.6.2")
29+
1930
git_override(
2031
module_name = "hedron_compile_commands",
2132
commit = "204aa593e002cbd177d30f11f54cff3559110bb9",

async_reference/BUILD.bazel

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,18 @@ ecsact_build_recipe(
1212
"ecsact_deserialize_action",
1313
"ecsact_deserialize_component",
1414
"ecsact_execute_systems",
15-
"ecsact_get_component",
1615
"ecsact_serialize_action",
1716
"ecsact_serialize_action_size",
1817
"ecsact_serialize_component",
1918
"ecsact_serialize_component_size",
2019
"ecsact_stream",
2120
],
2221
exports = [
23-
"ecsact_async_connect",
24-
"ecsact_async_disconnect",
2522
"ecsact_async_enqueue_execution_options",
2623
"ecsact_async_flush_events",
2724
"ecsact_async_get_current_tick",
25+
"ecsact_async_start",
26+
"ecsact_async_stop",
2827
"ecsact_async_stream",
2928
],
3029
)

async_reference/async.cc

Lines changed: 74 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <optional>
22
#include <stdarg.h>
33
#include <span>
4+
#include <map>
45
#include "ecsact/runtime/async.h"
56
#include "async_reference/async_reference.hh"
67
#include "async_reference/callbacks/async_callbacks.hh"
@@ -11,87 +12,121 @@ using namespace ecsact::async_reference;
1112
// NOTE: These are the singletons for managing the reference library state.
1213
// This file should be small. Declare a few variables and call a few
1314
// functions in the C function bodies. Keep the logic minimal.
14-
static auto async_callbacks = detail::async_callbacks{};
15+
static auto async_callbacks =
16+
std::map<ecsact_async_session_id, detail::async_callbacks>{};
1517
static auto request_id_factory = detail::request_id_factory{};
18+
static auto last_session_id = ecsact_async_session_id{};
1619
static auto reference = std::optional<detail::async_reference>{};
1720

18-
ecsact_async_request_id ecsact_async_connect(const char* connection_string) {
19-
auto req_id = request_id_factory.next_id();
20-
reference.emplace(async_callbacks);
21-
reference->connect(req_id, connection_string);
22-
return req_id;
21+
static auto generate_next_session_id() -> ecsact_async_session_id {
22+
return static_cast<ecsact_async_session_id>(
23+
++reinterpret_cast<int32_t&>(last_session_id)
24+
);
2325
}
2426

25-
void ecsact_async_disconnect() {
26-
if(reference) {
27-
reference->disconnect();
28-
reference.reset();
27+
auto ecsact_async_start( //
28+
const void* option_data,
29+
int32_t option_data_size
30+
) -> ecsact_async_session_id {
31+
if(!reference) {
32+
reference.emplace(async_callbacks);
2933
}
34+
35+
auto session_id = generate_next_session_id();
36+
auto connect_str = std::string_view{};
37+
if(option_data && option_data_size > 0) {
38+
connect_str = std::string_view{
39+
static_cast<const char*>(option_data),
40+
static_cast<size_t>(option_data_size)
41+
};
42+
}
43+
44+
reference->start(session_id, connect_str);
45+
46+
return session_id;
3047
}
3148

32-
void ecsact_async_flush_events(
49+
auto ecsact_async_stop(ecsact_async_session_id session_id) -> void {
50+
if(!reference) {
51+
return;
52+
}
53+
54+
reference->stop(session_id);
55+
56+
if(reference->session_count() == 0) {
57+
reference = std::nullopt;
58+
}
59+
}
60+
61+
auto ecsact_async_flush_events(
62+
ecsact_async_session_id session_id,
3363
const ecsact_execution_events_collector* execution_evc,
3464
const ecsact_async_events_collector* async_evc
35-
) {
36-
async_callbacks.invoke(async_evc);
37-
if(reference) {
38-
reference->invoke_execution_events(execution_evc);
65+
) -> void {
66+
if(!reference) {
67+
async_callbacks[session_id].invoke(session_id, async_evc);
68+
return;
3969
}
70+
71+
reference->flush_events(session_id, execution_evc, async_evc);
72+
async_callbacks[session_id].invoke(session_id, async_evc);
4073
}
4174

42-
ecsact_async_request_id ecsact_async_enqueue_execution_options(
75+
auto ecsact_async_enqueue_execution_options(
76+
ecsact_async_session_id session_id,
4377
const ecsact_execution_options options
44-
) {
78+
) -> ecsact_async_request_id {
4579
auto req_id = request_id_factory.next_id();
4680
if(!reference) {
47-
async_callbacks.add(detail::types::async_error{
81+
async_callbacks[session_id].add(detail::types::async_error{
4882
.error = ECSACT_ASYNC_ERR_NOT_CONNECTED,
4983
.request_ids = {req_id},
5084
});
5185
return req_id;
5286
}
5387

54-
reference->enqueue_execution_options(req_id, options);
88+
reference->enqueue_execution_options(session_id, req_id, options);
89+
5590
return req_id;
5691
}
5792

58-
int32_t ecsact_async_get_current_tick() {
59-
if(reference) {
60-
return reference->get_current_tick();
93+
auto ecsact_async_get_current_tick( //
94+
ecsact_async_session_id session_id
95+
) -> int32_t {
96+
if(!reference) {
97+
return 0;
6198
}
62-
return 0;
99+
return reference->get_current_tick(session_id);
63100
}
64101

65-
ecsact_async_request_id ecsact_async_stream(
66-
ecsact_entity_id entity,
67-
ecsact_component_id component_id,
68-
const void* component_data,
69-
const void* indexed_fields
70-
) {
71-
auto req_id = request_id_factory.next_id();
72-
// TODO: indexed fields
102+
auto ecsact_async_stream(
103+
ecsact_async_session_id session_id,
104+
ecsact_entity_id entity,
105+
ecsact_component_id component_id,
106+
const void* component_data,
107+
const void* indexed_fields
108+
) -> void {
73109
if(indexed_fields != nullptr) {
74-
async_callbacks.add(detail::types::async_error{
110+
async_callbacks[session_id].add(detail::types::async_error{
75111
.error = ECSACT_ASYNC_ERR_INTERNAL,
76-
.request_ids = {req_id},
112+
.request_ids = {ECSACT_INVALID_ID(async_request)},
77113
});
78-
return req_id;
114+
return;
79115
}
80116

81117
if(!reference) {
82-
async_callbacks.add(detail::types::async_error{
118+
async_callbacks[session_id].add(detail::types::async_error{
83119
.error = ECSACT_ASYNC_ERR_NOT_CONNECTED,
84-
.request_ids = {req_id},
120+
.request_ids = {ECSACT_INVALID_ID(async_request)},
85121
});
86-
return req_id;
122+
return;
87123
}
88124

89125
reference->stream( //
90-
req_id,
126+
session_id,
91127
entity,
92128
component_id,
93129
component_data,
94130
indexed_fields
95131
);
96-
return req_id;
97132
}

0 commit comments

Comments
 (0)