diff -ruN '-x*.h' '-x*.Po' '-x*.o' '-x*.a' 0.2.8-armagetronad-sty+ct/src/render/input.cpp /usr/src/0.2.8-armagetronad-sty+ct/src/render/input.cpp --- 0.2.8-armagetronad-sty+ct/src/render/input.cpp 1970-01-01 03:00:00.000000000 +0300 +++ /usr/src/0.2.8-armagetronad-sty+ct/src/render/input.cpp 2012-05-16 21:47:49.049074903 +0400 @@ -0,0 +1,151 @@ +#ifndef WIN32 +#include +#include +#include +#include "tCommandLine.h" + +class rStream: public tReferencable< rStream > +{ + rStream( rStream const & other ); +public: + rStream(){}; + virtual ~rStream(){}; + // reads from the descriptor and + // executes commands on newlines. + // Return value of 'false' means the stream should be removed. + virtual bool HandleInput(){ return true; } + // writes output to potential scripts + virtual void Output( char const * output ){} +}; +class rInputStream: public rStream +{ +public: + typedef int Descriptor; + rInputStream() + { + descriptor_ = fileno(stdin); + file_ = NULL; + Unblock(); + } + rInputStream( Descriptor descriptor, char const * name, FILE * file = NULL ) + : descriptor_( descriptor ), file_( file ), name_( name ) + { + Unblock(); + } + // reads from the descriptor and + // executes commands on newlines + bool HandleInput(); + ~rInputStream() + { + if( file_ ) + { + fclose( file_ ); + file_ = NULL; + } + } + tString const & GetName() + { + return name_; + } +protected: + Descriptor descriptor_; + FILE * file_; + tString name_; +private: + void Unblock() + { + int flag=fcntl(descriptor_,F_GETFL); + fcntl(descriptor_,F_SETFL,flag | O_NONBLOCK); + } + tString line_in_; +}; +bool rInputStream::HandleInput() +{ + // stdin commands are executed at owner level + tCurrentAccessLevel level( tAccessLevel_Owner, true ); + tConfItemBase::LoadPlayback( true ); + char c = 0; + int lenRead; + while ( (lenRead=read(descriptor_,&c,1))>0){ + line_in_ << c; + if (c=='\n') + { + std::istringstream s((char const *)line_in_); + if( name_.Len() > 1 ) + { + con << name_ << " : " << line_in_; + } + tConfItemBase::LoadAll(s, true); + line_in_=""; + } + } + // 0 return on lenRead means end of file, + // -1 means an error unless errno has these specific values, + // in which case there is just no data currently. + return ( lenRead == -1 && ( errno == EAGAIN || errno == EWOULDBLOCK ) ) || ( lenRead == 0 && file_ ); +} + + +static tArray< tJUST_CONTROLLED_PTR< rStream > > sr_inputStreams; + + +void sr_Read_stdin(){ + static bool inited = false; + if( !inited ) + { + inited = true; + sr_inputStreams[sr_inputStreams.Len()]= tNEW(rInputStream)(); + } + for( int i = sr_inputStreams.Len()-1; i >= 0; --i ) + { + if( !sr_inputStreams[i]->HandleInput() ) + { + // delete stream + if( i < sr_inputStreams.Len()-1 ) + { + sr_inputStreams[i] = sr_inputStreams[ sr_inputStreams.Len()-1 ]; + } + else + { + sr_inputStreams[i] = 0; + } + sr_inputStreams.SetLen( sr_inputStreams.Len()-1 ); + } + } +} + + +class rInputCommandLineAnalyzer: public tCommandLineAnalyzer +{ +public: + virtual bool DoAnalyze( tCommandLineParser & parser ) + { + tString pipe; + if( parser.GetOption( pipe, "--input" ) ) + { + FILE * f = fopen( pipe, "r" ); + if( f ) + { + sr_inputStreams[sr_inputStreams.Len()] = tNEW(rInputStream)( fileno(f), pipe, f ); + fseek( f, 0, SEEK_END ); + } + else + { + std::cerr << "Error opening input file '" << pipe << "': " + << strerror( errno ) << ". Using stdin to poll for input.\n"; + } + + return true; + } + return false; + } + + virtual void DoHelp( std::ostream & s ) + { // + s << "--input : Poll for input from this file in addition to/instead of\n" + << " (if -d is also given) stdin. Can be used multiple times.\n"; + } +}; +static rInputCommandLineAnalyzer sr_analyzer; + +#endif diff -ruN '-x*.h' '-x*.Po' '-x*.o' '-x*.a' 0.2.8-armagetronad-sty+ct/src/render/rConsoleGraph.cpp /usr/src/0.2.8-armagetronad-sty+ct/src/render/rConsoleGraph.cpp --- 0.2.8-armagetronad-sty+ct/src/render/rConsoleGraph.cpp 2012-04-17 16:29:37.000000000 +0400 +++ /usr/src/0.2.8-armagetronad-sty+ct/src/render/rConsoleGraph.cpp 2012-05-16 22:02:00.537297204 +0400 @@ -231,9 +231,16 @@ return tSysTimeFloat() - center_fadetime < 1.5; } +#include "input.cpp" // passes ladderlog output to external scripts (do nothing here) void sr_InputForScripts( char const * input ) -{} +{ + for( int i = sr_inputStreams.Len()-1; i >= 0; --i ) + { + sr_inputStreams[i]->Output( input ); + } +} + #else #include "rConsoleCout.cpp" diff -ruN '-x*.h' '-x*.Po' '-x*.o' '-x*.a' 0.2.8-armagetronad-sty+ct/src/tron/gGame.cpp /usr/src/0.2.8-armagetronad-sty+ct/src/tron/gGame.cpp --- 0.2.8-armagetronad-sty+ct/src/tron/gGame.cpp 2012-04-05 15:41:57.000000000 +0400 +++ /usr/src/0.2.8-armagetronad-sty+ct/src/tron/gGame.cpp 2012-05-16 21:50:40.821926665 +0400 @@ -1563,6 +1563,7 @@ bool newsg_singlePlayer = (humans<=1); #else + sr_Read_stdin(); //+++ bool newsg_singlePlayer = (sn_GetNetState() == nSTANDALONE); #endif if (sg_singlePlayer != newsg_singlePlayer && bool( sg_currentGame ) ) @@ -3725,6 +3726,7 @@ } } #endif + sr_Read_stdin(); //+++ // pings should not count as much in the between-round phase nPingAverager::SetWeight(1E-20); @@ -4946,6 +4948,7 @@ } } #endif + sr_Read_stdin(); //+++ // do the regular simulation tAdvanceFrame();