Skip to content

Instantly share code, notes, and snippets.

@jeffomatic
Created August 2, 2012 05:28
Show Gist options
  • Save jeffomatic/3233989 to your computer and use it in GitHub Desktop.
Save jeffomatic/3233989 to your computer and use it in GitHub Desktop.
blog: jl_signal, code: inheritance-based delegate
// For the purposes of this example, let's assume our slots only accept
// one parameter.
template< typename TSlotParam >
class Delegate
{
public:
virtual ~Delegate() {}
virtual void Invoke( TSlotParam v ) = 0;
};
template< typename TSlotParam, class TObserver >
class TypeSpecificDelegate : Delegate< TSlotParam >
{
public:
TObserver* m_pObserver;
void (TObserver::*m_fpSlot)( TSlotParam );
public:
TypeSpecificDelegate(
TObserver* pObserver,
void (TObserver::*fpSlot)(TSlotParam) )
: m_pObserver( pObserver )
, m_fpSlot( fpSlot )
{
// do nothing
}
void Invoke( TSlotParam v )
{
pObserver->*fpSlot(v);
}
};
template< typename TSlotParam >
class Signal
{
typedef Delegate< TSlotParam > TDelegate;
typedef std::vector< TDelegate* > DelegateList;
Delegate m_oDelegates;
public:
template< class TObserver, class TObserverDerived >
void Connect(
TObserverDerived* pObserverDerived,
void (TObserver::*fpSlot)(TSlotParam) )
{
// This gives us the correct pointer in cases where
// multiple inheritance is involved.
TObserver* p = static_cast< TObserver* >( pObserverDerived );
// Add our delegate to the list
m_oDelegates.push_back(
new TypeSpecificDelegate<TSlotParam, TObserver>(p, fpSlot)
);
}
void Emit( TSlotParam v )
{
for ( DelegateList::iterator i = m_oDelegates.begin();
i != m_oDelegates.end();
++i )
{
i->Invoke( v );
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment