1 // Copyright 2003 "Gilles Degottex"
3 // This file is part of "CppAddons"
5 // "CppAddons" is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation; either version 2.1 of the License, or
8 // (at your option) any later version.
10 // "CppAddons" is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <algorithm> // for: find
28 template<class Listener> class Talker;
30 template<class TListener>
33 friend class Talker<TListener>;
38 void todo(const string& fn){cerr << typeid(this).name() << "::" << fn << " not yet implemented" << endl;}
41 Listener() : m_isListenning(false) {}
43 bool isListenning() {return m_isListenning;}
46 template<class TListener, class TypeEvent>
49 void (TListener::*m_pfOccured)(TypeEvent*);
54 explicit FireFun(void (TListener::*pfOccured)(TypeEvent*), TypeEvent* evt)
55 : m_pfOccured(pfOccured), m_evt(evt)
58 void operator()(TListener* l) const {(l->*m_pfOccured)(m_evt);}
61 template<class SourceType>
67 EventObject(SourceType* source) : m_obj(source) {}
69 SourceType* getSource() const {return m_obj;}
72 template<class Listener>
76 typedef Listener TypeListener;
77 typedef list<TypeListener*> ListenersList;
78 typedef typename ListenersList::iterator ListenersIterator;
81 ListenersList m_removed;
85 ListenersList m_listeners;
90 while(!m_removed.empty())
92 m_removed.front()->m_isListenning = false;
93 m_listeners.remove(m_removed.front());
94 m_removed.pop_front();
98 #define MFireEventL(s, L) {Talker<L>::m_firing=true;for(Talker<L>::ListenersList::iterator _listenerIterator_=(Talker<L>::m_listeners).begin(); _listenerIterator_!=(Talker<L>::m_listeners).end(); ++_listenerIterator_) (*_listenerIterator_)->s;Talker<L>::m_firing=false;Talker<L>::removeRemoved();}
99 #define MFireEvent(s) MFireEventL(s, TypeListener)
101 template<typename TypeEvent>
102 void fireEvent(void (Listener::*fOccured)(TypeEvent*), TypeEvent* evt)
105 for_each( (Talker<Listener>::m_listeners).begin(),
106 (Talker<Listener>::m_listeners).end(),
107 FireFun<Listener, TypeEvent>(fOccured, evt));
113 Talker() : m_firing(false) {}
115 bool hasListeners(){return !m_listeners.empty();}
116 bool hasListener(Listener* l)
118 return find(m_listeners.begin(), m_listeners.end(), l)!=m_listeners.end();
120 void addListener(Listener* l)
122 m_listeners.push_back(l); // discutable: back/front
124 l->m_isListenning = true;
126 void removeListener(Listener* l)
128 if(m_firing) m_removed.push_back(l);
131 m_listeners.remove(l);
132 l->m_isListenning = false;
135 void toggleListener(Listener* l)
137 if(hasListener(l)) addListener(l);
138 else removeListener(l);
141 list<Listener*>& getListeners(){return m_listeners;}