#ifndef _TOYCLASS_H_
#define _TOYCLASS_H_

#include <hpcxx_rts.h>
#include <iostream.h>
#include <stdio.h>

#define ARR_SIZE 10

// tjs - 98.12.15
//
// This set of classes and associated global variables and global functions
// is to illustrate the object-oriented use of HPC++ global pointers to
// classes.
//
// In the parent Toy class, member data and functions used by the derived
// ToyServer and ToyClient classes.  If member functions are to be identical
// wholely used in the derived classes, then they are defined.  Otherwise
// they are declared as virtual and defined merely as stubs.
//
// The functions and variables of global scope are required to create and
// use HPC++ global pointers.  They are included in this file because they
// are invoked and accessed by member functions of the classes in this file.
// The global pointers could have been set up by the program(s) that use
// these classes, but in order to keep things as encapsulated as possible, I
// have moved that setup into the classes themselves.
//
// The implementation of HPC++ requires that any function that is remotely
// invoked must return a value.  As a result, some member functions in these
// classes return dummy variables.
//
// Because of templates of type Toy, certain member function calls depend on
// the Toy class being defined before they can be called from an object.
// Though common to all derived classes, these member functions are invoked
// from the derived classes instead of the parent class.


class Toy {

 protected:

  HPCxx_GlobalPtr<Toy>
    *ToyGP_Ptr;           // GP to the class

  int
    regVal;               // for registering functions

  int
    intArr[ARR_SIZE],     // two arrays to play with
    negArr[ARR_SIZE];

  hpcxx_id_t
    PrintID,              // IDs for the two member functions invoked remotely
    ExchangeID,
    getToyGPID;           // ID for the global function that returns the GP

  void regFuncs();

 public:

  Toy();

  ~Toy() {}

  virtual int printArr(void) { return(0); }

  void printLocal();

  virtual int exchangeArr(void) { return(0); }

  void readArr(int size);

  // the following are required by HPC++

  static int registrationID(){ return 345; }

  // HPC++ pack & unpack functions
  friend void hpcxx_pack(HPCxx_Buffer b, Toy *ToyObj, int size);
  friend void hpcxx_unpack(HPCxx_Buffer b, Toy *ToyObj, int size);
};

// Global variables and functions used by the client and server classes. 
//
// These declarations must go here.  They are invoked below this point, but
// the class on which the templates depend is defined above.  Thus if they
// are not here, the code will not compile.

HPCxx_GlobalPtr<Toy> getToyGP(void);     // get GP to class Toy

static HPCxx_GlobalPtr<Toy> gToyGP;     // GP to Toy class

class ToyServer : public Toy {

 public:

  ToyServer();

  ~ToyServer() {}

  virtual int printArr(void);

  virtual int exchangeArr(void);
};

class ToyClient : public Toy {

 public:

  ToyClient(HPCxx_ContextID *serverContextID);

  ~ToyClient() {};

  virtual int printArr(void);

  virtual int exchangeArr();

};

#endif
