QTfrontend/net/tcpBase.cpp
branchflibqtfrontend
changeset 8092 08960209db8c
parent 8082 675372256a01
child 8363 0b4ac686fc44
equal deleted inserted replaced
8091:e0a76056a633 8092:08960209db8c
    55     Game(args);
    55     Game(args);
    56 }
    56 }
    57 #endif
    57 #endif
    58 
    58 
    59 QList<TCPBase*> srvsList;
    59 QList<TCPBase*> srvsList;
    60 QPointer<QTcpServer> TCPBase::IPCServer(0);
       
    61 
    60 
    62 TCPBase::~TCPBase()
    61 TCPBase::~TCPBase()
    63 {
    62 {
    64     // make sure this object is not in the server list anymore
    63     // make sure this object is not in the server list anymore
    65     srvsList.removeOne(this);
    64     srvsList.removeOne(this);
    66 
       
    67     if (IPCSocket)
       
    68         IPCSocket->deleteLater();
       
    69 }
    65 }
    70 
    66 
    71 TCPBase::TCPBase(bool demoMode, QObject *parent) :
    67 TCPBase::TCPBase(QObject *parent) :
    72     QObject(parent),
    68     QObject(parent),
    73     m_hasStarted(false),
    69     m_hasStarted(false)
    74     m_isDemoMode(demoMode),
       
    75     IPCSocket(0)
       
    76 {
    70 {
    77     if(!IPCServer)
       
    78     {
       
    79         IPCServer = new QTcpServer(0);
       
    80         IPCServer->setMaxPendingConnections(1);
       
    81         if (!IPCServer->listen(QHostAddress::LocalHost))
       
    82         {
       
    83             QMessageBox deniedMsg(QApplication::activeWindow());
       
    84             deniedMsg.setIcon(QMessageBox::Critical);
       
    85             deniedMsg.setWindowTitle(QMessageBox::tr("TCP - Error"));
       
    86             deniedMsg.setText(QMessageBox::tr("Unable to start the server: %1.").arg(IPCServer->errorString()));
       
    87             deniedMsg.setWindowModality(Qt::WindowModal);
       
    88             deniedMsg.exec();
       
    89 
    71 
    90             exit(0); // FIXME - should be graceful exit here (lower Critical -> Warning above when implemented)
       
    91         }
       
    92     }
       
    93 #ifdef HWLIBRARY
       
    94     ipc_port=65000; //HACK
       
    95 #else
       
    96     ipc_port=IPCServer->serverPort();
       
    97 #endif
       
    98 }
       
    99 
       
   100 void TCPBase::NewConnection()
       
   101 {
       
   102     if(IPCSocket)
       
   103     {
       
   104         // connection should be already finished
       
   105         return;
       
   106     }
       
   107     disconnect(IPCServer, SIGNAL(newConnection()), this, SLOT(NewConnection()));
       
   108     IPCSocket = IPCServer->nextPendingConnection();
       
   109     if(!IPCSocket) return;
       
   110     connect(IPCSocket, SIGNAL(disconnected()), this, SLOT(ClientDisconnect()));
       
   111     connect(IPCSocket, SIGNAL(readyRead()), this, SLOT(ClientRead()));
       
   112     SendToClientFirst();
       
   113 }
    72 }
   114 
    73 
   115 void TCPBase::RealStart()
    74 void TCPBase::RealStart()
   116 {
    75 {
   117     connect(IPCServer, SIGNAL(newConnection()), this, SLOT(NewConnection()));
    76     onEngineStart();
   118     IPCSocket = 0;
       
   119 
    77 
   120 #ifdef HWLIBRARY
    78 #ifdef HWLIBRARY
   121     EngineThread engineThread;// = new EngineThread(this);
    79     EngineThread engineThread;// = new EngineThread(this);
   122     engineThread.start();
    80     engineThread.start();
   123 #else
    81 #else
   124     QProcess * process;
    82     QProcess * process;
       
    83 
   125     process = new QProcess();
    84     process = new QProcess();
   126     connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(StartProcessError(QProcess::ProcessError)));
    85     QStringList arguments = getArguments();
   127     QStringList arguments=getArguments();
       
   128 
    86 
   129     // redirect everything written on stdout/stderr
    87     // redirect everything written on stdout/stderr
   130     if(isDevBuild)
    88     if(isDevBuild)
   131         process->setProcessChannelMode(QProcess::ForwardedChannels);
    89         process->setProcessChannelMode(QProcess::ForwardedChannels);
   132 
    90 
   133     process->start(bindir->absolutePath() + "/hwengine", arguments);
    91     process->start(bindir->absolutePath() + "/hwengine", arguments);
   134 #endif
    92 #endif
   135     m_hasStarted = true;
    93     m_hasStarted = true;
   136 }
    94 }
   137 
    95 
   138 void TCPBase::ClientDisconnect()
    96 void TCPBase::clientDisconnected()
   139 {
    97 {
   140     disconnect(IPCSocket, SIGNAL(readyRead()), this, SLOT(ClientRead()));
    98     emit nextPlease();
   141     onClientDisconnect();
       
   142 
       
   143     emit isReadyNow();
       
   144     IPCSocket->deleteLater();
       
   145 
    99 
   146     deleteLater();
   100     deleteLater();
   147 }
   101 }
   148 
   102 
   149 void TCPBase::ClientRead()
   103 void TCPBase::iStart()
   150 {
   104 {
   151     QByteArray readed=IPCSocket->readAll();
   105     disconnect(srvsList.first(), SIGNAL(nextPlease()), this, SLOT(iStart()));
   152     if(readed.isEmpty()) return;
       
   153     readbuffer.append(readed);
       
   154     onClientRead();
       
   155 }
       
   156 
       
   157 void TCPBase::StartProcessError(QProcess::ProcessError error)
       
   158 {
       
   159     QMessageBox deniedMsg(QApplication::activeWindow());
       
   160     deniedMsg.setIcon(QMessageBox::Critical);
       
   161     deniedMsg.setWindowTitle(QMessageBox::tr("TCP - Error"));
       
   162     deniedMsg.setText(QMessageBox::tr("Unable to run engine at ") + bindir->absolutePath() + "/hwengine\n" +
       
   163                       QMessageBox::tr("Error code: %1").arg(error));
       
   164     deniedMsg.setWindowModality(Qt::WindowModal);
       
   165     deniedMsg.exec();
       
   166 
       
   167     ClientDisconnect();
       
   168 }
       
   169 
       
   170 void TCPBase::tcpServerReady()
       
   171 {
       
   172     disconnect(srvsList.first(), SIGNAL(isReadyNow()), this, SLOT(tcpServerReady()));
       
   173 
   106 
   174     RealStart();
   107     RealStart();
   175 }
   108 }
   176 
   109 
   177 void TCPBase::Start(bool couldCancelPreviousRequest)
   110 void TCPBase::start(bool couldCancelPreviousRequest)
   178 {
   111 {
   179     if(srvsList.isEmpty())
   112     if(srvsList.isEmpty())
   180     {
   113     {
   181         srvsList.push_back(this);
   114         srvsList.push_back(this);
       
   115 
   182         RealStart();
   116         RealStart();
   183     }
   117     }
   184     else
   118     else
   185     {
   119     {
   186         TCPBase * last = srvsList.last();
   120         TCPBase * last = srvsList.last();
   188             && last->couldBeRemoved()
   122             && last->couldBeRemoved()
   189             && (last->parent() == parent()))
   123             && (last->parent() == parent()))
   190         {
   124         {
   191             srvsList.removeLast();
   125             srvsList.removeLast();
   192             last->deleteLater();
   126             last->deleteLater();
   193             Start(couldCancelPreviousRequest);
   127             start(couldCancelPreviousRequest);
   194         } else
   128         } else
   195         {
   129         {
   196             connect(srvsList.last(), SIGNAL(isReadyNow()), this, SLOT(tcpServerReady()));
   130             connect(srvsList.last(), SIGNAL(nextPlease()), this, SLOT(iStart()));
   197             srvsList.push_back(this);
   131             srvsList.push_back(this);
   198         }
       
   199     }
       
   200 }
       
   201 
       
   202 void TCPBase::onClientRead()
       
   203 {
       
   204 }
       
   205 
       
   206 void TCPBase::onClientDisconnect()
       
   207 {
       
   208 }
       
   209 
       
   210 void TCPBase::SendToClientFirst()
       
   211 {
       
   212 }
       
   213 
       
   214 void TCPBase::SendIPC(const QByteArray & buf)
       
   215 {
       
   216     if (buf.size() > MAXMSGCHARS) return;
       
   217     quint8 len = buf.size();
       
   218     RawSendIPC(QByteArray::fromRawData((char *)&len, 1) + buf);
       
   219 }
       
   220 
       
   221 void TCPBase::RawSendIPC(const QByteArray & buf)
       
   222 {
       
   223     if (!IPCSocket)
       
   224     {
       
   225         toSendBuf += buf;
       
   226     }
       
   227     else
       
   228     {
       
   229         if (toSendBuf.size() > 0)
       
   230         {
       
   231             IPCSocket->write(toSendBuf);
       
   232             if(m_isDemoMode) demo.append(toSendBuf);
       
   233             toSendBuf.clear();
       
   234         }
       
   235         if(!buf.isEmpty())
       
   236         {
       
   237             IPCSocket->write(buf);
       
   238             if(m_isDemoMode) demo.append(buf);
       
   239         }
   132         }
   240     }
   133     }
   241 }
   134 }
   242 
   135 
   243 bool TCPBase::couldBeRemoved()
   136 bool TCPBase::couldBeRemoved()