libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
libxr_cb.hpp
1#pragma once
2
3#include <cstring>
4#include <tuple>
5#include <utility>
6
7#include "libxr_def.hpp"
8
9namespace LibXR
10{
11
26template <typename ArgType, typename... Args>
28{
29 bool running_ = false;
30 bool pending_ = false;
31 std::tuple<std::decay_t<Args>...> pending_args_{};
32
33 public:
37 using FunctionType = void (*)(bool, ArgType, Args...);
38
48 template <typename FunType, typename ArgT>
49 CallbackBlock(FunType&& fun, ArgT&& arg)
50 : fun_(std::forward<FunType>(fun)), arg_(std::forward<ArgT>(arg))
51 {
52 }
53
66 void Call(bool in_isr, Args... args)
67 {
68 if (!fun_)
69 {
70 return;
71 }
72
73 if (!running_)
74 {
75 running_ = true;
76
77 auto cur_args = std::tuple<std::decay_t<Args>...>{args...};
78
79 do
80 {
81 pending_ = false;
82 std::apply([&](auto&... a) { fun_(in_isr, arg_, a...); }, cur_args);
83
84 if (pending_)
85 {
86 cur_args = pending_args_; // overwrite pending args on reentry
87 }
88 } while (pending_);
89
90 running_ = false;
91 return;
92 }
93
94 // reentrant: cache one pending request (overwrite)
95 pending_args_ = std::tuple<std::decay_t<Args>...>{args...};
96 pending_ = true;
97 }
98
102 CallbackBlock(const CallbackBlock& other) = delete;
103 CallbackBlock& operator=(const CallbackBlock& other) = delete;
104
111 CallbackBlock(CallbackBlock&& other) noexcept
112 : fun_(std::exchange(other.fun_, nullptr)),
113 arg_(std::move(other.arg_)),
114 in_isr_(other.in_isr_)
115 {
116 }
117
126 {
127 if (this != &other)
128 {
129 fun_ = std::exchange(other.fun_, nullptr);
130 arg_ = std::move(other.arg_);
131 in_isr_ = other.in_isr_;
132 }
133 return *this;
134 }
135
136 private:
137 void (*fun_)(bool, ArgType, Args...);
138 ArgType arg_;
139 bool in_isr_ = false;
140};
141
148template <typename... Args>
150{
151 static void FunctionDefault(bool, void*, Args...) {}
152
153 public:
166 template <typename FunType, typename ArgType>
167 [[nodiscard]] static Callback Create(FunType fun, ArgType arg)
168 {
169 void (*fun_ptr)(bool, ArgType, Args...) = fun;
170 auto cb_block = new CallbackBlock<ArgType, Args...>(fun_ptr, arg);
171
172 auto cb_fun = [](bool in_isr, void* cb_block, Args... args)
173 {
174 auto* cb = static_cast<CallbackBlock<ArgType, Args...>*>(cb_block);
175 cb->Call(in_isr, std::forward<Args>(args)...);
176 };
177
178 return Callback(cb_block, cb_fun);
179 }
180
185
186 Callback(const Callback&) = default;
187 Callback& operator=(const Callback&) = default;
188
195 Callback(Callback&& other) noexcept
196 : cb_block_(std::exchange(other.cb_block_, nullptr)),
197 cb_fun_(std::exchange(other.cb_fun_, nullptr))
198 {
199 }
200
208 Callback& operator=(Callback&& other) noexcept
209 {
210 if (this != &other)
211 {
212 cb_block_ = std::exchange(other.cb_block_, nullptr);
213 cb_fun_ = std::exchange(other.cb_fun_, nullptr);
214 }
215 return *this;
216 }
217
224 template <typename... PassArgs>
225 void Run(bool in_isr, PassArgs&&... args) const
226 {
227 cb_fun_(in_isr, cb_block_, std::forward<PassArgs>(args)...);
228 }
229
236 bool Empty() const { return cb_block_ == nullptr; }
237
238 private:
246 Callback(void* cb_block, void (*cb_fun)(bool, void*, Args...))
247 : cb_block_(cb_block), cb_fun_(cb_fun)
248 {
249 }
250
251 void* cb_block_ = nullptr;
252 void (*cb_fun_)(bool, void*, Args...) =
253 FunctionDefault;
254};
255
256} // namespace LibXR
回调函数封装块,提供重入保护与参数绑定 / Callback block with argument binding and reentrancy guard
Definition libxr_cb.hpp:28
void(*)(bool, ArgType, Args...) FunctionType
回调函数类型定义 / Callback function type definition
Definition libxr_cb.hpp:37
CallbackBlock(const CallbackBlock &other)=delete
禁用拷贝构造与拷贝赋值 / Copy construction and copy assignment are disabled
CallbackBlock(FunType &&fun, ArgT &&arg)
构造回调块,绑定回调函数与参数 / Construct a callback block with bound function and argument
Definition libxr_cb.hpp:49
CallbackBlock & operator=(CallbackBlock &&other) noexcept
移动赋值运算符,转移回调函数与参数 / Move assignment operator transferring function and argument
Definition libxr_cb.hpp:125
void Call(bool in_isr, Args... args)
触发回调执行(带重入保护) / Trigger callback execution with reentrancy guard
Definition libxr_cb.hpp:66
bool in_isr_
是否在中断上下文中执行 / Whether executed in ISR context
Definition libxr_cb.hpp:139
CallbackBlock(CallbackBlock &&other) noexcept
移动构造函数,转移回调函数与参数 / Move constructor transferring function and argument
Definition libxr_cb.hpp:111
ArgType arg_
绑定的参数 / Bound argument
Definition libxr_cb.hpp:138
void(* fun_)(bool, ArgType, Args...)
绑定的回调函数 / Bound callback function
Definition libxr_cb.hpp:137
通用回调包装,支持动态参数传递 / Generic callback wrapper supporting dynamic argument passing
Definition libxr_cb.hpp:150
void * cb_block_
回调块指针 / Pointer to the callback block
Definition libxr_cb.hpp:251
Callback(void *cb_block, void(*cb_fun)(bool, void *, Args...))
私有构造函数,仅用于内部创建回调实例 / Private constructor used internally to create callback instances
Definition libxr_cb.hpp:246
Callback & operator=(Callback &&other) noexcept
移动赋值运算符,转移回调对象的所有权 / Move assignment operator transferring callback ownership
Definition libxr_cb.hpp:208
static Callback Create(FunType fun, ArgType arg)
创建回调对象并绑定回调函数与参数 / Create a callback instance with bound function and argument
Definition libxr_cb.hpp:167
void Run(bool in_isr, PassArgs &&... args) const
执行回调函数并传递参数 / Execute the callback with arguments
Definition libxr_cb.hpp:225
Callback(Callback &&other) noexcept
移动构造函数,转移回调对象的所有权 / Move constructor transferring callback ownership
Definition libxr_cb.hpp:195
bool Empty() const
检查回调是否为空 / Check whether the callback is empty
Definition libxr_cb.hpp:236
void(* cb_fun_)(bool, void *, Args...)
回调执行函数指针 / Callback invocation function pointer
Definition libxr_cb.hpp:252
Callback()
默认构造函数,创建空回调对象 / Default constructor creating an empty callback
Definition libxr_cb.hpp:184
LibXR 命名空间