⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acthandler.cpp

📁 自己写的robocup-2d程序
💻 CPP
字号:
/*
Copyright (c) 2000-2003, Jelle Kok, University of Amsterdam
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list 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 documentation
and/or other materials provided with the distribution.

3. Neither the name of the University of Amsterdam nor the names of its
contributors may be used to endorse or promote products derived from this
software 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, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF 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>     // SIGALARM

ActHandler* 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 WIN32
extern void CALLBACK sigalarmHandler(UINT , UINT , DWORD , DWORD , DWORD )
#else
extern 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 + -