diff -r 89d6a7a84779 -r 25a17d01db0c Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_fibonacci2_8cpp-source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_fibonacci2_8cpp-source.html Fri Jan 22 18:26:19 2010 +0000 @@ -0,0 +1,552 @@ + + +TB10.1 Example Applications: examples/Base/IPC/Async/Fibonacci2/Fibonacci2.cpp Source File + + + + +

examples/Base/IPC/Async/Fibonacci2/Fibonacci2.cpp

00001 // Copyright (c) 2000-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 // Example wraps a console in an active object and performs the 
+00015 // Fibonacci calculation in a separate thread.
+00016 // This is NOT the recommended way and serves only to compare with the 
+00017 // Fibonacci3 example which performs the calculation as
+00018 // a background active object.
+00019 //
+00020 
+00021 
+00022 #include <e32std.h>
+00023 #include <e32cons.h>
+00024 #include <e32base.h>
+00025 
+00026 //
+00027 // Common literals
+00028 //
+00029 _LIT(KTxtFibThread,"FibThread");
+00030 
+00031 
+00032 LOCAL_D CConsoleBase* console;
+00033 
+00034 _LIT(KTxtMainInstructions,"\n\nPress 'F' to start\n      'ESC' to exit\n      'C' to cancel, anytime\n");
+00035 
+00037 //
+00038 // -----> CActiveConsole (definition)
+00039 //
+00040 // An abstract class which provides the facility to issue key requests. 
+00041 //
+00043 class CActiveConsole : public CActive
+00044         {
+00045 public:
+00046           // Construction
+00047         CActiveConsole(CConsoleBase* aConsole);
+00048         void ConstructL();
+00049 
+00050           // Destruction
+00051         ~CActiveConsole();
+00052 
+00053           // Issue request
+00054         void RequestCharacter();
+00055         
+00056           // Cancel request.
+00057           // Defined as pure virtual by CActive;
+00058           // implementation provided by this class.
+00059         void DoCancel();
+00060 
+00061           // Service completed request.
+00062           // Defined as pure virtual by CActive;
+00063           // implementation provided by this class,
+00064         void RunL();
+00065 
+00066           // Called from RunL() - an implementation must be provided
+00067           // by derived classes to handle the completed request
+00068         virtual void ProcessKeyPress(TChar aChar) = 0; 
+00069           
+00070 protected:
+00071           // Data members defined by this class
+00072         CConsoleBase* iConsole; // A console for reading from
+00073         };
+00074 
+00075 
+00077 //
+00078 // -----> CExampleScheduler (definition)
+00079 //
+00081 
+00082 class CExampleScheduler : public CActiveScheduler
+00083         {
+00084 public:
+00085         void Error (TInt aError) const;
+00086         void WaitForAnyRequest();
+00087         void SetActiveObject(CActiveConsole* aActiveConsole);
+00088 private:
+00089           // data members defined for this class
+00090         CActiveConsole* iActiveConsole;
+00091         };
+00092 
+00093 
+00095 //
+00096 // -----> CFibonacciEngine (definition)
+00097 //
+00098 // This class provides the fibonacci calculation engine
+00099 //
+00101 
+00102 class CFibonacciEngine : public CBase
+00103         {
+00104 public:
+00105         void Calculate (TInt aTerms) ;
+00106 
+00107         TUint iResult ;
+00108         } ;
+00109 
+00110 
+00112 //
+00113 // -----> TFibonacciParameters (definition)
+00114 //
+00115 // This class provides for passing parameters to the thread 
+00116 //
+00118 
+00119 class TFibonacciParameters
+00120         {
+00121 public:
+00122         TInt iVar1 ;
+00123         TAny* iVar2 ;
+00124         TUint iResult ;
+00125         } ;
+00126 
+00127 
+00129 //
+00130 // -----> CFibonacciThreadHandler (definition)
+00131 //
+00132 // This class encapsulates the fibonacci thread that runs the fibonacci engine
+00133 //
+00135 
+00136 class CFibonacciThreadHandler : public CActive
+00137         {
+00138 public:
+00139         CFibonacciThreadHandler(CConsoleBase* aConsole, CFibonacciEngine* aFibonacciEngine) ;
+00140         ~CFibonacciThreadHandler() ;
+00141 
+00142         void CalculateFibonacciL(TInt aIterations) ;
+00143 
+00144 private:
+00145         void DoCancel() ;
+00146         void RunL() ;
+00147         static TInt FibonacciThread(TAny* aParameters) ;
+00148 
+00149 private:
+00150         CConsoleBase* iConsole ;
+00151         TFibonacciParameters iFibonacciParameters ;
+00152         CFibonacciEngine* iFibonacciEngine ;
+00153         };
+00154 
+00155 
+00157 //
+00158 // -----> CFibonacciKeyHandler (definition)
+00159 //
+00160 // This class encapsulates the fibonacci keyboard handler
+00161 //
+00163 
+00164 class CFibonacciKeyHandler : public CActiveConsole
+00165         {
+00166 public:
+00167         CFibonacciKeyHandler(   CConsoleBase* aConsole, 
+00168                                                         CFibonacciThreadHandler* iThreadHandler) ;
+00169         void ConstructL();
+00170 
+00171           // Static construction
+00172         static CFibonacciKeyHandler* NewLC(CConsoleBase* aConsole, CFibonacciThreadHandler* aHandler) ;
+00173 
+00174           // service request
+00175         void ProcessKeyPress(TChar aChar) ;
+00176 
+00177 private:
+00178         CConsoleBase* iConsole ;
+00179         CFibonacciThreadHandler* iThreadHandler ;
+00180         };
+00181 
+00182 
+00183 
+00184 
+00186 //
+00187 // -----> CActiveConsole (implementation)
+00188 //
+00190 CActiveConsole::CActiveConsole( CConsoleBase* aConsole) 
+00191         : CActive(CActive::EPriorityUserInput)
+00192           // Construct high-priority active object
+00193         {
+00194         iConsole = aConsole;
+00195         }
+00196 
+00197 void CActiveConsole::ConstructL()
+00198         {
+00199           // Add to active scheduler
+00200         CActiveScheduler::Add(this);
+00201         }
+00202 
+00203 CActiveConsole::~CActiveConsole()
+00204         {
+00205         // Make sure we're cancelled
+00206         Cancel();
+00207         }
+00208 
+00209 void  CActiveConsole::DoCancel()
+00210         {
+00211         iConsole->ReadCancel();
+00212         }
+00213 
+00214 void  CActiveConsole::RunL()
+00215         {
+00216           // Handle completed request
+00217         ProcessKeyPress(TChar(iConsole->KeyCode()));
+00218         }
+00219 
+00220 void CActiveConsole::RequestCharacter()
+00221         {
+00222           // A request is issued to the CConsoleBase to accept a
+00223           // character from the keyboard.
+00224         iConsole->Read(iStatus); 
+00225         SetActive();
+00226         }
+00227 
+00228 
+00230 //
+00231 // -----> CExampleScheduler (implementation)
+00232 //
+00234 void CExampleScheduler::Error(TInt aError) const
+00235         {
+00236         _LIT(KTxtSchedulerError,"CExampleScheduler - error");
+00237         User::Panic(KTxtSchedulerError,aError);
+00238         }
+00239 
+00240 
+00241 void CExampleScheduler::WaitForAnyRequest()
+00242         {
+00243         if (!(iActiveConsole->IsActive()))
+00244                 iActiveConsole->RequestCharacter();     
+00245         CActiveScheduler::WaitForAnyRequest();
+00246         }
+00247 
+00248 void CExampleScheduler::SetActiveObject(CActiveConsole* aActiveConsole)
+00249         {
+00250         iActiveConsole = aActiveConsole;
+00251         }
+00252 
+00253 
+00254 
+00255 
+00256 
+00258 // CFibonacciKeyHandler support routine
+00259 //   uses up arrow & down arrow to change number, Enter to select
+00261 
+00262 TInt GetValueFromKeyboard (TInt aInitial, TInt aStep, TInt lowerLimit, TInt upperLimit, const TDesC& aPrompt, CConsoleBase* aConsole)
+00263         {
+00264         TChar input ;
+00265         TInt value = aInitial ;
+00266 
+00267         aConsole->Printf(aPrompt) ;
+00268         do
+00269                 {
+00270                 aConsole->SetPos(0);
+00271                 _LIT(KFormat1,"%d  ");
+00272                 aConsole->Printf(KFormat1, value);
+00273                 input = aConsole->Getch() ;
+00274                 if (input == EKeyUpArrow && value < upperLimit) value = value + aStep ;
+00275                 if (input == EKeyDownArrow && value > lowerLimit) value = value - aStep ;
+00276                 }
+00277         while (input != EKeyEnter) ;
+00278 
+00279         return value ;
+00280         }
+00281 
+00282 
+00284 //
+00285 // -----> CFibonacciKeyHandler (implementation)
+00286 //
+00288 
+00289 
+00290 CFibonacciKeyHandler::CFibonacciKeyHandler(CConsoleBase* aConsole, CFibonacciThreadHandler* aThreadHandler )
+00291         : CActiveConsole(aConsole)
+00292           // construct zero-priority active object
+00293         {
+00294         iConsole = aConsole ;
+00295         iThreadHandler = aThreadHandler ;
+00296           // Add to active scheduler
+00297         CActiveScheduler::Add(this);
+00298           // Make this the active object
+00299         ((CExampleScheduler*)(CActiveScheduler::Current()))->SetActiveObject(this);
+00300         } 
+00301 
+00302 
+00303 void CFibonacciKeyHandler::ProcessKeyPress(TChar aChar)
+00304         {
+00305           // if key is ESC 
+00306           //   cancel any outstanding request
+00307           //   stop the scheduler
+00308         if (aChar == EKeyEscape)
+00309                 {
+00310                 CActiveScheduler::Stop();
+00311                 return;
+00312                 }
+00313 
+00314           // If key is "f" or "F"
+00315           //   cancel any outstanding request
+00316           //   issue a fibonacci request.
+00317         if (aChar == 'f' || aChar == 'F') 
+00318                 {
+00319                 _LIT(KTxtStartingFibonacci,"\nStarting Fibonacci....  \n");
+00320                 iConsole->Printf(KTxtStartingFibonacci);
+00321                 _LIT(KTxtReturnTermNumber,"\nENTER selects num\nUP    arrow increases num\nDOWN  arrow decreases num\n\n");
+00322                 TInt iterations = GetValueFromKeyboard(5,1,2,46, KTxtReturnTermNumber, iConsole) ;
+00323                 TRAPD(err,iThreadHandler->CalculateFibonacciL(iterations));
+00324                 if(err)
+00325                         {
+00326                                 _LIT(KFormat4,"CalculateFibonacciL failed: leave code=%d");
+00327                                 console->Printf(KFormat4, err); 
+00328                         }
+00329                 return;
+00330                 }
+00331 
+00332       // If key is "c" or "C" 
+00333           //    cancel any outstanding request  
+00334         if (aChar == 'c' || aChar == 'C')
+00335                 {
+00336                 _LIT(KTxtCancelFibonacci,"\nCancelling Fibonacci....  \n");
+00337                 iConsole->Printf(KTxtCancelFibonacci);
+00338                 iThreadHandler->Cancel();
+00339                 iConsole->Printf(KTxtMainInstructions);
+00340                 return;
+00341                 }
+00342 
+00343         _LIT(KTxtNotRecognised,"\nUnwanted key pressed");
+00344         iConsole->Printf(KTxtNotRecognised);
+00345         iConsole->Printf(KTxtMainInstructions);
+00346         }
+00347 
+00348 
+00350 //
+00351 // -----> CFibonacciThreadHandler (implementation)
+00352 //
+00354 
+00355 CFibonacciThreadHandler::CFibonacciThreadHandler(CConsoleBase* aConsole, CFibonacciEngine* aFibonacciEngine)
+00356 //
+00357 // Constructor
+00358 //
+00359         : CActive(EPriorityStandard)
+00360         {
+00361         iConsole = aConsole ;
+00362         iFibonacciEngine = aFibonacciEngine ;
+00363         CActiveScheduler::Add(this);
+00364         };
+00365 
+00366 
+00367 // destructor
+00368 CFibonacciThreadHandler::~CFibonacciThreadHandler() 
+00369         {
+00370         // cancel any requests and tell server 
+00371         Cancel() ;
+00372         }
+00373 
+00374 
+00375 void CFibonacciThreadHandler::DoCancel() 
+00376         {
+00377         // cancel the active object request 
+00378         RThread thread ;
+00379         thread.Open(KTxtFibThread) ;
+00380         thread.Close() ;
+00381         }
+00382 
+00383 
+00384 void CFibonacciThreadHandler::RunL() 
+00385         {
+00386         // handle requests - print out result and flag as handled (ie not cancelled)
+00387         _LIT(KFormat2,"    Result : %u \n");  //not used
+00388         iConsole->Printf(KFormat2, iFibonacciParameters.iResult) ;
+00389         iConsole->Printf(KTxtMainInstructions);
+00390         }
+00391 
+00392 
+00393 // initiate a request
+00394 void CFibonacciThreadHandler::CalculateFibonacciL(TInt aIterations)
+00395         {
+00396         const TInt KHeapSize = 0x800 ;
+00397         
+00398         _LIT(KTxtFibRequested,"\nFibonacci requested ...  ");
+00399         iConsole->Printf(KTxtFibRequested);
+00400 
+00401 
+00402         RThread thread ;
+00403 
+00404         // set up parameters to thread
+00405 
+00406         iFibonacciParameters.iVar1 = aIterations ;
+00407         iFibonacciParameters.iVar2 = iFibonacciEngine ;
+00408 
+00409         // generate thread, leave if fails
+00410         
+00411         TInt result = thread.Create(KTxtFibThread,(TThreadFunction)FibonacciThread, KDefaultStackSize,
+00412                                                                 KMinHeapSize, KHeapSize, &iFibonacciParameters, EOwnerThread) ;
+00413         User::LeaveIfError(result) ;
+00414 
+00415         // log on to thread -   sets iStatus to KRequestPending 
+00416         //                                              requests notification of thread completion
+00417         thread.Logon(iStatus) ;
+00418 
+00419         // give thread low priority 
+00420         thread.SetPriority(EPriorityMuchLess) ;
+00421 
+00422         // resume thread (wake it up sometime after this function returns)
+00423         thread.Resume() ;
+00424 
+00425         thread.Close() ;
+00426 
+00427         // ensure scheduler checks status 
+00428         SetActive() ;
+00429         
+00430         _LIT(KTxtOK,"OK  \n");
+00431         iConsole->Printf(KTxtOK);
+00432         }
+00433 
+00434 
+00436 //  Thread routine that sorts out parameters & calls engine
+00438 
+00439 TInt CFibonacciThreadHandler::FibonacciThread(TAny* aParameters)
+00440         {
+00441         // cast the parameters pointer
+00442         TFibonacciParameters* parameters = (TFibonacciParameters*) aParameters ;
+00443 
+00444         // get variables from parameters class
+00445         TInt iterations = parameters->iVar1 ;
+00446         CFibonacciEngine* fibonacciEngine = (CFibonacciEngine*)parameters->iVar2 ;
+00447 
+00448         // call the engine
+00449         fibonacciEngine->Calculate(iterations) ;
+00450 
+00451         // store result
+00452         parameters->iResult = fibonacciEngine->iResult ;
+00453 
+00454         return KErrNone ;
+00455 }
+00456 
+00457 
+00459 //
+00460 // -----> CFibonacciEngine (implementation)
+00461 //
+00463 
+00464 void CFibonacciEngine::Calculate (TInt aTerms) 
+00465         {
+00466         TInt iterations = aTerms ;
+00467 
+00468         TInt currentTotal = 1 ;
+00469         TInt previousTotal = 0 ;
+00470         _LIT(KTxtTooManyIterations,"Too many iterations");
+00471         __ASSERT_ALWAYS(iterations<47,User::Panic(KTxtTooManyIterations,iterations));
+00472 
+00473 
+00474         // if limit not yet reached
+00475         while (iterations-- > 0)        
+00476                 {
+00477                 // calculate next number in series
+00478                 TInt newTotal = currentTotal + previousTotal ;
+00479 
+00480                 // update variables
+00481                 previousTotal = currentTotal ;
+00482                 currentTotal = newTotal ;
+00483 
+00484                 // introduce a delay
+00485                 User::After(1000000) ;
+00486                 }  
+00487 
+00488         iResult = currentTotal ;
+00489 
+00490 //UserHal::ModifyLedMask(1,2);
+00491         } 
+00492 
+00493 
+00495 // This section deals with initialisation and ensuring we have a console active
+00497 
+00498 void doExampleL () ;
+00499 
+00500 void SetupConsoleL();
+00501 
+00502 GLDEF_C TInt E32Main()                          // main function called by E32
+00503     {
+00504         CTrapCleanup* cleanup=CTrapCleanup::New();              // get clean-up stack
+00505         TRAPD(error,SetupConsoleL());                                   // more initialization, then do example
+00506         _LIT(KTxtFibonacciExampleError,"Fibonacci example error");
+00507         __ASSERT_ALWAYS(!error,User::Panic(KTxtFibonacciExampleError,error));
+00508         delete cleanup;                                                                 // destroy clean-up stack
+00509         return 0;                                                                               // and return
+00510     }
+00511 
+00512 void SetupConsoleL()                             // initialize and call example code under cleanup stack
+00513     {
+00514         _LIT(KTxtFibActObjInThread,"Active Object and thread");
+00515         console=Console::NewL(KTxtFibActObjInThread,TSize(KConsFullScreen,KConsFullScreen));
+00516         CleanupStack::PushL(console);
+00517         console->Printf(KTxtMainInstructions) ;
+00518         TRAPD(error, doExampleL());                                                     // perform example function
+00519         if (error)
+00520                 {
+00521                 _LIT(KFormat3,"failed: leave code=%d");
+00522                 console->Printf(KFormat3, error);
+00523                 }
+00524         _LIT(KTxtPressAnyKey,"[Press any key to exit]");
+00525         console->Printf(KTxtPressAnyKey);
+00526         console->Getch();                                                               // get and ignore character
+00527         CleanupStack::PopAndDestroy(console);                                   // close console
+00528     }
+00529 
+00530 
+00532 //
+00533 // Do the example
+00534 //
+00536 void doExampleL()
+00537     {
+00538           // Construct and install the active scheduler; push onto cleanup stack.
+00539         CExampleScheduler*  exampleScheduler = new (ELeave) CExampleScheduler;
+00540         CleanupStack::PushL(exampleScheduler);
+00541          
+00542           // Install as the active scheduler
+00543         CActiveScheduler::Install(exampleScheduler);
+00544 
+00545         // Create CFibonacciEngine active object; push onto cleanup stack.
+00546         CFibonacciEngine* fibEngine = new (ELeave) CFibonacciEngine ;
+00547     CleanupStack::PushL(fibEngine);
+00548 
+00549           // Create CFibonacciThreadHandler active object; push onto cleanup stack.
+00550         CFibonacciThreadHandler* fibThreadHandler = new (ELeave) CFibonacciThreadHandler(console, fibEngine);
+00551     CleanupStack::PushL(fibThreadHandler);
+00552         
+00553           // Create CFibonacciKeyHandler active object; push onto cleanup stack.
+00554         CFibonacciKeyHandler* fibKeyHandler = new (ELeave) CFibonacciKeyHandler(console, fibThreadHandler);
+00555     CleanupStack::PushL(fibKeyHandler); 
+00556 
+00557           // issue initial request; push onto cleanup stack
+00558         fibKeyHandler->RequestCharacter() ;
+00559                         
+00560         // Main part of the program:
+00561         //    wait loop that cycles until ActiveScheduler::Stop called
+00562         CActiveScheduler::Start();
+00563 
+00564         // Remove from the cleanup stack and destroy:
+00565         CleanupStack::PopAndDestroy(4); 
+00566         }
+00567 
+00568 
+00569 
+00570 
+

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