Newer
Older
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...
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
// 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();
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
}
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);
}