00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kgameio.h"
00022 #include "kgameio.moc"
00023 #include "kgame.h"
00024 #include "kplayer.h"
00025 #include "kgamemessage.h"
00026 #include "kmessageio.h"
00027
00028 #include <kdebug.h>
00029
00030 #include <QWidget>
00031 #include <qbuffer.h>
00032 #include <QTimer>
00033
00034 #include <QGraphicsScene>
00035 #include <QMouseEvent>
00036 #include <QKeyEvent>
00037 #include <QEvent>
00038
00039 #include <stdlib.h>
00040
00041 class KGameIOPrivate
00042 {
00043 public:
00044 KGameIOPrivate()
00045 : mPlayer(0)
00046 {
00047 }
00048
00049 KPlayer *mPlayer;
00050 };
00051
00052
00053
00054 KGameIO::KGameIO()
00055 : d(new KGameIOPrivate)
00056 {
00057 kDebug(11001) << ": this=" << this << ", sizeof(this)" << sizeof(KGameIO);
00058 }
00059
00060 KGameIO::KGameIO(KPlayer* player)
00061 : d(new KGameIOPrivate)
00062 {
00063 kDebug(11001) << ": this=" << this << ", sizeof(this)" << sizeof(KGameIO);
00064 if (player)
00065 {
00066 player->addGameIO(this);
00067 }
00068 }
00069
00070 KGameIO::~KGameIO()
00071 {
00072 kDebug(11001) << ": this=" << this;
00073
00074 if (player())
00075 {
00076 player()->removeGameIO(this, false);
00077 }
00078 delete d;
00079 }
00080
00081 KPlayer* KGameIO::player() const
00082 {
00083 return d->mPlayer;
00084 }
00085
00086 void KGameIO::setPlayer(KPlayer *p)
00087 {
00088 d->mPlayer = p;
00089 }
00090
00091 void KGameIO::initIO(KPlayer *p)
00092 {
00093 setPlayer(p);
00094 }
00095
00096 void KGameIO::notifyTurn(bool b)
00097 {
00098 if (!player())
00099 {
00100 kWarning(11001) << ": player() is NULL";
00101 return;
00102 }
00103 bool sendit=false;
00104 QByteArray buffer;
00105 QDataStream stream(&buffer, QIODevice::WriteOnly);
00106 emit signalPrepareTurn(stream, b, this, &sendit);
00107 if (sendit)
00108 {
00109 QDataStream ostream(buffer);
00110 quint32 sender = player()->id();
00111 kDebug(11001) << "Prepare turn sendInput";
00112 sendInput(ostream, true, sender);
00113 }
00114 }
00115
00116 KGame* KGameIO::game() const
00117 {
00118 if (!player())
00119 {
00120 return 0;
00121 }
00122 return player()->game();
00123 }
00124
00125 bool KGameIO::sendInput(QDataStream& s, bool transmit, quint32 sender)
00126 {
00127 if (!player())
00128 {
00129 return false;
00130 }
00131 return player()->forwardInput(s, transmit, sender);
00132 }
00133
00134 void KGameIO::Debug()
00135 {
00136 kDebug(11001) << "------------------- KGAMEINPUT --------------------";
00137 kDebug(11001) << "this: " << this;
00138 kDebug(11001) << "rtti : " << rtti();
00139 kDebug(11001) << "Player: " << player();
00140 kDebug(11001) << "---------------------------------------------------";
00141 }
00142
00143
00144 class KGameKeyIOPrivate
00145 {
00146 };
00147
00148 KGameKeyIO::KGameKeyIO(QWidget *parent)
00149 : KGameIO(), d(0)
00150 {
00151 if (parent)
00152 {
00153 kDebug(11001) << "Key Event filter installed";
00154 parent->installEventFilter(this);
00155 }
00156 }
00157
00158 KGameKeyIO::~KGameKeyIO()
00159 {
00160 if (parent())
00161 {
00162 parent()->removeEventFilter(this);
00163 }
00164 delete d;
00165 }
00166
00167 int KGameKeyIO::rtti() const { return KeyIO; }
00168
00169 bool KGameKeyIO::eventFilter( QObject *o, QEvent *e )
00170 {
00171 if (!player())
00172 {
00173 return false;
00174 }
00175
00176
00177 if ( e->type() == QEvent::KeyPress ||
00178 e->type() == QEvent::KeyRelease )
00179 {
00180 QKeyEvent *k = (QKeyEvent*)e;
00181
00182 QByteArray buffer;
00183 QDataStream stream(&buffer,QIODevice::WriteOnly);
00184 bool eatevent=false;
00185 emit signalKeyEvent(this,stream,k,&eatevent);
00186 QDataStream msg(buffer);
00187
00188 if (eatevent && sendInput(msg))
00189 {
00190 return eatevent;
00191 }
00192 return false;
00193 }
00194 return QObject::eventFilter( o, e );
00195 }
00196
00197
00198
00199 class KGameMouseIOPrivate
00200 {
00201 };
00202
00203 KGameMouseIO::KGameMouseIO(QWidget *parent,bool trackmouse)
00204 : KGameIO(), d(0)
00205 {
00206 if (parent)
00207 {
00208 kDebug(11001) << "Mouse Event filter installed tracking=" << trackmouse;
00209 parent->installEventFilter(this);
00210 parent->setMouseTracking(trackmouse);
00211 }
00212 }
00213
00214 KGameMouseIO::KGameMouseIO(QGraphicsScene *parent,bool trackmouse)
00215 : KGameIO(), d(0)
00216 {
00217 if (parent)
00218 {
00219
00220 parent->installEventFilter(this);
00221
00222 }
00223 }
00224
00225 KGameMouseIO::~KGameMouseIO()
00226 {
00227 if (parent())
00228 {
00229 parent()->removeEventFilter(this);
00230 }
00231 delete d;
00232 }
00233
00234 int KGameMouseIO::rtti() const
00235 {
00236 return MouseIO;
00237 }
00238
00239 void KGameMouseIO::setMouseTracking(bool b)
00240 {
00241 if (parent())
00242 {
00243 ((QWidget*)parent())->setMouseTracking(b);
00244 }
00245 }
00246
00247 bool KGameMouseIO::eventFilter( QObject *o, QEvent *e )
00248 {
00249 if (!player())
00250 {
00251 return false;
00252 }
00253
00254
00255
00256 if ( e->type() == QEvent::MouseButtonPress ||
00257 e->type() == QEvent::MouseButtonRelease ||
00258 e->type() == QEvent::MouseButtonDblClick ||
00259 e->type() == QEvent::Wheel ||
00260 e->type() == QEvent::MouseMove ||
00261 e->type() == QEvent::GraphicsSceneMousePress ||
00262 e->type() == QEvent::GraphicsSceneMouseRelease ||
00263 e->type() == QEvent::GraphicsSceneMouseDoubleClick ||
00264 e->type() == QEvent::GraphicsSceneWheel ||
00265 e->type() == QEvent::GraphicsSceneMouseMove
00266 )
00267 {
00268 QMouseEvent *k = (QMouseEvent*)e;
00269
00270 QByteArray buffer;
00271 QDataStream stream(&buffer,QIODevice::WriteOnly);
00272 bool eatevent=false;
00273 emit signalMouseEvent(this,stream,k,&eatevent);
00274
00275 QDataStream msg(buffer);
00276 if (eatevent && sendInput(msg))
00277 {
00278 return eatevent;
00279 }
00280 return false;
00281 }
00282 return QObject::eventFilter( o, e );
00283 }
00284
00285
00286
00287 class KGameProcessIOPrivate
00288 {
00289 public:
00290 KGameProcessIOPrivate()
00291 {
00292
00293
00294 mProcessIO=0;
00295 }
00296
00297
00298 KMessageProcess *mProcessIO;
00299 };
00300
00301
00302 KGameProcessIO::KGameProcessIO(const QString& name)
00303 : KGameIO(), d(new KGameProcessIOPrivate)
00304 {
00305 kDebug(11001) << ": this=" << this << ", sizeof(this)=" << sizeof(KGameProcessIO);
00306
00307
00308
00309
00310
00311 kDebug(11001) << "================= KMEssageProcessIO ====================";
00312 d->mProcessIO=new KMessageProcess(this,name);
00313 kDebug(11001) << "================= KMEssage Add client ====================";
00314
00315
00316
00317 kDebug(11001) << "================= KMEssage: Connect ====================";
00318
00319
00320
00321
00322 connect(d->mProcessIO, SIGNAL(received(const QByteArray&)),
00323 this, SLOT(receivedMessage(const QByteArray&)));
00324
00325 connect(d->mProcessIO, SIGNAL(signalReceivedStderr(QString)),
00326 this, SIGNAL(signalReceivedStderr(QString)));
00327
00328 }
00329
00330 KGameProcessIO::~KGameProcessIO()
00331 {
00332 kDebug(11001) << ": this=" << this;
00333 kDebug(11001) << "player="<<player();
00334 if (player())
00335 {
00336 player()->removeGameIO(this,false);
00337 }
00338 if (d->mProcessIO)
00339 {
00340 delete d->mProcessIO;
00341 d->mProcessIO=0;
00342 }
00343 delete d;
00344 }
00345
00346 int KGameProcessIO::rtti() const
00347 {
00348 return ProcessIO;
00349 }
00350
00351 void KGameProcessIO::initIO(KPlayer *p)
00352 {
00353 KGameIO::initIO(p);
00354
00355 QByteArray buffer;
00356 QDataStream stream(&buffer, QIODevice::WriteOnly);
00357 qint16 id = p->userId();
00358 stream << id;
00359
00360 bool sendit=true;
00361 if (p)
00362 {
00363 emit signalIOAdded(this,stream,p,&sendit);
00364 if (sendit )
00365 {
00366 quint32 sender = p->id();
00367 kDebug(11001) << "Sending IOAdded to process player !!!!!!!!!!!!!! ";
00368 sendSystemMessage(stream, KGameMessage::IdIOAdded, 0, sender);
00369 }
00370 }
00371 }
00372
00373 void KGameProcessIO::notifyTurn(bool b)
00374 {
00375 if (!player())
00376 {
00377 kWarning(11001) << ": player() is NULL";
00378 return;
00379 }
00380 bool sendit=true;
00381 QByteArray buffer;
00382 QDataStream stream(&buffer,QIODevice::WriteOnly);
00383 stream << (qint8)b;
00384 emit signalPrepareTurn(stream,b,this,&sendit);
00385 if (sendit)
00386 {
00387 quint32 sender=player()->id();
00388 kDebug(11001) << "Sending Turn to process player !!!!!!!!!!!!!! ";
00389 sendSystemMessage(stream, KGameMessage::IdTurn, 0, sender);
00390 }
00391 }
00392
00393 void KGameProcessIO::sendSystemMessage(QDataStream &stream,int msgid, quint32 receiver, quint32 sender)
00394 {
00395 sendAllMessages(stream, msgid, receiver, sender, false);
00396 }
00397
00398 void KGameProcessIO::sendMessage(QDataStream &stream,int msgid, quint32 receiver, quint32 sender)
00399 {
00400 sendAllMessages(stream, msgid, receiver, sender, true);
00401 }
00402
00403 void KGameProcessIO::sendAllMessages(QDataStream &stream,int msgid, quint32 receiver, quint32 sender, bool usermsg)
00404 {
00405 kDebug(11001) << "==============> KGameProcessIO::sendMessage (usermsg="<<usermsg<<")";
00406
00407
00408
00409 if (usermsg)
00410 {
00411 msgid+=KGameMessage::IdUser;
00412 }
00413
00414 kDebug(11001) << "=============* ProcessIO (" << msgid << "," << receiver << "," << sender << ") ===========";
00415
00416 QByteArray buffer;
00417 QDataStream ostream(&buffer,QIODevice::WriteOnly);
00418 QBuffer *device=(QBuffer *)stream.device();
00419 QByteArray data=device->buffer();;
00420
00421 KGameMessage::createHeader(ostream,sender,receiver,msgid);
00422
00423 ostream.writeRawData(data.data(),data.size());
00424 kDebug(11001) << " Adding user data from pos="<< device->pos() <<" amount=" << data.size() << "byte";
00425
00426 if (d->mProcessIO)
00427 {
00428 d->mProcessIO->send(buffer);
00429 }
00430 }
00431
00432
00433 void KGameProcessIO::receivedMessage(const QByteArray& receiveBuffer)
00434 {
00435 QDataStream stream(receiveBuffer);
00436 int msgid;
00437 quint32 sender;
00438 quint32 receiver;
00439 KGameMessage::extractHeader(stream,sender,receiver,msgid);
00440
00441 kDebug(11001) << "************* Got process message sender =" << sender
00442 << "receiver=" << receiver << " msgid=" << msgid;
00443
00444
00445
00446 QBuffer *buf=(QBuffer *)stream.device();
00447 QByteArray newbuffer;
00448 newbuffer = QByteArray::fromRawData(buf->buffer().data()+buf->pos(),buf->size()-buf->pos());
00449 QDataStream ostream(newbuffer);
00450 kDebug(11001) << "Newbuffer size=" << newbuffer.size();
00451
00452
00453 if (msgid==KGameMessage::IdProcessQuery)
00454 {
00455 emit signalProcessQuery(ostream,this);
00456 }
00457 else if (player())
00458 {
00459 sender = player()->id();
00460 if (msgid==KGameMessage::IdPlayerInput)
00461 {
00462 sendInput(ostream,true,sender);
00463 }
00464 else
00465 {
00466 player()->forwardMessage(ostream,msgid,receiver,sender);
00467 }
00468 }
00469 else
00470 {
00471 kDebug(11001) << ": Got message from process but no player defined!";
00472 }
00473 newbuffer.clear();
00474 }
00475
00476
00477
00478 class KGameComputerIOPrivate
00479 {
00480
00481 public:
00482 KGameComputerIOPrivate()
00483 {
00484 mAdvanceCounter = 0;
00485 mReactionPeriod = 0;
00486
00487 mPauseCounter = 0;
00488
00489 mAdvanceTimer = 0;
00490 }
00491 int mAdvanceCounter;
00492 int mReactionPeriod;
00493
00494 int mPauseCounter;
00495
00496 QTimer* mAdvanceTimer;
00497 };
00498
00499 KGameComputerIO::KGameComputerIO()
00500 : KGameIO(), d(new KGameComputerIOPrivate)
00501 {
00502 }
00503
00504 KGameComputerIO::KGameComputerIO(KPlayer *p)
00505 : KGameIO(p), d(new KGameComputerIOPrivate)
00506 {
00507 }
00508
00509 KGameComputerIO::~KGameComputerIO()
00510 {
00511 if (d->mAdvanceTimer)
00512 {
00513 delete d->mAdvanceTimer;
00514 }
00515 delete d;
00516 }
00517
00518 int KGameComputerIO::rtti() const
00519 {
00520 return ComputerIO;
00521 }
00522
00523 void KGameComputerIO::setReactionPeriod(int calls)
00524 {
00525 d->mReactionPeriod = calls;
00526 }
00527
00528 int KGameComputerIO::reactionPeriod() const
00529 {
00530 return d->mReactionPeriod;
00531 }
00532
00533 void KGameComputerIO::setAdvancePeriod(int ms)
00534 {
00535 stopAdvancePeriod();
00536 d->mAdvanceTimer = new QTimer(this);
00537 connect(d->mAdvanceTimer, SIGNAL(timeout()), this, SLOT(advance()));
00538 d->mAdvanceTimer->start(ms);
00539 }
00540
00541 void KGameComputerIO::stopAdvancePeriod()
00542 {
00543 if (d->mAdvanceTimer)
00544 {
00545 d->mAdvanceTimer->stop();
00546 delete d->mAdvanceTimer;
00547 }
00548 }
00549
00550 void KGameComputerIO::pause(int calls)
00551 {
00552 d->mPauseCounter = calls;
00553 }
00554
00555 void KGameComputerIO::unpause()
00556 {
00557 pause(0);
00558 }
00559
00560 void KGameComputerIO::advance()
00561 {
00562 if (d->mPauseCounter > 0)
00563 {
00564 d->mPauseCounter--;
00565 return;
00566 }
00567 else if (d->mPauseCounter < 0)
00568 {
00569 return;
00570 }
00571 d->mAdvanceCounter++;
00572 if (d->mAdvanceCounter >= d->mReactionPeriod)
00573 {
00574 d->mAdvanceCounter = 0;
00575 reaction();
00576 }
00577 }
00578
00579 void KGameComputerIO::reaction()
00580 {
00581 emit signalReaction();
00582 }
00583
00584