Newer
Older
delete scene;
// delete clk; Don't delete the clock -- might be shared with other objects
}
Ppszg::Ppszg() {
scene = new PvScene();
st = NULL;
clipnear_ = 0.1;
clipfar_ = 2500;
focallen_ = 3;
snapfmt = NULL;
snapfno = 0;
pickrange = 3.5;
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
memset(home, 0, sizeof(home));
clk = new SClock();
clock_init( clk );
clock_set_speed( clk, 1.0 );
clk->continuous = 1;
clk->walltimed = 1;
memset( &path, 0, sizeof(path) );
playing = 0;
playevery = 0;
playidling = 0;
playspeed = 20;
framebase = 1;
playtimebase = 0;
playloop = 0;
timebasetime = 0;
subcam = 0;
/* List of connected arSockets */
socketList = NULL;
bool Ppszg::onStart( arSZGClient& SZGClient ) {
/*
* Add Transfer Fields to Framework so data is
* accessible and syncronized to all clients
* Added July 23, 2008 William Davis
*/
processid = SZGClient.getProcessID(); // for msg() log files
addTransferField("curtime", &(ppszg.clk->curtime), AR_DOUBLE, 1);
addTransferField("running", &(ppszg.clk->running), AR_INT, 1);
addTransferField("continuous", &(ppszg.clk->continuous), AR_INT, 1);
addTransferField("center_", &(ppszg.scene->center_), AR_FLOAT, 3);
addTransferField("censize_", &(ppszg.scene->censize_), AR_FLOAT, 1);
addTransferField("quitnow", &(ppszg.quitnow_), AR_INT, 1);
addInternalTransferField( "commands", AR_CHAR, 1 );
parti_bgcolor( "0 0 0" );
parti_add_commands( pp_parse_args, "partiview", NULL );
parti_add_reader( pp_read, "partiview", NULL );
plugin_init();
// pp_ui_init();
// ppui.view->pickbuffer( COUNT(pickbuffer), pickbuffer );
parti_clip( "0.1", "2500" );
parti_censize( 1.0 );
// parti_pickrange( 3.5 );
parti_object( "g1", NULL, 1 );
readrc( &ppszg.st );
for(int i = 1; i < globalArgc; i++) {
specks_read( &ppszg.st, globalArgv[i] );
// pp_ui_postinit();
return true;
#if 0
bool arMasterSlaveFramework::addInternalTransferField( std::string fieldName,
arDataType dataType,
int numElements );
The pointer argument is omitted, and the numElements argument now denotes the initial size. The size can be changed by calling:
bool arMasterSlaveFramework::setInternalTransferFieldSize( std::string fieldName,
arDataType dataType,
int newSize );
#endif
void Ppszg::onWindowStartGL( arGUIWindowInfo * ) {
set_dsp_context( 0 ); /* assign a display context, so texture code can track window changes */
}
void Ppszg::onPreExchange( void ) { // called on master only
// do navigation...
// process commands read from network...
// and package any with
/* Here we want to do the listening on the sockets to interpret
* any commands we might receive over them
*/
static int socketid = 0;
if(ppszg.listenSocket == 0) {
// Create listener socket. Do this only in a *live* master
/* arSockets - originally from salimiman by Jim Crowell */
/* I'm not sure if some of this should be done elsewhere */
msg("master on pid %d listening on port 8675", processid);
listenSocket = new arSocket(AR_LISTENING_SOCKET);
listenSocket->ar_create();
listenSocket->setSendBufferSize(2048);
listenSocket->setReceiveBufferSize(2048);
listenSocket->reuseAddress(true);
list<string> acceptMask;
listenSocket->setAcceptMask(acceptMask);
/* Bind to port 8675 */
listenSocket->ar_bind(NULL, 8675);
listenSocket->ar_listen(256);
}
if(ppszg.listenSocket->readable())
{
bufferedSocket* sockp = new bufferedSocket();
arSocketAddress addr;
ppszg.listenSocket->ar_accept(sockp, &addr);
warn("pid %d accepted connection", processid);
sockp->setID(socketid++);
sockp->next = ppszg.socketList;
ppszg.socketList = sockp;
cmdbuf_.clear(); // wipe master->slaves buffer for this cycle
/* Now read data into the buffer */
bufferedSocket* sock = ppszg.socketList;
bufferedSocket** previousSocketp = &ppszg.socketList;
int len = sock->poll();
while(len >= 0) { // repeat for all the lines in buffer
int maxargs = len/2 + 2; // max possible number of args
char **av = new char *[maxargs];
char tbuf[ 2*len + 1024 ];
// temp buffer. Extra room allows for $expansion etc.
// XXX should pass this length to tokenize!
int ac = tokenize( sock->str(), tbuf, maxargs, av, NULL );
if(ac > 0) {
// Not a comment nor a blank line. Try to parse it locally.
if( ! specks_parse_args( &ppszg.st, ac, av ) ) {
msg("Unrecognized control command: %s", sock->str());
}
// In any case, pass it on to slaves
PpCmd cmd( CMD_CONTROL, ac, av );
cmd.freezeInto( cmdbuf_ );
}
delete av;
len = sock->consume(); // Done processing that line. Got another on hand?
}
if(sock->expired()) {
*previousSocketp = sock->next;
delete sock;
} else {
previousSocketp = &sock->next;
}
sock = *previousSocketp;
}
// Now ship bundled commands to slaves
if(cmdbuf_.size() == 0)
cmdbuf_.append( 1, '\000' ); // ensure nonzero size
setInternalTransferFieldSize( "commands", AR_CHAR, cmdbuf_.size() );
if(cmdbuf_.size() > 1 && getenv("CMDTEST")) {
PpCmd tcmd;
int offset = 0;
int room = cmdbuf_.size();
msg("Got %d-bytes of command packet", room-1); // XXX DEBUG
while(offset+1 < room) {
int oof = offset;
if( tcmd.thawFrom( &cmdbuf_[0], offset, false ) < 0)
break;
// false -> build argc/argv which point into cmdp string directly
msg("Offset %d..%d: command [%d] %s", oof,offset, tcmd.argc, rejoinargs( 0, tcmd.argc, tcmd.argv ));
if(tcmd.argc <= 0 || oof == offset) {
msg("Had enough: tcmd.argc=%d, offset %d, room %d", tcmd.argc, offset, room);
break;
}
}
}
int room = 0;
char *cmdp = (char *)getTransferField( "commands", AR_CHAR, room );
if(cmdp == 0 || room != cmdbuf_.size()) {
msg("panic: transfer field size %d != the size %d we told it to be!\n",
room, cmdbuf_.size());
} else {
memcpy( cmdp, &cmdbuf_[0], room );
}
/*
* Added July 23, 2008 William Davis
* Forces the framework to listen to updates to navigation matrix
* changed from a "jump" command
*/
navUpdate();
clock_tick( ppszg.clk ); // let time advance
}
void Ppszg::onPostExchange( void ) // called on master + slaves
{
if(! this->getMaster() ) {
// We're a slave. Decode any commands passed by master this cycle.
int room = 0;
char *cmdp = (char *)getTransferField( "commands", AR_CHAR, room );
if(cmdp == 0) {
static int once = 1;
if(once) msg("Ppszg::onPostExchange: can't get transfer field \"commands\"");
once = 0;
return;
}
#if 0
if(room > 1) {
msg("postExchange: GOT %d-bytes of cmd pkt", room-1);
char unk[512];
int u,uu;
for(u=uu=0; u<room; u++)
uu += sprintf(&unk[uu], cmdp[u]<' ' ? "\\x%02x" : "%c", cmdp[u]);
unk[uu] = '\0';
msg("Received: \"%s\"", unk); // XXX debug
}
#endif
int oof = offset;
bool done;
done = (pp.thawFrom( cmdp, offset, false ) < 0);
// false -> build argc/argv which point into cmdp string directly
if(done || oof >= offset || pp.argc <= 0) {
msg("Had enough of cmd pkt: done %d offset %d was %d, room %d, argc %d, type 0x%x", done, offset, oof, room, pp.argc, pp.type);
break;
}
msg("postExchange: processing '%s'", rejoinargs(0,pp.argc,pp.argv));
if(pp.type == CMD_CONTROL) {
if(! specks_parse_args( &ppszg.st, pp.argc, pp.argv ) ) {
warn("Unrecognized control command on slave: %s",
rejoinargs( 0, pp.argc, pp.argv ));
}
} else {
warn("can only handle control cmds, not: %s",
rejoinargs(0, pp.argc, pp.argv));
}
}
}
/* terminate if we're asked to... */
/* is this the right way to do this? */
if(ppszg.quitnow_)
exit(0);
}
void Ppszg::onWindowInit( void ) { // clear to background...
glClearColor( bgcolor.x[0], bgcolor.x[1], bgcolor.x[2], 1 );
ar_defaultWindowInitCallback();
}
void Ppszg::onDraw( arGraphicsWindow& win, arViewport& vp ) {
/*
* Addded July 23, 2008 William Davis
* Loads the navigation matrix into the framework, making
* sure we listen to the changes enacted by the "jump" command
* in parti_setc2w()
*/
loadNavMatrix();
scene->draw();
}
void Ppszg::onDisconnectDraw( void ) {
glClearColor( 1, .1, .1, 1 );
glClear( GL_COLOR_BUFFER_BIT );
}
void Ppszg::onCleanup( void ) {
}
void Ppszg::onUserMessage( const string& messageBody ) {
// called in master on "dex <N> user <some message for this program>"
// parse messageBody, add to command queue for next preExchange time
}
#ifdef __linux__
#include <GL/glut.h> // hack: Syzygy uses glutWireSphere() in simulator mode, but freeglut insists on glutInit() first
#endif
int main(int argc, char *argv[])
{
#ifdef __linux__
int targc = 1; // rest of hack.
glutInit( &targc, argv );
#endif
globalArgc = argc; //Make these two variables accessible to the
globalArgv = argv; // onStart callback
if( ! ppszg.init( argc, argv ) ) {
fprintf(stderr, "arMasterSlaveFramework::init() failed, giving up...\n");
exit(1);
}
if( ! ppszg.start() ) {
fprintf(stderr, "arMasterSlaveFramework::start() failed, giving up...\n");
exit(1);
}
// Shouldn't reach here.
fprintf(stderr, "Shouldn't reach here.\n");
exit(2);
}