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

📄 client.h

📁 在LINUX下运行的仿真机器人服务器源代码
💻 H
字号:
// -*-c++-*-/***************************************************************************                          client.h  -  A basic client that connects to                          the server                             -------------------    begin                : 27-DEC-2001    copyright            : (C) 2001 by The RoboCup Soccer Server                            Maintenance Group.    email                : sserver-admin@lists.sourceforge.net ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU LGPL as published by the Free Software  * *   Foundation; either version 2 of the License, or (at your option) any  * *   later version.                                                        * *                                                                         * ***************************************************************************/#ifndef TESTCLIENT_H#define TESTCLIENT_H#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <rcssbase/net/udpsocket.hpp>#include <cstdio>#include <netdb.h>#include <rcssbase/net/socketstreambuf.hpp>#include <rcssbase/thread.h>#include "param.h"#include "compress.h"#include <cerrno>#include <fstream>#include <iostream>#include "utility.h"//  #include "test_8x8.xpm"#include <rcssbase/messagequeue.h>#include <rcssbase/sharedvar.h>#ifdef HAVE_SSTREAM#include <sstream>#else#include <strstream>#endif#include <rcssbase/gz/gzstream.hpp>#ifdef HAVE_LIBNCURSES#include <ncurses.h>#endifclass Client{private:  //friend  class ServerReader  {  private:    Client& M_client;    std::istream& M_src;  public:    ServerReader( Client& client,                  std::istream& src                  )      : M_client( client ),        M_src( src )    {}    ~ServerReader()    {}    void    operator()()    {      while( M_src.good() )        {          char buffer[ 8192 ];          M_src.getline( buffer, 8192, 0 );          M_client.processInput( buffer );        }      M_client.displayError( "Error receiving from server" );    }  };  //friend  class ServerWriter  {  private:    Client& M_client;    std::ostream& M_dest;  public:    ServerWriter( Client& client,                  std::ostream& dest )      : M_client( client ),        M_dest( dest )    {}    ~ServerWriter()    {}    void    operator()()    {      while( M_dest.good() )        {          char buffer[ 8192 ];          M_client.getData( buffer, 8192 );          M_dest << buffer << std::ends << std::flush;        }      M_client.displayError( "Error sending to server" );    }  };  rcss::net::UDPSocket M_socket;  rcss::net::SocketStreamBuf M_write_strmbuf;  rcss::net::SocketStreamBuf M_read_strmbuf;  rcss::gz::gzostream M_write_strm;  rcss::gz::gzistream M_read_strm;  rcss::thread::SharedVar< bool > M_cycle_is_clean;  rcss::thread::MessageQueue< int > M_level;  ServerWriter M_server_writer;  rcss::thread::Thread M_server_writer_thread;  ServerReader M_server_reader;  rcss::thread::Thread M_server_reader_thread;  void  setCompression( int level )  {    M_write_strm.setLevel( level );    M_read_strm.setLevel( level );    M_level.queueMessage( level );  }  void  waitForCompressionChange( long seconds, long nanoseconds = 0 )  {    try { M_level.getNext( seconds, nanoseconds ); }    catch(...) {}  }  void  processInput( const char* buffer )  {    doProcessInput( buffer );    { // limit the scope of the lock      rcss::thread::SharedVar< bool >::Lock lock( M_cycle_is_clean );      if( !M_cycle_is_clean.get( lock )           && ( strncmp( buffer, "(sense_body", 11 ) == 0               || strncmp( buffer, "(see_global", 11 ) == 0               || strncmp( buffer, "(init", 5 ) == 0 ) )        {          M_cycle_is_clean = true;          M_cycle_is_clean.signal();        }    }    if( !strncmp( buffer, "(ok compression", 15 ) )      {        int level;        if( sscanf( buffer, "(ok compression %d)", &level ) == 1 )          setCompression( level );      }    else if( strncmp( buffer, "(warning compression_unsupported)", 34 ) == 0 )      setCompression( -1 );  }  virtual  void  doProcessInput( const char* buffer ) = 0;        void    getData( char* buffer, int size )    {        static int compression_wait = false;        doGetData( buffer, size );        if( compression_wait )        {            waitForCompressionChange( 5 );            compression_wait = false;        }        {            rcss::thread::SharedVar< bool >::Lock lock( M_cycle_is_clean );            displayError( "Got lock\n" );            while( !M_cycle_is_clean.get( lock ) )                M_cycle_is_clean.wait( lock );            M_cycle_is_clean = false;        }        if( strncmp( "(compression", buffer, 12 ) == 0 )            compression_wait = true;    }    virtual  void  doGetData( char* buffer, int size ) = 0;  void  displayError( const char* msg )  { doDisplayError( msg ); }  virtual  void  doDisplayError( const char* msg ) = 0;public:    Client( const rcss::net::Addr dest )    : M_socket(),      M_write_strmbuf( M_socket, dest ),      M_read_strmbuf( M_socket, dest ),      M_write_strm( M_write_strmbuf ),      M_read_strm( M_read_strmbuf ),      M_cycle_is_clean( true ),      M_server_writer( *this, M_write_strm ),      M_server_writer_thread( M_server_writer ),      M_server_reader( *this, M_read_strm ),      M_server_reader_thread( M_server_reader )  {    M_write_strm.setLevel( -1 );    M_read_strm.setLevel( -1 );  }  virtual ~Client()  {}  void  start()  {    M_server_writer_thread.start();    M_server_reader_thread.start();    M_server_writer_thread.join();    M_server_reader_thread.cancel();        M_server_reader_thread.join();      }};class NoGuiClient  : public Client{private:  virtual  void  doProcessInput( const char* buffer )  { std::cout << buffer << std::endl; }  virtual  void  doGetData( char* buffer, int size )  { std::cin.getline( buffer, size ); }  virtual  void  doDisplayError( const char* msg )  { std::cerr << msg << std::endl; }  public:    NoGuiClient( const rcss::net::Addr& dest )        : Client( dest )    {        std::cout << "Sending to " << dest << std::endl;    }      virtual  ~NoGuiClient()  {}};#ifdef HAVE_LIBNCURSESclass NCursesClient  : public Client{private:  int M_height;  int M_width;  WINDOW* M_output_win_border;  WINDOW* M_output_win;  WINDOW* M_visual_win;  WINDOW* M_sb_win;  WINDOW* M_other_win;  WINDOW* M_input_win;  WINDOW* M_input_header;  virtual  void  doProcessInput( const char* buffer )  {    int size = strlen( buffer );    if( size >= 4 && strncmp( buffer, "(see", 4 ) == 0 )      {        wclear( M_visual_win );        mvwaddstr( M_visual_win, 0, 0, buffer );        wrefresh( M_visual_win );      }    else if( size >= 6 && strncmp( buffer, "(sense", 6 ) == 0 )      {        wclear( M_sb_win );        mvwaddstr( M_sb_win, 0, 0, buffer );        wrefresh( M_sb_win );      }    else      {        wclear( M_other_win );        mvwaddstr( M_other_win, 0, 0, buffer );        wrefresh( M_other_win );      }  }  virtual  void  doGetData( char* buffer, int size )  {    int idx = 0;    char curr;    do      {        curr = getch();        if( curr == 74 || curr == 7 )          {            if( idx > 0 )              {                --idx;                mvwaddch( M_input_win, 1, idx + 3, ' ' );                mvwaddch( M_input_win, 1, idx + 2, '_' | A_BLINK | A_BOLD );                wrefresh( M_input_win );              }          }        else if( curr == 0 || curr == '\n' || curr == EOF )          {            curr = 0;            buffer[ idx ] = curr;            ++idx;            wclear( M_input_win );            mvwaddstr( M_input_win, 0, 0, "> " );            waddstr( M_input_win, buffer );            mvwaddstr( M_input_win, 1, 0, "> " );            waddch( M_input_win, '_' | A_BLINK | A_BOLD );            wrefresh( M_input_win );          }        else          {            mvwaddch( M_input_win, 1, idx + 2, curr | A_BOLD );            mvwaddch( M_input_win, 1, idx + 3, '_' | A_BLINK | A_BOLD );            wrefresh( M_input_win );            buffer[ idx ] = curr;            ++idx;          }      }    while( idx < size - 1 && curr != 0 );    buffer[ idx ] = 0;  }  virtual  void  doDisplayError( const char* msg )  {     wclear( M_other_win );    mvwaddstr( M_other_win, 0, 0, msg );    wrefresh( M_other_win );  }  public:    NCursesClient( const rcss::net::Addr& dest )    : Client( dest )  {    initscr();    cbreak();    noecho();    curs_set( 0 );    refresh();    int height, width;    getmaxyx( stdscr, height, width );    keypad( stdscr, true );    WINDOW* header = newwin( 1, width, 0, 0 );    wattron( header, A_REVERSE );    wbkgdset( header, A_REVERSE );    wclear( header );    mvwprintw( header, 0, 2, "RCSSClient-%s",               VERSION );#ifdef HAVE_SSTREAM        std::ostringstream tmp;#else        std::ostrstream tmp;#endif    tmp << dest;#ifndef HAVE_SSTREAM    tmp << std::ends;#endif#ifdef HAVE_SSTREAM    mvwaddstr( header, 0, width - tmp.str().length() - 2, tmp.str().c_str() );#else    mvwaddstr( header, 0, width - strlen( tmp.str() ) - 2, tmp.str() );    tmp.freeze( false );#endif    wrefresh( header );        getmaxyx( stdscr, M_height, M_width );    int outheight = M_height - 4;    M_output_win = newwin( outheight, M_width, 1, 0 );    wbkgdset( M_output_win, ACS_HLINE | A_REVERSE );    wclear( M_output_win );    wbkgdset( M_output_win, A_REVERSE );    int visheight = ( outheight + 1 ) / 2 - 1;    M_visual_win = subwin( M_output_win, visheight, M_width, 2, 0 );    wbkgdset( M_visual_win, A_NORMAL );    wclear( M_visual_win );    int sbheight = visheight / 2;    M_sb_win = subwin( M_output_win, sbheight, M_width, 3 + visheight, 0 );    wbkgdset( M_sb_win, A_NORMAL );    wclear( M_sb_win );    int otherheight = outheight - visheight - sbheight - 3;    M_other_win = subwin( M_output_win, otherheight, M_width,                          outheight-otherheight+1, 0 );    wbkgdset( M_other_win, A_NORMAL );    wclear( M_other_win );    wattron( M_output_win, A_REVERSE );    mvwaddstr( M_output_win, 0, 2, " Visuals " );    mvwaddstr( M_output_win, 1 + visheight, 2, " Sense Body " );    mvwaddstr( M_output_win, outheight-otherheight-1, 2, " Other " );    wattroff( M_output_win, A_REVERSE );    wrefresh( M_output_win );        M_input_header = newwin( 1, M_width, M_height-3, 0 );    M_input_win = newwin( 2, M_width, M_height-2, 0 );    wbkgdset( M_input_header, ACS_HLINE | A_STANDOUT );    wclear( M_input_header );    wbkgdset( M_input_header, A_STANDOUT );    mvwaddstr( M_input_header, 0, 2, " Input " );    wrefresh( M_input_header );    mvwaddstr( M_input_win, 1, 0, "> " );    mvwaddch( M_input_win, 1, 2, '_' | A_BLINK | A_BOLD );    wrefresh( M_input_win );  }  ~NCursesClient()  {    delwin( M_visual_win );    delwin( M_sb_win );    delwin( M_other_win );    delwin( M_output_win );    delwin( M_output_win_border );        delwin( M_input_win );    delwin( M_input_header );    endwin();  }};#endif // HAVE_LIBNCURSES#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -