📄 acthandler.cpp
字号:
/*Copyright (c) 2000-2003, Jelle Kok, University of AmsterdamAll rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions are met:1. Redistributions of source code must retain the above copyright notice, thislist of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice,this list of conditions and the following disclaimer in the documentationand/or other materials provided with the distribution.3. Neither the name of the University of Amsterdam nor the names of itscontributors may be used to endorse or promote products derived from thissoftware without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLEFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIALDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ORSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVERCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USEOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*//*! \file ActHandler.cpp<pre><b>File:</b> ActHandler.cpp<b>Project:</b> Robocup Soccer Simulation Team: UvA Trilearn<b>Authors:</b> Jelle Kok<b>Created:</b> 28/11/2000<b>Last Revision:</b> $ID$<b>Contents:</b> This file contains the class definitions for the ActHandler that handles the outgoing messages to the server.<hr size=2><h2><b>Changes</b></h2><b>Date</b> <b>Author</b> <b>Comment</b>28/11/2000 Jelle Kok Initial version created</pre>*/#include "ActHandler.h"#ifndef WIN32 #include <poll.h> // poll #include <sys/poll.h> // poll#endif#include <signal.h> // SIGALARMActHandler* ACT; /*!< Pointer to ActHandler class needed by signal handler *//*! This function is executed when a SIGALARM singal arrives. The time this signal comes is defined by the SenseHandler (depending on incoming sense_body messages). When the signal arrives, the commands currently stored in the queue of the ActHandler are send to the server (using the method sendCommands). \param i is ignored */#ifdef WIN32extern void CALLBACK sigalarmHandler(UINT , UINT , DWORD , DWORD , DWORD )#elseextern void sigalarmHandler( int i )#endif{ Log.logFromSignal( 2, "alarm handler!!" ); ACT->sendCommands( );}/*! This is the constructor for the ActHandler class. All the variables are initialized. \param c Connection that is connected with the soccerserver \param wm WorldModel, used to set performed commands \param ss ServerSettings in which server settings are defined */ActHandler::ActHandler( Connection *c, WorldModel *wm, ServerSettings *ss ){ connection = c; SS = ss; WM = wm; m_iMultipleCommands = 0; ACT = this; // needed to let signal call method from class}/*! This method empties the queue in which all the commands are stored. */void ActHandler::emptyQueue( ){ m_queueOneCycleCommand.commandType = CMD_ILLEGAL; for( int i = 0; i < CMD_MAX_COMMANDS - 1 ; i ++ ) m_queueMultipleCommands[i].commandType = CMD_ILLEGAL; m_iMultipleCommands=0;}/*! This method returns whether the current queue contains no commands \return true when queue is empty, false otherwise */bool ActHandler::isQueueEmpty(){ return m_queueOneCycleCommand.commandType == CMD_ILLEGAL && m_iMultipleCommands == 0;}/*! This method converts all commands in the queue to text strings and sends these text strings to the server (connected by Connection). When the server didn't execute the commands from the previous cycle (this information is stored in the WorldModel) the commands in the queue are not sent, since it is probably the case that these commands will be performed this cycle and we don't want a clash (two commands in one cycle). In this case false is returned. \return true when sending of messages succeeded, false otherwise */bool ActHandler::sendCommands( ){ static Time timeLastSent = -1; bool bNoOneCycle = false; char strCommand[MAX_MSG]; strCommand[0] = '\0'; if( WM->getCurrentTime() == timeLastSent ) { Log.logFromSignal( 2, " already sent message; don't send" ); return false; } if( WM->isQueuedActionPerformed() == false && // don't send action when m_queueOneCycleCommand.commandType != CMD_CATCH && // previous one is not WM->isFullStateOn() == false ) // fullstate sense not { // not processed yet Log.logFromSignal( 2, " previous message not processed yet; don't send" ); return false; // except with catch since } // too important // make string of primary action and put it in 'strCommand' variable bool bReturn = m_queueOneCycleCommand.getCommandString( strCommand, SS ); if( bReturn == false ) cerr << WM->getCurrentCycle() << ", " << WM->getPlayerNumber() << " " << "Acthandler::failed to create primary command string" << endl; if( strCommand[0] == '\0' ) { bNoOneCycle = true; Log.logFromSignal( 2, " no primary action in queue" ); } // make string of all other commands and add them to the end of 'strCommand' for( int i = 0; i < m_iMultipleCommands ; i ++ ) { bReturn = m_queueMultipleCommands[i].getCommandString( &strCommand[strlen(strCommand)], SS ); if( bReturn == false ) cerr << WM->getCurrentCycle() << ", " << WM->getPlayerNumber() << " " << "Acthandler::failed to create secondary command string " << m_queueMultipleCommands[i].commandType << endl; } char strComm[MAX_SAY_MSG]; strcpy( strComm, WM->getCommunicationString() ); if( strlen( strComm ) != 0 ) { sprintf( &strCommand[strlen(strCommand)], "(say \"%s\")", strComm ); WM->setCommunicationString( "" ); } // send the string to the server (example string: (dash 100)(turn_neck -19)) if( strCommand[0] != '\0' ) { timeLastSent = WM->getCurrentTime(); connection->sendMessage( strCommand ); Log.logFromSignal( 2, " send queued action to server: %s", strCommand); } else { Log.logFromSignal( 2, " no action in queue??" ); return false; } if( ! bNoOneCycle ) // if primary action was send, place it at end of array m_queueMultipleCommands[m_iMultipleCommands++] = m_queueOneCycleCommand; // let worldmodel know which commands were sent to the server WM->processQueuedCommands( m_queueMultipleCommands, m_iMultipleCommands ); m_iMultipleCommands = 0; // decrease amount of times primary action still has to be sent, if 0 delete // it, furthermore set number of multiple commands to zero if( --m_queueOneCycleCommand.iTimes == 0 ) m_queueOneCycleCommand.commandType = CMD_ILLEGAL; for( int i = 0; i < CMD_MAX_COMMANDS; i++ ) m_queueMultipleCommands[i].commandType = CMD_ILLEGAL; return true;}/*! This method returns the primary command that is currently stored in the queue. */SoccerCommand ActHandler::getPrimaryCommand( ){ return m_queueOneCycleCommand;}/*! This method puts a SoccerCommand in the queue. The last added command will be sent to the soccerserver when the method sendCommands is performed. Normally this is done when a signal set by the SenseHandler arrives. \param command SoccerCommand that should be put in the queue. \return true when command is added, false otherwise (queue is full) */bool ActHandler::putCommandInQueue( SoccerCommand command ){ int i; bool bOverwritten = false; if( command.commandType == CMD_ILLEGAL ) return false; if( SoccerTypes::isPrimaryCommand( command.commandType ) ) m_queueOneCycleCommand = command; // overwrite primary command else // non-primary command { for( i = 0; i < m_iMultipleCommands ; i ++ ) if( m_queueMultipleCommands[i].commandType == command.commandType ) { m_queueMultipleCommands[i] = command; // if command already in queue bOverwritten = true; // overwrite it } // 1 less to save space for primary command if( bOverwritten == false && m_iMultipleCommands == CMD_MAX_COMMANDS-1 ) { cerr << "(ActHandler::putCommandInQueue) too many commands" << endl; return false; } if( bOverwritten == false ) // add it when command was not yet in queue m_queueMultipleCommands[m_iMultipleCommands++] = command; } return true;}/*! This method sends a single command directly to the server. First a string is made from the SoccerCommand and afterwards this string is send to the server using the method sendMessage. \param soc SoccerCommand that should be send to the server. \return true when message was sent, false otherwise */bool ActHandler::sendCommand( SoccerCommand soc ){ char strCommand[MAX_MSG]; soc.getCommandString( strCommand, SS ); return sendMessage( strCommand );}/*! This method sends a single string directly to the server. To make sure this message arrives, the time of one complete cycle is waited before and after the message is sent. \param str string that should be sent to the server \return true when message was sent, false otherwise */bool ActHandler::sendMessage( char * str ){ emptyQueue( );#ifdef WIN32 Sleep( SS->getSimulatorStep() );#else poll( 0, 0, SS->getSimulatorStep() );#endif bool bReturn = connection->sendMessage( str ); Log.logFromSignal( 2, " send message to server and wait: %s", str);#ifdef WIN32 Sleep( SS->getSimulatorStep() );#else poll( 0, 0, SS->getSimulatorStep() );#endif return bReturn;}/*! This method sends a single command directly to the server. First a string is made from the SoccerCommand and afterwards this string is send to the server using the method sendMessageDirect. \param soc SoccerCommand that should be send to the server. \return true when message was sent, false otherwise */bool ActHandler::sendCommandDirect( SoccerCommand soc ){ char strCommand[MAX_MSG]; if( soc.commandType == CMD_ILLEGAL ) return false; soc.getCommandString( strCommand, SS ); return sendMessageDirect( strCommand );}/*! This method sends a single string directly to the server. \param str string that should be sent to the server \return true when message was sent, false otherwise */bool ActHandler::sendMessageDirect( char * str ){ bool bReturn = connection->sendMessage( str ); Log.logFromSignal( 2, " send message to server directly: %s", str); return bReturn;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -