tiny_signal.hpp 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #ifndef SOPHIAR2_TINY_SIGNAL_HPP
  2. #define SOPHIAR2_TINY_SIGNAL_HPP
  3. #include <boost/intrusive/list.hpp>
  4. #include <type_traits>
  5. namespace sophiar {
  6. template<typename... Args>
  7. class signal_muxer;
  8. template<typename... Args>
  9. class tiny_signal {
  10. public:
  11. using muxer_type = signal_muxer<Args...>;
  12. using hook_type = boost::intrusive::list_base_hook<
  13. boost::intrusive::link_mode<
  14. boost::intrusive::auto_unlink>>;
  15. // 其他对象不得持有 listener
  16. // 所有调用应该以引用进行
  17. struct listener_type : public hook_type {
  18. virtual ~listener_type() = default;
  19. virtual void on_signal_received(Args... args) = 0;
  20. };
  21. using list_type = boost::intrusive::list<
  22. listener_type, boost::intrusive::constant_time_size<false>>;
  23. void add_listener(listener_type &node) {
  24. if (node.is_linked()) {
  25. node.unlink();
  26. }
  27. node_list.push_back(node);
  28. }
  29. void emit_signal(Args... args) {
  30. for (auto &node: node_list) {
  31. node.on_signal_received(args...);
  32. }
  33. }
  34. private:
  35. list_type node_list;
  36. };
  37. }
  38. #endif //SOPHIAR2_TINY_SIGNAL_HPP