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>{};
1517static auto request_id_factory = detail::request_id_factory{};
18+ static auto last_session_id = ecsact_async_session_id{};
1619static 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