Rose
Signals.h
Go to the documentation of this file.
1 
9 #pragma once
10 
11 #include <memory>
12 #include <functional>
13 #include <vector>
14 
15 namespace rose {
16 
24  template<typename ... Args>
25  struct Slot : public std::enable_shared_from_this<Slot<Args...>> {
26  using signal_function = std::function<void(Args...)>;
27 
28  signal_function receiver{};
29  };
30 
39  template<typename ... Args>
40  class Signal {
41  protected:
42  std::vector<std::weak_ptr<Slot<Args...>>> callList{};
43 
44  public:
45  using signal_function = std::function<void(Args...)>;
46 
47  explicit operator bool () {
48  return !callList.empty();
49  }
50 
54  void clean() {
55  callList.erase(std::remove_if(callList.begin(), callList.end(), [](auto weak) {
56  return weak.expired();
57  }), callList.end());
58  }
59 
64  void connect(std::shared_ptr<Slot<Args...>> &slot) {
65  if (slot) {
66  clean();
67  for (auto &weak : callList) {
68  if (auto locked = weak.lock(); locked) {
69  if (locked == slot)
70  return;
71  }
72  }
73 
74  callList.push_back(slot);
75  }
76  }
77 
82  void disconnect(std::shared_ptr<Slot<Args...>> &slot) {
83  callList.erase(std::remove_if(callList.begin(), callList.end(), [&](auto weak) {
84  if (weak.expired())
85  return true;
86  if (auto strong = weak.lock(); strong)
87  return strong == slot;
88  return false;
89  }));
90  }
91 
96  void transmit(Args ... args) {
97  bool expired = false;
98  for (auto &weak : callList) {
99  if (auto slot = weak.lock(); slot) {
100  if (slot->receiver)
101  slot->receiver(args...);
102  } else {
103  expired = true;
104  }
105  }
106 
107  if (expired)
108  clean();
109  }
110  };
111 
121  template<typename ... Args>
122  struct Protocol {
123  typedef std::shared_ptr<Slot<Args...>> slot_type;
124  typedef Signal<Args...> signal_type;
125 
131  return std::make_shared<Slot<Args...>>();
132  }
133  };
134 
135 }
A convenience structure that composes Signal and Slot types from a protocol signature, and provides a Slot factory.
Definition: Signals.h:122
void disconnect(std::shared_ptr< Slot< Args... >> &slot)
Disconnect a Slot from the Signal, if it is connected.
Definition: Signals.h:82
static slot_type createSlot()
The Protocol Slot factory.
Definition: Signals.h:130
std::shared_ptr< Slot< Args... > > slot_type
Composed Slot type.
Definition: Signals.h:123
void transmit(Args ... args)
Transmit the Signal data to all connected and non-expired Slots.
Definition: Signals.h:96
Signal< Args... > signal_type
Composed Signal type.
Definition: Signals.h:124
void clean()
Groom the Slot list.
Definition: Signals.h:54
void connect(std::shared_ptr< Slot< Args... >> &slot)
Connect a Slot to the Signal only if it has not already been connected.
Definition: Signals.h:64
ToDo: There is an issue that the initial scroll interaction is lost if the click/press lands on a Wid...
Definition: CelestialOverlay.cpp:13
The transmitter portion of a Signal-Slot transmitter receiver pair.
Definition: Signals.h:40
The receiver portion of a Signal-Slot transmitter receiver pair.
Definition: Signals.h:25