#pragma once #include // std::enable_if, std::is_constructible, etc #include // std::invoke #include "tl/functional.h" #include "tl/vector_map.h" #include "tl/unordered_map.h" #include "tl/hash_and_combine.h" #include "tl/memory_buffer.h" #include "tl/detail/internal_assert.h" #include "tl/atomic.h" #include #include "compact_signal.h" namespace tl { namespace detail { struct signal_mt_thread_policy { using mutex_t = std::mutex; using connection_id_counter_t = tl::atomic; using data_ptr_t = tl::atomic; }; } using signal_system_mt = signal_system; using connection_mt = signal_system_mt::scoped_connection; template class signal_mt; template class signal_mt { public: signal_mt() noexcept = default; signal_mt(const signal_mt&) noexcept = delete; signal_mt(signal_mt&&) noexcept = delete; ~signal_mt() noexcept { disconnect_all_slots(); } signal_mt& operator=(const signal_mt&) = delete; signal_mt& operator=(signal_mt&&) = delete; connection_mt connect(tl::function delegate) noexcept { return signal_system_mt::add((intptr_t)this, 0, std::move(delegate)); } void invoke(Args... args) const noexcept { signal_system_mt::invoke((intptr_t)this, 0, std::forward(args)...); } void disconnect_all_slots() const noexcept { signal_system_mt::remove_all((intptr_t)this); } bool has_slots() const { return signal_system_mt::get_slot_count((intptr_t)this, 0) > 0; } }; }