mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-14 16:14:38 +00:00
Add SlotSignal for handle automatic disconnect on Signal or SignalSlot destruction.
Example:
```
Win32WindowManager::Win32WindowManager()
{
// Register in the process list.
mOnProcessSignalSlot.setDelegate( this, &Win32WindowManager::_process );
Process::notify( mOnProcessSignalSlot, PROCESS_INPUT_ORDER );
// When Signal it's destroyed, all slots are disconected.
// When a SignalSlot it's destroyed, it's disconected from Signal.
}
```
This commit is contained in:
parent
aca58356ee
commit
0137c86765
1 changed files with 103 additions and 0 deletions
|
|
@ -77,6 +77,8 @@ protected:
|
||||||
|
|
||||||
void insert(DelegateLink* node, F32 order);
|
void insert(DelegateLink* node, F32 order);
|
||||||
void unlink();
|
void unlink();
|
||||||
|
|
||||||
|
virtual ~DelegateLink() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
DelegateLink mList;
|
DelegateLink mList;
|
||||||
|
|
@ -92,6 +94,78 @@ protected:
|
||||||
Vector<DelegateLink*> mTriggerNext;
|
Vector<DelegateLink*> mTriggerNext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Signature> class SignalBaseT;
|
||||||
|
|
||||||
|
/// Class for handle automatic diconnect form Signal when destroyed
|
||||||
|
template< typename Signature >
|
||||||
|
class SignalSlot
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Delegate< Signature > DelegateSig;
|
||||||
|
typedef SignalBaseT< Signature > SignalSig;
|
||||||
|
|
||||||
|
SignalSlot() : mSignal(NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~SignalSlot()
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
const DelegateSig& getDelegate() { return mDlg; }
|
||||||
|
|
||||||
|
/// setDelegate disconect form Signal old delegate and connect new delegate
|
||||||
|
template<typename X>
|
||||||
|
void setDelegate( const X &fn ) { setDelegate( DelegateSig( fn ) ); }
|
||||||
|
|
||||||
|
template<typename X, typename Y>
|
||||||
|
void setDelegate( const X &ptr, const Y &fn ) { setDelegate( DelegateSig( ptr, fn ) ); }
|
||||||
|
|
||||||
|
void setDelegate( const DelegateSig &dlg)
|
||||||
|
{
|
||||||
|
SignalSig* signal = mSignal;
|
||||||
|
if( isConnected() )
|
||||||
|
disconnect();
|
||||||
|
|
||||||
|
mDlg = dlg;
|
||||||
|
if( signal && mDlg )
|
||||||
|
signal->notify( mDlg );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// is connected to Signal
|
||||||
|
bool isConnected() const { return mSignal; }
|
||||||
|
|
||||||
|
/// disconnect from Signal
|
||||||
|
void disconnect()
|
||||||
|
{
|
||||||
|
if( mSignal )
|
||||||
|
{
|
||||||
|
SignalSig *oldSignal = mSignal;
|
||||||
|
mSignal = NULL;
|
||||||
|
oldSignal->remove( mDlg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class SignalSig;
|
||||||
|
|
||||||
|
void _setSignal(SignalSig *sig)
|
||||||
|
{
|
||||||
|
mSignal = sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalSig* _getSignal() const { return mSignal; }
|
||||||
|
|
||||||
|
DelegateSig mDlg;
|
||||||
|
SignalSig *mSignal;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SignalSlot( const SignalSlot&) {}
|
||||||
|
SignalSlot& operator=( const SignalSlot&) {}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Signature> class SignalBaseT : public SignalBase
|
template<typename Signature> class SignalBaseT : public SignalBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -163,6 +237,18 @@ public:
|
||||||
notify(dlg, order);
|
notify(dlg, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void notify( SignalSlot<Signature> &slot, F32 order = 0.5f)
|
||||||
|
{
|
||||||
|
if( !slot.getDelegate() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( slot.isConnected() )
|
||||||
|
slot.disconnect();
|
||||||
|
|
||||||
|
slot._setSignal( this );
|
||||||
|
mList.insert( new SlotLinkImpl(slot), order );
|
||||||
|
}
|
||||||
|
|
||||||
template <class T,class U>
|
template <class T,class U>
|
||||||
void remove(T obj,U func)
|
void remove(T obj,U func)
|
||||||
{
|
{
|
||||||
|
|
@ -198,6 +284,23 @@ protected:
|
||||||
DelegateLinkImpl(DelegateSig dlg) : mDelegate(dlg) {}
|
DelegateLinkImpl(DelegateSig dlg) : mDelegate(dlg) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SlotLinkImpl : public DelegateLinkImpl
|
||||||
|
{
|
||||||
|
SlotLinkImpl(SignalSlot<Signature>& slot) : mSlot( &slot ), DelegateLinkImpl( slot.getDelegate() )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~SlotLinkImpl()
|
||||||
|
{
|
||||||
|
if( mSlot )
|
||||||
|
mSlot->_setSignal( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SignalSlot<Signature> *mSlot;
|
||||||
|
};
|
||||||
|
|
||||||
DelegateSig & getDelegate(SignalBase::DelegateLink * link)
|
DelegateSig & getDelegate(SignalBase::DelegateLink * link)
|
||||||
{
|
{
|
||||||
return ((DelegateLinkImpl*)link)->mDelegate;
|
return ((DelegateLinkImpl*)link)->mDelegate;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue