C++模拟QT信号槽

C++模拟QT信号槽


  1. 测试代码
  //创建信号
  Events event1{};

  //注册信号槽,使用Lambda
  event1 += [](bool flag) {MyLog << "slot1:" << flag; return true; };

  //信号发送
  event1(false);

  MyLog << "--------------------------------------------------------";

  //创建信号2
  auto event2 = MakeEvents();

  //注册信号槽,使用函数指针
  event2->RegisterLastObserver(Slot2);

  //信号发送
  event2->Emit(true);

  MyLog << "--------------------------------------------------------";

  //连接信号
  event1.AddLastPipeLine(event2);

  //信号发送
  event1.Emit(false);

  MyLog << "--------------------------------------------------------";
  1. 测试结果
测试结果
  1. 代码实现
template
class Events :
  protected NoCopiable
{
  using EventsWeakPtr = std::weak_ptr;
  using EventsSharedPtr = std::shared_ptr;
public:
  //true 事件放行
  using stl_func_type = std::function ;

  template
  void operator+=(Fn &&func)
  {
    observers_.push_back(std::forward(func));
  }

  template
  void operator-=(Fn &&func)
  {
    observers_.push_front(std::forward(func));
  }

  template
  void RegisterLastObserver(Fn &&func)
  {
    operator +=(std::forward(func));
  }

  template
  void RegisterFirstObserver(Fn &&func)
  {
    operator -=(std::forward(func));
  }

  void AddLastPipeLine(EventsWeakPtr e_other)
  {
    observers_.push_back([e_other](Args&&...args)
    {
      if (auto sp = e_other.lock()) {
        return (*sp)(std::forward(args)...);
      } else {
        return true;
      }
    });
  }

  void AddFirstPipeLine(EventsWeakPtr e_other)
  {
    observers_.push_front([e_other](Args&&...args)
    {
      if (auto sp = e_other.lock()) {
        return (*sp)(std::forward(args)...);
      } else {
        return true;
      }
    });
  }

  void operator+=(EventsWeakPtr e_other) { AddLastPipeLine(e_other); }
  void operator-=(EventsWeakPtr e_other) { AddFirstPipeLine(e_other); }

  void operator+=(EventsSharedPtr e_other) { AddLastPipeLine(e_other); }
  void operator-=(EventsSharedPtr e_other) { AddFirstPipeLine(e_other); }

  template
  bool operator()(_Args&&...args)
  {
    return Emit(std::forward(args)...);
  }

  template
  bool Emit(_Args&&...args)
  {
    return std::find_if(observers_.begin(), observers_.end(), [&](stl_func_type const&fn) {
      return !fn(std::forward(args)...);
    }) == observers_.end();
  }

private:
  std::list observers_;
};

template
using EventsPtr = std::shared_ptr>;

template
inline decltype(auto) MakeEvents()
{
  return std::make_shared>();
}

更多内容详见 helper/event_observer.h

你可能感兴趣的:(C++模拟QT信号槽)