1#ifndef NEFORCE_CORE_ASYNC_SIGNALS_HPP__
2#define NEFORCE_CORE_ASYNC_SIGNALS_HPP__
19NEFORCE_BEGIN_NAMESPACE__
100 constexpr oneshot_t()
noexcept =
default;
152 NEFORCE_NODISCARD
bool connected() const noexcept {
return connected_ && *connected_; }
183 conn_(_NEFORCE
move(conn)) {}
198 conn_(_NEFORCE
move(other.conn_)) {}
210 conn_ = _NEFORCE
move(other.conn_);
223 NEFORCE_NODISCARD
bool connected() const noexcept {
return conn_.connected(); }
235template <
typename... Types>
244template <
typename... Types>
249 bool released_ =
false;
257 blocked_flag_(sig.block_flag()) {
258 old_value_ = *blocked_flag_;
259 *blocked_flag_ =
true;
266 if (blocked_flag_ && !released_) {
267 *blocked_flag_ = old_value_;
280 if (blocked_flag_ && !released_) {
281 *blocked_flag_ = old_value_;
295template <
typename... Types>
305 callback_type callback;
310 callback(_NEFORCE
move(cb)),
311 connected_flag(_NEFORCE
move(flag)),
317 mutable mutex mutex_;
319 template <
typename T>
323 template <
typename T>
327 template <
typename T>
328 static T* lock_if_weak(T* self)
noexcept {
332 template <
typename Func>
333 auto with_lock(Func&& func)
const {
338 template <
typename Func>
339 auto with_lock(Func&& func) {
352 template <
typename Self,
typename MemFn>
353 auto bind(Self self, MemFn memfn) {
354 return [self = _NEFORCE
move(self), memfn](Types... args) {
355 auto ptr = signal::lock_if_weak(self);
356 if (ptr ==
nullptr) {
373 template <
typename Self,
typename MemFn>
374 auto bind(Self self, MemFn memfn,
oneshot_t one) {
375 return [self = _NEFORCE
move(self), memfn](Types... args) {
376 auto ptr = signal::lock_if_weak(self);
377 if (ptr ==
nullptr) {
394 template <
typename Self,
typename MemFn>
395 auto bind(Self self, MemFn memfn,
nshot_t n) {
396 return [self = _NEFORCE
move(self), memfn, n =
static_cast<size_t>(n)](Types... args)
mutable {
400 auto ptr = signal::lock_if_weak(self);
401 if (ptr ==
nullptr) {
420 template <
typename Func>
425 auto it = slots_.begin();
426 while (it != slots_.end() && it->priority >= priority) {
429 slots_.emplace(it, _NEFORCE
move(callback), conn.
flag(), priority);
441 template <
typename Func>
446 auto wrapped = [callback = _NEFORCE
move(callback)](Types... args)
mutable {
451 auto it = slots_.begin();
452 while (it != slots_.end() && it->priority >= priority) {
455 slots_.emplace(it, _NEFORCE
move(wrapped), conn.
flag(), priority);
460 size_t slot_count_unlocked()
const noexcept {
462 for (
const auto& slot: slots_) {
463 if (slot.connected_flag && *slot.connected_flag) {
470 template <
size_t... Is>
472 this->
emit(args[Is].
template convert<Types>()...);
477 ~signal()
override =
default;
478 signal(
const signal&) =
delete;
479 signal& operator=(
const signal&) =
delete;
480 signal(signal&&) =
delete;
481 signal& operator=(signal&&) =
delete;
493 template <
typename Self,
typename MemFn,
typename... Tag>
495 return this->
connect(_NEFORCE
move(self), memfn, 0, tag...);
505 template <
typename Func>
507 return this->with_lock([
this, callback = _NEFORCE
move(callback), priority] {
508 return this->connect_impl(_NEFORCE
move(callback), priority);
523 template <
typename Self,
typename MemFn,
typename... Tag>
525 static_assert(
sizeof...(Tag) <= 1,
"only zero or one tag is allowed");
527 return this->with_lock([
this, self = _NEFORCE
move(self), memfn = _NEFORCE
move(memfn), priority, tag...] {
530 auto it = slots_.begin();
531 while (it != slots_.end() && it->priority >= priority) {
534 slots_.emplace(it, this->bind(_NEFORCE
move(self), memfn, tag...), conn.flag(), priority);
557 for (
auto& slot: snapshot) {
558 if (!slot.connected_flag || !(*slot.connected_flag)) {
564 *slot.connected_flag =
false;
571 _NEFORCE
remove_if(slots_.begin(), slots_.end(),
572 [](
const slot_entry& s) { return !s.connected_flag || !(*s.connected_flag); }),
585 template <
typename Executor>
590 executor.
post([
this, weak_flag = _NEFORCE
move(weak_flag), args_tuple = _NEFORCE
move(args_tuple)]()
mutable {
591 if (weak_flag.expired()) {
595 _NEFORCE
apply([
this](
auto&&... a) { this->
emit(_NEFORCE
forward<
decltype(a)>(a)...); },
596 _NEFORCE
move(args_tuple));
604 template <
typename... Args>
613 this->with_lock([
this] { slots_.clear(); });
626 [other_ptr = &other](Types... args) {
627 other_ptr->emit(args...);
628 return callback_result::keep;
643 [other](Types... args) {
645 other->emit(args...);
663 template <
typename Func,
typename Predicate>
669 [callback = _NEFORCE
move(callback), pred = _NEFORCE
move(pred)](Types... args)
mutable {
671 callback(_NEFORCE forward<Types>(args)...);
691 template <
typename Self,
typename MemFn,
typename Predicate,
typename... Tag>
695 static_assert(
sizeof...(Tag) <= 1,
"only zero or one tag is allowed");
697 auto bound = this->bind(_NEFORCE
move(self), memfn, tag...);
700 [bound = _NEFORCE
move(bound), pred = _NEFORCE
move(pred)](Types... args)
mutable {
702 return bound(_NEFORCE forward<Types>(args)...);
720 template <
typename Func,
typename Filter>
723 [callback = _NEFORCE
move(callback), filter = _NEFORCE
move(filter)](Types... args)
mutable {
724 auto filtered = filter(args...);
726 auto filtered_tuple = _NEFORCE make_tuple(_NEFORCE move(*filtered));
728 [&callback](auto&&... filtered_args) {
729 callback(_NEFORCE forward<decltype(filtered_args)>(filtered_args)...);
731 _NEFORCE move(filtered_tuple));
749 template <
typename Func,
typename Transform>
751 static_assert(
is_invocable_v<Transform, Types...>,
"only function inputs are allowed");
755 callback(transform(_NEFORCE forward<Types>(args)...));
756 return callback_result::keep;
771 bool is_blocked() const noexcept
override {
return blocked_flag_ && *blocked_flag_; }
778 *blocked_flag_ =
true;
787 *blocked_flag_ =
false;
796 return this->with_lock([
this] {
return slot_count_unlocked(); });
806 this->
connect([cb = _NEFORCE
move(callback)](Types... args) {
807 vector<reflect::meta_any> wrapped;
808 wrapped.reserve(sizeof...(Types));
809 (wrapped.emplace_back(_NEFORCE forward<Types>(args)), ...);
811 return callback_result::keep;
820 if (args.
size() <
sizeof...(Types)) {
830 NEFORCE_NODISCARD
bool empty() const noexcept {
831 return this->with_lock([
this] {
return slot_count_unlocked() == 0; });
837NEFORCE_END_NAMESPACE__
shared_ptr< bool > flag() const noexcept
获取连接标志的内部指针
bool connected() const noexcept
检查连接是否有效
connection()
默认构造函数,创建处于已连接状态的对象
void disconnect() noexcept
断开连接
void post(handler_type handler) const
投递 handler 到执行器
bool connected() const noexcept
检查连接是否有效
scope_connection & operator=(scope_connection &&other) noexcept
移动赋值运算符
scope_connection(scope_connection &&other) noexcept
移动构造函数
scope_connection(connection conn) noexcept
从连接构造
~scope_connection()
析构函数,自动断开连接
void disconnect() noexcept
手动断开连接
scope_connection()=default
默认构造函数
connection release() noexcept
释放连接所有权
virtual bool is_blocked() const =0
是否处于阻塞状态
virtual size_t slot_count() const =0
获取已连接槽数量
virtual void connect_dynamic(function< void(const vector< reflect::meta_any > &)> callback)=0
动态连接槽回调(类型擦除版本)
virtual void emit_dynamic(const vector< reflect::meta_any > &args)=0
通过 meta_any 参数列表触发信号(类型擦除版本)
virtual void block()=0
阻塞信号触发
virtual void unblock()=0
解除阻塞
virtual void disconnect_all()=0
断开所有连接
signal_blocker(signal< Types... > &sig) noexcept
构造函数,阻塞指定信号
~signal_blocker()
析构函数,恢复原状态
void unblock() noexcept
手动解除阻塞
constexpr size_type size() const noexcept
获取当前元素数量
shared_ptr< T > lock() const noexcept
尝试获取共享智能指针
constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr bool is_boolean_v
is_boolean的便捷变量模板
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
integer_sequence< size_t, Values... > index_sequence
索引序列
make_integer_sequence< size_t, Size > make_index_sequence
生成指定长度的索引序列
typename inner::__invoke_result_aux< F, Args... >::type invoke_result_t
invoke_result的便捷别名
constexpr bool is_invocable_v
is_invocable的便捷变量模板
constexpr bool is_invocable_r_v
is_invocable_r的便捷变量模板
constexpr size_t erase(Container &cont, const U &value)
从容器中删除所有等于指定值的元素
constexpr Iterator remove_if(Iterator first, Iterator last, Predicate pred)
移除范围中满足谓词的元素
enable_if_t<!is_unbounded_array_v< T > &&is_constructible_v< T, Args... >, shared_ptr< T > > make_shared(Args &&... args)
融合分配创建共享指针
constexpr Iterator2 transform(Iterator1 first, Iterator1 last, Iterator2 result, UnaryOperation op) noexcept(noexcept(++first) &&noexcept(++result) &&noexcept(*result=op(*first)))
对范围元素应用一元变换
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr oneshot_t oneshot
一次性连接标签实例
constexpr decltype(auto) apply(Func &&f, Tuple &&t) noexcept(inner::__apply_unpack_tuple< _NEFORCE is_nothrow_invocable, Func, Tuple >::value)
将元组元素解包作为参数调用函数
constexpr tuple< unwrap_ref_decay_t< Types >... > make_tuple(Types &&... args)
从参数创建元组
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
shared_ptr< bool > block_flag() const noexcept
获取阻塞标志
connection connect(Self self, MemFn memfn, Tag... tag)
连接成员函数(默认优先级0)
bool is_blocked() const noexcept override
void emit_executor(Executor &executor, Types... args)
执行器触发信号
void emit(Types... args)
触发信号
connection connect(Func callback, int priority=0)
连接普通函数/lambda
connection connect_filtered(Func callback, Filter filter, int priority=0)
过滤连接
void disconnect_all() override
断开所有连接
connection connect_transformed(Func callback, Transform transform, int priority=0)
变换连接
connection connect(Self self, MemFn memfn, int priority, Tag... tag)
连接成员函数
void connect_dynamic(function< void(const vector< reflect::meta_any > &)> callback) override
动态连接(类型擦除版本)
void unblock() override
解除阻塞
void emit_dynamic(const vector< reflect::meta_any > &args) override
通过 meta_any 触发信号(类型擦除版本)
connection connect_if(Func callback, Predicate pred, int priority=0)
条件连接
void operator()(Args &&... args)
函数调用操作符
bool empty() const noexcept
检查信号是否为空(无活跃槽)
connection connect_signal(signal &other, int priority=0)
连接另一个信号
size_t slot_count() const noexcept override
获取活跃槽的数量
connection connect_signal(signal *other, int priority=0)
连接另一个信号(指针版本)
void block() override
阻塞信号触发
connection connect_if(Self self, MemFn memfn, Predicate pred, int priority, Tag... tag)
条件连接(成员函数版本)