1
1
#include < optional>
2
2
#include < stdarg.h>
3
3
#include < span>
4
+ #include < map>
4
5
#include " ecsact/runtime/async.h"
5
6
#include " async_reference/async_reference.hh"
6
7
#include " async_reference/callbacks/async_callbacks.hh"
@@ -11,87 +12,121 @@ using namespace ecsact::async_reference;
11
12
// NOTE: These are the singletons for managing the reference library state.
12
13
// This file should be small. Declare a few variables and call a few
13
14
// 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>{};
15
17
static auto request_id_factory = detail::request_id_factory{};
18
+ static auto last_session_id = ecsact_async_session_id{};
16
19
static auto reference = std::optional<detail::async_reference>{};
17
20
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
+ );
23
25
}
24
26
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);
29
33
}
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;
30
47
}
31
48
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,
33
63
const ecsact_execution_events_collector* execution_evc,
34
64
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 ;
39
69
}
70
+
71
+ reference->flush_events (session_id, execution_evc, async_evc);
72
+ async_callbacks[session_id].invoke (session_id, async_evc);
40
73
}
41
74
42
- ecsact_async_request_id ecsact_async_enqueue_execution_options (
75
+ auto ecsact_async_enqueue_execution_options (
76
+ ecsact_async_session_id session_id,
43
77
const ecsact_execution_options options
44
- ) {
78
+ ) -> ecsact_async_request_id {
45
79
auto req_id = request_id_factory.next_id ();
46
80
if (!reference) {
47
- async_callbacks.add (detail::types::async_error{
81
+ async_callbacks[session_id] .add (detail::types::async_error{
48
82
.error = ECSACT_ASYNC_ERR_NOT_CONNECTED,
49
83
.request_ids = {req_id},
50
84
});
51
85
return req_id;
52
86
}
53
87
54
- reference->enqueue_execution_options (req_id, options);
88
+ reference->enqueue_execution_options (session_id, req_id, options);
89
+
55
90
return req_id;
56
91
}
57
92
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 ;
61
98
}
62
- return 0 ;
99
+ return reference-> get_current_tick (session_id) ;
63
100
}
64
101
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 {
73
109
if (indexed_fields != nullptr ) {
74
- async_callbacks.add (detail::types::async_error{
110
+ async_callbacks[session_id] .add (detail::types::async_error{
75
111
.error = ECSACT_ASYNC_ERR_INTERNAL,
76
- .request_ids = {req_id },
112
+ .request_ids = {ECSACT_INVALID_ID (async_request) },
77
113
});
78
- return req_id ;
114
+ return ;
79
115
}
80
116
81
117
if (!reference) {
82
- async_callbacks.add (detail::types::async_error{
118
+ async_callbacks[session_id] .add (detail::types::async_error{
83
119
.error = ECSACT_ASYNC_ERR_NOT_CONNECTED,
84
- .request_ids = {req_id },
120
+ .request_ids = {ECSACT_INVALID_ID (async_request) },
85
121
});
86
- return req_id ;
122
+ return ;
87
123
}
88
124
89
125
reference->stream ( //
90
- req_id ,
126
+ session_id ,
91
127
entity,
92
128
component_id,
93
129
component_data,
94
130
indexed_fields
95
131
);
96
- return req_id;
97
132
}
0 commit comments