kgameio.cpp

00001 /*
00002     This file is part of the KDE games library
00003     Copyright (C) 2001 Martin Heni (martin@heni-online.de)
00004     Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de)
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License version 2 as published by the Free Software Foundation.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 /*
00021     $Id: kgameio.cpp 465369 2005-09-29 14:33:08Z mueller $
00022 */
00023 
00024 #include "kgameio.h"
00025 #include "kgameio.moc"
00026 #include "kgame.h"
00027 #include "kplayer.h"
00028 #include "kgamemessage.h"
00029 #include "kmessageio.h"
00030 
00031 #include <kdebug.h>
00032 
00033 #include <qwidget.h>
00034 #include <qbuffer.h>
00035 #include <qtimer.h>
00036 
00037 #include <stdlib.h>
00038 
00039 // ----------------------- Generic IO -------------------------
00040 KGameIO::KGameIO() : QObject(0,0)
00041 {
00042   kdDebug(11001) << k_funcinfo << ": this=" << this << ", sizeof(this)" << sizeof(KGameIO) << endl;
00043   mPlayer = 0;
00044 }
00045 
00046 KGameIO::KGameIO(KPlayer* player) : QObject(0,0)
00047 {
00048   kdDebug(11001) << k_funcinfo << ": this=" << this << ", sizeof(this)" << sizeof(KGameIO) << endl;
00049   mPlayer = 0;
00050   if (player)
00051   {
00052     player->addGameIO(this);
00053   }
00054 }
00055 
00056 KGameIO::~KGameIO()
00057 {
00058   kdDebug(11001) << k_funcinfo << ": this=" << this << endl;
00059   // unregister ourselves
00060   if (player())
00061   {
00062     player()->removeGameIO(this, false);
00063   }
00064 }
00065 
00066 void KGameIO::initIO(KPlayer *p)
00067 {
00068   setPlayer(p);
00069 }
00070 
00071 void KGameIO::notifyTurn(bool b)
00072 {
00073   if (!player())
00074   {
00075     kdWarning(11001) << k_funcinfo << ": player() is NULL" << endl;
00076     return;
00077   }
00078   bool sendit=false;
00079   QByteArray buffer;
00080   QDataStream stream(buffer, IO_WriteOnly);
00081   emit signalPrepareTurn(stream, b, this, &sendit);
00082   if (sendit)
00083   {
00084     QDataStream ostream(buffer,IO_ReadOnly);
00085     Q_UINT32 sender = player()->id();  // force correct sender
00086     kdDebug(11001) << "Prepare turn sendInput" << endl;
00087     sendInput(ostream, true, sender);
00088   }
00089 }
00090 
00091 KGame* KGameIO::game() const
00092 {
00093   if (!player())
00094   {
00095     return 0;
00096   }
00097   return player()->game();
00098 }
00099 
00100 bool KGameIO::sendInput(QDataStream& s, bool transmit, Q_UINT32 sender)
00101 {
00102   if (!player())
00103   {
00104     return false;
00105   }
00106   return player()->forwardInput(s, transmit, sender);
00107 }
00108 
00109 void KGameIO::Debug()
00110 {
00111   kdDebug(11001) << "------------------- KGAMEINPUT --------------------" << endl;
00112   kdDebug(11001) << "this:    " << this << endl;
00113   kdDebug(11001) << "rtti :   " << rtti() << endl;
00114   kdDebug(11001) << "Player:  " << player() << endl;
00115   kdDebug(11001) << "---------------------------------------------------" << endl;
00116 }
00117 
00118 
00119 // ----------------------- Key IO ---------------------------
00120 KGameKeyIO::KGameKeyIO(QWidget *parent) 
00121    : KGameIO()
00122 {
00123   if (parent)
00124   {
00125     kdDebug(11001) << "Key Event filter installed" << endl;
00126     parent->installEventFilter(this);
00127   }
00128 }
00129 
00130 KGameKeyIO::~KGameKeyIO()
00131 {
00132   if (parent())
00133   {
00134     parent()->removeEventFilter(this);
00135   }
00136 }
00137 
00138 int KGameKeyIO::rtti() const { return KeyIO; }
00139 
00140 bool KGameKeyIO::eventFilter( QObject *o, QEvent *e )
00141 {
00142   if (!player())
00143   {
00144     return false;
00145   }
00146 
00147   // key press/release
00148   if ( e->type() == QEvent::KeyPress ||
00149        e->type() == QEvent::KeyRelease )
00150   {
00151      QKeyEvent *k = (QKeyEvent*)e;
00152   //   kdDebug(11001) << "KGameKeyIO " << this << " key press/release " <<  k->key() << endl ;
00153      QByteArray buffer;
00154      QDataStream stream(buffer,IO_WriteOnly);
00155      bool eatevent=false;
00156      emit signalKeyEvent(this,stream,k,&eatevent);
00157      QDataStream msg(buffer,IO_ReadOnly);
00158 
00159      if (eatevent && sendInput(msg))
00160      {
00161        return eatevent;
00162      }
00163      return false; // do not eat otherwise
00164   }
00165   return QObject::eventFilter( o, e );    // standard event processing
00166 }
00167 
00168 
00169 // ----------------------- Mouse IO ---------------------------
00170 KGameMouseIO::KGameMouseIO(QWidget *parent,bool trackmouse) 
00171    : KGameIO()
00172 {
00173   if (parent)
00174   {
00175     kdDebug(11001) << "Mouse Event filter installed tracking=" << trackmouse << endl;
00176     parent->installEventFilter(this);
00177     parent->setMouseTracking(trackmouse);
00178   }
00179 }
00180 
00181 KGameMouseIO::~KGameMouseIO()
00182 {
00183   if (parent())
00184   {
00185     parent()->removeEventFilter(this);
00186   }
00187 }
00188 
00189 int KGameMouseIO::rtti() const
00190 {
00191   return MouseIO;
00192 }
00193 
00194 void KGameMouseIO::setMouseTracking(bool b)
00195 {
00196   if (parent())
00197   {
00198     ((QWidget*)parent())->setMouseTracking(b);
00199   }
00200 }
00201 
00202 bool KGameMouseIO::eventFilter( QObject *o, QEvent *e )
00203 {
00204   if (!player())
00205   {
00206     return false;
00207   }
00208 //  kdDebug(11001) << "KGameMouseIO " << this  << endl ;
00209 
00210   // mouse action
00211   if ( e->type() == QEvent::MouseButtonPress ||
00212        e->type() == QEvent::MouseButtonRelease ||
00213        e->type() == QEvent::MouseButtonDblClick ||
00214        e->type() == QEvent::Wheel ||
00215        e->type() == QEvent::MouseMove
00216        )
00217   {
00218      QMouseEvent *k = (QMouseEvent*)e;
00219      // kdDebug(11001) << "KGameMouseIO " << this  << endl ;
00220      QByteArray buffer;
00221      QDataStream stream(buffer,IO_WriteOnly);
00222      bool eatevent=false;
00223      emit signalMouseEvent(this,stream,k,&eatevent);
00224 //     kdDebug(11001) << "################# eatevent=" << eatevent << endl;
00225      QDataStream msg(buffer,IO_ReadOnly);
00226      if (eatevent && sendInput(msg))
00227      {
00228        return eatevent;
00229      }
00230      return false; // do not eat otherwise
00231   }
00232   return QObject::eventFilter( o, e );    // standard event processing
00233 }
00234 
00235 
00236 // ----------------------- KGameProcesPrivate ---------------------------
00237 class KGameProcessIO::KGameProcessIOPrivate
00238 {
00239 public:
00240   KGameProcessIOPrivate()
00241   {
00242     //mMessageServer = 0;
00243     //mMessageClient = 0;
00244     mProcessIO=0;
00245   }
00246   //KMessageServer *mMessageServer;
00247   //KMessageClient *mMessageClient;
00248   KMessageProcess *mProcessIO;
00249 };
00250 
00251 // ----------------------- Process IO ---------------------------
00252 KGameProcessIO::KGameProcessIO(const QString& name) 
00253    : KGameIO()
00254 {
00255   kdDebug(11001) << k_funcinfo << ": this=" << this << ", sizeof(this)=" << sizeof(KGameProcessIO) << endl;
00256   d = new KGameProcessIOPrivate;
00257 
00258   //kdDebug(11001) << "================= KMEssageServer ==================== " << endl;
00259   //d->mMessageServer=new KMessageServer(0,this);
00260   //kdDebug(11001) << "================= KMEssageClient ==================== " << endl;
00261   //d->mMessageClient=new KMessageClient(this);
00262   kdDebug(11001) << "================= KMEssageProcessIO ==================== " << endl;
00263   d->mProcessIO=new KMessageProcess(this,name);
00264   kdDebug(11001) << "================= KMEssage Add client ==================== " << endl;
00265   //d->mMessageServer->addClient(d->mProcessIO);
00266   //kdDebug(11001) << "================= KMEssage SetSErver ==================== " << endl;
00267   //d->mMessageClient->setServer(d->mMessageServer);
00268   kdDebug(11001) << "================= KMEssage: Connect ==================== " << endl;
00269   //connect(d->mMessageClient, SIGNAL(broadcastReceived(const QByteArray&, Q_UINT32)),
00270   //        this, SLOT(clientMessage(const QByteArray&, Q_UINT32)));
00271   //connect(d->mMessageClient, SIGNAL(forwardReceived(const QByteArray&, Q_UINT32, const QValueList <Q_UINT32> &)),
00272   //        this, SLOT(clientMessage(const QByteArray&, Q_UINT32, const QValueList <Q_UINT32> &)));
00273   connect(d->mProcessIO, SIGNAL(received(const QByteArray&)),
00274           this, SLOT(receivedMessage(const QByteArray&)));
00275   //kdDebug(11001) << "Our client is id="<<d->mMessageClient->id() << endl;
00276 }
00277 
00278 KGameProcessIO::~KGameProcessIO()
00279 {
00280   kdDebug(11001) << k_funcinfo << ": this=" << this << endl;
00281   kdDebug(11001) << "player="<<player() << endl;
00282   if (player())
00283   {
00284     player()->removeGameIO(this,false);
00285   }
00286   if (d->mProcessIO)
00287   {
00288     delete d->mProcessIO;
00289     d->mProcessIO=0;
00290   }
00291   delete d;
00292 }
00293 
00294 int KGameProcessIO::rtti() const
00295 {
00296   return ProcessIO;
00297 }
00298 
00299 void KGameProcessIO::initIO(KPlayer *p)
00300 {
00301   KGameIO::initIO(p);
00302   // Send 'hello' to process
00303   QByteArray buffer;
00304   QDataStream stream(buffer, IO_WriteOnly);
00305   Q_INT16 id = p->userId();
00306   stream << id;
00307 
00308   bool sendit=true;
00309   if (p)
00310   {
00311     emit signalIOAdded(this,stream,p,&sendit);
00312     if (sendit )
00313     {
00314       Q_UINT32 sender = p->id();
00315       kdDebug(11001) <<  "Sending IOAdded to process player !!!!!!!!!!!!!! " << endl;
00316       sendSystemMessage(stream, KGameMessage::IdIOAdded, 0, sender);
00317     }
00318   }
00319 }
00320 
00321 void KGameProcessIO::notifyTurn(bool b)
00322 {
00323   if (!player())
00324   {
00325     kdWarning(11001) << k_funcinfo << ": player() is NULL" << endl;
00326     return;
00327   }
00328   bool sendit=true;
00329   QByteArray buffer;
00330   QDataStream stream(buffer,IO_WriteOnly);
00331   stream << (Q_INT8)b;
00332   emit signalPrepareTurn(stream,b,this,&sendit);
00333   if (sendit)
00334   {
00335     Q_UINT32 sender=player()->id();
00336     kdDebug(11001) <<  "Sending Turn to process player !!!!!!!!!!!!!! " << endl;
00337     sendSystemMessage(stream, KGameMessage::IdTurn, 0, sender);
00338   }
00339 }
00340 
00341 void KGameProcessIO::sendSystemMessage(QDataStream &stream,int msgid, Q_UINT32 receiver, Q_UINT32 sender)
00342 {
00343   sendAllMessages(stream, msgid, receiver, sender, false);
00344 }
00345 
00346 void KGameProcessIO::sendMessage(QDataStream &stream,int msgid, Q_UINT32 receiver, Q_UINT32 sender)
00347 {
00348   sendAllMessages(stream, msgid, receiver, sender, true);
00349 }
00350 
00351 void KGameProcessIO::sendAllMessages(QDataStream &stream,int msgid, Q_UINT32 receiver, Q_UINT32 sender, bool usermsg)
00352 {
00353   kdDebug(11001) << "==============>  KGameProcessIO::sendMessage (usermsg="<<usermsg<<")" << endl;
00354   // if (!player()) return ;
00355   //if (!player()->isActive()) return ;
00356 
00357   if (usermsg)
00358   {
00359     msgid+=KGameMessage::IdUser;
00360   }
00361 
00362   kdDebug(11001) << "=============* ProcessIO (" << msgid << "," << receiver << "," << sender << ") ===========" << endl;
00363 
00364   QByteArray buffer;
00365   QDataStream ostream(buffer,IO_WriteOnly);
00366   QBuffer *device=(QBuffer *)stream.device();
00367   QByteArray data=device->buffer();;
00368 
00369   KGameMessage::createHeader(ostream,sender,receiver,msgid);
00370   // ostream.writeRawBytes(data.data()+device->at(),data.size()-device->at());
00371   ostream.writeRawBytes(data.data(),data.size());
00372   kdDebug(11001) << "   Adding user data from pos="<< device->at() <<" amount= " << data.size() << " byte " << endl;
00373   //if (d->mMessageClient) d->mMessageClient->sendBroadcast(buffer);
00374   if (d->mProcessIO)
00375   {
00376     d->mProcessIO->send(buffer);
00377   }
00378 }
00379 
00380 //void KGameProcessIO::clientMessage(const QByteArray& receiveBuffer, Q_UINT32 clientID, const QValueList <Q_UINT32> &recv)
00381 void KGameProcessIO::receivedMessage(const QByteArray& receiveBuffer)
00382 {
00383   QDataStream stream(receiveBuffer,IO_ReadOnly);
00384   int msgid;
00385   Q_UINT32 sender;
00386   Q_UINT32 receiver;
00387   KGameMessage::extractHeader(stream,sender,receiver,msgid);
00388 
00389   kdDebug(11001) << "************* Got process message sender =" << sender 
00390           << " receiver=" << receiver << "   msgid=" << msgid << endl;
00391 
00392 
00393   // Cut out the header part...to not confuse network code
00394   QBuffer *buf=(QBuffer *)stream.device();
00395   QByteArray newbuffer;
00396   newbuffer.setRawData(buf->buffer().data()+buf->at(),buf->size()-buf->at());
00397   QDataStream ostream(newbuffer,IO_ReadOnly);
00398   kdDebug(11001) << "Newbuffer size=" << newbuffer.size() << endl;
00399 
00400 
00401 
00402 // This is a dummy message which allows us the process to talk with its owner
00403   if (msgid==KGameMessage::IdProcessQuery)
00404   {
00405     emit signalProcessQuery(ostream,this);
00406   }
00407   else if (player())
00408   {
00409     sender = player()->id();  // force correct sender
00410     if (msgid==KGameMessage::IdPlayerInput) 
00411     {
00412       sendInput(ostream,true,sender);
00413     }
00414     else
00415     {
00416       player()->forwardMessage(ostream,msgid,receiver,sender);
00417     }
00418   }
00419   else
00420   {
00421     kdDebug(11001) << k_funcinfo << ": Got message from process but no player defined!" << endl;
00422   }
00423   newbuffer.resetRawData(buf->buffer().data()+buf->at(),buf->size()-buf->at());
00424 }
00425 
00426 
00427 // ----------------------- Computer IO --------------------------
00428 class KGameComputerIO::KGameComputerIOPrivate
00429 {
00430 //TODO: maybe these should be KGameProperties!!
00431 public:
00432   KGameComputerIOPrivate()
00433   {
00434     mAdvanceCounter = 0;
00435     mReactionPeriod = 0;
00436 
00437     mPauseCounter = 0;
00438 
00439     mAdvanceTimer = 0;
00440   }
00441   int mAdvanceCounter;
00442   int mReactionPeriod;
00443 
00444   int mPauseCounter;
00445 
00446   QTimer* mAdvanceTimer;
00447 };
00448 
00449 KGameComputerIO::KGameComputerIO() : KGameIO()
00450 {
00451   init();
00452 }
00453 
00454 KGameComputerIO::KGameComputerIO(KPlayer* p) : KGameIO(p)
00455 {
00456   init();
00457 }
00458 
00459 void KGameComputerIO::init()
00460 {
00461   d = new KGameComputerIOPrivate;
00462 }
00463 
00464 KGameComputerIO::~KGameComputerIO()
00465 {
00466   if (d->mAdvanceTimer)
00467   {
00468     delete d->mAdvanceTimer;
00469   }
00470   delete d;
00471 }
00472 
00473 int KGameComputerIO::rtti() const
00474 {
00475   return ComputerIO;
00476 }
00477 
00478 void KGameComputerIO::setReactionPeriod(int calls)
00479 {
00480  d->mReactionPeriod = calls;
00481 }
00482 
00483 int KGameComputerIO::reactionPeriod() const
00484 {
00485   return d->mReactionPeriod;
00486 }
00487 
00488 void KGameComputerIO::setAdvancePeriod(int ms)
00489 {
00490   stopAdvancePeriod();
00491   d->mAdvanceTimer = new QTimer(this);
00492   connect(d->mAdvanceTimer, SIGNAL(timeout()), this, SLOT(advance()));
00493   d->mAdvanceTimer->start(ms);
00494 }
00495 
00496 void KGameComputerIO::stopAdvancePeriod()
00497 {
00498   if (d->mAdvanceTimer)
00499   {
00500     d->mAdvanceTimer->stop();
00501     delete d->mAdvanceTimer;
00502   }
00503 }
00504 
00505 void KGameComputerIO::pause(int calls)
00506 {
00507   d->mPauseCounter = calls;
00508 }
00509 
00510 void KGameComputerIO::unpause()
00511 {
00512   pause(0);
00513 }
00514 
00515 void KGameComputerIO::advance()
00516 {
00517   if (d->mPauseCounter > 0)
00518   {
00519     d->mPauseCounter--;
00520     return;
00521   }
00522   else if (d->mPauseCounter < 0)
00523   {
00524     return;
00525   }
00526   d->mAdvanceCounter++;
00527   if (d->mAdvanceCounter >= d->mReactionPeriod)
00528   {
00529     d->mAdvanceCounter = 0;
00530     reaction();
00531   }
00532 }
00533 
00534 void KGameComputerIO::reaction()
00535 {
00536   emit signalReaction();
00537 }
00538 
00539 
KDE Home | KDE Accessibility Home | Description of Access Keys