Skip to content
Snippets Groups Projects
szgPartiview.cc 32 KiB
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] );

#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;
  while( sock != NULL ) {
	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?
	}
	   *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();

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

#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);
}