Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 20, 2009, 4:27:38 PM (15 years ago)
Author:
scheusso
Message:

merged netp4 back to trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/orxonox/gamestates/GSDedicated.cc

    r3196 r3198  
    3333#include "core/Clock.h"
    3434#include "core/CommandLine.h"
     35#include "core/CommandExecutor.h"
    3536#include "core/Game.h"
    3637#include "core/GameMode.h"
    3738#include "network/Server.h"
    3839
     40#include <iostream>
     41#include <iomanip>
     42#include <boost/bind.hpp>
     43
     44#ifndef ORXONOX_PLATFORM_WINDOWS
     45#include <termios.h>
     46#endif
     47
     48
    3949namespace orxonox
    4050{
     51    const unsigned int MAX_COMMAND_LENGTH = 255;
     52   
    4153    AddGameState(GSDedicated, "dedicated");
     54   
     55    termios* GSDedicated::originalTerminalSettings_;
    4256
    4357    GSDedicated::GSDedicated(const std::string& name)
     
    4559        , server_(0)
    4660        , timeSinceLastUpdate_(0)
    47     {
     61        , closeThread_(false)
     62        , inputIterator_(0)
     63        , cleanLine_(true)
     64        , cursorX_(0)
     65        , cursorY_(0)
     66    {
     67        this->commandLine_ = new unsigned char[MAX_COMMAND_LENGTH];
     68//         memset( this->commandLine_, 0, MAX_COMMAND_LENGTH );
    4869    }
    4970
     
    5576    {
    5677        GameMode::setHasServer(true);
     78       
     79        this->inputThread_ = new boost::thread(boost::bind(&GSDedicated::inputThread, this));
     80       
     81#ifndef ORXONOX_PLATFORM_WINDOWS
     82        this->originalTerminalSettings_ = new termios;
     83        this->setTerminalMode();
     84#endif
    5785
    5886        this->server_ = new Server(CommandLine::getValue("port"));
     
    6694        this->server_->close();
    6795        delete this->server_;
     96       
     97        closeThread_ = true;
     98#ifndef ORXONOX_PLATFORM_WINDOWS
     99        std::cout << "\033[0G\033[K";
     100        std::cout.flush();
     101        resetTerminalMode();
     102        delete this->originalTerminalSettings_;
     103#endif
     104        //inputThread_->join();
    68105
    69106        GameMode::setHasServer(false);
     
    72109    void GSDedicated::update(const Clock& time)
    73110    {
    74 //        static float startTime = time.getSecondsPrecise();
    75 //        static int nrOfTicks = 0;
    76111        timeSinceLastUpdate_ += time.getDeltaTime();
    77112        if (timeSinceLastUpdate_ >= NETWORK_PERIOD)
    78113        {
    79 //            ++nrOfTicks;
    80 //            COUT(0) << "estimated ticks/sec: " << nrOfTicks/(time.getSecondsPrecise()-startTime) << endl;
    81114            timeSinceLastUpdate_ -= static_cast<unsigned int>(timeSinceLastUpdate_ / NETWORK_PERIOD) * NETWORK_PERIOD;
    82115            server_->update(time);
     
    84117        else
    85118        {
    86             usleep((int)((NETWORK_PERIOD - timeSinceLastUpdate_) * 1000 * 1000));
     119            usleep((unsigned int)((NETWORK_PERIOD - timeSinceLastUpdate_)*1000*1000 ));
     120            usleep(NETWORK_PERIOD*1000*1000); // NOTE: this is to throttle the non-network framerate
    87121//            COUT(0) << "sleeping for " << (int)((NETWORK_PERIOD - timeSinceLastUpdate_) * 1000 * 1000) << " usec" << endl;
    88122        }
    89     }
     123        processQueue();
     124        printLine();
     125    }
     126   
     127    void GSDedicated::inputThread()
     128    {
     129        unsigned char c;
     130        unsigned int  escapeChar=0;
     131        while(!closeThread_)
     132        {
     133            c = getchar();
     134            {
     135//                 boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
     136                if ( inputIterator_>=MAX_COMMAND_LENGTH-1 && c!='\n' )
     137                    continue;
     138                if( escapeChar > 0 )
     139                {
     140                    if( c == '[' )
     141                    {
     142                        escapeChar = 2;
     143                        continue;
     144                    }
     145                    else if ( escapeChar == 2 )
     146                    {
     147                        switch (c)
     148                        {
     149                            case 'A': //keyup
     150                               
     151                                break;
     152                            case 'B': //keydown
     153                               
     154                                break;
     155                            case 'C': //keyright
     156                                if(cursorX_<inputIterator_)
     157                                    ++cursorX_;
     158                                break;
     159                            case 'D': //keyleft
     160                                if(cursorX_>0)
     161                                    --cursorX_;
     162                                break;
     163                            default: //not supported...
     164//                                 std::cout << endl << c << endl;
     165                                break;
     166                        }
     167                        escapeChar = 0;
     168                    }
     169                }
     170                else // not in escape sequence mode
     171                {
     172                    switch (c)
     173                    {
     174                        case '\n':
     175                            this->cleanLine_ = true;
     176                            {
     177                                boost::recursive_mutex::scoped_lock(this->inputQueueMutex_);
     178                                boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
     179                                this->commandQueue_.push( std::string((const char*)this->commandLine_,inputIterator_) );
     180                            }
     181                            memset( this->commandLine_, 0, inputIterator_ );
     182                            inputIterator_ = 0;
     183                            this->cursorX_ = 0;
     184                            this->cursorY_ = 0;
     185                            std::cout << endl;
     186                            break;
     187                        case 127: // backspace
     188                        case '\b':
     189                            deleteCharacter( this->cursorX_ );
     190                            break;
     191                        case '\t':
     192                        {
     193//                             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
     194                            std::cout << endl << CommandExecutor::hint( std::string((const char*)this->commandLine_,inputIterator_) ) << endl;
     195                            strncpy((char*)this->commandLine_, CommandExecutor::complete( std::string((const char*)this->commandLine_,inputIterator_) ).c_str(), MAX_COMMAND_LENGTH);
     196                            inputIterator_ = strlen((const char*)this->commandLine_);
     197                            break;
     198                        }
     199                        case '\033': // 1. escape character
     200                            escapeChar = 1;
     201                            break;
     202                        default:
     203                            insertCharacter( this->cursorX_, c );
     204                            break;
     205                    }
     206                }
     207            }
     208        }
     209    }
     210   
     211    void GSDedicated::printLine()
     212    {
     213#ifndef ORXONOX_PLATFORM_WINDOWS
     214        // set cursor to the begining of the line and erase the line
     215        std::cout << "\033[0G\033[K";
     216//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
     217        // print status line
     218        std::cout << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, " << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms avg ticktime # ";
     219        //save cursor position
     220        std::cout << "\033[s";
     221        //print commandLine buffer
     222        std::cout << std::string((const char*)this->commandLine_, inputIterator_);
     223        //restore cursor position and move it cursorX_ to the right
     224        std::cout << "\033[u";
     225        if( this->cursorX_ > 0 )
     226            std::cout << "\033[" << this->cursorX_ << "C";
     227        std::cout.flush();
     228#endif
     229    }
     230   
     231    void GSDedicated::processQueue()
     232    {
     233        std::string tempstr;
     234        {
     235            boost::recursive_mutex::scoped_lock lock1(this->inputQueueMutex_);
     236            while(true)
     237            {
     238                if ( !this->commandQueue_.empty() )
     239                {
     240                    tempstr = this->commandQueue_.front();
     241                    this->commandQueue_.pop();
     242                    lock1.unlock();
     243                }
     244                else
     245                    break;
     246                CommandExecutor::execute(tempstr, true);
     247            }
     248        }
     249    }
     250   
     251    void GSDedicated::setTerminalMode()
     252    {
     253#ifndef ORXONOX_PLATFORM_WINDOWS
     254        termios new_settings;
     255     
     256        tcgetattr(0,this->originalTerminalSettings_);
     257        new_settings = *this->originalTerminalSettings_;
     258        new_settings.c_lflag &= ~( ICANON | ECHO );
     259//         new_settings.c_lflag |= ( ISIG | IEXTEN );
     260        new_settings.c_cc[VTIME] = 0;
     261        new_settings.c_cc[VMIN] = 1;
     262        tcsetattr(0,TCSANOW,&new_settings);
     263        COUT(0) << endl;
     264//       atexit(&GSDedicated::resetTerminalMode);
     265#endif
     266    }
     267   
     268    void GSDedicated::resetTerminalMode()
     269    {
     270#ifndef ORXONOX_PLATFORM_WINDOWS
     271        tcsetattr(0, TCSANOW, GSDedicated::originalTerminalSettings_);
     272#endif
     273    }
     274   
     275    void GSDedicated::insertCharacter( unsigned int position, char c )
     276    {
     277//         std::cout << endl << (unsigned int)c << endl;
     278        // check that we do not exceed MAX_COMMAND_LENGTH
     279        if( inputIterator_+1 < MAX_COMMAND_LENGTH )
     280        {
     281            // if cursor not at end of line then move the rest of the line
     282            if( position != this->inputIterator_ )
     283                    memmove( this->commandLine_+position+1, this->commandLine_+position, this->inputIterator_-position);
     284//             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
     285            this->commandLine_[position] = c;
     286            ++this->cursorX_;
     287            ++this->inputIterator_;
     288        }
     289    }
     290    void GSDedicated::deleteCharacter( unsigned int position )
     291    {
     292//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
     293        if ( this->inputIterator_>0 && position>0 )
     294        {
     295            if ( position != this->inputIterator_ )
     296                memmove( this->commandLine_+position-1, this->commandLine_+position, this->inputIterator_-position);
     297            --this->cursorX_;
     298            --this->inputIterator_;
     299        }
     300    }
     301   
    90302}
Note: See TracChangeset for help on using the changeset viewer.