| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- #ifndef SOPHIAR2_TINY_SIGNAL_HPP
- #define SOPHIAR2_TINY_SIGNAL_HPP
- #include <boost/intrusive/list.hpp>
- #include <spdlog/spdlog.h>
- #include <cassert>
- #include <type_traits>
- #include <utility>
- namespace sophiar {
- using slot_hook_type = boost::intrusive::list_base_hook<
- boost::intrusive::link_mode<
- boost::intrusive::auto_unlink>>;
- struct [[deprecated]] tiny_slot_base : public slot_hook_type {
- bool is_enabled = true;
- virtual ~tiny_slot_base() = default;
- void disconnect() {
- assert(this->is_linked());
- this->unlink();
- SPDLOG_TRACE("Slot {} is disconnected.", fmt::ptr(this));
- }
- };
- struct tiny_signal_base {
- virtual ~tiny_signal_base() = default;
- virtual void add_slot_base(tiny_slot_base *slot_base) = 0;
- };
- template<typename... Args>
- class [[deprecated]] tiny_signal : public tiny_signal_base {
- public:
- class slot_type : public tiny_slot_base {
- public:
- void signal_received(Args... args) {
- if (!is_enabled) return;
- on_signal_received(std::move(args)...);
- }
- protected:
- virtual void on_signal_received(Args... args) = 0;
- };
- void add_slot_base(tiny_slot_base *slot_base) override {
- auto slot_ptr = dynamic_cast<slot_type *>(slot_base);
- assert(slot_ptr != nullptr);
- slot_list.push_back(*slot_ptr);
- SPDLOG_TRACE("Slot {} is connected to signal {}.",
- fmt::ptr(slot_ptr), fmt::ptr(this));
- }
- void emit(Args... args) {
- auto iter = slot_list.begin(), iter_end = slot_list.end();
- while (iter != iter_end) {
- auto this_iter = iter++;
- if (iter == iter_end) {
- this_iter->signal_received(std::move(args)...);
- } else {
- this_iter->signal_received(args...);
- }
- }
- }
- private:
- using slot_list_type = boost::intrusive::list<
- slot_type, boost::intrusive::constant_time_size<false>>;
- slot_list_type slot_list;
- };
- }
- #endif //SOPHIAR2_TINY_SIGNAL_HPP
|