Re: [sigc] How to use sigc::bind<>
- From: timf <timf trdlnk com>
- To: Martin Schulze <martin-ml hippogriff de>, Jeff Franks <jcf tpg com au>
- Cc: libsigc-list gnome org
- Subject: Re: [sigc] How to use sigc::bind<>
- Date: Mon, 10 Nov 2003 08:53:36 -0600
with the help of several people from this list, i wrote for myself some code
illustrating all the ways i had figured out to connect sigc's slots and
signals. here it is.
-tim
#include <iostream>
#include <sigc++/sigc++.h>
#include <sigc++/retype.h>
#include <sigc++/retype_return.h>
/*****************************************************************************
This is intended to be an example of all the different ways you can connect
libsigc++ signals to slots. A slot can be a global function, static class
function, or object function.
*****************************************************************************/
using namespace SigC;
using namespace std;
// These are sample callback functions. There is no meaning intended by
// their contents, I just put something there to show that they were called.
void callback_void_return_no_parameters()
{
cout << "callback_void_return_no_parameters()" << endl;
}
void callback_void_return_int_parameter(int i)
{
cout << "callback_void_return_int_parameter(" << i << ")" << endl;
}
float callback_float_return_int_parameter(int i)
{
return static_cast<float>(i) / 2;
}
int callback_int_return_float_parameter(float f)
{
return static_cast<int>(f);
}
void callback_void_return_int_reference_parameter(int& i)
{
cout << "Good luck binding to this!" << endl;
}
bool marshalled_callback_1()
{
cout << "marshalled_callback_1()" << endl;
return false; // Not done handling signal.
}
bool marshalled_callback_2()
{
cout << "marshalled_callback_2()" << endl;
return true; // Done handling signal.
}
bool marshalled_callback_3()
{
cout << "marshalled_callback_3()" << endl;
return false; // Not done handling signal.
}
class SigCDerivedClass : public SigC::Object
{
/**
This is a sample class used below to show how to connect a signal to
non-static functions belonging to a class.
In order to connect a signal to a slot made from a non-static function
which is a member of a class, that class must derive from SigC::Object.
*/
public:
SigCDerivedClass() : SigC::Object() {};
// You will get a compiler error if you don't impliment the destructor
// in a class deriving from SigC::Object.
~SigCDerivedClass() {};
void NonStaticFunction()
{ cout << "SigCDerivedClass::NonStaticFunction()" << endl; };
};
class NonSigCDerivedClass
{
/**
*/
public:
NonSigCDerivedClass();
void NonStaticFunction();
static void StaticClassFunction()
{ cout << "NonSigCDerivedClass::StaticClassFunction()" << endl; };
};
class BoolMarshal
{
public:
typedef bool OutType;
typedef bool InType;
BoolMarshal() {}
OutType value() { return false; }
static OutType default_value() { return true; }
bool marshal(InType new_val)
{
return new_val;
}
private:
};
main()
{
SigCDerivedClass object;
Connection connection;
// ******************************************************************
// How to connect a signal with no parameters and void return type to
// slots of varying signature.
// ******************************************************************
cout << "Calling a signal with void return type, no parameters:" << endl
<< "------------------------------------------------------" << endl;
Signal0<void> signal_void_return_no_parameters;
// A slot from a global function.
signal_void_return_no_parameters.connect(
slot(&callback_void_return_no_parameters) );
// A slot from a static class function.
signal_void_return_no_parameters.connect(
slot(&NonSigCDerivedClass::StaticClassFunction) );
// A slot from a function in an object.
signal_void_return_no_parameters.connect(
slot(object, &SigCDerivedClass::NonStaticFunction) );
// A slot which expects an integer parameter.
signal_void_return_no_parameters.connect(
bind(slot(&callback_void_return_int_parameter), 10) );
signal_void_return_no_parameters();
cout << endl;
// ******************************************************************
// ******************************************************************
// How to connect a signal with an integer parameter and void return
// type to slots of varying signature.
// ******************************************************************
cout << "Calling a signal with void return type and an integer parameter:"
<< endl
<< "----------------------------------------------------------------"
<< endl;
Signal1<void, int> signal_void_return_int_parameter;
// A slot from a global function.
signal_void_return_int_parameter.connect(
slot(&callback_void_return_int_parameter) );
// A slot with no parameters.
signal_void_return_int_parameter.connect(
hide<int>(slot(&callback_void_return_no_parameters)) );
// A slot with which returns a float.
signal_void_return_int_parameter.connect(
hide_return(slot(&callback_float_return_int_parameter)) );
signal_void_return_int_parameter(1);
cout << endl;
// ******************************************************************
// ******************************************************************
// How to connect a signal with an integer parameter and float return
// type to slots of varying signature.
// ******************************************************************
cout << "Calling a signal with float return type and an integer parameter:"
<< endl
<< "-----------------------------------------------------------------"
<< endl;
Signal1<float, int> signal_float_return_int_parameter;
// A slot from a global function.
connection =
signal_float_return_int_parameter.connect(
slot(&callback_float_return_int_parameter)
);
cout << "signal_float_return_int_parameter(1) returns "
<< signal_float_return_int_parameter(1) << endl;
connection.disconnect();
// A slot which returns void.
signal_float_return_int_parameter.connect(
bind_return<float>(slot(&callback_void_return_int_parameter), 0.0) );
cout << "signal_float_return_int_parameter(3) connected to" << endl
<< "\tcallback_void_return_int_parameter through bind_return" << endl
<< "\treturns " << signal_float_return_int_parameter(3) << endl;
connection.disconnect();
// A slot whose return type is int and that takes an integer parameter.
signal_float_return_int_parameter.connect(
retype<float, int>(slot(&callback_int_return_float_parameter)) );
cout << "signal_float_return_int_parameter(9) connected to" << endl
<< "\tcallback_int_return_float_parameter through" << endl
<< "\tretype<float, int> returns "
<< signal_float_return_int_parameter(9) << endl;
cout << endl;
// This illustrates the order that call backs are called in, as a
// consequence of the order they are connected to a signal.
SigC::Signal0<bool> signal_order_example;
signal_order_example.connect(slot(&marshalled_callback_1));
signal_order_example.connect(slot(&marshalled_callback_2));
signal_order_example.connect(slot(&marshalled_callback_3));
cout << "These callbacks were connected in ascending order." << endl
<< "Here's what happens when the signal is emitted:" << endl;
signal_order_example();
cout << endl;
// This illustrates how a marshaller affects callbacks.
cout << "The marshalled callbacks are now connected to a signal which" << endl
<< "was instantiated with the BoolMarshaller class as its" << endl
<< "marshaller template parameter. Notice it stops after" << endl
<< "callback_2, which returns true." << endl;
SigC::Signal0<bool, BoolMarshal> signal_marshal_example;
// SigC::Signal0<bool, Marshal<bool> > signal_marshal_example;
signal_marshal_example.connect(slot(&marshalled_callback_1));
signal_marshal_example.connect(slot(&marshalled_callback_2));
signal_marshal_example.connect(slot(&marshalled_callback_3));
signal_marshal_example();
// **************************************************************************
// Common errors (well, common to tim anyway)
// ------------------------------------------
// These are errors i tend to make repeatedly while trying to connect
// signals to slots. Uncomment the lines to see the type of error message
// you will get if you too make these mistakes.
// **************************************************************************
// 1. Trying to make a slot out of a function of an object which doesn.t
// derive from SigC::Object. This results in a link-time error.
// NonSigCDerivedClass non_sigc_derived_object;
// signal_void_return_no_parameters.connect(
// slot(non_sigc_derived_object, &NonSigCDerivedClass::NonStaticFunction));
// 2. Trying to bind a signal to a slot which takes a reference parameter
// for the parameter being bound. This results in a link time error
// because the compiler can't figure out you are tring to bind a
// reference to a variable (in this case an integer) instead of the
// integer itself, that is it when you bind an integer, it is looking
// for a function that takes an integer parameteter, not an integer
// reference parameter. Even if the compiler was able to figure out
// you wanted to bind to a slot created from a function with a
// reference parameter, the example below would fail because you can't
// take a reference to the literal '1'.
// signal_void_return_no_parameters.connect(
// bind(slot(&callback_void_return_int_reference_parameter), 1) );
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]