From 7532a2d82dcf666f4eba9dd35f2c6cef0b1c2536 Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Sun, 19 Jan 2025 14:55:51 -0800 Subject: [PATCH 01/10] feat: async session api --- .bazelversion | 2 +- ecsact/runtime/async.h | 55 +++++++++++++++++++++++++++-------------- ecsact/runtime/async.hh | 30 ++++++++++++---------- ecsact/runtime/common.h | 1 + test/.bazelversion | 1 + 5 files changed, 56 insertions(+), 33 deletions(-) create mode 100644 test/.bazelversion diff --git a/.bazelversion b/.bazelversion index 15020207..815da58b 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -7.3.0 +7.4.1 diff --git a/ecsact/runtime/async.h b/ecsact/runtime/async.h index 0437babe..978b7ad1 100644 --- a/ecsact/runtime/async.h +++ b/ecsact/runtime/async.h @@ -79,6 +79,8 @@ typedef enum { /** * When an error occurs due to an async request this callback is invoked. * + * @param session_id the session that received the error + * * @param async_err when there is no async error this will be @ref * ECSACT_ASYNC_OK otherwise @see ecsact_async_error @@ -89,6 +91,7 @@ typedef enum { * ecsact_async_events_collector::error_callback_user_data */ typedef void (*ecsact_async_error_callback)( // + ecsact_async_session_id session_id, ecsact_async_error async_err, int request_ids_length, ecsact_async_request_id* request_ids, @@ -98,10 +101,12 @@ typedef void (*ecsact_async_error_callback)( // /** * When an occurs from the system execution this callback is invoked. * + * @param session_id the session that received the error * @param execute_err when there is no system execution error, this will be * @ref ECSACT_EXEC_SYS_OK other @see ecsact_execute_systems_error */ typedef void (*ecsact_execute_sys_error_callback)( // + ecsact_async_session_id session_id, ecsact_execute_systems_error execute_err, void* callback_user_data ); @@ -110,6 +115,7 @@ typedef void (*ecsact_execute_sys_error_callback)( // * Handler for when a request is done (error or success) */ typedef void (*ecsact_async_request_done_callback)( // + ecsact_async_session_id session_id, int request_ids_length, ecsact_async_request_id* request_ids, void* callback_user_data @@ -166,6 +172,7 @@ ECSACT_ASYNC_API_FN( ecsact_async_enqueue_execution_options ) ( // + ecsact_async_session_id session_id, const ecsact_execution_options options ); @@ -181,29 +188,38 @@ ECSACT_ASYNC_API_FN(void, ecsact_async_flush_events) ); /** - * @param connection_string - null-terminated string used to connect to the - * underlying async runtime. This may be a hostname/ip address + port or - * some other string deinfed by the implementation. Please review - * documentation for your ecsact async api provider. May be NULL to - * indicate wanting to connect to the 'default' if available. - * @returns a request ID representing this async request. Later used in @ref - * ecsact_async_error_callback if an error occurs + * @param option_data implementation defined options used to start the async + * session. This usually contains information such as the host/ip, port, and + * authentication for a network connection or various settings that affect the + * simulation. It is recommended that all implementations handle `NULL` as the + * 'default' options. You should refer to the implementations documentation for + * what should be passed here. + * + * @param option_data_size length (in bytes) of @p option_data + * + * @returns an ID that represents the session that all other async functions + * take in */ -ECSACT_ASYNC_API_FN(ecsact_async_request_id, ecsact_async_connect) +ECSACT_ASYNC_API_FN(ecsact_async_session_id, ecsact_async_start) ( // - const char* connection_string + const void* option_data, + int32_t option_data_size ); /** - * Starts a disconnect. May happen in background, but is guaranteed to - * disconnect before any new @ref ecsact_async_connect resolves. + * Begins stopping the session. May happen in background. + * @param session_id the session that should stop */ -ECSACT_ASYNC_API_FN(void, ecsact_async_disconnect)(void); +ECSACT_ASYNC_API_FN(void, ecsact_async_stop)( // + ecsact_async_session_id session_id +); /** * Gets the current tick */ -ECSACT_ASYNC_API_FN(int32_t, ecsact_async_get_current_tick)(void); +ECSACT_ASYNC_API_FN(int32_t, ecsact_async_get_current_tick)( // + ecsact_async_session_id session_id +); /** * Sends Ecsact stream data to the specified registry. Stream data will be @@ -215,10 +231,11 @@ ECSACT_ASYNC_API_FN(int32_t, ecsact_async_get_current_tick)(void); */ ECSACT_ASYNC_API_FN(void, ecsact_async_stream) ( // - ecsact_entity_id entity, - ecsact_component_id component_id, - const void* component_data, - const void* indexed_field_values + ecsact_async_session_id session_id, + ecsact_entity_id entity, + ecsact_component_id component_id, + const void* component_data, + const void* indexed_field_values ); #ifdef ECSACT_MSVC_TRADITIONAL @@ -227,8 +244,8 @@ ECSACT_ASYNC_API_FN(void, ecsact_async_stream) # define FOR_EACH_ECSACT_ASYNC_API_FN(fn, ...) \ fn(ecsact_async_enqueue_execution_options, __VA_ARGS__); \ fn(ecsact_async_flush_events, __VA_ARGS__); \ - fn(ecsact_async_connect, __VA_ARGS__); \ - fn(ecsact_async_disconnect, __VA_ARGS__); \ + fn(ecsact_async_start, __VA_ARGS__); \ + fn(ecsact_async_stop, __VA_ARGS__); \ fn(ecsact_async_get_current_tick, __VA_ARGS__); \ fn(ecsact_async_stream, __VA_ARGS__) #endif diff --git a/ecsact/runtime/async.hh b/ecsact/runtime/async.hh index 468321e5..3b7f85fc 100644 --- a/ecsact/runtime/async.hh +++ b/ecsact/runtime/async.hh @@ -139,24 +139,28 @@ private: } }; -[[nodiscard]] ECSACT_ALWAYS_INLINE auto connect( - const std::string& connection_string -) -> ecsact_async_request_id { - return ecsact_async_connect(connection_string.c_str()); +[[nodiscard]] ECSACT_ALWAYS_INLINE auto start( // + int32_t size, + const void* data +) -> ecsact_async_session_id { + return ecsact_async_start(size, data); } -ECSACT_ALWAYS_INLINE auto disconnect() -> void { - ecsact_async_disconnect(); +ECSACT_ALWAYS_INLINE auto stop(ecsact_async_session_id id) -> void { + ecsact_async_stop(id); } -[[nodiscard]] ECSACT_ALWAYS_INLINE auto get_current_tick() -> int32_t { - return ecsact_async_get_current_tick(); +[[nodiscard]] ECSACT_ALWAYS_INLINE auto get_current_tick( + ecsact_async_session_id id +) -> int32_t { + return ecsact_async_get_current_tick(id); } [[nodiscard]] ECSACT_ALWAYS_INLINE auto enqueue_execution_options( + ecsact_async_session_id id, ecsact::core::execution_options& options ) -> ecsact_async_request_id { - return ecsact_async_enqueue_execution_options(options.c()); + return ecsact_async_enqueue_execution_options(id, options.c()); } ECSACT_ALWAYS_INLINE auto flush_events() -> void { @@ -165,8 +169,8 @@ ECSACT_ALWAYS_INLINE auto flush_events() -> void { template requires(std::convertible_to< - decltype(std::declval().c()), - const ecsact_execution_events_collector>) + decltype(std::declval().c()), + const ecsact_execution_events_collector>) ECSACT_ALWAYS_INLINE auto flush_events( // ExecutionEventsCollector&& evc ) -> void { @@ -176,8 +180,8 @@ ECSACT_ALWAYS_INLINE auto flush_events( // template requires(std::convertible_to< - decltype(std::declval().c()), - const ecsact_async_events_collector>) + decltype(std::declval().c()), + const ecsact_async_events_collector>) ECSACT_ALWAYS_INLINE auto flush_events( // AsyncEventsCollector&& async_evc ) -> void { diff --git a/ecsact/runtime/common.h b/ecsact/runtime/common.h index b3bac3bc..ac0d2777 100644 --- a/ecsact/runtime/common.h +++ b/ecsact/runtime/common.h @@ -69,6 +69,7 @@ ECSACT_TYPED_ID(ecsact_registry_id); ECSACT_TYPED_ID(ecsact_entity_id); ECSACT_TYPED_ID(ecsact_placeholder_entity_id); ECSACT_TYPED_ID(ecsact_system_generates_id); +ECSACT_TYPED_ID(ecsact_async_session_id); ECSACT_TYPED_ID(ecsact_async_request_id); ECSACT_TYPED_ID(ecsact_decl_id); diff --git a/test/.bazelversion b/test/.bazelversion new file mode 100644 index 00000000..815da58b --- /dev/null +++ b/test/.bazelversion @@ -0,0 +1 @@ +7.4.1 From 0819cbb7a72f4ffff2b68875135f7f99ab1702ff Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Sun, 19 Jan 2025 14:58:46 -0800 Subject: [PATCH 02/10] chore: update clang format --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a99624f3..261ee615 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@v4 - uses: greut/eclint-action@v0 - uses: jidicula/clang-format-action@v4.11.0 - with: { clang-format-version: "18" } + with: { clang-format-version: "19" } test-windows: if: >- From 1fb4809ee9552ea7fb718b2477dd114dbf150fb1 Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Sun, 19 Jan 2025 15:04:16 -0800 Subject: [PATCH 03/10] chore: format --- ecsact/runtime/serialize.hh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ecsact/runtime/serialize.hh b/ecsact/runtime/serialize.hh index b3833b55..ddd080f2 100644 --- a/ecsact/runtime/serialize.hh +++ b/ecsact/runtime/serialize.hh @@ -16,8 +16,7 @@ namespace ecsact { * @returns serialized action or component bytes */ template - requires(!std::is_same_v, ecsact_component> && - !std::is_same_v, ecsact_action>) + requires(!std::is_same_v, ecsact_component> && !std::is_same_v, ecsact_action>) ECSACT_ALWAYS_INLINE auto serialize( // const T& component_or_action ) -> std::vector { From bde06b4d8ef232c28f1deeb254687f5dcd582314 Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Sun, 19 Jan 2025 15:11:14 -0800 Subject: [PATCH 04/10] feat: add default overload --- ecsact/runtime/async.hh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ecsact/runtime/async.hh b/ecsact/runtime/async.hh index 3b7f85fc..7fbb521c 100644 --- a/ecsact/runtime/async.hh +++ b/ecsact/runtime/async.hh @@ -139,6 +139,10 @@ private: } }; +[[nodiscard]] ECSACT_ALWAYS_INLINE auto start() -> ecsact_async_session_id { + return ecsact_async_start(0, nullptr); +} + [[nodiscard]] ECSACT_ALWAYS_INLINE auto start( // int32_t size, const void* data From 7953d81a621b1e6cd8a4e26bc9fd39c3130b3382 Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Tue, 21 Jan 2025 11:04:24 -0800 Subject: [PATCH 05/10] feat: require session id for flush events --- ecsact/runtime/async.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ecsact/runtime/async.h b/ecsact/runtime/async.h index 978b7ad1..43674c06 100644 --- a/ecsact/runtime/async.h +++ b/ecsact/runtime/async.h @@ -183,6 +183,7 @@ ECSACT_ASYNC_API_FN( */ ECSACT_ASYNC_API_FN(void, ecsact_async_flush_events) ( // + ecsact_async_session_id session_id, const ecsact_execution_events_collector* execution_events, const ecsact_async_events_collector* async_events ); @@ -210,14 +211,16 @@ ECSACT_ASYNC_API_FN(ecsact_async_session_id, ecsact_async_start) * Begins stopping the session. May happen in background. * @param session_id the session that should stop */ -ECSACT_ASYNC_API_FN(void, ecsact_async_stop)( // +ECSACT_ASYNC_API_FN(void, ecsact_async_stop) +( // ecsact_async_session_id session_id ); /** * Gets the current tick */ -ECSACT_ASYNC_API_FN(int32_t, ecsact_async_get_current_tick)( // +ECSACT_ASYNC_API_FN(int32_t, ecsact_async_get_current_tick) +( // ecsact_async_session_id session_id ); From 79baeb2308660167440e4033e0821fc31b7bfb3e Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Tue, 21 Jan 2025 12:00:18 -0800 Subject: [PATCH 06/10] feat: add new session event callback --- ecsact/runtime/async.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/ecsact/runtime/async.h b/ecsact/runtime/async.h index 43674c06..81cd0f60 100644 --- a/ecsact/runtime/async.h +++ b/ecsact/runtime/async.h @@ -76,6 +76,18 @@ typedef enum { ECSACT_ASYNC_ERR_CUSTOM_END = 200, } ecsact_async_error; +typedef enum { + /** + * The session has started + */ + ECSACT_ASYNC_SESSION_STARTED = 0, + + /** + * The session has stopped + */ + ECSACT_ASYNC_SESSION_STOPPED = 1, +} ecsact_async_session_event; + /** * When an error occurs due to an async request this callback is invoked. * @@ -121,6 +133,15 @@ typedef void (*ecsact_async_request_done_callback)( // void* callback_user_data ); +/** + * Handler async session events + */ +typedef void (*ecsact_async_session_event_callback)( // + ecsact_async_session_id session_id, + ecsact_async_session_event event, + void* callback_user_data +); + typedef struct ecsact_async_events_collector { /** * invoked when an async request failed. @@ -157,6 +178,16 @@ typedef struct ecsact_async_events_collector { * `callback_user_data` passed to `async_request_done_callback` */ void* async_request_done_callback_user_data; + + /** + * invoked when a session event has occured. @see ecsact_async_session_event + */ + ecsact_async_session_event_callback async_session_event_callback; + + /** + * `callback_user_data` passed to `async_session_event_callback` + */ + void* async_session_event_callback_user_data; } ecsact_async_events_collector; /** From 3735a1bcc5f19547738c299689d45c543e41fd9f Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Tue, 21 Jan 2025 15:42:42 -0800 Subject: [PATCH 07/10] feat: add another session event --- ecsact/runtime/async.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ecsact/runtime/async.h b/ecsact/runtime/async.h index 81cd0f60..15947988 100644 --- a/ecsact/runtime/async.h +++ b/ecsact/runtime/async.h @@ -78,14 +78,19 @@ typedef enum { typedef enum { /** - * The session has started + * The session has stopped */ - ECSACT_ASYNC_SESSION_STARTED = 0, + ECSACT_ASYNC_SESSION_STOPPED = 0, /** - * The session has stopped + * The session is attempting to start but hasn't yet. + */ + ECSACT_ASYNC_SESSION_PENDING = 1, + + /** + * The session has started */ - ECSACT_ASYNC_SESSION_STOPPED = 1, + ECSACT_ASYNC_SESSION_START = 2, } ecsact_async_session_event; /** From 267c007ee0ee2bbd6b743b3176a41dc7f75da048 Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Wed, 22 Jan 2025 09:48:37 -0800 Subject: [PATCH 08/10] feat: add stop all async method --- ecsact/runtime/async.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ecsact/runtime/async.h b/ecsact/runtime/async.h index 15947988..a812f29e 100644 --- a/ecsact/runtime/async.h +++ b/ecsact/runtime/async.h @@ -252,6 +252,11 @@ ECSACT_ASYNC_API_FN(void, ecsact_async_stop) ecsact_async_session_id session_id ); +/** + * Begins stopping all active sessions. May happen in background. + */ +ECSACT_ASYNC_API_FN(void, ecsact_async_stop_all)(); + /** * Gets the current tick */ From bc5626f399874c69f8d3f1eb4279d9e2baa83a81 Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Wed, 22 Jan 2025 09:59:04 -0800 Subject: [PATCH 09/10] feat: add force reset method --- ecsact/runtime/async.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ecsact/runtime/async.h b/ecsact/runtime/async.h index a812f29e..f875b606 100644 --- a/ecsact/runtime/async.h +++ b/ecsact/runtime/async.h @@ -257,6 +257,14 @@ ECSACT_ASYNC_API_FN(void, ecsact_async_stop) */ ECSACT_ASYNC_API_FN(void, ecsact_async_stop_all)(); +/** + * Stops all active sessions immediately making all session IDs invalid. + * + * NOTE: `ecsact_async_stop_all` is a more graceful option and should be + * preferred. + */ +ECSACT_ASYNC_API_FN(void, ecsact_async_force_reset)(); + /** * Gets the current tick */ @@ -290,6 +298,8 @@ ECSACT_ASYNC_API_FN(void, ecsact_async_stream) fn(ecsact_async_flush_events, __VA_ARGS__); \ fn(ecsact_async_start, __VA_ARGS__); \ fn(ecsact_async_stop, __VA_ARGS__); \ + fn(ecsact_async_stop_all, __VA_ARGS__); \ + fn(ecsact_async_force_reset, __VA_ARGS__); \ fn(ecsact_async_get_current_tick, __VA_ARGS__); \ fn(ecsact_async_stream, __VA_ARGS__) #endif From 840629e1e97a0ec6b601f5e3f5afffcdd62648c9 Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Wed, 22 Jan 2025 11:23:41 -0800 Subject: [PATCH 10/10] chore: fixed typos --- ecsact/runtime/async.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ecsact/runtime/async.h b/ecsact/runtime/async.h index f875b606..399e9a0c 100644 --- a/ecsact/runtime/async.h +++ b/ecsact/runtime/async.h @@ -185,7 +185,7 @@ typedef struct ecsact_async_events_collector { void* async_request_done_callback_user_data; /** - * invoked when a session event has occured. @see ecsact_async_session_event + * invoked when a session event has occurred. @see ecsact_async_session_event */ ecsact_async_session_event_callback async_session_event_callback;