all repos — fluxbox @ 144d716a42072bd59f6c99e95e86be4486285782

custom fork of the fluxbox windowmanager

Simplify Slot.hh

Replace CallbackHolder, FunctorHolder and SlotHolder with a (smaller) set of polymorphic classes.
SignalHolder now stores a (smart) pointer to the class.
Pavel Labath pavelo@centrum.sk
commit

144d716a42072bd59f6c99e95e86be4486285782

parent

4b47675441b76620519b0204497686b09113daaa

2 files changed, 70 insertions(+), 254 deletions(-)

jump to
M src/FbTk/Signal.hhsrc/FbTk/Signal.hh

@@ -22,6 +22,7 @@

#ifndef FBTK_SIGNAL_HH #define FBTK_SIGNAL_HH +#include "RefCount.hh" #include "Slot.hh" #include <list> #include <map>

@@ -49,7 +50,7 @@ virtual void disconnect(SignalHolder& signal) = 0;

}; /// Do not use this type outside this class - typedef std::list<SlotHolder> SlotList; + typedef std::list<RefCount<SlotBase> > SlotList; typedef SlotList::iterator Iterator; typedef Iterator SlotID;

@@ -91,7 +92,7 @@ Iterator begin() { return m_slots.begin(); }

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<SlotBase>& slot) { return m_slots.insert(m_slots.end(), slot); }

@@ -111,16 +112,17 @@ template <typename ReturnType,

typename Arg1 = SigImpl::EmptyArg, typename Arg2 = SigImpl::EmptyArg, typename Arg3 = SigImpl::EmptyArg > class Signal: public SigImpl::SignalHolder { public: - typedef SigImpl::Slot3<ReturnType, Arg1, Arg2, Arg3> SlotType; - void emit(Arg1 arg1, Arg2 arg2, Arg3 arg3) { for ( Iterator it = begin(); it != end(); ++it ) { - static_cast<SlotType&>(*it)(arg1, arg2, arg3); + static_cast<SigImpl::SlotBase3<ReturnType, Arg1, Arg2, Arg3> &>(**it)(arg1, arg2, arg3); } } - SlotID connect(const SlotType& slot) { - return SignalHolder::connect(slot); + template<typename Functor> + SlotID connect(const Functor& functor) { + return SignalHolder::connect(FbTk::RefCount<SigImpl::SlotBase>( + new SigImpl::Slot3<ReturnType, Arg1, Arg2, Arg3, Functor>(functor) + )); } };

@@ -128,16 +130,17 @@ /// Specialization for two arguments.

template <typename ReturnType, typename Arg1, typename Arg2> class Signal<ReturnType, Arg1, Arg2, SigImpl::EmptyArg>: public SigImpl::SignalHolder { public: - typedef SigImpl::Slot2<ReturnType, Arg1, Arg2> SlotType; - void emit(Arg1 arg1, Arg2 arg2) { for ( Iterator it = begin(); it != end(); ++it ) { - static_cast<SlotType&>(*it)(arg1, arg2); + static_cast<SigImpl::SlotBase2<ReturnType, Arg1, Arg2> &>(**it)(arg1, arg2); } } - SlotID connect(const SlotType& slot) { - return SignalHolder::connect(slot); + template<typename Functor> + SlotID connect(const Functor& functor) { + return SignalHolder::connect(FbTk::RefCount<SigImpl::SlotBase>( + new SigImpl::Slot2<ReturnType, Arg1, Arg2, Functor>(functor) + )); } };

@@ -145,16 +148,17 @@ /// Specialization for one argument.

template <typename ReturnType, typename Arg1> class Signal<ReturnType, Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg>: public SigImpl::SignalHolder { public: - typedef SigImpl::Slot1<ReturnType, Arg1> SlotType; - void emit(Arg1 arg) { for ( Iterator it = begin(); it != end(); ++it ) { - static_cast<SlotType&>(*it)(arg); + static_cast<SigImpl::SlotBase1<ReturnType, Arg1> &>(**it)(arg); } } - SlotID connect(const SlotType& slot) { - return SignalHolder::connect(slot); + template<typename Functor> + SlotID connect(const Functor& functor) { + return SignalHolder::connect(FbTk::RefCount<SigImpl::SlotBase>( + new SigImpl::Slot1<ReturnType, Arg1, Functor>(functor) + )); } };

@@ -162,16 +166,17 @@ /// Specialization for no arguments.

template <typename ReturnType> class Signal<ReturnType, SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg>: public SigImpl::SignalHolder { public: - typedef SigImpl::Slot0<ReturnType> SlotType; - void emit() { for ( Iterator it = begin(); it != end(); ++it ) { - static_cast<SlotType&>(*it)(); + static_cast<SigImpl::SlotBase0<ReturnType> &>(**it)(); } } - SlotID connect(const SlotType& slot) { - return SignalHolder::connect(slot); + template<typename Functor> + SlotID connect(const Functor& functor) { + return SignalHolder::connect(FbTk::RefCount<SigImpl::SlotBase>( + new SigImpl::Slot0<ReturnType, Functor>(functor) + )); } };
M src/FbTk/Slot.hhsrc/FbTk/Slot.hh

@@ -27,268 +27,79 @@

/// \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 <typename Functor> -class FunctorHolder: public CallbackHolder { +template<typename ReturnType> +class SlotBase0: public SlotBase { public: - /// This type. - typedef FunctorHolder<Functor> 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&>(*self)); - } - - static void kill(CallbackHolder* self) { - // Destroy functor - static_cast<Self*>( self )->m_functor.~Functor(); - } - - Functor m_functor; ///< the functor to use when a signal is emitted. + virtual ReturnType operator()() = 0; }; +template<typename ReturnType, typename Functor> +class Slot0: public SlotBase0<ReturnType> { +public: + virtual ReturnType operator()() { return m_functor(); } + Slot0(Functor functor) : m_functor(functor) {} -/// Callback with no arguments. -template <typename Functor, typename ReturnType > -struct Callback0 { - static ReturnType callback(CallbackHolder* base) { - static_cast< FunctorHolder<Functor>* >( base )->m_functor(); - return ReturnType(); - } - - static CallbackFunc functionAddress() { - return reinterpret_cast<CallbackFunc>(&callback); - } +private: + Functor m_functor; }; -/// Callback with one argument -template <typename Functor, typename ReturnType, typename Arg1> -struct Callback1 { - typedef ReturnType (Functor::* CallbackType)(CallbackHolder*, Arg1); - - static ReturnType callback(CallbackHolder* base, Arg1 arg1) { - static_cast< FunctorHolder<Functor>* >( base )->m_functor(arg1); - return ReturnType(); - } - - static CallbackFunc functionAddress() { - return reinterpret_cast<CallbackFunc>(&callback); - } +template<typename ReturnType, typename Arg1> +class SlotBase1: public SlotBase { +public: + virtual ReturnType operator()(Arg1) = 0; }; -/// Callback with two arguments -template <typename Functor, typename ReturnType, - typename Arg1, typename Arg2> -struct Callback2 { - typedef ReturnType (Functor::* CallbackType)(CallbackHolder*, Arg1, Arg2); +template<typename ReturnType, typename Arg1, typename Functor> +class Slot1: public SlotBase1<ReturnType, Arg1> { +public: + virtual ReturnType operator()(Arg1 arg1) { return m_functor(arg1); } - static ReturnType callback(CallbackHolder* base, Arg1 arg1, Arg2 arg2) { - static_cast< FunctorHolder<Functor>* >( base )->m_functor(arg1, arg2); - return ReturnType(); - } + Slot1(Functor functor) : m_functor(functor) {} - static CallbackFunc functionAddress() { - return reinterpret_cast<CallbackFunc>(&callback); - } +private: + Functor m_functor; }; -/// Callback with three arguments -template <typename Functor, typename ReturnType, - typename Arg1, typename Arg2, typename Arg3> -struct Callback3 { - typedef ReturnType (Functor::* CallbackType)(CallbackHolder*, Arg1, Arg2, Arg3); - - static ReturnType callback(CallbackHolder* base, Arg1 arg1, Arg2 arg2, Arg3 arg3) { - static_cast< FunctorHolder<Functor>* >( base )->m_functor( arg1, arg2, arg3 ); - return ReturnType(); - } - - static CallbackFunc functionAddress() { - return reinterpret_cast<CallbackFunc>(&callback); - } -}; - -/// Holds callback holder and handles the copying of callback holders for the -/// \c Slots. -class SlotHolder { +template<typename ReturnType, typename Arg1, typename Arg2> +class SlotBase2: public SlotBase { 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; - } - - SlotHolder():m_holder( 0 ) { } - -protected: - explicit SlotHolder(CallbackHolder* holder): - m_holder( holder ) { - } - - CallbackHolder* m_holder; + virtual ReturnType operator()(Arg1, Arg2) = 0; }; -/// Slot with no argument. -template <typename ReturnType> -class Slot0: public SlotHolder { +template<typename ReturnType, typename Arg1, typename Arg2, typename Functor> +class Slot2: public SlotBase2<ReturnType, Arg1, Arg2> { public: - typedef ReturnType (*CallbackType)(CallbackHolder*); + virtual ReturnType operator()(Arg1 arg1, Arg2 arg2) { return m_functor(arg1, arg2); } - template <typename Functor> - Slot0( const Functor& functor ): - SlotHolder( new FunctorHolder<Functor> - (functor, Callback0<Functor, ReturnType>::functionAddress())) { - } + Slot2(Functor functor) : m_functor(functor) {} - void operator()() { - if (m_holder) - reinterpret_cast<CallbackType>(m_holder->m_callback)( m_holder ); - } +private: + Functor m_functor; }; -/// Slot with one argument. -template <typename ReturnType, typename Arg1> -class Slot1:public SlotHolder { +template<typename ReturnType, typename Arg1, typename Arg2, typename Arg3> +class SlotBase3: public SlotBase { public: - typedef ReturnType (*CallbackType)(CallbackHolder*, Arg1); - - template <typename Functor> - Slot1( const Functor& functor ): - SlotHolder( new FunctorHolder<Functor> - (functor, Callback1<Functor, ReturnType, Arg1>::functionAddress())){ - - } - - void operator()(Arg1 arg) { - if (m_holder) - reinterpret_cast<CallbackType>(m_holder->m_callback)(m_holder, arg); - } - + virtual ReturnType operator()(Arg1, Arg2, Arg3) = 0; + virtual ~SlotBase3() {} }; -/// Slot with two arguments -template <typename ReturnType, typename Arg1, typename Arg2> -class Slot2: public SlotHolder { +template<typename ReturnType, typename Arg1, typename Arg2, typename Arg3, typename Functor> +class Slot3: public SlotBase3<ReturnType, Arg1, Arg2, Arg3> { public: - typedef ReturnType (*CallbackType)(CallbackHolder*, Arg1, Arg2); - template <typename Functor> - Slot2( const Functor& functor ): - SlotHolder( new FunctorHolder<Functor> - (functor, Callback2<Functor, ReturnType, Arg1, Arg2>::functionAddress())){ - - } + virtual ReturnType operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3) + { return m_functor(arg1, arg2, arg3); } - void operator()(Arg1 arg1, Arg2 arg2) { - if (m_holder) - reinterpret_cast<CallbackType>(m_holder->m_callback)(m_holder, arg1, arg2); - } -}; - -/// Slot with three arguments -template <typename ReturnType, typename Arg1, typename Arg2, typename Arg3> -class Slot3: public SlotHolder { -public: - typedef ReturnType (*CallbackType)(CallbackHolder*, Arg1, Arg2, Arg3); - template <typename Functor> - Slot3( const Functor& functor ): - SlotHolder( new FunctorHolder<Functor> - (functor, Callback3<Functor, ReturnType, Arg1, Arg2, Arg3>::functionAddress())){ - - } + Slot3(Functor functor) : m_functor(functor) {} - void operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3) { - if (m_holder) - reinterpret_cast<CallbackType>(m_holder->m_callback) - ( m_holder, arg1, arg2, arg3 ); - } +private: + Functor m_functor; }; } // namespace SigImpl