no virtuals needed Signals, added leaveAll for SignalTracker which must be used before all screens dies.

This commit is contained in:
Henrik Kinnunen 2008-09-21 12:02:49 +02:00
parent 75cf24da28
commit f5113e2ec1
2 changed files with 24 additions and 16 deletions

View file

@ -46,7 +46,7 @@ public:
typedef Iterator SlotID; typedef Iterator SlotID;
typedef SlotList::const_iterator ConstIterator; typedef SlotList::const_iterator ConstIterator;
virtual ~SignalHolder() { } ~SignalHolder() { }
/// Remove a specific slot \c id from this signal /// Remove a specific slot \c id from this signal
void disconnect(SlotID slotIt) { void disconnect(SlotID slotIt) {
@ -81,7 +81,7 @@ class Signal0: public SignalHolder {
public: public:
typedef Slot0<ReturnType> SlotType; typedef Slot0<ReturnType> SlotType;
virtual ~Signal0() { } ~Signal0() { }
void emit() { void emit() {
for ( Iterator it = begin(); it != end(); ++it ) { for ( Iterator it = begin(); it != end(); ++it ) {
@ -101,7 +101,7 @@ class Signal1: public SignalHolder {
public: public:
typedef Slot1<ReturnType, Arg1> SlotType; typedef Slot1<ReturnType, Arg1> SlotType;
virtual ~Signal1() { } ~Signal1() { }
void emit(Arg1 arg) { void emit(Arg1 arg) {
for ( Iterator it = begin(); it != end(); ++it ) { for ( Iterator it = begin(); it != end(); ++it ) {
@ -121,7 +121,7 @@ class Signal2: public SignalHolder {
public: public:
typedef Slot2<ReturnType, Arg1, Arg2> SlotType; typedef Slot2<ReturnType, Arg1, Arg2> SlotType;
virtual ~Signal2() { } ~Signal2() { }
void emit(Arg1 arg1, Arg2 arg2) { void emit(Arg1 arg1, Arg2 arg2) {
for ( Iterator it = begin(); it != end(); ++it ) { for ( Iterator it = begin(); it != end(); ++it ) {
@ -140,7 +140,7 @@ class Signal3: public SignalHolder {
public: public:
typedef Slot3<ReturnType, Arg1, Arg2, Arg3> SlotType; typedef Slot3<ReturnType, Arg1, Arg2, Arg3> SlotType;
virtual ~Signal3() { } ~Signal3() { }
void emit(Arg1 arg1, Arg2 arg2, Arg3 arg3) { void emit(Arg1 arg1, Arg2 arg2, Arg3 arg3) {
for ( Iterator it = begin(); it != end(); ++it ) { for ( Iterator it = begin(); it != end(); ++it ) {
@ -191,15 +191,12 @@ public:
class SignalTracker { class SignalTracker {
public: public:
/// Internal type, do not use. /// Internal type, do not use.
typedef std::map<SigImpl::SignalHolder*, SigImpl::SignalHolder::SlotID> Connections; typedef std::list< std::pair<SigImpl::SignalHolder*,
SigImpl::SignalHolder::SlotID> > Connections;
typedef Connections::iterator TrackID; ///< \c ID type for join/leave. typedef Connections::iterator TrackID; ///< \c ID type for join/leave.
virtual ~SignalTracker() { ~SignalTracker() {
// disconnect all connections leaveAll();
for ( Connections::iterator conIt = m_connections.begin();
conIt != m_connections.end(); ++conIt)
conIt->first->disconnect( conIt->second );
m_connections.clear();
} }
/// Starts tracking a signal. /// Starts tracking a signal.
@ -220,10 +217,22 @@ public:
/// Leave tracking for a signal /// Leave tracking for a signal
/// @param sig the signal to leave /// @param sig the signal to leave
template <typename Signal> template <typename Signal>
void leave(Signal &sig) { void leave(const Signal &sig) {
m_connections.erase(&sig); m_connections.erase(&sig);
} }
void leaveAll() {
// disconnect all connections
for ( Connections::iterator conIt = m_connections.begin();
conIt != m_connections.end(); ) {
// keep temporary, while disconnecting we can
// in some strange cases get a call to this again
Connections::value_type tmp = *conIt;
conIt = m_connections.erase(conIt);
tmp.first->disconnect(tmp.second);
}
}
private: private:
/// holds all connections to different signals and slots. /// holds all connections to different signals and slots.
Connections m_connections; Connections m_connections;

View file

@ -427,11 +427,10 @@ Fluxbox::~Fluxbox() {
// key commands cause a segfault when the XLayerItem is destroyed // key commands cause a segfault when the XLayerItem is destroyed
m_key.reset(0); m_key.reset(0);
leaveAll(); // leave all connections
// destroy screens (after others, as they may do screen things) // destroy screens (after others, as they may do screen things)
while (!m_screen_list.empty()) { while (!m_screen_list.empty()) {
// this needs to be done before the signal is destroyed
leave( m_screen_list.back()->workspaceCountSig() );
delete m_screen_list.back(); delete m_screen_list.back();
m_screen_list.pop_back(); m_screen_list.pop_back();
} }