From 144d716a42072bd59f6c99e95e86be4486285782 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Mon, 2 May 2011 15:10:42 +0200 Subject: Simplify Slot.hh Replace CallbackHolder, FunctorHolder and SlotHolder with a (smaller) set of polymorphic classes. SignalHolder now stores a (smart) pointer to the class. --- src/FbTk/Signal.hh | 49 +++++----- src/FbTk/Slot.hh | 275 +++++++++-------------------------------------------- 2 files changed, 70 insertions(+), 254 deletions(-) diff --git a/src/FbTk/Signal.hh b/src/FbTk/Signal.hh index 79d001f..71a4d6e 100644 --- a/src/FbTk/Signal.hh +++ b/src/FbTk/Signal.hh @@ -22,6 +22,7 @@ #ifndef FBTK_SIGNAL_HH #define FBTK_SIGNAL_HH +#include "RefCount.hh" #include "Slot.hh" #include #include @@ -49,7 +50,7 @@ public: }; /// Do not use this type outside this class - typedef std::list SlotList; + typedef std::list > SlotList; typedef SlotList::iterator Iterator; typedef Iterator SlotID; @@ -91,7 +92,7 @@ protected: Iterator end() { return m_slots.end(); } /// Connect a slot to this signal. Must only be called by child classes. - SlotID connect(const SlotHolder& slot) { + SlotID connect(const RefCount& slot) { return m_slots.insert(m_slots.end(), slot); } @@ -111,16 +112,17 @@ template class Signal: public SigImpl::SignalHolder { public: - typedef SigImpl::Slot3 SlotType; - void emit(Arg1 arg1, Arg2 arg2, Arg3 arg3) { for ( Iterator it = begin(); it != end(); ++it ) { - static_cast(*it)(arg1, arg2, arg3); + static_cast &>(**it)(arg1, arg2, arg3); } } - SlotID connect(const SlotType& slot) { - return SignalHolder::connect(slot); + template + SlotID connect(const Functor& functor) { + return SignalHolder::connect(FbTk::RefCount( + new SigImpl::Slot3(functor) + )); } }; @@ -128,16 +130,17 @@ public: template class Signal: public SigImpl::SignalHolder { public: - typedef SigImpl::Slot2 SlotType; - void emit(Arg1 arg1, Arg2 arg2) { for ( Iterator it = begin(); it != end(); ++it ) { - static_cast(*it)(arg1, arg2); + static_cast &>(**it)(arg1, arg2); } } - SlotID connect(const SlotType& slot) { - return SignalHolder::connect(slot); + template + SlotID connect(const Functor& functor) { + return SignalHolder::connect(FbTk::RefCount( + new SigImpl::Slot2(functor) + )); } }; @@ -145,16 +148,17 @@ public: template class Signal: public SigImpl::SignalHolder { public: - typedef SigImpl::Slot1 SlotType; - void emit(Arg1 arg) { for ( Iterator it = begin(); it != end(); ++it ) { - static_cast(*it)(arg); + static_cast &>(**it)(arg); } } - SlotID connect(const SlotType& slot) { - return SignalHolder::connect(slot); + template + SlotID connect(const Functor& functor) { + return SignalHolder::connect(FbTk::RefCount( + new SigImpl::Slot1(functor) + )); } }; @@ -162,16 +166,17 @@ public: template class Signal: public SigImpl::SignalHolder { public: - typedef SigImpl::Slot0 SlotType; - void emit() { for ( Iterator it = begin(); it != end(); ++it ) { - static_cast(*it)(); + static_cast &>(**it)(); } } - SlotID connect(const SlotType& slot) { - return SignalHolder::connect(slot); + template + SlotID connect(const Functor& functor) { + return SignalHolder::connect(FbTk::RefCount( + new SigImpl::Slot0(functor) + )); } }; diff --git a/src/FbTk/Slot.hh b/src/FbTk/Slot.hh index 9080d53..3daca4e 100644 --- a/src/FbTk/Slot.hh +++ b/src/FbTk/Slot.hh @@ -27,268 +27,79 @@ namespace FbTk { /// \namespace Implementation details for signals, do not use anything in this namespace namespace SigImpl { -class CallbackHolder; - -/// Placeholder type for typed callbacks -typedef void* (*CallbackFunc)(void *); -/// Clone function callback type for cloning typed callback holders -typedef CallbackHolder* (*CloneFunc)(CallbackHolder*); -/// Kill function callback type for destroying type specific information in -/// FunctorHolder -typedef void (*KillFunc)(CallbackHolder*); - -/// Holds clone, functor callback, and the kill function for FunctorHolder. -class CallbackHolder { +class SlotBase { public: - /** - * @param callback The callback to call when a slot receives a signal. - * @param clone The callback to use for cloning a type specific instance of - * this classinstance. - * @param kill The callback that knows how to free the memory in type - * specific instance of this class. - */ - CallbackHolder(CallbackFunc callback, - CloneFunc clone, - KillFunc kill): - m_callback(callback), - m_kill(kill), - m_clone(clone) { } - - ~CallbackHolder() { - (*m_kill)(this); - } - - /// @return a clone of this instance - CallbackHolder* clone() { - return (*m_clone)(this); - } - - /// \c Callback to \c Functor specific callback - CallbackFunc m_callback; - -protected: - - CallbackHolder& operator = (const CallbackHolder& other) { - if ( this == &other ) { - return *this; - } - m_callback = other.m_callback; - m_clone = other.m_clone; - m_kill = other.m_kill; - - return *this; - } - - CallbackHolder(const CallbackHolder& other) { - *this = other; - } - -private: - /// This function is called to kill this instance - KillFunc m_kill; - /// Functions that knows how to clone a specific \c Functor type - CloneFunc m_clone; + virtual ~SlotBase() {} }; - -/// Holds the functor and creates a clone callback for \c Functor specific type -template -class FunctorHolder: public CallbackHolder { +template +class SlotBase0: public SlotBase { public: - /// This type. - typedef FunctorHolder Self; - /** - * @param functor The functor to be used when a signal is emitted. - * @param callback The callback to call when a signal is emitted. - */ - FunctorHolder(const Functor& functor, CallbackFunc callback): - CallbackHolder(callback, &clone, &kill), - m_functor(functor) { - } - - /// Specific clone for this Functor type - static CallbackHolder* clone(CallbackHolder* self) { - return new Self( static_cast(*self)); - } - - static void kill(CallbackHolder* self) { - // Destroy functor - static_cast( self )->m_functor.~Functor(); - } - - Functor m_functor; ///< the functor to use when a signal is emitted. -}; - - - -/// Callback with no arguments. -template -struct Callback0 { - static ReturnType callback(CallbackHolder* base) { - static_cast< FunctorHolder* >( base )->m_functor(); - return ReturnType(); - } - - static CallbackFunc functionAddress() { - return reinterpret_cast(&callback); - } + virtual ReturnType operator()() = 0; }; -/// Callback with one argument -template -struct Callback1 { - typedef ReturnType (Functor::* CallbackType)(CallbackHolder*, Arg1); - - static ReturnType callback(CallbackHolder* base, Arg1 arg1) { - static_cast< FunctorHolder* >( base )->m_functor(arg1); - return ReturnType(); - } - - static CallbackFunc functionAddress() { - return reinterpret_cast(&callback); - } -}; - -/// Callback with two arguments -template -struct Callback2 { - typedef ReturnType (Functor::* CallbackType)(CallbackHolder*, Arg1, Arg2); +template +class Slot0: public SlotBase0 { +public: + virtual ReturnType operator()() { return m_functor(); } - static ReturnType callback(CallbackHolder* base, Arg1 arg1, Arg2 arg2) { - static_cast< FunctorHolder* >( base )->m_functor(arg1, arg2); - return ReturnType(); - } + Slot0(Functor functor) : m_functor(functor) {} - static CallbackFunc functionAddress() { - return reinterpret_cast(&callback); - } +private: + Functor m_functor; }; -/// Callback with three arguments -template -struct Callback3 { - typedef ReturnType (Functor::* CallbackType)(CallbackHolder*, Arg1, Arg2, Arg3); - - static ReturnType callback(CallbackHolder* base, Arg1 arg1, Arg2 arg2, Arg3 arg3) { - static_cast< FunctorHolder* >( base )->m_functor( arg1, arg2, arg3 ); - return ReturnType(); - } - - static CallbackFunc functionAddress() { - return reinterpret_cast(&callback); - } +template +class SlotBase1: public SlotBase { +public: + virtual ReturnType operator()(Arg1) = 0; }; -/// Holds callback holder and handles the copying of callback holders for the -/// \c Slots. -class SlotHolder { +template +class Slot1: public SlotBase1 { public: - SlotHolder(const SlotHolder& other): - m_holder( other.m_holder ? other.m_holder->clone() : 0 ) { - } - - ~SlotHolder() { - delete m_holder; - } - - SlotHolder& operator = (const SlotHolder& other) { - if ( &other == this ) { - return *this; - } - delete m_holder; - if ( other.m_holder ) { - m_holder = other.m_holder->clone(); - } else { - m_holder = 0; - } - return *this; - } + virtual ReturnType operator()(Arg1 arg1) { return m_functor(arg1); } - SlotHolder():m_holder( 0 ) { } + Slot1(Functor functor) : m_functor(functor) {} -protected: - explicit SlotHolder(CallbackHolder* holder): - m_holder( holder ) { - } - - CallbackHolder* m_holder; +private: + Functor m_functor; }; -/// Slot with no argument. -template -class Slot0: public SlotHolder { +template +class SlotBase2: public SlotBase { public: - typedef ReturnType (*CallbackType)(CallbackHolder*); - - template - Slot0( const Functor& functor ): - SlotHolder( new FunctorHolder - (functor, Callback0::functionAddress())) { - } - - void operator()() { - if (m_holder) - reinterpret_cast(m_holder->m_callback)( m_holder ); - } + virtual ReturnType operator()(Arg1, Arg2) = 0; }; -/// Slot with one argument. -template -class Slot1:public SlotHolder { +template +class Slot2: public SlotBase2 { public: - typedef ReturnType (*CallbackType)(CallbackHolder*, Arg1); - - template - Slot1( const Functor& functor ): - SlotHolder( new FunctorHolder - (functor, Callback1::functionAddress())){ - - } + virtual ReturnType operator()(Arg1 arg1, Arg2 arg2) { return m_functor(arg1, arg2); } - void operator()(Arg1 arg) { - if (m_holder) - reinterpret_cast(m_holder->m_callback)(m_holder, arg); - } + Slot2(Functor functor) : m_functor(functor) {} +private: + Functor m_functor; }; -/// Slot with two arguments -template -class Slot2: public SlotHolder { +template +class SlotBase3: public SlotBase { public: - typedef ReturnType (*CallbackType)(CallbackHolder*, Arg1, Arg2); - template - Slot2( const Functor& functor ): - SlotHolder( new FunctorHolder - (functor, Callback2::functionAddress())){ - - } - - void operator()(Arg1 arg1, Arg2 arg2) { - if (m_holder) - reinterpret_cast(m_holder->m_callback)(m_holder, arg1, arg2); - } + virtual ReturnType operator()(Arg1, Arg2, Arg3) = 0; + virtual ~SlotBase3() {} }; -/// Slot with three arguments -template -class Slot3: public SlotHolder { +template +class Slot3: public SlotBase3 { public: - typedef ReturnType (*CallbackType)(CallbackHolder*, Arg1, Arg2, Arg3); - template - Slot3( const Functor& functor ): - SlotHolder( new FunctorHolder - (functor, Callback3::functionAddress())){ - - } + virtual ReturnType operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3) + { return m_functor(arg1, arg2, arg3); } - void operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3) { - if (m_holder) - reinterpret_cast(m_holder->m_callback) - ( m_holder, arg1, arg2, arg3 ); - } + Slot3(Functor functor) : m_functor(functor) {} + +private: + Functor m_functor; }; } // namespace SigImpl -- cgit v0.11.2