Toast Engine
Loading...
Searching...
No Matches
proto_event.hpp
Go to the documentation of this file.
1
8#pragma once
9
10#include "event.hpp"
11#include "ffi/events.h"
12#include "listener.hpp"
13
14#include <cstdint>
15#include <string>
16#include <vector>
17
18namespace event {
19
20namespace _detail {
21
29struct ProtoEntry {
30 int (*send)(const uint8_t* data, uint32_t size);
31 void (*subscribe)(
32 Listener&, event_callback, void* user_data, char priority, const char* label
33 );
34 void (*unsubscribe)(Listener&, const char* label);
35};
36
38void registerProtoEntry(std::string name, ProtoEntry entry);
39
40}
41
42template<ExposedEvent T>
43void registerProtoEvent() {
44 using Traits = ProtoTraits<T>;
45 using Proto = typename Traits::Proto;
46
47 EventSystem::registerEvent<T>();
48
50 .send = [](const uint8_t* data, uint32_t size) -> int {
51 Proto p;
52 if (not p.ParseFromArray(data, static_cast<int>(size))) {
53 return -2;
54 }
55 event::send<T>(Traits::fromProto(p));
56 return 0;
57 },
58 .subscribe =
59 [](Listener& l, event_callback callback, void* user_data, char priority, const char* label) {
60 l.subscribe<T>(
61 std::string {label},
62 [callback, user_data](T& ev) -> bool {
63 try {
64 Proto p = Traits::toProto(ev);
65 std::string bytes = p.SerializeAsString();
66 std::string name {Proto::descriptor()->full_name()};
67 return callback(
68 name.c_str(),
69 reinterpret_cast<const uint8_t*>(bytes.data()),
70 static_cast<uint32_t>(bytes.size()),
71 user_data
72 ) != 0;
73 } catch (const std::exception& e) {
74 // swallow serialization failures so one bad event doesn't kill the whole chain
75 TOAST_WARN("Events", "Failed to serialize event {}: {}", Proto::descriptor()->full_name(), e.what());
76 return false;
77 }
78 },
79 priority
80 );
81 },
82 .unsubscribe = [](Listener& l, const char* label) { l.unsubscribe<T>(std::string_view {label}); },
83 };
84
85 _detail::registerProtoEntry(std::string {Proto::descriptor()->full_name()}, entry);
86}
87
88namespace _detail {
89
91inline auto protoRegistrars() -> std::vector<void (*)()>& {
92 static std::vector<void (*)()> registrars;
93 return registrars;
94}
95
98template<ExposedEvent T>
99struct ProtoAutoRegister {
100 ProtoAutoRegister() {
101 protoRegistrars().push_back([] { registerProtoEvent<T>(); });
102 }
103};
104
105}
106
107}
108
109#define TOAST_PROTO_CAT_IMPL(a, b) a##b
110#define TOAST_PROTO_CAT(a, b) TOAST_PROTO_CAT_IMPL(a, b)
111
113#define TOAST_PROTO_EVENT(EventType) \
114 static const ::event::_detail::ProtoAutoRegister<EventType> TOAST_PROTO_CAT(_proto_auto_, __LINE__) { }
manages the lifetime, subscription, and unsubscription of callbacks
Definition listener.hpp:39
#define TOAST_WARN(sink,...)
Indicates possible code missuse.
Definition log.hpp:94
auto protoRegistrars() -> std::vector< void(*)()> &
Returns the global list of proto registration callbacks; each TOAST_PROTO_EVENT() macro appends one e...
Definition proto_event.hpp:91
Specialization point that exposes a C++ event type over the C# FFI via protobuf.
Definition event.hpp:188
Dispatch table for one protobuf-backed event type over the FFI.
Definition proto_event.hpp:29
void(* unsubscribe)(Listener &, const char *label)
cancels a subscription by label
Definition proto_event.hpp:34
int(* send)(const uint8_t *data, uint32_t size)
C# -> engine: deserializes bytes and dispatches the event.
Definition proto_event.hpp:30
void(* subscribe)(Listener &, event_callback, void *user_data, char priority, const char *label)
engine -> C#: serializes the event and calls the C# callback
Definition proto_event.hpp:31