Signal.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef ADCHPP_SIGNAL_H
00020 #define ADCHPP_SIGNAL_H
00021
00022 namespace adchpp {
00023
00024 struct Connection : private boost::noncopyable {
00025 public:
00026 Connection() { }
00027 virtual ~Connection() { }
00028
00029 virtual void disconnect() = 0;
00030 };
00031
00032 typedef std::unique_ptr<Connection> ConnectionPtr;
00033
00034 template<typename F>
00035 class Signal {
00036 public:
00037 typedef std::function<F> Slot;
00038 typedef std::list<Slot> SlotList;
00039 typedef F FunctionType;
00040
00041 template<typename T0>
00042 void operator()(T0&& t0) {
00043 for(auto i = slots.begin(), iend = slots.end(); i != iend;) {
00044 (*i++)(std::forward<T0>(t0));
00045 }
00046 }
00047
00048 template<typename T0, typename T1>
00049 void operator()(T0&& t0, T1&& t1) {
00050 for(auto i = slots.begin(), iend = slots.end(); i != iend;) {
00051 (*i++)(std::forward<T0>(t0), std::forward<T1>(t1));
00052 }
00053 }
00054
00055 template<typename T0, typename T1, typename T2>
00056 void operator()(T0&& t0, T1&& t1, T2&& t2) {
00057 for(auto i = slots.begin(), iend = slots.end(); i != iend;) {
00058 (*i++)(std::forward<T0>(t0), std::forward<T1>(t1), std::forward<T2>(t2));
00059 }
00060 }
00061
00062 template<typename T>
00063 ConnectionPtr connect(const T& f) { return ConnectionPtr(new SlotConnection(this, slots.insert(slots.end(), f))); }
00064
00065 ~Signal() { }
00066 private:
00067 SlotList slots;
00068
00069 void disconnect(const typename SlotList::iterator& i) {
00070 slots.erase(i);
00071 }
00072
00073 struct SlotConnection : public Connection {
00074 SlotConnection(Signal<F>* sig_, const typename SlotList::iterator& i_) : sig(sig_), i(i_) { }
00075
00076 virtual void disconnect() { if(sig) sig->disconnect(i), sig = 0; }
00077 Signal<F>* sig;
00078 typename Signal<F>::SlotList::iterator i;
00079 };
00080 };
00081
00082 struct ManagedConnection : private boost::noncopyable {
00083 ManagedConnection(ConnectionPtr&& conn_) : conn(move(conn_)) {
00084 }
00085
00086 void disconnect() {
00087 if(conn.get()) {
00088 conn->disconnect();
00089 conn.reset();
00090 }
00091 }
00092
00093 void release() {
00094 conn.reset();
00095 }
00096
00097 ~ManagedConnection() {
00098 disconnect();
00099 }
00100 private:
00101 ConnectionPtr conn;
00102 };
00103
00104 typedef shared_ptr<ManagedConnection> ManagedConnectionPtr;
00105
00106 template<typename F1, typename F2>
00107 ManagedConnectionPtr manage(Signal<F1>* signal, const F2& f) {
00108 return make_shared<ManagedConnection>(signal->connect(f));
00109 }
00110
00111 template<typename F>
00112 struct SignalTraits {
00113 typedef adchpp::Signal<F> Signal;
00114 typedef adchpp::ConnectionPtr Connection;
00115 typedef adchpp::ManagedConnectionPtr ManagedConnection;
00116 };
00117
00118 }
00119
00120 #endif // SIGNAL_H