VuSessionEntity

friend class VuMainThread;
public:
  // constructors & destructor
  VuSessionEntity(ulong domainMask, char *callsign);
  VuSessionEntity(VU_BYTE **stream);
  VuSessionEntity(FILE *file);
  virtual ~VuSessionEntity();

  // virtual function interface
  virtual int SaveSize();
  virtual int Save(VU_BYTE **stream);
  virtual int Save(FILE *file);

  // accessors
  ulong DomainMask()  { return domainMask_; }
  VU_SESSION_ID SessionId() { return sessionId_; }
  char *Callsign()  { return callsign_; }
  VU_BYTE LoadMetric()  { return loadMetric_; }
  VU_ID GameId()  { return gameId_; }
  VuGameEntity *Game();
  int LastMessageReceived() { return lastMsgRecvd_; }
  VU_TIME KeepaliveTime();

  // setters
  void SetCallsign(char *callsign);
  void SetLoadMetric(VU_BYTE newMetric) { loadMetric_ = newMetric; }
  VU_ERRCODE JoinGroup(VuGroupEntity *newgroup);  //  < 0 retval ==> failure
  VU_ERRCODE LeaveGroup(VuGroupEntity *group);
  VU_ERRCODE LeaveAllGroups();
  VU_ERRCODE JoinGame(VuGameEntity *newgame);  //  < 0 retval ==> failure
  VU_GAME_ACTION GameAction() { return action_; }
  void SetLastMessageReceived(int id) { lastMsgRecvd_ = id; }
  void SetKeepaliveTime(VU_TIME ts);

#ifdef VU_SIMPLE_LATENCY
  int TimeDelta()  { return timeDelta_; }
  void SetTimeDelta(int delta) { timeDelta_ = delta; }
  int Latency()  { return latency_; }
  void SetLatency(int latency) { latency_ = latency; }
#endif VU_SIMPLE_LATENCY
#ifdef VU_TRACK_LATENCY
  VU_BYTE TimeSyncState() { return timeSyncState_; }
  VU_TIME Latency()  { return latency_; }
  void SetTimeSync(VU_BYTE newstate);
  void SetLatency(VU_TIME latency);
#endif VU_TRACK_LATENCY

  // Special VU type getters
  virtual VU_BOOL IsSession(); // returns TRUE

  virtual VU_BOOL HasTarget(VU_ID id);  // TRUE --> id contains (or is) ent
  virtual VU_BOOL InTarget(VU_ID id);   // TRUE --> ent contained by (or is) id

  VU_ERRCODE AddGroup(VU_ID gid);
  VU_ERRCODE RemoveGroup(VU_ID gid);
  VU_ERRCODE PurgeGroups();

#ifdef VU_USE_COMMS
  virtual VuTargetEntity *ForwardingTarget(VuMessage *msg = 0);
#endif

  // Rough dead reckoning interface
#if VU_MAX_SESSION_CAMERAS > 0
  int CameraCount() { return cameraCount_; }
  VuEntity *Camera(int index);
  int AttachCamera(VU_ID camera);
  int RemoveCamera(VU_ID camera);
  void ClearCameras(void);
#endif

  // event Handlers
#ifdef VU_LOW_WARNING_VERSION
  virtual VU_ERRCODE Handle(VuErrorMessage *error);
  virtual VU_ERRCODE Handle(VuPushRequest *msg);
  virtual VU_ERRCODE Handle(VuPullRequest *msg);
  virtual VU_ERRCODE Handle(VuEvent *event);
  virtual VU_ERRCODE Handle(VuFullUpdateEvent *event);
  virtual VU_ERRCODE Handle(VuPositionUpdateEvent *event);
  virtual VU_ERRCODE Handle(VuEntityCollisionEvent *event);
  virtual VU_ERRCODE Handle(VuTransferEvent *event);
  virtual VU_ERRCODE Handle(VuSessionEvent *event);
#else
  virtual VU_ERRCODE Handle(VuEvent *event);
  virtual VU_ERRCODE Handle(VuFullUpdateEvent *event);
  virtual VU_ERRCODE Handle(VuSessionEvent *event);
#endif VU_LOW_WARNING_VERSION

protected:
  VuSessionEntity(int typeindex, ulong domainMask, char *callsign);
  VU_SESSION_ID OpenSession(); // returns session id
  void CloseSession();
  virtual VU_ERRCODE InsertionCallback();
  virtual VU_ERRCODE RemovalCallback();

private:
  int LocalSize();                      // returns local bytes written

// DATA
protected:
  // shared data
  VU_SESSION_ID sessionId_;
  ulong domainMask_;
  char *callsign_;
  VU_BYTE loadMetric_;
  VU_ID gameId_;
  VU_BYTE groupCount_;
  VuGroupNode *groupHead_;
#ifdef VU_SIMPLE_LATENCY
  int timeDelta_;
  int latency_;
#endif VU_SIMPLE_LATENCY;
#ifdef VU_TRACK_LATENCY
  VU_BYTE timeSyncState_;
  VU_TIME latency_;
  VU_TIME masterTime_;  // time from master
  VU_TIME masterTimePostTime_; // local time of net msg post
  VU_TIME responseTime_;  // local time local msg post
  VU_SESSION_ID masterTimeOwner_; // sender of master msg
  // local data
  // time synchro statistics
  VU_TIME lagTotal_;
  int lagPackets_;
  int lagUpdate_; // when packets > update, change latency value
#endif VU_TRACK_LATENCY
  // msg tracking
  int lastMsgRecvd_;
#if VU_MAX_SESSION_CAMERAS > 0
  VU_BYTE cameraCount_;
  VU_ID cameras_[VU_MAX_SESSION_CAMERAS];
#endif
  // local data
  VuGameEntity *game_;
  VU_GAME_ACTION action_;
};