mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Handle deletion of SignalObservers
Add a beingDeleted signal called in the SignalObserver destructor.
This commit is contained in:
@@ -44,18 +44,77 @@
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class SignalObserver
|
||||
class SignalEmitter;
|
||||
class SignalObserver;
|
||||
|
||||
//==================================================================================================
|
||||
/// Basic delete signal emitted by any observer when deleted.
|
||||
/// Allows a regular signal to disconnect from the observer.
|
||||
//==================================================================================================
|
||||
class DeleteSignal
|
||||
{
|
||||
public:
|
||||
virtual ~SignalObserver() = default;
|
||||
using DisconnectCallback = std::function<void( SignalObserver* )>;
|
||||
|
||||
DeleteSignal( SignalObserver* observer )
|
||||
: m_observer( observer )
|
||||
{
|
||||
}
|
||||
|
||||
template <typename ClassType>
|
||||
void connect( ClassType* signal )
|
||||
{
|
||||
static_assert( std::is_convertible<ClassType*, SignalObserver*>::value,
|
||||
"Only classes that inherit SignalObserver can connect as an observer of a Signal." );
|
||||
|
||||
DisconnectCallback lambda = [=]( SignalObserver* observer ) { ( signal->disconnect )( observer ); };
|
||||
auto signalCasted = dynamic_cast<SignalObserver*>( signal );
|
||||
|
||||
if ( signalCasted ) m_disconnectCallbacks[signalCasted] = lambda;
|
||||
}
|
||||
void disconnect( SignalObserver* observer ) { m_disconnectCallbacks.erase( observer ); }
|
||||
void send()
|
||||
{
|
||||
for ( auto signalCallbackPair : m_disconnectCallbacks )
|
||||
{
|
||||
signalCallbackPair.second( m_observer );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<SignalObserver*, DisconnectCallback> m_disconnectCallbacks;
|
||||
|
||||
SignalObserver* m_observer;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// SignalEmitter
|
||||
/// Should be inherited by any object that emits signals.
|
||||
//==================================================================================================
|
||||
class SignalEmitter
|
||||
{
|
||||
public:
|
||||
virtual ~SignalEmitter() = default;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// SignalObserver.
|
||||
/// Should be inherited by any object that observes and reacts to signals.
|
||||
//==================================================================================================
|
||||
class SignalObserver
|
||||
{
|
||||
public:
|
||||
DeleteSignal beingDeleted;
|
||||
|
||||
public:
|
||||
SignalObserver()
|
||||
: beingDeleted( this )
|
||||
{
|
||||
}
|
||||
virtual ~SignalObserver() { beingDeleted.send(); }
|
||||
|
||||
}; // namespace caf
|
||||
|
||||
//==================================================================================================
|
||||
/// General signal class.
|
||||
/// Connect any member function with the signature void(const Signal*, const SignalData* data)
|
||||
@@ -63,7 +122,7 @@ public:
|
||||
/// The method should accept that data may be nullptr
|
||||
//==================================================================================================
|
||||
template <typename... Args>
|
||||
class Signal
|
||||
class Signal : public SignalObserver
|
||||
{
|
||||
public:
|
||||
using MemberCallback = std::function<void( const SignalEmitter*, Args... args )>;
|
||||
@@ -74,7 +133,13 @@ public:
|
||||
: m_emitter( emitter )
|
||||
{
|
||||
}
|
||||
virtual ~Signal() = default;
|
||||
virtual ~Signal()
|
||||
{
|
||||
for ( auto observerCallbackPair : m_observerCallbacks )
|
||||
{
|
||||
observerCallbackPair.first->beingDeleted.disconnect( this );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ClassType>
|
||||
void connect( ClassType* observer, void ( ClassType::*method )( const SignalEmitter*, Args... args ) )
|
||||
@@ -86,9 +151,14 @@ public:
|
||||
( observer->*method )( emitter, args... );
|
||||
};
|
||||
m_observerCallbacks[observer] = std::make_pair( lambda, true );
|
||||
observer->beingDeleted.connect( this );
|
||||
}
|
||||
|
||||
void disconnect( SignalObserver* observer ) { m_observerCallbacks.erase( observer ); }
|
||||
void disconnect( SignalObserver* observer )
|
||||
{
|
||||
m_observerCallbacks.erase( observer );
|
||||
observer->beingDeleted.disconnect( this );
|
||||
}
|
||||
void send( Args... args )
|
||||
{
|
||||
for ( auto observerCallbackPair : m_observerCallbacks )
|
||||
|
||||
Reference in New Issue
Block a user