Skip to content
Snippets Groups Projects
szgPartiview.cc 30.8 KiB
Newer Older
  pp_ui_postinit();

#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;
    arSocketAddress addr;
    ppszg.listenSocket->ar_accept(sockp, &addr);

    if(sockp != NULL)
    {
      if(ppszg.socketList == NULL)
      {
         /*If it's the only connection*/
         sockp->next = NULL;
         ppszg.socketList = sockp;
      }
      else
      {
         /* Put it at the beginning of the list*/
         sockp->next = ppszg.socketList;
         ppszg.socketList = sockp;
      }
      sockp->setID(socketid++);
    }
  }

  cmdbuf_.resize( 0 );		// wipe master->slaves buffer for this cycle

  /* Now read data into the buffer */
  bufferedSocket* sock = ppszg.socketList;
  bufferedSocket* previousSocket = NULL;
  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?
       }
       int destroy = 0;
       if(sock->giveup()) {
           // Remove socket from list, however you do that
           destroy = 1;
           if(previousSocket == NULL)
             ppszg.socketList = sock->next;
           else
             previousSocket->next = sock->next;
       }
       previousSocket = sock;
       sock = sock->next;
       if(destroy)
       {
           previousSocket->ar_close();
           delete previousSocket; 
       }
  }

  // Now ship bundled commands to slaves
  setInternalTransferFieldSize( "commands", AR_CHAR, cmdbuf_.size() );

  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();
void Ppszg::onPostExchange( void ) {	// called on master + slaves
    if(!getMaster()) {
	// We're a slave.  Decode any commands passed by master this cycle.
	int room = 0;
	char *cmdp = (char *)getTransferField( "commands", AR_CHAR, room );
	PpCmd pp;
	int offset = 0;
	while(offset+1 < room) {
	    pp.thawFrom( cmdp, offset, false );
	    // false -> build argc/argv which point into cmdp string directly
	    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
}


int main(int argc, char *argv[])
{
    // What should happen in main() now??  Is this it?

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