/***********************************************************************
tjs - 98.12.04

This example is to show the following:

- Attaching a seperately compiled and executing client to a server

- Remote function invocation to get the global pointers and to sync
  the end of the client and server programs

- The use of a global pointer to transfer data from server to client

- The use of a global pointer to transfer member data from a class
  in the server to a class in the client

- The use of a global pointer and 

- The invocation of member functions in a class on the server by using
  a global pointer on the client.

tjs - 98.12.15

Pulling out stuff for local array and concentrating on class stuff.

***********************************************************************/
#define coutline cout << __FILE__ << ": line " << __LINE__ << endl << flush;

#include <HPCxx_Profile.h>
#include <math.h>
#include <assert.h>
#include "Complex.C"
#include <iostream.h>
#include <hpcxx_rts.h>
#include "allHPCxxTemplates.h"
#include "ToyClass.h"
#include "ClientServerAttach.h"

int setWaitVal(int intVal)              // for releasing server
{
  return(0);
}

int main(int argc, char* argv[])
{
  int
    rtrnVal;

  // initialize HPC++

  HPCxx_Group* group;
  hpcxx_init(argc, argv, group);

  cout << "client: HPC++ initialized" << endl << flush;


  HPCxx_ContextID *serverContextID = clientAttach("gpServer.url");

  cout << "client: attached to server" << endl << flush;

  // register the functions that will provide the GPs 
  // and the function to release the server

  hpcxx_id_t setWaitValID = hpcxx_register(setWaitVal,12);

  cout << "client: remote functions registered" << endl << flush;

  // Register the class and declare the GP
  // get GP from the server

  Toy *localToyObj = new ToyClient(serverContextID);

  // The client constructor handles all the details of registering creating
  // its own global pointer.  Note: this involves calling two functions
  // outside of the object.  See ToyClass.h for details.

  cout << "client: localToyObj->intArr before GP read" << endl << flush;
  localToyObj->printLocal();

  // Global pointer read operation wrapped in method in Toy class.
  // This allows hiding of the member GP

  localToyObj->readArr(10);
  localToyObj->readArr(-10);

  cout << "client: localToyObj->intArr after GP read" << endl << flush;
  localToyObj->printLocal();
  cout << "client: access to member data complete" << endl << flush;

  cout << "client: accessing remote functions through local class object"
    << endl << flush;
  
  localToyObj->printArr();
  localToyObj->exchangeArr();
  localToyObj->printArr();

  cout << "client at barrier" << endl << flush;
  int tmpInt = 0;

  hpcxx_invoke(*serverContextID, rtrnVal, setWaitValID, tmpInt);
  cout << "setWaitVal returned " << rtrnVal << endl << flush;
  return hpcxx_exit(group);
}

