#ifndef __Signal1_h__ #define __Signal1_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" //========================================================================================================================================= // Slot tempplate. //========================================================================================================================================= /** * Abstract base class for Slots with 1 parameter(s). */ template class Slot1 : public slot_base { public: /** * Method which performs the actual callback. Must be overridden. * * @return Returns an object of type T_return; the result of the user callback. */ virtual T_return operator() (T_arg0 a0) const = 0; }; // // a concrete Slot class for a normal function // template class Slot1_function: public Slot1 { public: typedef T_return (*FUNCTION_POINTER)(T_arg0 a0); Slot1_function( const FUNCTION_POINTER func ) { // convert and store function pointer in slot_base this->data[0] = safe_horrible_cast(func); } T_return operator() (T_arg0 a0) const { // retrieve data from slot_base and convert back to a function pointer FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); // call function return func(a0); } }; // // a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') // template class Slot1_method: public Slot1 { public: Slot1_method(const T_object* p_object, const T_member p_member) { // convert and store object pointer and member function pointer in slot_base this->data[0] = safe_horrible_cast(p_object); this->data[1] = safe_horrible_cast(p_member); } T_return operator() (T_arg0 a0) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer T_object* p_object = dangerous_horrible_cast(this->data[0]); T_member p_member = dangerous_horrible_cast (this->data[1]); // call member function return (p_object->*p_member)(a0); } }; //========================================================================================================================================= // Signal tempplate. //========================================================================================================================================= template< typename T_return, typename T_arg0 > class Signal1: public signal_base { public: //----------------------------------------------------------------------------------------------------------------------------------------- // Execute the Signal: // - Walk the list of Slot nodes. //----------------------------------------------------------------------------------------------------------------------------------------- void operator() (T_arg0 a0) { if( IsSignalEmitting( ) ) { #if defined( _DEBUG ) printf("WARNING: Signal1<...> @ 0x%p recursive Emit attempt\n", this); #endif return; } BeginEmit( ); list_node* cur = GetFirstNode( ); // iterate through the list while( cur ) { // make the slot_base pointer a Slot1 pointer Slot1* s = static_cast*>(cur->slot); // call the Signal (*s)(a0); // move to next Slot in the list. cur = cur->next; } EndEmit( ); } //========================================================================================================================================= // Signal connections //========================================================================================================================================= typedef T_return (*FUNCTION_POINTER)(T_arg0 a0); // Functions //----------------------------------------------------------------------------------------------------------------------------------------- bool Connect( FUNCTION_POINTER func ) { // make a copy of the Slot to store in our list Slot1* sNewFunc = new Slot1_function( func ); // add it to the end of our linked list return bind(sNewFunc); } // Object methods //----------------------------------------------------------------------------------------------------------------------------------------- template bool Connect(T_object* p_object, T_member p_member) { // make a copy of the Slot to store in our list Slot1* sNewMethod = new Slot1_method( p_object, p_member ); // add it to the end of our linked list return bind(sNewMethod); } //========================================================================================================================================= // Signal Disconnections //========================================================================================================================================= // Functions //----------------------------------------------------------------------------------------------------------------------------------------- bool Disconnect( FUNCTION_POINTER func ) { // make a temporary Slot we can use to find a match in the list Slot1_function sTest( func ); // search and remove it return unbind(&sTest); } // Object method //----------------------------------------------------------------------------------------------------------------------------------------- template bool Disconnect(T_object* p_object, T_member p_member) { // make a temporary Slot we can use to find a match in the list Slot1_method sTemp(p_object,p_member); // search and remove it return unbind(&sTemp); } }; #endif // __Signal1_h__