From a8c9924456e5335c964e4e55b2dde1963c88726f Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 17 Feb 2010 01:24:36 +0000 Subject: Added KDE3 version of Knights git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/knights@1091568 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- knights/io_engine.cpp | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100644 knights/io_engine.cpp (limited to 'knights/io_engine.cpp') diff --git a/knights/io_engine.cpp b/knights/io_engine.cpp new file mode 100644 index 0000000..d9a15a7 --- /dev/null +++ b/knights/io_engine.cpp @@ -0,0 +1,312 @@ +/*************************************************************************** + io_engine.cpp - description + ------------------- + begin : Sat Jun 30 2001 + copyright : (C) 2003 by Troy Corbin Jr. + email : tcorbin@users.sourceforge.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include + +#include +#include + +#include +#include +#include + +#include "io_engine.moc" +#include "definitions.h" +#include "proto_base.h" +#include "proto_xboard.h" +#include "proto_uci.h" + +io_engine::io_engine( QWidget *parent, resource *Rsrc ) : io_base( parent, Rsrc ) +{ + myType = io_base::LOCAL; + engine = NULL; + Log = NULL; + proto = NULL; + SafeToSend = TRUE; + CleanBuffer = TRUE; + SendSIGINT = FALSE; + Forced = TRUE; + Protocol = XBoard; + FIFO_In = ""; + FIFO_Out = ""; +} +// +io_engine::~io_engine() +{ + if( engine ) + { + Kill(); + } + if( Log ) + { + Log->close(); + delete Log; + } + if( proto ) + { + delete proto; + } +} +/////////////////////////////////////// +// +// io_engine::Start +// +/////////////////////////////////////// +void io_engine::Start( const int side ) +{ + QStringList args; + unsigned int tmp; + int ID; + bool Army; + + /* Stop accidents */ + if( engine != NULL ) + return; + engine = new KProcess(); + + /* Convert 'side' to 'ID' */ + if( side == WHITE ) + { + ID = ENGINE_WHITE; + Army = WHITE; + } + else if( side == BLACK ) + { + ID = ENGINE_BLACK; + Army = BLACK; + } + else if( side == WHITE_HELPER ) + { + ID = ENGINE_WHITE_BK; + Army = WHITE; + } + else + { + ID = ENGINE_BLACK_BK; + Army = BLACK; + } + + /* Get and parse engine config from resource */ + for( IT = myResource->engines.begin(); IT != myResource->engines.end(); ++IT ) + { + if( (*IT).CurrentRef & ID ) + break; + } + if( IT == myResource->engines.end() ) + { + kdError() << "io_engine::Start: Can not find engine resource ID " << ID << endl; + return; + } + + /* ...protocol */ + Protocol = (*IT).Protocol; + switch( Protocol ) + { + case UCI: + proto = new proto_uci( myID ); + break; + case XBoard: + default: + proto = new proto_xboard( myID ); + break; + } + connect( proto, SIGNAL( output( const QString& ) ), this, SLOT( WriteFIFO( const QString& ) ) ); + connect( proto, SIGNAL( output( const Command& ) ), this, SLOT( recvProtoCMD( const Command& ) ) ); + + /* ...engine's display name */ + proto->parse( Command( myID, CMD_Set_Name, (*IT).Name ) ); + + /* ...engine file name */ + (*engine) << (*IT).Filename; + + /* ...command line arguments */ + args = QStringList::split( QString(" "), (*IT).Arguments, FALSE ); + for( tmp = 0; tmp < args.count(); tmp++ ) + { + (*engine) << args[tmp]; + } + + /* ...log file */ + if( !(*IT).LogFile.isEmpty() ) + { + Log = new QFile( (*IT).LogFile ); + if( !Log->open( IO_WriteOnly | IO_Append ) ) + if( !Log->open( IO_WriteOnly ) ) + kdError() << "io_engine::Start: Can not open " << (*IT).LogFile << " for writing." << endl; + } + + /* Showtime */ + if( !engine->start( KProcess::NotifyOnExit, KProcess::All ) ) + { + kdError() << "io_engine::Start: Can not run the engine: " << (*IT).Filename << endl; + return; + } + connect( engine, SIGNAL( wroteStdin( KProcess* ) ), this, SLOT( SendClear( KProcess* ) ) ); + connect( engine, SIGNAL( receivedStdout( KProcess*, char*, int ) ), this, SLOT( Recv( KProcess*, char*, int ) ) ); + connect( engine, SIGNAL( receivedStderr( KProcess*, char*, int ) ), this, SLOT( Recv( KProcess*, char*, int ) ) ); + + proto->parse( Command( myID, CMD_Init ) ); + + if( myResource->OPTION_Ponder ) + proto->parse( Command( myID, CMD_Ponder ) ); + else + proto->parse( Command( myID, CMD_No_Pondering ) ); + + proto->parse( Command( myID, CMD_NewGame ) ); + + if( Army == WHITE ) + proto->parse( Command( myID, CMD_Play_White ) ); + else + proto->parse( Command( myID, CMD_Play_Black ) ); + return; +} +/////////////////////////////////////// +// +// io_engine::Kill +// +/////////////////////////////////////// +void io_engine::Kill( void ) +{ + proto->parse( Command( myID, CMD_Exit ) ); + if( engine != NULL ) + delete engine; +} +/////////////////////////////////////// +// +// io_engine::sendToChild +// +/////////////////////////////////////// +void io_engine::sendToChild( void ) +{ + if( !SafeToSend || FIFO_Out.isEmpty() || !engine->isRunning() ) + return; + + /* Interrupt those engines that want or need it */ + if( SendSIGINT ) + { + engine->kill( SIGINT ); + SendSIGINT = FALSE; + } + + /* Write it */ + SafeToSend = FALSE; + if( engine->writeStdin( FIFO_Out.latin1(), FIFO_Out.length() ) ) + { + /* Print the output to the log file */ + if( Log ) + { + FIFO_Out.prepend( "<- " ); + Log->writeBlock( FIFO_Out.latin1(), FIFO_Out.length() ); + } + FIFO_Out = ""; + } + else + kdError() << "io_engine::sendToChild: Could not write to engine." << endl; +} +/////////////////////////////////////// +// +// io_engine::Recv +// +/////////////////////////////////////// +void io_engine::Recv( KProcess*, char *buffer, int bufLen ) +{ + char *newBuff = new char[bufLen + 1]; + strncpy( newBuff, buffer, bufLen ); + newBuff[bufLen] = 0; + FIFO_In += newBuff; + delete newBuff; + + if( FIFO_In.contains( QChar('\n') ) ) + { + QString proc = FIFO_In.left( FIFO_In.findRev( QChar('\n') ) ); + FIFO_In = FIFO_In.right( FIFO_In.length() - proc.length() ); + + /* Split and Parse Full Lines of Input */ + QStringList strList = QStringList::split( "\n", proc ); + for( unsigned int loop = 0; loop < strList.count(); loop++ ) + { + /* Print the input to the log file */ + if( Log ) + { + QString data = "-> " + strList[loop] + "\n"; + Log->writeBlock( data.latin1(), data.length() ); + } + proto->parse( strList[loop] ); + } + } + return; +} +/////////////////////////////////////// +// +// io_engine::WriteFIFO +// +/////////////////////////////////////// +void io_engine::WriteFIFO( const QString &Data ) +{ + QString data = Data; + if( data.isEmpty() ) + return; + if( data.right(1) != "\n" ) + data += "\n"; + FIFO_Out += data; + sendToChild(); + return; +} +/////////////////////////////////////// +// +// io_engine::recvCMD +// +/////////////////////////////////////// +void io_engine::recvCMD( const Command &command ) +{ + proto->parse( command ); +} + +/////////////////////////////////////// +// +// io_engine::recvProtoCMD +// +/////////////////////////////////////// +void io_engine::recvProtoCMD( const Command &command ) +{ + Command cmd = command; + + switch( cmd.getCommand() ) + { + /* Command: Send_SIGTERM */ + case CMD_Send_SIGTERM: + engine->kill(); + break; + /* Command: Send_SIGINT */ + case CMD_Send_SIGINT: + SendSIGINT = TRUE; + break; + /* Command to Core */ + default: + emit sendCMD( command ); + break; + } +} + +void io_engine::SendClear( KProcess* ) +{ + SafeToSend = TRUE; + if( !FIFO_Out.isEmpty() ) + sendToChild(); +} + -- cgit v1.2.3