Signal.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006-2010 Jacek Sieka, arnetheduck on gmail point com
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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
Generated on Sat Nov 27 23:37:53 2010 for adchpp by  doxygen 1.6.3