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() |