Listing 5: An application that uses the SwitchBoard

#include <iostream.h> 
#include <String.h> 
#include "SwitchBoard.h" 
#include "SubscriberHookup.h"

// PersonnelList Class ///////////////////////////////////////////
////
class PersonnelList
{
private:
  SubscriberHookup* _swsub;

public:
  PersonnelList();
  ~PersonnelList();

  // PersonnelList code here

  // persistent store and SwitchBoard saveYourself message handler
  void store();
};


// -- implementation ---------------------------------------------
////
PersonnelList::PersonnelList()
{
  _swsub = newSwitchBoardSubscribtion("saveYourself", this, store);
  // rest of the constructor code here
}

PersonnelList::~PersonnelList()
{
  delete _swsub;
  // rest of destructor code here
}

void PersonnelList::store()
{
  // persistent store
  SwitchBoard::post("busy", "PersonnelList - saving...");

  // save the personnel list

  SwitchBoard::post("notBusy");
}

// ApplicationShell Class ////////////////////////////////////////
////
class ApplicationShell
{ 
private:
  int    _busy_ref_count; // tracks how busy the application is
  String _status;         // current message as displayed in the
                          // status bar
  String _idle_status;    // the before busy status message that
                          // needs to be restored

public:
  ApplicationShell();

  // busyness management center
  bool isBusy() { return(_busy_ref_count > 0);  }
  void setStatus(const char* status);
  void busy(const char* status_msg = NULL);
  void notBusy();

  // application state management
  void refresh();
  void save();
};

// -- instantiation ----------------------------------------------
////
ApplicationShell::ApplicationShell()
  : _busy_ref_count(0)
{
  // construct the application GUI
  setStatus("Ready.");

  // subscribe to the busy and notBusy messages
  newSwitchBoardSubscribtion("busy", this, busy);
  newSwitchBoardSubscribtion("notBusy", this, notBusy);
}

// -- busyness management center ---------------------------------
////
void ApplicationShell::setStatus(const char* status)
{
  _status = status;        // save the status

  // for the example just print the status message and depth
  cerr << replicate(' ', _busy_ref_count) << status << endl;
}

void ApplicationShell::busy(const char* status /* NULL */)
{
  // post the message telling each visible object to switch its
  // cursor to the busy one
  SwitchBoard::post("setBusyCursor");

  // if this is the first call save the current status message
  // for later restoration
  if (!isBusy())
    _idle_status = _status;

  // if going busy with a message show the user the new message
  if (status)
    setStatus(status);

  // increment the reference count so notBusy() will know when
  // to stop
  _busy_ref_count++;
}

void ApplicationShell::notBusy()
{
  if (--_busy_ref_count < 0)
    _busy_ref_count = 0;

  if (!isBusy())
  {
    // the application is no longer busy, so switch back to the
    // default cursor
    SwitchBoard::post("restoreDefaultCursor");

    // restore the status message before work began
    if (!_idle_status.empty())
      setStatus(_idle_status);
    _idle_status = NULL;
  }
}

// -- application state managment --------------------------------
////
void ApplicationShell::refresh()
{
  SwitchBoard::post("busy", "Refreshing...");

  // refresh the application state

  SwitchBoard::post("notBusy");
}

void ApplicationShell::save()
{
  // swith the application into a busy state
  SwitchBoard::post("busy", "Saving the application state...");

  // code to save the application state ...

  // notify all the persistent objects that it's now time to save
  SwitchBoard::post("saveYourself");

  refresh();

  // return to the normal state
  SwitchBoard::post("notBusy");
}

// Main //////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
  // instantiate the application
  ApplicationShell app;

  // just for kicks, declare a personnel list outside of the
  // application
  PersonnelList personnel_list;

  // save the application state
  app.save();

  return(0);
}

/* End of File */