kplayer.cpp

Go to the documentation of this file.
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: kplayer.cpp 465369 2005-09-29 14:33:08Z mueller $
00022 */
00023 
00024 
00025 #include "kgame.h"
00026 #include "kgameio.h"
00027 #include "kplayer.h"
00028 #include "kgamemessage.h"
00029 #include "kgamepropertyhandler.h"
00030 
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 
00034 #include <qbuffer.h>
00035 
00036 #include <stdio.h>
00037 #include <assert.h>
00038 
00039 #define KPLAYER_LOAD_COOKIE 7285
00040 
00041 class KPlayerPrivate
00042 {
00043 public:
00044    KPlayerPrivate()
00045    {
00046       mNetworkPlayer = 0;
00047    }
00048 
00049    Q_UINT32 mId;
00050    bool mVirtual; // virtual player
00051    int mPriority; // tag for replacement
00052 
00053    KPlayer* mNetworkPlayer; // replacement player
00054 
00055    KGamePropertyHandler mProperties;
00056 
00057 // Playerdata
00058    KGamePropertyQString mName;
00059    KGamePropertyQString mGroup;
00060 };
00061 
00062 KPlayer::KPlayer() : QObject(0,0)
00063 {
00064  init();
00065 }
00066 
00067 KPlayer::KPlayer(KGame* game) : QObject(0, 0)
00068 {
00069  init();
00070  game->addPlayer(this);
00071 }
00072 
00073 void KPlayer::init()
00074 {
00075 // note that NO KGame object exists here! so we cannot use KGameProperty::send!
00076    kdDebug(11001) << k_funcinfo << ": this=" << this << ", sizeof(this)="<<sizeof(KPlayer) << endl;
00077    kdDebug(11001) << "sizeof(m_Group)="<<sizeof(d->mGroup)<<endl;
00078    d = new KPlayerPrivate;
00079 
00080    d->mProperties.registerHandler(KGameMessage::IdPlayerProperty,
00081                                   this,SLOT(sendProperty(int, QDataStream&, bool*)),
00082                                        SLOT(emitSignal(KGamePropertyBase *)));
00083    d->mVirtual=false;
00084    mActive=true;
00085    mGame=0;
00086    d->mId=0; // "0" is always an invalid ID!
00087    d->mPriority=0;
00088    // I guess we cannot translate the group otherwise no
00089    // international conenctions are possible
00090 
00091    mUserId.registerData(KGamePropertyBase::IdUserId, this, i18n("UserId"));
00092    mUserId.setLocal(0);
00093    d->mGroup.registerData(KGamePropertyBase::IdGroup, this, i18n("Group"));
00094    d->mGroup.setLocal(i18n("default"));
00095    d->mName.registerData(KGamePropertyBase::IdName, this, i18n("Name"));
00096    d->mName.setLocal(i18n("default"));
00097 
00098    mAsyncInput.registerData(KGamePropertyBase::IdAsyncInput, this, i18n("AsyncInput"));
00099    mAsyncInput.setLocal(false);
00100    mMyTurn.registerData(KGamePropertyBase::IdTurn, this, i18n("myTurn"));
00101    mMyTurn.setLocal(false);
00102    mMyTurn.setEmittingSignal(true);
00103    mMyTurn.setOptimized(false);
00104 }
00105 
00106 KPlayer::~KPlayer()
00107 {
00108   kdDebug(11001) << k_funcinfo << ": this=" << this <<", id=" << this->id() << endl;
00109 
00110   // Delete IODevices
00111   KGameIO *input;
00112   while((input=mInputList.first()))
00113   {
00114     delete input;
00115   }
00116   if (game())
00117   {
00118     game()->playerDeleted(this);
00119   }
00120 
00121 // note: mProperties does not use autoDelete or so - user must delete objects
00122 // himself
00123   d->mProperties.clear();
00124   delete d;
00125 //  kdDebug(11001) << k_funcinfo << " done" << endl;
00126 }
00127 
00128 bool KPlayer::forwardMessage(QDataStream &msg,int msgid,Q_UINT32 receiver,Q_UINT32 sender)
00129 {
00130   if (!isActive())
00131   {
00132     return false;
00133   }
00134   if (!game())
00135   {
00136     return false;
00137   }
00138   kdDebug(11001) << k_funcinfo << ": to game sender="<<sender<<"" << "recv="<<receiver <<"msgid="<<msgid << endl;
00139   return game()->sendSystemMessage(msg,msgid,receiver,sender);
00140 }
00141 
00142 bool KPlayer::forwardInput(QDataStream &msg,bool transmit,Q_UINT32 sender)
00143 {
00144   if (!isActive())
00145   {
00146     return false;
00147   }
00148   if (!game())
00149   {
00150     return false;
00151   }
00152 
00153   kdDebug(11001) << k_funcinfo << ": to game playerInput(sender="<<sender<<")" << endl;
00154   if (!asyncInput() && !myTurn())
00155   {
00156     kdDebug(11001) << k_funcinfo << ": rejected cause it is not our turn" << endl;
00157     return false;
00158   }
00159 
00160   // AB: I hope I remember the usage correctly:
00161   // this function is called twice (on sender side) - once with transmit = true
00162   // where it sends the input to the comserver and once with transmit = false
00163   // where it really looks at the input
00164   if (transmit)
00165   {
00166     kdDebug(11001) << "indirect playerInput" << endl;
00167     return game()->sendPlayerInput(msg,this,sender);
00168   }
00169   else
00170   {
00171     kdDebug(11001) << "direct playerInput" << endl;
00172     return game()->systemPlayerInput(msg,this,sender);
00173   }
00174 }
00175 
00176 void KPlayer::setId(Q_UINT32 newid)
00177 {
00178   // Needs to be after the sendProcess
00179   d->mId=newid;
00180 }
00181 
00182 
00183 void KPlayer::setGroup(const QString& group)
00184 { d->mGroup = group; }
00185 
00186 const QString& KPlayer::group() const
00187 { return d->mGroup.value(); }
00188 
00189 void KPlayer::setName(const QString& name)
00190 { d->mName = name; }
00191 
00192 const QString& KPlayer::name() const
00193 { return d->mName.value(); }
00194 
00195 Q_UINT32 KPlayer::id() const
00196 { return d->mId; }
00197 
00198 KGamePropertyHandler * KPlayer::dataHandler()
00199 { return &d->mProperties; }
00200 
00201 void KPlayer::setVirtual(bool v)
00202 { d->mVirtual = v; }
00203 
00204 bool KPlayer::isVirtual() const
00205 { return d->mVirtual;}
00206 
00207 void KPlayer::setNetworkPlayer(KPlayer* p)
00208 { d->mNetworkPlayer = p; }
00209 
00210 KPlayer* KPlayer::networkPlayer() const
00211 { return d->mNetworkPlayer; }
00212 
00213 int KPlayer::networkPriority() const
00214 { return d->mPriority; }
00215 
00216 void KPlayer::setNetworkPriority(int p)
00217 { d->mPriority = p; }
00218 
00219 bool KPlayer::addGameIO(KGameIO *input)
00220 {
00221   if (!input)
00222   {
00223     return false;
00224   }
00225   mInputList.append(input); 
00226   input->initIO(this); // set player and init device
00227   return true;
00228 }
00229 
00230 // input=0, remove all
00231 bool KPlayer::removeGameIO(KGameIO *targetinput,bool deleteit)
00232 {
00233   kdDebug(11001) << k_funcinfo << ": " << targetinput << " delete=" << deleteit<< endl;
00234   bool result=true;
00235   if (!targetinput) // delete all
00236   {
00237     KGameIO *input;
00238     while((input=mInputList.first()))
00239     {
00240       if (input) removeGameIO(input,deleteit);
00241     }
00242   }
00243   else
00244   {
00245 //    kdDebug(11001) << "remove IO " << targetinput << endl;
00246     if (deleteit)
00247     {
00248       delete targetinput;
00249     }
00250     else
00251     {
00252       targetinput->setPlayer(0);
00253       result=mInputList.remove(targetinput);
00254     }
00255   }
00256   return result;
00257 }
00258 
00259 KGameIO * KPlayer::findRttiIO(int rtti) const
00260 {
00261   QPtrListIterator<KGameIO> it(mInputList);
00262   while (it.current())
00263   {
00264     if (it.current()->rtti() == rtti)
00265     {
00266       return it.current();
00267     }
00268     ++it;
00269   }
00270   return 0;
00271 }
00272 
00273 int KPlayer::calcIOValue()
00274 {
00275   int value=0;
00276   QPtrListIterator<KGameIO> it(mInputList);
00277   while (it.current())
00278   {
00279     value|=it.current()->rtti();
00280     ++it;
00281   }
00282   return value;
00283 }
00284 
00285 bool KPlayer::setTurn(bool b, bool exclusive)
00286 {
00287   kdDebug(11001) << k_funcinfo << ": " << id() << " (" << this << ") to " << b << endl;
00288   if (!isActive())
00289   {
00290     return false;
00291   }
00292 
00293   // if we get to do an exclusive turn all other players are disallowed
00294   if (exclusive && b && game())
00295   {
00296      KPlayer *player;
00297      KGame::KGamePlayerList *list=game()->playerList();
00298      for ( player=list->first(); player != 0; player=list->next() )
00299      {
00300        if (player==this)
00301        {
00302          continue;
00303        }
00304        player->setTurn(false,false);
00305      }
00306   }
00307 
00308   // Return if nothing changed
00309   mMyTurn = b;
00310 
00311   return true;
00312 }
00313 
00314 bool KPlayer::load(QDataStream &stream)
00315 {
00316   Q_INT32 id,priority;
00317   stream >> id >> priority;
00318   setId(id);
00319   setNetworkPriority(priority);
00320 
00321   // Load Player Data
00322   //FIXME: maybe set all properties setEmitSignal(false) before?
00323   d->mProperties.load(stream);
00324 
00325   Q_INT16 cookie;
00326   stream >> cookie;
00327   if (cookie==KPLAYER_LOAD_COOKIE)
00328   {
00329       kdDebug(11001) << "   Player loaded propertly"<<endl;
00330   }
00331   else
00332   {
00333       kdError(11001) << "   Player loading error. probably format error"<<endl;
00334   }
00335 
00336   // emit signalLoad(stream);
00337   return true;
00338 }
00339 
00340 bool KPlayer::save(QDataStream &stream)
00341 {
00342   stream << (Q_INT32)id() << (Q_INT32)networkPriority();
00343 
00344   d->mProperties.save(stream);
00345 
00346   stream << (Q_INT16)KPLAYER_LOAD_COOKIE;
00347 
00348   //emit signalSave(stream);
00349   return true;
00350 }
00351 
00352 
00353 void KPlayer::networkTransmission(QDataStream &stream,int msgid,Q_UINT32 sender)
00354 {
00355   //kdDebug(11001) << k_funcinfo ": msgid=" << msgid << " sender=" << sender << " we are=" << id() << endl;
00356   // PlayerProperties processed
00357   bool issender;
00358   if (game())
00359   {
00360     issender=sender==game()->gameId();
00361   }
00362   else
00363   {
00364     issender=true;
00365   }
00366   if (d->mProperties.processMessage(stream,msgid,issender))
00367   {
00368         return ;
00369   }
00370   switch(msgid)
00371   {
00372     case KGameMessage::IdPlayerInput:
00373       {
00374         kdDebug(11001) << k_funcinfo << ": Got player move "
00375                 << "KPlayer (virtual) forwards it to the game object" << endl;
00376         forwardInput(stream,false);
00377       }
00378     break;
00379     default:
00380         emit signalNetworkData(msgid - KGameMessage::IdUser,
00381                 ((QBuffer*)stream.device())->readAll(),sender,this);
00382         kdDebug(11001) << k_funcinfo << ": "
00383                 << "User data msgid " << msgid << endl;
00384     break;
00385   }
00386 
00387 }
00388 
00389 KGamePropertyBase* KPlayer::findProperty(int id) const
00390 {
00391   return d->mProperties.find(id);
00392 }
00393 
00394 bool KPlayer::addProperty(KGamePropertyBase* data)
00395 {
00396   return d->mProperties.addProperty(data);
00397 }
00398 
00399 void KPlayer::sendProperty(int msgid, QDataStream& stream, bool* sent)
00400 {
00401   if (game())
00402   {
00403     bool s = game()->sendPlayerProperty(msgid, stream, id());
00404     if (s)
00405     {
00406       *sent = true;
00407     }
00408   }
00409 }
00410 
00411 void KPlayer::emitSignal(KGamePropertyBase *me)
00412 {
00413   // Notify KGameIO (Process) for a new turn
00414   if (me->id()==KGamePropertyBase::IdTurn)
00415   {
00416     //kdDebug(11001) << k_funcinfo << ": for KGamePropertyBase::IdTurn " << endl;
00417     QPtrListIterator<KGameIO> it(mInputList);
00418     while (it.current())
00419     {
00420       it.current()->notifyTurn(mMyTurn.value());
00421       ++it;
00422     }
00423   }
00424   emit signalPropertyChanged(me,this);
00425 }
00426 
00427 // --------------------- DEBUG --------------------
00428 void KPlayer::Debug()
00429 {
00430    kdDebug(11001) << "------------------- KPLAYER -----------------------" << endl;
00431    kdDebug(11001) << "this:    " << this << endl;
00432    kdDebug(11001) << "rtti:    " << rtti() << endl;
00433    kdDebug(11001) << "id  :    " << id() << endl;
00434    kdDebug(11001) << "Name :   " << name() << endl;
00435    kdDebug(11001) << "Group:   " << group() << endl;
00436    kdDebug(11001) << "Async:   " << asyncInput() << endl;
00437    kdDebug(11001) << "myTurn:  " << myTurn() << endl;
00438    kdDebug(11001) << "Virtual: " << isVirtual() << endl;
00439    kdDebug(11001) << "Active:  " << isActive() << endl;
00440    kdDebug(11001) << "Priority:" << networkPriority() << endl;
00441    kdDebug(11001) << "Game   : " << game() << endl;
00442    kdDebug(11001) << "#IOs:    " << mInputList.count() << endl;
00443    kdDebug(11001) << "---------------------------------------------------" << endl;
00444 }
00445 
00446 #include "kplayer.moc"

Generated on Wed Aug 23 18:04:18 2006 for libkdegames by  doxygen 1.4.6