examples/Bluetooth/BTExample1/src/dealer.cpp

00001 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
00002 // All rights reserved.
00003 // This component and the accompanying materials are made available
00004 // under the terms of "Eclipse Public License v1.0"
00005 // which accompanies this distribution, and is available
00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
00007 //
00008 // Initial Contributors:
00009 // Nokia Corporation - initial contribution.
00010 //
00011 // Contributors:
00012 //
00013 // Description:
00014 //
00015 
00016 #include <e32base.h>
00017 #include <e32cons.h>
00018 
00019 #include <btsdp.h>
00020 #include "dealer.h"
00021 #include "cardgamedealer.h"
00022 
00023 
00024 
00028 CScabbyQueenDealer* CScabbyQueenDealer::NewL(CConsoleBase& aConsole, 
00029                                                                                          RArray<TInetAddr>& aRemoteNames, 
00030                                                                                          RSocket& aSocket)
00031         {
00032         CScabbyQueenDealer* self = new CScabbyQueenDealer(aConsole, aRemoteNames, aSocket);
00033         self->ConstructL();
00034         return self;
00035         }
00036 
00040 CScabbyQueenDealer::CScabbyQueenDealer(CConsoleBase& aConsole, 
00041                                                                            RArray<TInetAddr>& aRemoteNames, 
00042                                                                            RSocket& aSocket)
00043                                                                            :iConsole(aConsole) 
00044         {
00045         TRAPD(err,CCardGameDealer::ConstructL(aRemoteNames, aSocket));
00046         }
00047 
00048 void CScabbyQueenDealer::StartTheGame()
00049         {
00050         InformStaticPlayers();
00051         }
00052 
00056 CScabbyQueenDealer::~CScabbyQueenDealer()
00057         {
00058         iLostPlayers.Close();
00059         iFinishedPlayers.Close();
00060         iCurrentPlayers.Close();
00061         }
00062 
00066 void CScabbyQueenDealer::ConstructL()
00067         {
00068         iPlayerToken = 0;
00069         // construct the deck.
00070         iFullDeck = HBufC8::NewL(KDeckBufferLength);
00071         iFullDeck->Des().Append(KHearts);
00072         iFullDeck->Des().Append(KDiamonds);
00073         iFullDeck->Des().Append(KSpades);
00074         iFullDeck->Des().Append(KClubs);
00075         iGameOverBuffer = KErrCompletion;
00076         iPlayerNum = 0;
00077         }
00078         
00082 void CScabbyQueenDealer::SendPlayerNumbers()
00083         {
00084         // Player are waiting to receive player numbers from 
00085         // us so give them
00086         if (iPlayerNum() < iRemoteNames.Count())
00087                 {               
00088                 iSendMode = ESendPlayerNum;
00089                 BaseSendTo(iPlayerNum, iRemoteNames[iPlayerNum()]);
00090                 iPlayerNum()++;
00091                 }
00092 
00093         }
00097 void CScabbyQueenDealer::DealDeckL()
00098         {
00099         DealCardsL(*iFullDeck);
00100         iConsole.Printf(_L("\nDealt"));
00101         iFullDeck->Des().Delete(0, iFullDeck->Length());
00102         }
00103         
00104 
00108 void CScabbyQueenDealer::SendComplete(TInt aError)
00109         {
00110         switch(iSendMode)       
00111                 {
00112                 case ESendPlayerNum:
00113                 SendPlayerNumbers();
00114                 break;
00115                 case ESendRecvToken:
00116                         ReceivingPlayerInformed(aError);
00117                 break;
00118         
00119                 case ESendSendToken:
00120                         RecvHandSize(aError);
00121                 break;
00122         
00123                 case ESendWaitToken:
00124                         SendCompleted(aError);
00125                 break;
00126         
00127                 case ESendCard:
00128                         CardSent();
00129                 break;
00130         
00131                 case ESendCheckRecvStatus:
00132                         SendOfCheckStatusComplete(aError);
00133                 break;
00134         
00135                 case ESendCheckSenderStatus:
00136                         SendOfCheckStatusComplete(aError);
00137                 break;
00138         
00139                 case ESendReadyInquiry:
00140                         ReadyInquirySent(aError);
00141                 break;
00142         
00143                 case ESendPlayerUpdate:
00144                         PlayerUpdateSent(aError);
00145                 break;
00146         
00147                 case ESendHandSize:
00148                         SendCompleted(aError);
00149                 break;
00150         
00151                 case ESendPlayerCardNumber:
00152                         SendCompleted(aError);
00153                 break;
00154 
00155                 case ESendGameOver:
00156                         SentGameOverMessage();
00157                 break;
00158                 default:
00159                 break;
00160                 }
00161         }
00162         
00163 
00164         
00168 void CScabbyQueenDealer::RecvComplete(TInetAddr /*aRecvAddr*/, TInt /*aError*/)
00169         {
00170 
00171         switch (iRecvMode)
00172                 {                       
00173                 case ERecvSuccess:
00174                         InformSendingPlayer();
00175                 break;
00176                 
00177                 case ERecvCardNotification:
00178                         RecvOfFinishNotify();
00179                 break;
00180                 
00181                 case EDealerRecvCard:
00182                         RecvOfCardComplete();
00183                 break;
00184                 
00185                 case ERecvStatusRecv:
00186                         DealWithStatusFromRecv();
00187                 break;
00188                 
00189                 case ERecvStatusSender:
00190                         DealWithStatusFromSender();
00191                 break;
00192                 
00193                 case ERecvReadyResult:
00194                         SendReadyInquiry();// call the next
00195                 break;
00196                 
00197                 case ERecvUpdateResult:
00198                         SendPlayerUpdate();//call the next
00199                 break;
00200         
00201                 case EDealerRecvHandSize:
00202                         SendHandSize();
00203                 break;
00204                 
00205                 case EDealerRecvCardNum:
00206                         SendCardNumber();
00207                 break;
00208                         
00209                 case EDealerRecvAck:
00210                         RecvOfAckComplete();
00211                 break;
00212                         
00213                 default:
00214                         break;
00215                 }
00216 
00217         
00218         }
00219         
00220 void CScabbyQueenDealer::TimerComplete()
00221         {
00222         // the ack timer has complete before we have received the ack
00223         iConsole.Printf(_L("\nTimed out! Informing players of Game Over"));
00224         iConsole.Printf(_L("\nFatal Error, exiting game"));
00225         BaseCancelSendTo();
00226         InformNextGameOver();
00227 
00228         }
00229         
00230         
00234 void CScabbyQueenDealer::ShowDeckL()
00235         {
00236         TInt cardNum;
00237         iConsole.Printf(_L("\nThe Deck...\n"));
00238         
00239         for (TInt i=0; i<=iFullDeck->Length()-KCardLength; i=i+KCardLength)
00240                 {
00241                 if (i==0)
00242                         cardNum = i;
00243                 else
00244                         cardNum = i/2;
00245                 HBufC16* buffer = HBufC16::NewL(4);
00246                 buffer->Des().Copy(iFullDeck->Mid(i,2));
00247                 iConsole.Printf(_L("%d - %S | "),cardNum,buffer);
00248                 }
00249         iConsole.Getch();
00250         }
00251         
00252 
00257 void CScabbyQueenDealer::InformReceivingPlayer()
00258         {
00259         if (iPlayerToken == iRemoteNames.Count())
00260                 {
00261                 // reset the Token to start of socket array
00262                 iPlayerToken = 0;
00263                 }
00264                 
00265         iRecvMode = ERecvSuccess;
00266         iCheckSize.Create(iAck);
00267         BaseRecvFrom(iAck); // On return iRecvDes will be filled with iAck
00268         iCheckSize.Close();
00269         //iAckTimer->Cancel();
00270         StopTimer();
00271         iStatusBuffer = EReceiving;
00272         iSendMode = ESendRecvToken;// set the mode for the active object
00273         BaseSendTo(iStatusBuffer, iRemoteNames[iPlayerToken]);
00274         StartTimer(KMaxSendTime);
00275         }
00276 
00284 void CScabbyQueenDealer::ReceivingPlayerInformed(TInt aError)
00285         {
00286         if (aError == KErrNone)
00287                 {
00288 
00289                 }
00290         else
00291                 {
00292                 // send has failed.
00293                 StopTimer();
00294                 BaseCancelRecvFrom();
00295                 // that the game is over.
00296                 iConsole.Printf(_L("\nFatal Error, exiting game"));
00297                 iCount = iSender;
00298                 InformNextGameOver();
00299                 }
00300         }
00301 
00305 void CScabbyQueenDealer::InformSendingPlayer()
00306         {
00307         if (iAck() == KErrNone)
00308                 {
00309                 StopTimer();
00310                 // We wont set an ack this time, instead when the sender sends
00311                 // back their hand size we will use this as an ack.
00312                 iStatusBuffer = ESending;
00313                 iSendMode = ESendSendToken;
00314                 BaseSendTo(iStatusBuffer, iRemoteNames[iSender]);
00315                 StartTimer(KMaxSendTime);
00316                 }
00317         else
00318                 {
00319                 // We did get an Ack back but it was what we expected
00320                 }
00321 
00322         }
00323 
00328 void CScabbyQueenDealer::InformStaticPlayers()
00329         {
00330         StopTimer();
00331         InformStaticPlayersProcess();
00332         }
00333         
00337 void CScabbyQueenDealer::InformStaticPlayersProcess()
00338         {       
00339         // inform everyone except current receviver (iPlayerToken) and iSender
00340         while (iFinishedPlayers.Find(iPlayerToken) != KErrNotFound)// make sure we are not a finished player
00341                 {
00342                 iPlayerToken++;
00343                 if (iPlayerToken == iRemoteNames.Count())
00344                         iPlayerToken = 0;// we have come to the end so start over.
00345                 }
00346         iCount++;// increment count, this will be used to address the socket array.
00347 
00348         if (iPlayerToken == 0)
00349                 iSender = iRemoteNames.Count()-1;
00350         else
00351                 iSender = iPlayerToken-1;
00352         
00353         if (iPlayerCount == 2)
00354                 {
00355                 InformReceivingPlayer();// no waiting players so move directly to next stage
00356                 }
00357         else
00358                 {
00359                 // as there are more that 2 players we need to send out wait nofitications
00360                 if (iCount == iRemoteNames.Count())
00361                         {
00362                         iCount = 0;
00363                         }
00364                         
00365         
00366                 if (iCount != iPlayerToken && iCount != iSender)
00367                         // make sure that iCount isn't a sender or receiver
00368                         {
00369                         // Get ready to receive the ack back
00370                         iRecvMode = EDealerRecvAck;
00371                         iCheckSize.Create(iAck);
00372                         BaseRecvFrom(iAck);
00373                         iCheckSize.Close();
00374                         StopTimer();
00375                         iSendMode = ESendWaitToken;
00376                         iStatusBuffer = EWaiting;
00377                         BaseSendTo(iStatusBuffer, iRemoteNames[iCount]);
00378                         StartTimer(KMaxSendTime);
00379                         }
00380                 else
00381                         {
00382                         // If iCount is a S or R then recall the function to increment iCount
00383                         InformStaticPlayers();
00384                         }
00385                 }
00386         }
00387 
00395 void CScabbyQueenDealer::StaticPlayersInformed(TInt aError)
00396         {
00397         StopTimer();    
00398         if (aError == KErrNone)
00399                 {
00400                 // this will be called when all static players have been informed
00401                 iResponseCount = 0;
00402                 InformReceivingPlayer();
00403                 }
00404         else
00405                 {
00406                 // send has failed.
00407                 BaseCancelSendTo();
00408                 iConsole.Printf(_L("\nFatal Error, exiting game"));
00409                 InformNextGameOver();   
00410                 }
00411 
00412         }
00413 
00417 void CScabbyQueenDealer::RecvHandSize(TInt aError)
00418         {
00419         if (aError == KErrNone)
00420                 {
00421                 // This will also act as the ack for sender token send as well
00422                 iRecvMode = EDealerRecvHandSize;
00423                 iCheckSize.Create(iSenderHandSize);
00424                 BaseRecvFrom(iSenderHandSize);
00425                 iCheckSize.Close();
00426                 }
00427         else
00428                 {
00429                 // send has failed.
00430                 BaseCancelSendTo();     
00431                 iConsole.Printf(_L("\nFatal Error, exiting game"));
00432                 iCount = iSender;
00433                 InformNextGameOver();
00434                 }
00435 
00436         }
00437 
00438 
00444 void CScabbyQueenDealer::RecvOfAckComplete()
00445         {
00446         // when the ack recv completes we will get called.
00447         // if all is ok then we want to setup the next stage.
00448         iResendCount = 0;
00449         StopTimer();
00450         if (iAck() == KErrNone)// did they receive it ok?
00451                 {
00452                 switch (iSendMode)
00453                         {
00454                         case ESendHandSize:
00455                                 ReceiveCardNum();
00456                         break;
00457 
00458                         case ESendWaitToken:
00459                                 {
00460                                 // We have received the ack after dealer told waiting player
00461                                 iWaitingPlayerCount++;
00462                                 if (iWaitingPlayerCount == iPlayerCount-2)
00463                                         {
00464                                         // All waiting players informed
00465                                         StaticPlayersInformed(KErrNone);
00466                                         iWaitingPlayerCount = 0; 
00467                                         }
00468                                 else
00469                                         {
00470                                         //we havent finished telling all the waiting players yet
00471                                         InformStaticPlayers();
00472                                         }       
00473                                 }
00474 
00475                         break;
00476                         default:
00477                         break;
00478                         }
00479                 }
00480         else
00481                 {
00482                 // we have the ack back but the sender has reported an error
00483                 iConsole.Printf(_L("\nFatal Error, exiting game"));
00484                 iCount = 0;
00485                 BaseCancelSendTo();
00486                 InformNextGameOver();
00487                 }
00488         }
00489 
00495 void CScabbyQueenDealer::SendHandSize()
00496         {
00497         // We have now recv the hand size from sender, this is also the ack.
00498         if (iSenderHandSize() >= 0)
00499                 {
00500                 StopTimer();
00501                 // get ready to receive the ack
00502                 iRecvMode = EDealerRecvAck;
00503                 iCheckSize.Create(iAck);
00504                 BaseRecvFrom(iAck);
00505                 iCheckSize.Close();
00506                 //now send the hand size on
00507                 iSendMode = ESendHandSize;
00508                 BaseSendTo(iSenderHandSize, iRemoteNames[iPlayerToken]);
00509                 StartTimer(KMaxSendTime);
00510                 }
00511         else
00512                 {
00513                 // We have fail to send twice 
00514                 iConsole.Printf(_L("\nFatal Error, exiting game"));
00515                 BaseCancelSendTo();
00516                 iCount = iPlayerToken;
00517                 InformNextGameOver();
00518                 }
00519 
00520         }
00521         
00522         
00527 void CScabbyQueenDealer::InformNextGameOver()
00528         {
00529 
00530         if (iRemoteNames.Count() > iLostPlayers.Count())// still got players?
00531                 {
00532                 // before we tell the next player that we have finished
00533                 // check that we havent already disconnected.
00534                 TInt index = iLostPlayers.Find(iCount);
00535                 if (index == KErrNotFound)
00536                         {
00537                         // remove the device just lost
00538                         iLostPlayers.Append(iCount);
00539                         iRemoteNames.Remove(iCount);
00540                         iCount++;//move onto next
00541                         // we are ok to disconnect a device
00542                         
00543                         if (iCount == iRemoteNames.Count())
00544                                 iCount = 0;
00545                         //now send the hand size on
00546                         iSendMode = ESendGameOver;
00547                         BaseSendTo(iGameOverBuffer, iRemoteNames[iCount]);
00548                         }
00549                 else
00550                         {
00551                         // device already disconnected, move onto next
00552                         iCount++;
00553                         InformNextGameOver();
00554                         }       
00555                 }
00556         else
00557                 {
00558                 iConsole.Printf(_L("\nAll players have left the game"));
00559                 }
00560 
00561         }
00562 
00566 void CScabbyQueenDealer::ReceiveCardNum()
00567         {
00568         iRecvMode = EDealerRecvCardNum;
00569         BaseSendTo(iCardNum, iRemoteNames[iPlayerToken]);
00570         }
00571         
00576 void CScabbyQueenDealer::SendCardNumber()
00577         {
00578         if (iCardNum() >= 0)
00579                 {
00580                 StopTimer();
00581                 // get ready to receive the card (this will also be the ack)
00582                 RecvCard();
00583                 // send the player the card number we just received
00584                 iSendMode = ESendPlayerCardNumber;
00585                 BaseSendTo(iCardNum, iRemoteNames[iSender]);
00586                 StartTimer(KMaxSendTime);
00587                 }
00588         else
00589                 {
00590                 // We have failed to send twice, start the game over procedure.
00591                 iConsole.Printf(_L("\nFatal Error, exiting game"));
00592                 BaseCancelSendTo();
00593                 BaseCancelRecvFrom();
00594                 iCount = iPlayerToken;
00595                 InformNextGameOver();
00596                 }
00597         }
00598 
00604 void CScabbyQueenDealer::SendCompleted(TInt aError)
00605         {
00606         // in the case where the send completes successfully nothing will be done.
00607         // if there was an error in the send we will cancel the timer and attempt a resend
00608         if (aError !=KErrNone)
00609                 {
00610                 // we have failed to send
00611                 // cancel timer
00612                 StopTimer();
00613                 BaseCancelRecvFrom();
00614                 // We have failed to send twice, start the game over procedure.
00615                 iConsole.Printf(_L("\nFatal Error, exiting game"));
00616                 iCount = 0;
00617                 InformNextGameOver();
00618                 }
00619         else
00620                 {
00621                 //we have sent successfully, timer will continue.
00622                 // when recv of ack completes we can proceed
00623                 }
00624         }
00625         
00626         
00630 void CScabbyQueenDealer::RecvCard()
00631         {
00632         iRecvMode = EDealerRecvCard;
00633         BaseRecvFrom(iReceivedCard);
00634         }
00635 
00636 
00641 void CScabbyQueenDealer::RecvOfCardComplete()
00642         {
00643         // we have recvd the card from sender. this is also the ack.
00644         if (iReceivedCard != KNullDesC8)
00645                 {
00646                 StopTimer();
00647                 iSendMode = ESendCard;
00648                 BaseSendTo(iReceivedCard, iRemoteNames[iPlayerToken]);
00649                 }
00650         else
00651                 {
00652                 // We have failed to send twice so start the Game over procedure.
00653                 iConsole.Printf(_L("\nFatal Error, exiting game"));
00654                 iCount = iSender;
00655                 BaseCancelSendTo();
00656                 InformNextGameOver();
00657                 }
00658                         
00659         }
00660 
00665 void CScabbyQueenDealer::CardSent()
00666         {
00667         // We have sent the card to the player, now get ready to receive an ack from them
00668         iRecvMode = ERecvCardNotification;
00669         iCheckSize.Create(iStatusBuffer);
00670         BaseRecvFrom(iStatusBuffer);
00671         iCheckSize.Close();
00672         }
00673         
00674         
00680 void CScabbyQueenDealer::RecvOfFinishNotify()
00681         {
00682         // receiver has told us he has received the card, he and the sender are waiting
00683         // this stuff want to go into function called after we have heard back from player status
00684         if (iStatusBuffer() == EReceivedCard)
00685                 {
00686                 iConsole.Printf(_L("\nPlayer[%d] ----> Player[%d]"),iSender , iPlayerToken);
00687                 CheckPlayerStatus();
00688                 }
00689         else
00690                 {
00691                 iConsole.Printf(_L("\nWe were expecting received card!"));
00692                 }
00693 
00694         }
00695 
00701 void CScabbyQueenDealer::SendOfCheckStatusComplete(TInt aError)
00702         {
00703         if (iSendMode == ESendCheckRecvStatus)
00704                 {
00705                 // we have sent to the recv'r
00706                 if (aError == KErrNone)
00707                         {
00708                         iRecvMode = ERecvStatusRecv;
00709                         iCheckSize.Create(iGameStatus);
00710                         BaseRecvFrom(iGameStatus);
00711                         iCheckSize.Close();
00712                         }
00713                 else
00714                         {
00715                         // send has failed.
00716                         StartTimer(KMaxSendTime);
00717                         BaseCancelSendTo();
00718                         iConsole.Printf(_L("\nFatal Error, exiting game"));
00719                         iCount = iSender;
00720                         InformNextGameOver();
00721                         }
00722                 }
00723         else
00724                 {
00725                 // we have sent to the sender.
00726                 if (aError == KErrNone)
00727                         {
00728                         iRecvMode = ERecvStatusSender;
00729                         iCheckSize.Create(iGameStatus);
00730                         BaseRecvFrom(iGameStatus);
00731                         iCheckSize.Close();
00732                         }
00733                 else
00734                         {
00735                         // send has failed.
00736                         StopTimer();
00737                         BaseCancelSendTo();
00738                         iConsole.Printf(_L("\nFatal Error, exiting game"));
00739                         iCount = iPlayerToken;  
00740                         InformNextGameOver();
00741                         }
00742                 }
00743         }
00744 
00745         
00750 void CScabbyQueenDealer::DealWithStatusFromSender()
00751         {
00752         // We have got the status of the Sender, deal with it
00753         StopTimer();
00754         iResendCount = 0;
00755         DealWithGameStatus(iGameStatus());
00756         }
00757         
00763 void CScabbyQueenDealer::DealWithStatusFromRecv()
00764         {
00765         // We have got the status from receiver, deal with it
00766         StopTimer();
00767         iResendCount = 0;
00768         DealWithGameStatus(iGameStatus());
00769         // Now we want to tell the Sender to send their status
00770         iGameStatus = EGameStatusRequest;
00771         iSendMode = ESendCheckSenderStatus;
00772         BaseSendTo(iGameStatus, iRemoteNames[iSender]);
00773         StartTimer(KMaxSendTime);
00774         }
00775         
00776         
00780 void CScabbyQueenDealer::CheckPlayerStatus()
00781         {
00782         // Tell the Receiver that we want their game status
00783         StopTimer();
00784         iGameStatus = EGameStatusRequest;
00785         iSendMode = ESendCheckRecvStatus;
00786         BaseSendTo(iGameStatus, iRemoteNames[iPlayerToken]);
00787         StartTimer(KMaxSendTime);
00788         }
00789 
00790 
00797 void CScabbyQueenDealer::DealWithGameStatus(TGameStatus aGameStatus)
00798         {
00799 
00800         if (iResponseCount == 0)
00801                 {
00802                 // First response, reset Update
00803                 iCurrentPlayers.Reset();
00804                 iPlayerUpdate.Delete(0,iPlayerUpdate.Length());
00805                 }
00806                 
00807         iResponseCount++;
00808         
00809         // Check the enum status that we have received, and append the
00810         // appropriate player number to the appropriate array.
00811         switch(aGameStatus)
00812                 {
00813                 case EPlayingZero:
00814                         iCurrentPlayers.Append(0);
00815                 break;
00816                 
00817                 case EPlayingOne:
00818                         iCurrentPlayers.Append(1);
00819                 break;
00820                 
00821                 case EPlayingTwo:
00822                         iCurrentPlayers.Append(2);      
00823                 break;
00824                 
00825                 case EPlayingThree:
00826                         iCurrentPlayers.Append(3);              
00827                 break;
00828                 
00829                 case EPlayingFour:
00830                         iCurrentPlayers.Append(4);              
00831                 break;
00832                 
00833                 case EPlayingFive:              
00834                         iCurrentPlayers.Append(5);
00835                 break;
00836         
00837                 case EPlayingSix:               
00838                         iCurrentPlayers.Append(6);
00839                 break;
00840                 
00841                 case EPlayingSeven:             
00842                         iCurrentPlayers.Append(7);
00843                 break;
00844         
00845                 case EFinishedZero:             
00846                         iFinishedPlayers.Append(0);
00847                 break;
00848 
00849                 case EFinishedOne:              
00850                         iFinishedPlayers.Append(1);
00851                 break;
00852                 
00853                 case EFinishedTwo:              
00854                         iFinishedPlayers.Append(2);
00855                 break;
00856                 
00857                 case EFinishedThree:            
00858                         iFinishedPlayers.Append(3);
00859                 break;
00860         
00861                 case EFinishedFour:             
00862                         iFinishedPlayers.Append(4);
00863                 break;
00864         
00865                 case EFinishedFive:             
00866                         iFinishedPlayers.Append(5);
00867                 break;
00868 
00869                 case EFinishedSix:              
00870                 iFinishedPlayers.Append(6);
00871                 break;
00872                 
00873                 case EFinishedSeven:            
00874                         iFinishedPlayers.Append(7);
00875                 break;
00876                 
00877                 default:
00878                 break;
00879                 }
00880                         
00881         if (iResponseCount == 2)// heard back from both
00882                 {
00883                 if (iOldPlayerUpdate == KNullDesC8)// first time 
00884                         {
00885                         // as this is the first time we can construct the
00886                         // update descriptor as follows
00887                         // append any finished players
00888                         for (TInt i=0;i<iFinishedPlayers.Count();i++)
00889                                 {
00890                                 iPlayerUpdate.AppendNum(iFinishedPlayers[i]);
00891                                 }
00892                         // append the F that seperates In and Out Players.
00893                         iPlayerUpdate.Append('F');
00894                         
00895                         // append the players that are still in
00896                         for (TInt i=0;i<iCurrentPlayers.Count();i++)
00897                                 {
00898                                 iPlayerUpdate.AppendNum(iCurrentPlayers[i]);
00899                                 }
00900                                 
00901                         // append all the players that didnt do nothing
00902                         for (TInt i=0;i<iRemoteNames.Count();i++)
00903                                 { 
00904                                 if (i == iPlayerToken || i == iSender)
00905                                         {       
00906                                         }
00907                                 else
00908                                         {
00909                                         iPlayerUpdate.AppendNum(i);
00910                                         }
00911                                 } 
00912                         }
00913                 else
00914                         {
00915 
00916                         // as oldupdate contains something then this isn't the first time
00917                         // a card has been exchanged we need to inspect the finished array.
00918                         // for each of the values in the array we need to check whether it is to the left of the 
00919                         // F (we already know that they have finished) if it isn't then we need to add it.
00920                         // and remove it from the right of the F (these are the current players)
00921                         
00922                         
00923                         TInt index = 0;
00924                         // locate where the F is
00925                         while (iOldPlayerUpdate[index] != 'F')
00926                                 {
00927                                 index++;
00928                                 }
00929                                 
00930                         // index is position of F
00931                         // get a pointer to finished players
00932                         TPtrC8 playersOut(iOldPlayerUpdate.Mid(0, index));
00933 
00934 
00935                         for (TInt i=0; i<iFinishedPlayers.Count();i++)
00936                                 {
00937                                 // i is a finished player, check that we have this number to the left of the F
00938                                 // if we dont then add it.
00939                                 TBuf8<1> num;
00940                                 num.AppendNum(iFinishedPlayers[i]);
00941                                 TInt loc = playersOut.Find(num);// has num finished already
00942                                 if (loc == KErrNotFound)
00943                                         {
00944                                         // we have finished with i but it isnt in the finished descriptor list
00945                                         iPlayerUpdate.AppendNum(iFinishedPlayers[i]);
00946                                         TInt match = iOldPlayerUpdate.Find(num);
00947                                         if (match != KErrNotFound)
00948                                                 {
00949                                                 iOldPlayerUpdate.Delete(match, 1);
00950                                                 }
00951                                         }
00952                                 }
00953                         iPlayerUpdate.Insert(0, playersOut);
00954                         index = 0;
00955                         // locate where the F is
00956                         while (iOldPlayerUpdate[index] != 'F')
00957                                 {
00958                                 index++;
00959                                 }
00960                         iOldPlayerUpdate.Delete(0, index);
00961                         }
00962         
00963 
00964                 if (iOldPlayerUpdate.Length() == 2)//  we only have one char to the right of the F
00965                         {
00966                         // we have our loser. hopefully they will have the scabby queen!
00967                         // instead of sending a ready inquiry send a notification that tells the user game has finished.
00968                         iGameOver = ETrue;
00969                         }
00970                         
00971                 iPlayerUpdate.Append(iOldPlayerUpdate);
00972                 iOldPlayerUpdate.Copy(iPlayerUpdate);
00973                 TBufC16<20> buffer;
00974                 buffer.Des().Copy(iPlayerUpdate);
00975                 iConsole.Printf(_L("Update : %S"), &buffer);
00976                 
00977                 iResponseCount=0;
00978                 iCount = 0;
00979                 SendReadyInquiry();
00980                 }
00981         }
00982         
00987 void CScabbyQueenDealer::TimerCompleted()
00988         {
00989         // the ack timer has complete before we have received the ack
00990         iConsole.Printf(_L("\nTimed out! Informing players of Game Over"));
00991         iConsole.Printf(_L("\nFatal Error, exiting game"));
00992         BaseCancelSendTo();
00993         InformNextGameOver();
00994         }
00995 
00996 
01001 void CScabbyQueenDealer::ReadyInquirySent(TInt aError)
01002         {
01003         // we have sent a size update
01004         if (aError == KErrNone)
01005                 {
01006                 iRecvMode = ERecvReadyResult;
01007                 iCheckSize.Create(iGameStatus);
01008                 BaseRecvFrom(iGameStatus);
01009                 iCheckSize.Close();
01010                 iCount++;
01011                 }
01012         else
01013                 {
01014                 // send has failed.
01015                 iConsole.Printf(_L("\nFatal Error, exiting game"));
01016                 BaseCancelSendTo();
01017                 InformNextGameOver();
01018                 }
01019 
01020         }
01021 
01022 
01027 void CScabbyQueenDealer::SendReadyInquiry()
01028         {
01029         StopTimer();
01030         if (iCount < iRemoteNames.Count())
01031                 {
01032                 iSendMode = ESendReadyInquiry;
01033                 iUpdateSize = iPlayerUpdate.Length();// this is the update size
01034                 BaseSendTo(iUpdateSize, iRemoteNames[iCount]);
01035                 StartTimer(KMaxSendTime);
01036                 }
01037         else
01038                 {
01039                 // all are ready, move on to send update
01040                 iCount = 0;
01041                 SendPlayerUpdate();
01042                 }
01043         }
01044 
01049 void CScabbyQueenDealer::SendPlayerUpdate()
01050         {// here we need to a send update       
01051         StopTimer();
01052         BaseCancelSendTo();
01053         if (iCount < iRemoteNames.Count())
01054                 {
01055                 iSendMode = ESendPlayerUpdate;
01056                 BaseSendTo(iPlayerUpdate, iRemoteNames[iCount]);
01057                 StartTimer(KMaxSendTime);
01058                 }
01059         else
01060                 {// all are ready, move on to send update
01061                         //DONE!
01062                 if (iGameOver)
01063                         {
01064                         iConsole.Printf(_L("\n          GAME OVER"));
01065                         }
01066                 else
01067                         {
01068                         iCount = 0;
01069                         iPlayerToken++;// player token is on reciever always!!
01070                         InformStaticPlayers();//START OVER
01071                         }
01072                 }
01073         }
01074 
01079 void CScabbyQueenDealer::PlayerUpdateSent(TInt aError)
01080         {
01081         if (aError == KErrNone)
01082                 {
01083                 iRecvMode = ERecvUpdateResult;
01084                 iCheckSize.Create(iGameStatus);
01085                 BaseRecvFrom(iGameStatus);
01086                 iCheckSize.Close();
01087                 iCount++;
01088                 }
01089         else
01090                 {
01091                 // send has failed.
01092                 StopTimer();
01093                 BaseCancelSendTo();
01094                 iConsole.Printf(_L("\nFatal Error, exiting game"));
01095                 InformNextGameOver();
01096                 }
01097         }
01098         
01103 void CScabbyQueenDealer::SentGameOverMessage()
01104         {
01105         // we have sent a message to a player, move onto next
01106         iConsole.Printf(_L("\nPlayer %d has left the game"), iCount);
01107         InformNextGameOver();
01108         }

Generated on Thu Jan 21 10:32:57 2010 for TB10.1 Example Applications by  doxygen 1.5.3