/** @file sample for sigc++ disconnect
 *
 * Last CVS checkin:
 * $Date: $
 * $Author: scheff $
 */

/**************************************************************************/

// standard C/C++ header:
#include <iostream>
#include <string>

// Gnome header:
#include <sigc++/sigc++.h>
#include <glibmm/init.h>

using namespace std;

/**************************************************************************/

/// provides a class representing data.
class Data {

  // signal:
  public:
    sigc::signal<void> sig;

};

/**************************************************************************/

/// provides a class representing a data view.
class View {

  // variables:
  private:
    /// pointer to data
    Data *_pData;
    /// connection
    struct Connection {
      sigc::connection sig;
      void disconnect(void)
      {
        sig.disconnect();
      }
      ~Connection(void) { disconnect(); }
    } _connection;

  // methods:
  public:
    /// @name Construction & Destruction
    //@{

    /** constructs a view for a certain data.
     *
     * @param data the data
     */
    View(Data &data);

    /// destroys view.
    virtual ~View(void);

    //@}
  protected:
    /// @name Signal Handling
    //@{

    /// called for data.
    void onData(void);

    //@}
};

/**************************************************************************/

// Construction & Destruction

View::View(Data &data): _pData(&data)
{
  _connection.sig
    = data.sig.connect(sigc::mem_fun(*this, &View::onData));
}

View::~View(void) { cout << "View::~View()" << endl; }

// Signal Handling

void View::onData(void)
{
  cout << "View::onData(): _pData = " << _pData << endl;
}

/**************************************************************************/

/** waits for user confirm.
 *
 * @param action text with next action
 */
static void pause(const char *action)
{
  cout << "Press [ENTER] to " << action << ": " << flush;
  string str; getline(cin, str);
}

/** provides the main function of application.
 *
 * @param argc number of command line arguments
 * @param argv pointer to array of pointers to strings with command line
 *        arguments
 * @return 0 ... application exited regularly\n
 *         else ... execution of application aborted
 */
int main(int argc, char *argv[])
{
  Glib::init();
  // signals
  pause("start");
  {
    Data data; // a Data instance
    { View view(data); // a view
      data.sig(); // emit a signal
    } // life time of view ends here
    data.sig(); // emit another signal
  } // life time of Data instance ends here
  // done
  pause("finish");
  return 0;
}

