/*
Things to do to base objects to convert from VRPN version 4.XX to 5.00:
In the header file:
Include the BaseClass header
Derive from the BaseClass
Remove mainloop() pure virtual from the base class
Remove connectionPtr from the base class
Remove connection and my_id from the data objects
Declare register_types()
In the source file:
Call the base-class constructor
Call the base-class init() routine.
Remove parts of the constructor
Dealing with service and connection set up
Dealing with registering the sender
deleting the servicename
Move the constructor code to register the types into a separate function
Replace the message registration commands with calls to autodelete ones
Delete the unregister commands for the message handlers
Remove the connectionPtr function
Remove the vrpn_get_connection_by_name clause from the remote
constructor
Change connection-> to d_connection->
Change my_id to d_sender_id
Remove the timeout parameter to all mainloop() functions
Put a call to client_mainloop() in the Remote object mainloop() function
Things to do in the server object (server device) files to convert from 4.XX
to 5.00:
Replace the message registration commands with calls to autodelete ones
(Note that the handler for update rate has been removed from
the tracker
class -- it should not have been there in the first place.
This saves the
derived class from having to unregister the old one before
registering its
own).
Delete the unregister commands for the message handlers
Change connection-> to d_connection->
Change my_id to d_sender_id
Remove the timeout parameter to all mainloop() functions
Put a call to server_mainloop() in each server mainloop()
*/
#ifndef VRPN_BASECLASS
#define VRPN_BASECLASS
#include "vrpn_Shared.h"
#ifndef VRPN_NO_STREAMS
#include <iostream.h>
#endif
#include "vrpn_Connection.h"
const int vrpn_MAX_BCADRS = 100;
typedef enum {vrpn_TEXT_NORMAL = 0, vrpn_TEXT_WARNING = 1, vrpn_TEXT_ERROR = 2} vrpn_TEXT_SEVERITY;
const unsigned vrpn_MAX_TEXT_LEN = 1024;
class vrpn_BaseClass;
// It is a system class, with one instance of it in existence. Each object in
// the system registers with this class when it is constructed. By default,
// this class prints all Warning and Error messages to stdout, prefaced by
// "vrpn Warning(0) from MUMBLE: ", where the 0 indicates the level of the
// message and Warning the severity, and MUMBLE the
// name of the object that sent the message.
// The user could create their own TextPrinter, and attach whatever objects
// they want to it.
class vrpn_TextPrinter {
public:
vrpn_TextPrinter();
~vrpn_TextPrinter();
int add_object(vrpn_BaseClass *o);
void remove_object(vrpn_BaseClass *o);
void set_min_level_to_print(vrpn_TEXT_SEVERITY severity, vrpn_uint32 level = 0)
{ d_severity_to_print = severity; d_level_to_print = level; };
#ifdef VRPN_NO_STREAMS
void set_ostream_to_use(FILE *o) { d_ostream = o; };
#else
void set_ostream_to_use(ostream *o) { d_ostream = o; };
#endif
protected:
class vrpn_TextPrinter_Watch_Entry {
public:
vrpn_BaseClass *obj;
vrpn_TextPrinter *me;
vrpn_TextPrinter_Watch_Entry *next;
};
vrpn_TextPrinter_Watch_Entry *d_first_watched_object;
#ifdef VRPN_NO_STREAMS
FILE *d_ostream;
#else
ostream *d_ostream;
#endif
vrpn_TEXT_SEVERITY d_severity_to_print;
vrpn_uint32 d_level_to_print;
static int text_message_handler(void *userdata, vrpn_HANDLERPARAM p);
};
extern vrpn_TextPrinter vrpn_System_TextPrinter;
class vrpn_BaseClassUnique {
friend class vrpn_TextPrinter;
public:
vrpn_BaseClassUnique();
virtual ~vrpn_BaseClassUnique();
protected:
vrpn_Connection *d_connection;
char *d_servicename;
vrpn_int32 d_sender_id;
vrpn_int32 d_text_message_id;
vrpn_int32 d_ping_message_id;
vrpn_int32 d_pong_message_id;
// This is a wrapper for the vrpn_Connection call that registers
// message handlers. It should be used rather than the connection's
// function because this one will remember to unregister all of its handlers
// at object deletion time.
// XXX In the future, should write an unregister function, in case
// someone wants it.
int register_autodeleted_handler(vrpn_int32 type,
vrpn_MESSAGEHANDLER handler, void *userdata,
vrpn_int32 sender = vrpn_ANY_SENDER);
static int encode_text_message_to_buffer(
char *buf, vrpn_TEXT_SEVERITY severity, vrpn_uint32 level, const char *msg);
static int decode_text_message_from_buffer(
char *msg, vrpn_TEXT_SEVERITY *severity, vrpn_uint32 *level, const char *buf);
int send_text_message(const char *msg, struct timeval timestamp,
vrpn_TEXT_SEVERITY type = vrpn_TEXT_NORMAL, vrpn_uint32 level = 0);
void server_mainloop(void);
void client_mainloop(void);
private:
struct {
vrpn_MESSAGEHANDLER handler;
vrpn_int32 sender;
vrpn_int32 type;
void *userdata;
} d_handler_autodeletion_record[vrpn_MAX_BCADRS];
int d_num_autodeletions;
int d_first_mainloop;
struct timeval d_time_first_ping;
struct timeval d_time_last_warned;
int d_unanswered_ping;
int d_flatline;
static int handle_ping(void *userdata, vrpn_HANDLERPARAM p);
static int handle_pong(void *userdata, vrpn_HANDLERPARAM p);
static int handle_connection_dropped(void *userdata, vrpn_HANDLERPARAM p);
void initiate_ping_cycle(void);
};
//---------------------------------------------------------------
class vrpn_BaseClass : virtual public vrpn_BaseClassUnique {
public:
vrpn_BaseClass (const char * name, vrpn_Connection * c = NULL);
virtual ~vrpn_BaseClass();
virtual void mainloop () = 0;
virtual vrpn_Connection *connectionPtr() {return d_connection;};
protected:
virtual int init(void);
virtual int register_senders(void);
virtual int register_types(void) = 0;
};
// End of defined VRPN_BASECLASS for vrpn_BaseClass.h
#endif