Skip to content

Commit d4069af

Browse files
Kelwanzaucy
andauthored
Add Async Implementation Reference Module (#82)
Co-authored-by: Zaucy <[email protected]>
1 parent 4eec253 commit d4069af

30 files changed

+2405
-47
lines changed

WORKSPACE.bazel

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ hedron_compile_commands_setup()
6060

6161
http_archive(
6262
name = "com_grail_bazel_toolchain",
63-
sha256 = "7fa5a8624b1148c36e09c7fa29ef6ee8b83f865219c9c219c9125aac78924758",
64-
strip_prefix = "bazel-toolchain-c3131a6894804ee586d059c57ffe8e88d44172e1",
65-
url = "https://github.com/grailbio/bazel-toolchain/archive/c3131a6894804ee586d059c57ffe8e88d44172e1.zip",
63+
sha256 = "3cf5ac4bb7dae3776da586fe85685274f5d89cbb59436f50f572928354e72198",
64+
strip_prefix = "bazel-toolchain-70a0fb556662fe3cadb07da32c91e232eb0d883d",
65+
url = "https://github.com/grailbio/bazel-toolchain/archive/70a0fb556662fe3cadb07da32c91e232eb0d883d.zip",
6666
)
6767

6868
load("@com_grail_bazel_toolchain//toolchain:deps.bzl", "bazel_toolchain_dependencies")
@@ -74,7 +74,8 @@ load("@com_grail_bazel_toolchain//toolchain:rules.bzl", "llvm_toolchain")
7474
llvm_toolchain(
7575
name = "llvm_toolchain",
7676
cxx_standard = {"linux": "c++20"},
77-
llvm_version = "14.0.0",
77+
distribution = "clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz",
78+
llvm_version = "15.0.6",
7879
)
7980

8081
load("@llvm_toolchain//:toolchains.bzl", "llvm_register_toolchains")

bazel/copts.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
copts = select({
22
"@bazel_tools//tools/cpp:msvc": ["/std:c++20", "/Zc:preprocessor", "/permissive-"],
3-
"//conditions:default": ["-std=c++20"],
3+
"//conditions:default": ["-std=c++20", "-fexperimental-library"],
44
})

ecsact/runtime/async.h

Lines changed: 79 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -53,51 +53,107 @@ typedef enum {
5353
*/
5454
ECSACT_ASYNC_ERR_PERMISSION_DENIED,
5555

56+
/**
57+
* Client sent invalid connection options
58+
*/
59+
ECSACT_ASYNC_INVALID_CONNECTION_STRING,
60+
5661
/**
5762
* Connection to the client is closed
5863
*/
5964
ECSACT_ASYNC_ERR_CONNECTION_CLOSED,
6065

6166
/**
62-
* ExecutionOptions failed to merge
67+
* ExecutionOptions failed to merge, and upon failure the connection is closed
6368
*/
6469
ECSACT_ASYNC_ERR_EXECUTION_MERGE_FAILURE,
6570
} ecsact_async_error;
6671

6772
/**
68-
* When an error occurs due to an async request this callback is invoked, only
69-
* either @p async_err or @p execute_err will have a non-ok value.
73+
* When an error occurs due to an async request this callback is invoked.
7074
*
7175
* @param async_err when there is no async error this will be @ref
7276
* ECSACT_ASYNC_OK otherwise @see ecsact_async_error
73-
* @param execute_err when there is no system execution error, this will be @ref
74-
* ECSACT_EXEC_SYS_OK other @see ecsact_execute_systems_error
75-
* @param request_id the request ID returned by an async request function that
77+
78+
* @param request_ids A list of request IDs returned by an async request
79+
function that
7680
* was responsible for this error
7781
* @param callback_user_data the @ref
7882
* ecsact_async_events_collector::error_callback_user_data
7983
*/
8084
typedef void (*ecsact_async_error_callback)(
8185
//
82-
ecsact_async_error async_err,
86+
ecsact_async_error async_err,
87+
int request_ids_length,
88+
ecsact_async_request_id* request_ids,
89+
void* callback_user_data
90+
);
91+
92+
/**
93+
* When an occurs from the system execution this callback is invoked.
94+
*
95+
* @param execute_err when there is no system execution error, this will be
96+
* @ref ECSACT_EXEC_SYS_OK other @see ecsact_execute_systems_error
97+
*/
98+
typedef void (*ecsact_execute_sys_error_callback)(
99+
//
83100
ecsact_execute_systems_error execute_err,
84-
ecsact_async_request_id request_id,
85101
void* callback_user_data
86102
);
87103

104+
/**
105+
* When an entity is sucessfully created this callback is
106+
* invoked.
107+
*
108+
* @param entity_id the entity id of the created entity
109+
* @param request_id the request ID returned by the create entity callback
110+
* @param callback_user_data the @ref
111+
* ecsact_async_events_collector::error_callback_user_data
112+
*/
113+
typedef void (*ecsact_async_create_entity_callback)(
114+
//
115+
ecsact_entity_id entity_id,
116+
ecsact_async_request_id request_id,
117+
void* callback_user_data
118+
);
119+
88120
typedef struct ecsact_async_events_collector {
89121
/**
90122
* invoked when an async request failed.
91123
* @see ecsact_async_error_callback
92124
* @see ecsact_async_error
125+
*/
126+
ecsact_async_error_callback async_error_callback;
127+
128+
/**
129+
* `callback_user_data` passed to `async_error_callback`
130+
*/
131+
void* async_error_callback_user_data;
132+
133+
/**
134+
* Invoked when a create entity request succeeds.
135+
* @see ecsact_async_create_entity_callback
136+
* @see ecsact_entity_id
137+
* @see ecsact_async_error
138+
*/
139+
ecsact_async_create_entity_callback async_entity_callback;
140+
141+
/**
142+
* `callback_user_data` passed to `async_entity_callback`
143+
*/
144+
void* async_entity_callback_user_data;
145+
146+
/**
147+
* invoked when a system execution error occurred.
148+
* @see ecsact_execute_sys_error_callback
93149
* @see ecsact_execute_systems_error
94150
*/
95-
ecsact_async_error_callback error_callback;
151+
ecsact_execute_sys_error_callback system_error_callback;
96152

97153
/**
98154
* `callback_user_data` passed to `error_callback`
99155
*/
100-
void* error_callback_user_data;
156+
void* system_error_callback_user_data;
101157
} ecsact_async_events_collector;
102158

103159
/**
@@ -116,34 +172,10 @@ ECSACT_ASYNC_API_FN(
116172
const ecsact_execution_options options
117173
);
118174

119-
/**
120-
* Enqueues system execution options at the specified ticks. If multiple
121-
* invocations of `ecsact_async_enqueue_execution_options_at` happen for the
122-
* same tick(s) the execution options will be _merged_.
123-
*
124-
* @param list_length the length of @p tick_list and @p options_list
125-
* @param tick_list a sequential list of ticks the execution options in @p
126-
* options_list will be used during system exeuction. Length is determined by @p
127-
* list_length
128-
* @param options_list a sequential list of execution options. Length is
129-
* determined by @p list_length
130-
* @returns a request ID representing this async request. Later used in @ref
131-
* ecsact_async_error_callback if an error occurs
132-
*/
133-
134-
ECSACT_ASYNC_API_FN(
135-
ecsact_async_request_id,
136-
ecsact_async_enqueue_execution_options_at
137-
)
138-
( //
139-
int list_length,
140-
const int* tick_list,
141-
const ecsact_execution_options* options_list
142-
);
143-
144175
/**
145176
* Invokes the various callbacks in `execution_events` and `async_events` that
146-
* have been pending.
177+
* have been pending. If either a system or async error occurs it's treated
178+
* as a call to ecscact_async_disconnect
147179
*/
148180
ECSACT_ASYNC_API_FN(void, ecsact_async_flush_events)
149181
( //
@@ -171,12 +203,17 @@ ECSACT_ASYNC_API_FN(ecsact_async_request_id, ecsact_async_connect)
171203
*/
172204
ECSACT_ASYNC_API_FN(void, ecsact_async_disconnect)(void);
173205

174-
#define FOR_EACH_ECSACT_ASYNC_API_FN(fn, ...) \
175-
fn(ecsact_async_enqueue_execution_options, __VA_ARGS__); \
176-
fn(ecsact_async_enqueue_execution_options_at, __VA_ARGS__); \
177-
fn(ecsact_async_flush_events, __VA_ARGS__); \
178-
fn(ecsact_async_connect, __VA_ARGS__); \
179-
fn(ecsact_async_disconnect, __VA_ARGS__);
206+
/**
207+
* Returns an entity
208+
*/
209+
ECSACT_ASYNC_API_FN(ecsact_async_request_id, ecsact_async_create_entity)(void);
210+
211+
#define FOR_EACH_ECSACT_ASYNC_API_FN(fn, ...) \
212+
fn(ecsact_async_enqueue_execution_options, __VA_ARGS__); \
213+
fn(ecsact_async_flush_events, __VA_ARGS__); \
214+
fn(ecsact_async_connect, __VA_ARGS__); \
215+
fn(ecsact_async_disconnect, __VA_ARGS__); \
216+
fn(ecsact_async_create_entity, __VA_ARGS__);
180217

181218
#undef ECSACT_ASYNC_API
182219
#undef ECSACT_ASYNC_API_FN

ecsact/runtime/serialize.hh

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,38 @@ std::vector<std::byte> serialize(const T& component_or_action) {
4646
return bytes;
4747
}
4848

49+
/**
50+
* Serializes an ecsact_component when the type is unknown.
51+
* @returns serialized action bytes
52+
*/
53+
inline std::vector<std::byte> serialize(const ecsact_component& component) {
54+
std::vector<std::byte> out_component;
55+
out_component.resize(ecsact_serialize_component_size(component.component_id));
56+
57+
ecsact_serialize_component(
58+
component.component_id,
59+
component.component_data,
60+
reinterpret_cast<uint8_t*>(out_component.data())
61+
);
62+
return out_component;
63+
}
64+
65+
/**
66+
* Serializes an ecsact_action when the type is unknown.
67+
* @returns serialized component bytes
68+
*/
69+
inline std::vector<std::byte> serialize(const ecsact_action& action) {
70+
std::vector<std::byte> out_action;
71+
out_action.resize(ecsact_serialize_action_size(action.action_id));
72+
73+
ecsact_serialize_action(
74+
action.action_id,
75+
action.action_data,
76+
reinterpret_cast<uint8_t*>(out_action.data())
77+
);
78+
return out_action;
79+
}
80+
4981
/**
5082
* Calls `ecsact_deserialize_action` or `ecsact_deserialize_component` based on
5183
* the type of @tp T.
@@ -115,4 +147,43 @@ int deserialize(
115147
::ecsact::deserialize<T>(serialized_component_or_action, read_amount);
116148
return read_amount;
117149
}
150+
151+
/**
152+
* Deserializes an ecsact_component when the type is unknown.
153+
* @returns an ecsact_action
154+
*/
155+
inline std::vector<std::byte> deserialize(
156+
const ecsact_action_id& id,
157+
std::vector<std::byte>& serialized_action
158+
) {
159+
std::vector<std::byte> action_data;
160+
action_data.resize(serialized_action.size());
161+
162+
ecsact_deserialize_action(
163+
id,
164+
reinterpret_cast<uint8_t*>(serialized_action.data()),
165+
action_data.data()
166+
);
167+
return action_data;
168+
}
169+
170+
/**
171+
* Deserializes an ecsact_component when the type is unknown.
172+
* @returns an ecsact_component_id
173+
*/
174+
inline std::vector<std::byte> deserialize(
175+
const ecsact_component_id& id,
176+
std::vector<std::byte>& serialized_component
177+
) {
178+
std::vector<std::byte> component_data;
179+
component_data.resize(serialized_component.size());
180+
181+
ecsact_deserialize_component(
182+
id,
183+
reinterpret_cast<uint8_t*>(serialized_component.data()),
184+
component_data.data()
185+
);
186+
return component_data;
187+
}
188+
118189
} // namespace ecsact

reference/async_reference/BUILD.bazel

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
load("@rules_cc//cc:defs.bzl", "cc_library")
2+
load("//bazel:copts.bzl", "copts")
3+
4+
package(default_visibility = ["//visiblity:public"])
5+
6+
exports_files([
7+
"async_reference.hh",
8+
"async_reference.cc",
9+
"async.cc",
10+
])
11+
12+
cc_library(
13+
name = "async_reference",
14+
srcs = ["async_reference.cc"],
15+
hdrs = ["async_reference.hh"],
16+
copts = copts,
17+
visibility = ["//visibility:public"],
18+
deps = [
19+
"//:async",
20+
"//:core",
21+
"//reference/async_reference/callbacks:async_callbacks",
22+
"//reference/async_reference/callbacks:execution_callbacks",
23+
"//reference/async_reference/detail/c_execution_options",
24+
"//reference/async_reference/entity_manager",
25+
"//reference/async_reference/tick_manager",
26+
"//reference/async_reference/util",
27+
"//reference/async_reference/util:types",
28+
],
29+
)
30+
31+
cc_library(
32+
name = "async",
33+
srcs = ["async.cc"],
34+
copts = copts,
35+
defines = ["ECSACT_ASYNC_API_EXPORT="],
36+
visibility = ["//visibility:public"],
37+
deps = [
38+
":async_reference",
39+
"//:async",
40+
],
41+
)

reference/async_reference/async.cc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include <optional>
2+
3+
#include "ecsact/runtime/async.h"
4+
#include "async_reference.hh"
5+
6+
namespace async {
7+
std::optional<async_reference> reference;
8+
}
9+
10+
ecsact_async_request_id ecsact_async_connect(const char* connection_string) {
11+
async::reference.emplace();
12+
return async::reference->connect(connection_string);
13+
}
14+
15+
void ecsact_async_disconnect() {
16+
async::reference->disconnect();
17+
async::reference.reset();
18+
}
19+
20+
void ecsact_async_flush_events(
21+
const ecsact_execution_events_collector* execution_events,
22+
const ecsact_async_events_collector* async_events
23+
) {
24+
async::reference->flush_events(execution_events, async_events);
25+
}
26+
27+
ecsact_async_request_id ecsact_async_create_entity() {
28+
return async::reference->create_entity_request();
29+
}
30+
31+
ecsact_async_request_id ecsact_async_enqueue_execution_options(
32+
const ecsact_execution_options options
33+
) {
34+
return async::reference->enqueue_execution_options(options);
35+
}

0 commit comments

Comments
 (0)