Skip to content

Commit 6582788

Browse files
authored
feat: async session api (#273)
1 parent 22010eb commit 6582788

File tree

7 files changed

+116
-36
lines changed

7 files changed

+116
-36
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.4.1

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
- uses: actions/checkout@v4
2323
- uses: greut/eclint-action@v0
2424
- uses: jidicula/[email protected]
25-
with: { clang-format-version: "18" }
25+
with: { clang-format-version: "19" }
2626

2727
test-windows:
2828
if: >-

ecsact/runtime/async.h

Lines changed: 90 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,28 @@ typedef enum {
7676
ECSACT_ASYNC_ERR_CUSTOM_END = 200,
7777
} ecsact_async_error;
7878

79+
typedef enum {
80+
/**
81+
* The session has stopped
82+
*/
83+
ECSACT_ASYNC_SESSION_STOPPED = 0,
84+
85+
/**
86+
* The session is attempting to start but hasn't yet.
87+
*/
88+
ECSACT_ASYNC_SESSION_PENDING = 1,
89+
90+
/**
91+
* The session has started
92+
*/
93+
ECSACT_ASYNC_SESSION_START = 2,
94+
} ecsact_async_session_event;
95+
7996
/**
8097
* When an error occurs due to an async request this callback is invoked.
8198
*
99+
* @param session_id the session that received the error
100+
*
82101
* @param async_err when there is no async error this will be @ref
83102
* ECSACT_ASYNC_OK otherwise @see ecsact_async_error
84103
@@ -89,6 +108,7 @@ typedef enum {
89108
* ecsact_async_events_collector::error_callback_user_data
90109
*/
91110
typedef void (*ecsact_async_error_callback)( //
111+
ecsact_async_session_id session_id,
92112
ecsact_async_error async_err,
93113
int request_ids_length,
94114
ecsact_async_request_id* request_ids,
@@ -98,10 +118,12 @@ typedef void (*ecsact_async_error_callback)( //
98118
/**
99119
* When an occurs from the system execution this callback is invoked.
100120
*
121+
* @param session_id the session that received the error
101122
* @param execute_err when there is no system execution error, this will be
102123
* @ref ECSACT_EXEC_SYS_OK other @see ecsact_execute_systems_error
103124
*/
104125
typedef void (*ecsact_execute_sys_error_callback)( //
126+
ecsact_async_session_id session_id,
105127
ecsact_execute_systems_error execute_err,
106128
void* callback_user_data
107129
);
@@ -110,11 +132,21 @@ typedef void (*ecsact_execute_sys_error_callback)( //
110132
* Handler for when a request is done (error or success)
111133
*/
112134
typedef void (*ecsact_async_request_done_callback)( //
135+
ecsact_async_session_id session_id,
113136
int request_ids_length,
114137
ecsact_async_request_id* request_ids,
115138
void* callback_user_data
116139
);
117140

141+
/**
142+
* Handler async session events
143+
*/
144+
typedef void (*ecsact_async_session_event_callback)( //
145+
ecsact_async_session_id session_id,
146+
ecsact_async_session_event event,
147+
void* callback_user_data
148+
);
149+
118150
typedef struct ecsact_async_events_collector {
119151
/**
120152
* invoked when an async request failed.
@@ -151,6 +183,16 @@ typedef struct ecsact_async_events_collector {
151183
* `callback_user_data` passed to `async_request_done_callback`
152184
*/
153185
void* async_request_done_callback_user_data;
186+
187+
/**
188+
* invoked when a session event has occurred. @see ecsact_async_session_event
189+
*/
190+
ecsact_async_session_event_callback async_session_event_callback;
191+
192+
/**
193+
* `callback_user_data` passed to `async_session_event_callback`
194+
*/
195+
void* async_session_event_callback_user_data;
154196
} ecsact_async_events_collector;
155197

156198
/**
@@ -166,6 +208,7 @@ ECSACT_ASYNC_API_FN(
166208
ecsact_async_enqueue_execution_options
167209
)
168210
( //
211+
ecsact_async_session_id session_id,
169212
const ecsact_execution_options options
170213
);
171214

@@ -176,34 +219,59 @@ ECSACT_ASYNC_API_FN(
176219
*/
177220
ECSACT_ASYNC_API_FN(void, ecsact_async_flush_events)
178221
( //
222+
ecsact_async_session_id session_id,
179223
const ecsact_execution_events_collector* execution_events,
180224
const ecsact_async_events_collector* async_events
181225
);
182226

183227
/**
184-
* @param connection_string - null-terminated string used to connect to the
185-
* underlying async runtime. This may be a hostname/ip address + port or
186-
* some other string deinfed by the implementation. Please review
187-
* documentation for your ecsact async api provider. May be NULL to
188-
* indicate wanting to connect to the 'default' if available.
189-
* @returns a request ID representing this async request. Later used in @ref
190-
* ecsact_async_error_callback if an error occurs
228+
* @param option_data implementation defined options used to start the async
229+
* session. This usually contains information such as the host/ip, port, and
230+
* authentication for a network connection or various settings that affect the
231+
* simulation. It is recommended that all implementations handle `NULL` as the
232+
* 'default' options. You should refer to the implementations documentation for
233+
* what should be passed here.
234+
*
235+
* @param option_data_size length (in bytes) of @p option_data
236+
*
237+
* @returns an ID that represents the session that all other async functions
238+
* take in
239+
*/
240+
ECSACT_ASYNC_API_FN(ecsact_async_session_id, ecsact_async_start)
241+
( //
242+
const void* option_data,
243+
int32_t option_data_size
244+
);
245+
246+
/**
247+
* Begins stopping the session. May happen in background.
248+
* @param session_id the session that should stop
191249
*/
192-
ECSACT_ASYNC_API_FN(ecsact_async_request_id, ecsact_async_connect)
250+
ECSACT_ASYNC_API_FN(void, ecsact_async_stop)
193251
( //
194-
const char* connection_string
252+
ecsact_async_session_id session_id
195253
);
196254

197255
/**
198-
* Starts a disconnect. May happen in background, but is guaranteed to
199-
* disconnect before any new @ref ecsact_async_connect resolves.
256+
* Begins stopping all active sessions. May happen in background.
200257
*/
201-
ECSACT_ASYNC_API_FN(void, ecsact_async_disconnect)(void);
258+
ECSACT_ASYNC_API_FN(void, ecsact_async_stop_all)();
259+
260+
/**
261+
* Stops all active sessions immediately making all session IDs invalid.
262+
*
263+
* NOTE: `ecsact_async_stop_all` is a more graceful option and should be
264+
* preferred.
265+
*/
266+
ECSACT_ASYNC_API_FN(void, ecsact_async_force_reset)();
202267

203268
/**
204269
* Gets the current tick
205270
*/
206-
ECSACT_ASYNC_API_FN(int32_t, ecsact_async_get_current_tick)(void);
271+
ECSACT_ASYNC_API_FN(int32_t, ecsact_async_get_current_tick)
272+
( //
273+
ecsact_async_session_id session_id
274+
);
207275

208276
/**
209277
* Sends Ecsact stream data to the specified registry. Stream data will be
@@ -215,10 +283,11 @@ ECSACT_ASYNC_API_FN(int32_t, ecsact_async_get_current_tick)(void);
215283
*/
216284
ECSACT_ASYNC_API_FN(void, ecsact_async_stream)
217285
( //
218-
ecsact_entity_id entity,
219-
ecsact_component_id component_id,
220-
const void* component_data,
221-
const void* indexed_field_values
286+
ecsact_async_session_id session_id,
287+
ecsact_entity_id entity,
288+
ecsact_component_id component_id,
289+
const void* component_data,
290+
const void* indexed_field_values
222291
);
223292

224293
#ifdef ECSACT_MSVC_TRADITIONAL
@@ -227,8 +296,10 @@ ECSACT_ASYNC_API_FN(void, ecsact_async_stream)
227296
# define FOR_EACH_ECSACT_ASYNC_API_FN(fn, ...) \
228297
fn(ecsact_async_enqueue_execution_options, __VA_ARGS__); \
229298
fn(ecsact_async_flush_events, __VA_ARGS__); \
230-
fn(ecsact_async_connect, __VA_ARGS__); \
231-
fn(ecsact_async_disconnect, __VA_ARGS__); \
299+
fn(ecsact_async_start, __VA_ARGS__); \
300+
fn(ecsact_async_stop, __VA_ARGS__); \
301+
fn(ecsact_async_stop_all, __VA_ARGS__); \
302+
fn(ecsact_async_force_reset, __VA_ARGS__); \
232303
fn(ecsact_async_get_current_tick, __VA_ARGS__); \
233304
fn(ecsact_async_stream, __VA_ARGS__)
234305
#endif

ecsact/runtime/async.hh

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -139,24 +139,32 @@ private:
139139
}
140140
};
141141

142-
[[nodiscard]] ECSACT_ALWAYS_INLINE auto connect(
143-
const std::string& connection_string
144-
) -> ecsact_async_request_id {
145-
return ecsact_async_connect(connection_string.c_str());
142+
[[nodiscard]] ECSACT_ALWAYS_INLINE auto start() -> ecsact_async_session_id {
143+
return ecsact_async_start(0, nullptr);
144+
}
145+
146+
[[nodiscard]] ECSACT_ALWAYS_INLINE auto start( //
147+
int32_t size,
148+
const void* data
149+
) -> ecsact_async_session_id {
150+
return ecsact_async_start(size, data);
146151
}
147152

148-
ECSACT_ALWAYS_INLINE auto disconnect() -> void {
149-
ecsact_async_disconnect();
153+
ECSACT_ALWAYS_INLINE auto stop(ecsact_async_session_id id) -> void {
154+
ecsact_async_stop(id);
150155
}
151156

152-
[[nodiscard]] ECSACT_ALWAYS_INLINE auto get_current_tick() -> int32_t {
153-
return ecsact_async_get_current_tick();
157+
[[nodiscard]] ECSACT_ALWAYS_INLINE auto get_current_tick(
158+
ecsact_async_session_id id
159+
) -> int32_t {
160+
return ecsact_async_get_current_tick(id);
154161
}
155162

156163
[[nodiscard]] ECSACT_ALWAYS_INLINE auto enqueue_execution_options(
164+
ecsact_async_session_id id,
157165
ecsact::core::execution_options& options
158166
) -> ecsact_async_request_id {
159-
return ecsact_async_enqueue_execution_options(options.c());
167+
return ecsact_async_enqueue_execution_options(id, options.c());
160168
}
161169

162170
ECSACT_ALWAYS_INLINE auto flush_events() -> void {
@@ -165,8 +173,8 @@ ECSACT_ALWAYS_INLINE auto flush_events() -> void {
165173

166174
template<typename ExecutionEventsCollector>
167175
requires(std::convertible_to<
168-
decltype(std::declval<ExecutionEventsCollector>().c()),
169-
const ecsact_execution_events_collector>)
176+
decltype(std::declval<ExecutionEventsCollector>().c()),
177+
const ecsact_execution_events_collector>)
170178
ECSACT_ALWAYS_INLINE auto flush_events( //
171179
ExecutionEventsCollector&& evc
172180
) -> void {
@@ -176,8 +184,8 @@ ECSACT_ALWAYS_INLINE auto flush_events( //
176184

177185
template<typename AsyncEventsCollector>
178186
requires(std::convertible_to<
179-
decltype(std::declval<AsyncEventsCollector>().c()),
180-
const ecsact_async_events_collector>)
187+
decltype(std::declval<AsyncEventsCollector>().c()),
188+
const ecsact_async_events_collector>)
181189
ECSACT_ALWAYS_INLINE auto flush_events( //
182190
AsyncEventsCollector&& async_evc
183191
) -> void {

ecsact/runtime/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ ECSACT_TYPED_ID(ecsact_registry_id);
6969
ECSACT_TYPED_ID(ecsact_entity_id);
7070
ECSACT_TYPED_ID(ecsact_placeholder_entity_id);
7171
ECSACT_TYPED_ID(ecsact_system_generates_id);
72+
ECSACT_TYPED_ID(ecsact_async_session_id);
7273
ECSACT_TYPED_ID(ecsact_async_request_id);
7374

7475
ECSACT_TYPED_ID(ecsact_decl_id);

ecsact/runtime/serialize.hh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ namespace ecsact {
1616
* @returns serialized action or component bytes
1717
*/
1818
template<typename T>
19-
requires(!std::is_same_v<std::remove_cvref_t<T>, ecsact_component> &&
20-
!std::is_same_v<std::remove_cvref_t<T>, ecsact_action>)
19+
requires(!std::is_same_v<std::remove_cvref_t<T>, ecsact_component> && !std::is_same_v<std::remove_cvref_t<T>, ecsact_action>)
2120
ECSACT_ALWAYS_INLINE auto serialize( //
2221
const T& component_or_action
2322
) -> std::vector<std::byte> {

test/.bazelversion

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
7.4.1

0 commit comments

Comments
 (0)