Newer
Older
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->readable())
{
bufferedSocket* sockp = new bufferedSocket();
arSocketAddress addr;
ppszg.listenSocket->ar_accept(sockp, &addr);
sockp->setID(socketid++);
sockp->next = ppszg.socketList;
ppszg.socketList = sockp;
cmdbuf_.resize( 1 ); // 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
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;
tcmd.thawFrom( &cmdbuf_[0], offset, false );
// 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 ));
}
}
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;
}
PpCmd pp;
int offset = 0;
if(room > 1)
msg("Got %d-bytes of command packet", room-1); // XXX DEBUG
while(offset+1 < room) {
pp.thawFrom( cmdp, offset, false );
// false -> build argc/argv which point into cmdp string directly
msg("Processing command %s", rejoinargs( 0, pp.argc, pp.argv )); // XXX DEBUG
if(pp.type == CMD_CONTROL) {
if(! specks_parse_args( &ppszg.st, pp.argc, pp.argv ) ) {
msg("Unrecognized control command on slave: %s",
rejoinargs( 0, pp.argc, pp.argv ));
}
} else {
msg("can only handle control cmds, not: %s",
rejoinargs(0, pp.argc, pp.argv));
}
}
}
}
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);
}