co_usb
Loading...
Searching...
No Matches
event_handler_ref.hpp
Go to the documentation of this file.
1
6#pragma once
7
10#include <concepts>
11#include <utility>
12
13namespace co_usb::ev
14{
15
34{
35 explicit inline event_handler_ref () noexcept
36 {
37 }
38
39 template <detail::EventHandler HandlerTy>
40 requires(!std::same_as<HandlerTy, event_handler_ref>)
41 event_handler_ref(HandlerTy &handler) : m_original(&handler), m_vtable(make_vtable(handler))
42 {
43 ref();
44 }
45
46 template <detail::EventHandler HandlerTy>
47 requires(!std::same_as<HandlerTy, event_handler_ref>)
48 event_handler_ref &operator=(HandlerTy &handler)
49 {
50 if (m_original == &handler)
51 return *this;
52 m_original = &handler;
53 m_vtable = make_vtable(handler);
54 ref();
55 return *this;
56 }
57
59 : m_original(other.m_original), m_vtable(other.m_vtable)
60 {
61 ref();
62 }
63
65 {
66 if (this == &other)
67 return *this;
68 if (m_original)
69 unref();
70 m_original = other.m_original;
71 m_vtable = other.m_vtable;
72 ref();
73 return *this;
74 }
75
77 : m_original(other.m_original), m_vtable(other.m_vtable)
78 {
79 other.m_original = nullptr;
80 }
81
83 {
84 if (this == &other)
85 {
86 return *this;
87 }
88 if (m_original)
89 unref();
90 m_original = other.m_original;
91 m_vtable = other.m_vtable;
92 other.m_original = nullptr;
93 return *this;
94 }
95
97 {
98 unref();
99 }
100
101 inline auto valid () const noexcept -> bool
102 {
103 return m_original != nullptr;
104 }
105
106 auto start (libusb_context *usb_ctx, std::stop_token stop) -> bool
107 {
108 if (!m_original)
109 {
110 return false;
111 }
112 return m_vtable.start_fn(m_original, usb_ctx, std::move(stop));
113 }
114
115 auto ref () noexcept -> void
116 {
117 if (!m_original)
118 {
119 return;
120 }
121 return m_vtable.ref_fn(m_original);
122 }
123
124 auto unref () noexcept -> void
125 {
126 if (!m_original)
127 {
128 return;
129 }
130 return m_vtable.unref_fn(m_original);
131 }
132
133 auto stop () -> void
134 {
135 if (!m_original)
136 {
137 return;
138 }
139 return m_vtable.stop_fn(m_original);
140 }
141
142 private:
143 struct vtable
144 {
145 using start_fn_t = auto (*)(void *, libusb_context *, std::stop_token) -> bool;
146 using ref_fn_t = auto (*)(void *) -> void;
147 using unref_fn_t = auto (*)(void *) -> void;
148 using stop_fn_t = auto (*)(void *) -> void;
149
150 start_fn_t start_fn{nullptr};
151 ref_fn_t ref_fn{nullptr};
152 unref_fn_t unref_fn{nullptr};
153 stop_fn_t stop_fn{nullptr};
154 };
155
156 template <detail::EventHandler HandlerTy>
157 requires(!std::same_as<HandlerTy, event_handler_ref>)
158 auto make_vtable (HandlerTy &handler) -> vtable
159 {
160 (void)handler; // used for type deduction
161 return vtable{
162 .start_fn = +[] (void *orig, libusb_context *ctx, std::stop_token stop) -> bool
163 { return static_cast<HandlerTy *>(orig)->start(ctx, stop); },
164 .ref_fn = +[] (void *orig) -> void { return static_cast<HandlerTy *>(orig)->ref(); },
165 .unref_fn = +[] (void *orig) -> void
166 { return static_cast<HandlerTy *>(orig)->unref(); },
167 .stop_fn = +[] (void *orig) -> void { return static_cast<HandlerTy *>(orig)->stop(); },
168 };
169 }
170
171 private:
172 void *m_original{nullptr};
173 vtable m_vtable;
174};
175
176static_assert(detail::EventHandler<event_handler_ref>, "Not a proper USB event handler");
177
178} // namespace co_usb::ev
Owning type-erased wrapper for EventHandler.
Specification and implementation of EventHandler concept.
Definition any_event_handler.hpp:15
Type-erased reference to any event handler.
Definition event_handler_ref.hpp:34
auto start(libusb_context *usb_ctx, std::stop_token stop) -> bool
Definition event_handler_ref.hpp:106
event_handler_ref(event_handler_ref const &other)
Definition event_handler_ref.hpp:58
event_handler_ref(HandlerTy &handler)
Definition event_handler_ref.hpp:41
auto ref() noexcept -> void
Definition event_handler_ref.hpp:115
auto stop() -> void
Definition event_handler_ref.hpp:133
auto unref() noexcept -> void
Definition event_handler_ref.hpp:124
event_handler_ref & operator=(event_handler_ref const &other)
Definition event_handler_ref.hpp:64
auto valid() const noexcept -> bool
Definition event_handler_ref.hpp:101
~event_handler_ref()
Definition event_handler_ref.hpp:96
event_handler_ref() noexcept
Definition event_handler_ref.hpp:35
event_handler_ref(event_handler_ref &&other) noexcept
Definition event_handler_ref.hpp:76
event_handler_ref & operator=(event_handler_ref &&other) noexcept
Definition event_handler_ref.hpp:82