*/
00047 #include "ActHandler.h"
00048
00049 #include // poll
00050 #include // poll
00051 #include // SIGALARM
00052
00053 ActHandler* ACT;
00061 extern void sigalarmHandler( int i )
00062 {
00063 ACT->sendCommands( );
00064 }
00065
00071 ActHandler::ActHandler( Connection *c, WorldModel *wm, ServerSettings *ss )
00072 {
00073 connection = c;
00074 SS = ss;
00075 WM = wm;
00076
00077 m_iMultipleCommands = 0;
00078 ACT = this; // needed to let signal call method from class
00079 }
00080
00082 void ActHandler::emptyQueue( )
00083 {
00084 m_queueOneCycleCommand.commandType = CMD_ILLEGAL;
00085 for( int i = 0; i < MAX_COMMANDS - 1 ; i ++ )
00086 m_queueMultipleCommands.commandType = CMD_ILLEGAL;
00087 m_iMultipleCommands=0;
00088 }
00089
00092 bool ActHandler::isQueueEmpty()
00093 {
00094 return m_queueOneCycleCommand.commandType == CMD_ILLEGAL &&
00095 m_iMultipleCommands == 0;
00096 }
00097
00106 bool ActHandler::sendCommands( )
00107 {
00108 static Time timeLastSent = -1;
00109 bool bNoOneCycle = false;
00110 char strCommand[MAX_MSG];
00111 strCommand[0] = '\0';
00112
00113 if( WM->getCurrentTime() == timeLastSent )
00114 {
00115 Log.logWithTime( 2, " already sent message; don't send" );
00116 return false;
00117 }
00118
00119 if( WM->isQueuedActionPerformed() == false && // don't send action when
00120 m_queueOneCycleCommand.commandType != CMD_CATCH) // previous one is not
00121 { // not processed yet
00122 Log.logWithTime( 2, " previous message not processed yet; don't send" );
00123 return false; // except with catch since
00124 } // too important
00125
00126 // make string of primary action and put it in 'strCommand' variable
00127 m_queueOneCycleCommand.getCommandString( strCommand, SS );
00128
00129 if( strCommand[0] == '\0' )
00130 {
00131 bNoOneCycle = true;
00132 Log.logWithTime( 2, " no primary action in queue" );
00133 }
00134
00135 // make string of all other commands and add them to the end of 'strCommand'
00136 for( int i = 0; i < m_iMultipleCommands ; i ++ )
00137 {
00138 m_queueMultipleCommands.getCommandString(
00139 &strCommand[strlen(strCommand)], SS );
00140 }
00141
00142 // send the string to the server (example string: '(dash 100)(turn_neck -19)')
00143 if( strCommand[0] != '\0' )
00144 {
00145 timeLastSent = WM->getCurrentTime();
00146 connection->sendMessage( strCommand );
00147 Log.logWithTime( 2, " send queued action to server: %s", strCommand);
00148 }
00149 else
00150 {
00151 Log.logWithTime( 2, " no action in queue??" );
00152 return false;
00153 }
00154
00155 if( ! bNoOneCycle ) // if primary action was send, place it at end of array
00156 m_queueMultipleCommands[m_iMultipleCommands++] = m_queueOneCycleCommand;
00157
00158 // let worldmodel know which commands were sent to the server
00159 WM->processQueuedCommands( m_queueMultipleCommands, m_iMultipleCommands );
00160 m_iMultipleCommands = 0;
00161
00162 // decrease amount of times primary action still has to be sent, if 0 delete
00163 // it, furthermore set number of multiple commands to zero
00164 if( --m_queueOneCycleCommand.iTimes == 0 )
00165 m_queueOneCycleCommand.commandType = CMD_ILLEGAL;
00166
00167 for( int i = 0; i < MAX_COMMANDS; i++ )
00168 m_queueMultipleCommands.commandType = CMD_ILLEGAL;
00169
00170 return true;
00171 }
00172
00178 bool ActHandler::putCommandInQueue( SoccerCommand command )
00179 {
00180 int i = 0;
00181 bool bOverwritten = false;
00182
00183 if( command.commandType == CMD_ILLEGAL )
00184 return false;
00185 if( SoccerTypes::isPrimaryCommand( command.commandType ) )
00186 m_queueOneCycleCommand = command; // overwrite primary command
00187 else // non-primary command
00188 {
00189 for( i = 0; i < m_iMultipleCommands ; i ++ )
00190 if( m_queueMultipleCommands.commandType == command.commandType )
00191 {
00192 m_queueMultipleCommands = command; // if command already in queue
00193 bOverwritten = true; // overwrite it
00194 }
00195
00196 // 1 less to save space for primary command
00197 if( bOverwritten == false && m_iMultipleCommands == MAX_COMMANDS-1 )
00198 {
00199 cerr << "(ActHandler::putCommandInQueue) too many commands" << endl;
00200 return false;
00201 }
00202 if( bOverwritten == false ) // add it when command was not yet in queue
00203 m_queueMultipleCommands[m_iMultipleCommands++] = command;
00204 }
00205
00206 return true;
00207 }
00208
00214 bool ActHandler::sendCommand( SoccerCommand soc )
00215 {
00216 char strCommand[MAX_MSG];
00217 soc.getCommandString( strCommand, SS );
00218 return sendMessage( strCommand );
00219 }
00220
00226 bool ActHandler::sendMessage( char * str )
00227 {
00228 emptyQueue( );
00229 poll( 0, 0, SS->getSimulatorStep() );
00230
00231 bool bReturn = connection->sendMessage( str );
00232 Log.logWithTime( 2, " send message to server and wait: %s", str);
00233
00234 poll( 0, 0, SS->getSimulatorStep() );
00235 return bReturn;
00236 }
00237
00243 bool ActHandler::sendCommandDirect( SoccerCommand soc )
00244 {
00245 char strCommand[MAX_MSG];
00246 if( soc.commandType == CMD_ILLEGAL )
00247 return false;
00248 soc.getCommandString( strCommand, SS );
00249 return sendMessageDirect( strCommand );
00250 }
00251
00255 bool ActHandler::sendMessageDirect( char * str )
00256 {
00257 bool bReturn = connection->sendMessage( str );
00258 Log.logWithTime( 2, " send message to server directly: %s", str);
00259 return bReturn;
00260 }
00261
|