Callbacks

GUI applications are event driven, eg. the user pushes a button and an email is sent. The common way to do this is to create a TPushButton object and to instruct it to call you back when is was pushed:

class TMailApplication:
  public TWindow
{
  public:
    TMailApplication() {
      ...
      // create a pushbutton and...
      TPushButton *btn = new TPushButton(this, "Send emailpush me");                         
      // ... and tell it to call 'this->sendMail()' when it is pushed
      CONNECT(btn->sigClicked, this, sendMail);         
      ...
    }
 
    void sendMail() {     
      cout << "calling 'sendmail'" << endl;                                  
      ...
    }
};

The following happens here:

Below are some more examples to get the feel of it.

A feature which do I consider extremly cool is the TCLOSURE macro below. It mimics SmallTalk closures and allows you to write the code to be called back at the same place where you connect it to TSignal.

#include <toad/connect.hh>
 
struct TMySource
{
  TSignal sigAction;
    int value;
    int getValue() { return value; }
};
      
struct TMyDestination
{
   void doIt(int n) { cout << "doIt: " << n << endl; }
};
        
int
main()
{
  TMySource *source = new TMySource();
  source->value = 42;
  TMyDestination *destination = new TMyDestination();
 
  // ANSI C+ compatible call interface
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  connect(
    source->sigAction,                   // when triggered
    destination, &TMyDestination::doIt); // call method
 
  connect_value_of(
    source->sigAction,                   // when triggered
    destination, &TMyDestination::doIt,  // call method
    source, &TMySource::getValue);       // with the return value of method
    
  connect_value_of(
    source->sigAction,                   // when triggered
    destination, &TMyDestination::doIt,  // call method
    &source->value);                     // with the return value of variable
 
  connect_value(
    source->sigAction,                   // when triggered
    destination, &TMyDestination::doIt,  // call method
    source);                             // with the return value of 'getValue()'
 
  // GNU C++ compatible call interface
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  CONNECT(
    source->sigAction,                   // when triggered
    destination, doIt);                  // call method
  
  CONNECT_VALUE_OF(
    source->sigAction,                   // when triggered
    destination, doIt,                   // call method
    source, getValue());                 // with the return value of method
  
  CONNECT_VALUE(
    source->sigAction,                   // when triggered
    destination, doIt,                   // call method
    source);                             // with the return value of 'getValue()'
  
  TCLOSURE2(                             // closure with two variables
    source->sigAction,                   // the signal
    dst, destination,                    // dst := destination
    src, source,                         // src := source
    dst->doIt(src->getValue()*10);       // and execute this code
  )
  
  // triggering a signal
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  source->sigAction();
  
  // disconnecting a signal
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  disconnect(source->sigAction);         // remove all links
}