diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_fibonacci3_8cpp_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_fibonacci3_8cpp_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,541 @@ + + + + +TB9.2 Example Applications: examples/Base/IPC/Async/Fibonacci3/Fibonacci3.cpp Source File + + + + + +

examples/Base/IPC/Async/Fibonacci3/Fibonacci3.cpp

00001 // Copyright (c) 1997-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 as a background active object.
+00016 // The technique used is similar to, but not identical, to that used by CIdle, where
+00017 // the background active object is repeatedly called provided the other (higher priority)
+00018 // active objects are not ready to run. 
+00019 // Fibonacci Active Objects example
+00020 //
+00021 
+00022 #include <e32cons.h>
+00023 #include <e32base.h>
+00024 #include <e32std.h>
+00025 
+00027 //nclude <e32hal.h>
+00028 
+00029 
+00030 LOCAL_D CConsoleBase* console;
+00031 
+00032 _LIT(KTxtMainInstructions,"\n\nPress 'F' to start\n      'ESC' to exit\n      'C' to cancel, anytime\n");
+00033 
+00035 //
+00036 // -----> CActiveConsole (definition)
+00037 //
+00038 // An abstract class which provides the facility to issue key requests. 
+00039 //
+00041 class CActiveConsole : public CActive
+00042         {
+00043 public:
+00044           // Construction
+00045         CActiveConsole(CConsoleBase* aConsole);
+00046         void ConstructL();
+00047 
+00048           // Destruction
+00049         ~CActiveConsole();
+00050 
+00051           // Issue request
+00052         void RequestCharacter();
+00053         
+00054           // Cancel request.
+00055           // Defined as pure virtual by CActive;
+00056           // implementation provided by this class.
+00057         void DoCancel();
+00058 
+00059           // Service completed request.
+00060           // Defined as pure virtual by CActive;
+00061           // implementation provided by this class,
+00062         void RunL();
+00063 
+00064           // Called from RunL() - an implementation must be provided
+00065           // by derived classes to handle the completed request
+00066         virtual void ProcessKeyPress(TChar aChar) = 0; 
+00067           
+00068 protected:
+00069           // Data members defined by this class
+00070         CConsoleBase* iConsole; // A console for reading from
+00071         };
+00072 
+00073 
+00075 //
+00076 // -----> CExampleScheduler (definition)
+00077 //
+00079 class CActiveConsole;
+00080 
+00081 class CExampleScheduler : public CActiveScheduler
+00082         {
+00083 public:
+00084         void Error (TInt aError) const;
+00085         void WaitForAnyRequest();
+00086         void SetActiveObject(CActiveConsole* aActiveConsole);
+00087 private:
+00088           // data members defined for this class
+00089         CActiveConsole* iActiveConsole;
+00090         };
+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         CFibonacciEngine() ;
+00106         void StartCalculate (TInt aTerms) ;
+00107         void StepCalculate () ;
+00108         
+00109         TUint iResult ;
+00110 
+00111         enum TEngineState {eInactive, eCalculating, eCompleted}   ;
+00112         TEngineState iState ;
+00113 
+00114 private:
+00115         TUint iCurrentTotal ;
+00116         TUint iPreviousTotal ;
+00117         TInt iTermsLeftToDo ;
+00118         } ;
+00119 
+00120 
+00122 //
+00123 // -----> CFibonacciApplication (definition)
+00124 //
+00125 // This class encapsulates the fibonacci thread that runs the fibonacci engine
+00126 //
+00128 
+00129 class CFibonacciApplication : public CActive
+00130         {
+00131 public:
+00132         CFibonacciApplication(CConsoleBase* aConsole, CFibonacciEngine* aFibonacciEngine) ;
+00133         ~CFibonacciApplication() ;
+00134 
+00135         void CalculateFibonacci(TInt aIterations) ;
+00136 
+00137 private:
+00138         void DoCancel() ;
+00139         void RunL() ;
+00140 
+00141 private:
+00142         CConsoleBase* iConsole ;
+00143         CFibonacciEngine* iFibonacciEngine ;
+00144         } ;
+00145 
+00146 
+00148 //
+00149 // -----> CFibonacciKeyHandler (definition)
+00150 //
+00151 // This class encapsulates the fibonacci keyboard handler
+00152 //
+00154 
+00155 class CFibonacciKeyHandler : public CActiveConsole
+00156         {
+00157 public:
+00158         CFibonacciKeyHandler(   CConsoleBase* aConsole, 
+00159                                                         CFibonacciApplication* aApplication) ;
+00160         void ConstructL();
+00161 
+00162           // Static construction
+00163         static CFibonacciKeyHandler* NewLC(CConsoleBase* aConsole, CFibonacciApplication* aHandler) ;
+00164 
+00165           // service request
+00166         void ProcessKeyPress(TChar aChar) ;
+00167 
+00168 private:
+00169         CConsoleBase* iConsole ;
+00170         CFibonacciApplication* iApplication ;
+00171         };
+00172 
+00173 
+00175 //
+00176 // -----> CActiveConsole (implementation)
+00177 //
+00179 CActiveConsole::CActiveConsole( CConsoleBase* aConsole) 
+00180         : CActive(CActive::EPriorityUserInput)
+00181           // Construct high-priority active object
+00182         {
+00183         iConsole = aConsole;
+00184         __DECLARE_NAME(_S("CActiveConsole"));
+00185 
+00186         }
+00187 
+00188 void CActiveConsole::ConstructL()
+00189         {
+00190           // Add to active scheduler
+00191         CActiveScheduler::Add(this);
+00192         }
+00193 
+00194 CActiveConsole::~CActiveConsole()
+00195         {
+00196         // Make sure we're cancelled
+00197         Cancel();
+00198         }
+00199 
+00200 void  CActiveConsole::DoCancel()
+00201         {
+00202         iConsole->ReadCancel();
+00203         }
+00204 
+00205 void  CActiveConsole::RunL()
+00206         {
+00207           // Handle completed request
+00208         ProcessKeyPress(TChar(iConsole->KeyCode()));
+00209         }
+00210 
+00211 void CActiveConsole::RequestCharacter()
+00212         {
+00213           // A request is issued to the CConsoleBase to accept a
+00214           // character from the keyboard.
+00215         iConsole->Read(iStatus); 
+00216         SetActive();
+00217         }
+00218 
+00219 
+00221 //
+00222 // -----> CExampleScheduler (implementation)
+00223 //
+00225 void CExampleScheduler::Error(TInt aError) const
+00226         {
+00227         _LIT(KTxtSchedulerError,"CExampleScheduler - error");
+00228         User::Panic(KTxtSchedulerError,aError);
+00229         }
+00230 
+00231 
+00232 void CExampleScheduler::WaitForAnyRequest()
+00233         {
+00234         if (!(iActiveConsole->IsActive()))
+00235                 iActiveConsole->RequestCharacter();     
+00236         CActiveScheduler::WaitForAnyRequest();
+00237         }
+00238 
+00239 void CExampleScheduler::SetActiveObject(CActiveConsole* aActiveConsole)
+00240         {
+00241         iActiveConsole = aActiveConsole;
+00242         }
+00243 
+00244 
+00245 
+00247 // CFibonacciKeyHandler support routine
+00248 //   uses up arrow & down arrow to change number, Enter to select
+00250 
+00251 TInt GetValueFromKeyboard (TInt aInitial, TInt aStep, TInt lowerLimit, TInt upperLimit, const TDesC& aPrompt, CConsoleBase* aConsole)
+00252         {
+00253         TChar input ;
+00254         TInt value = aInitial ;
+00255 
+00256         aConsole->Printf(aPrompt) ;
+00257         do
+00258                 {
+00259                 aConsole->SetPos(0);
+00260                 _LIT(KFormat1,"%d  ");
+00261                 aConsole->Printf(KFormat1, value);
+00262                 input = aConsole->Getch() ;
+00263                 if (input == EKeyUpArrow && value < upperLimit) value = value + aStep ;
+00264                 if (input == EKeyDownArrow && value > lowerLimit) value = value - aStep ;
+00265                 }
+00266         while (input != EKeyEnter) ;
+00267 
+00268         return value ;
+00269         }
+00270 
+00271 
+00273 //
+00274 // -----> CFibonacciKeyHandler (implementation)
+00275 //
+00277 
+00278 CFibonacciKeyHandler::CFibonacciKeyHandler(CConsoleBase* aConsole, CFibonacciApplication* aApplication)
+00279         : CActiveConsole(aConsole)
+00280           // construct zero-priority active object
+00281         {
+00282         iConsole = aConsole ;
+00283         iApplication = aApplication ;
+00284 
+00285         __DECLARE_NAME(_S("CFibonacciApplication"));
+00286           // Add to active scheduler
+00287         CActiveScheduler::Add(this);
+00288           // Make this the active object
+00289         ((CExampleScheduler*)(CActiveScheduler::Current()))->SetActiveObject(this);
+00290         } 
+00291 
+00292 
+00293 void CFibonacciKeyHandler::ProcessKeyPress(TChar aChar)
+00294         {
+00295           // if key is ESC, cancel any outstanding request & stop the scheduler
+00296         if (aChar == EKeyEscape)
+00297                 {
+00298                 CActiveScheduler::Stop();
+00299                 return;
+00300                 }
+00301 
+00302           // If key is "f" or "F", issue a Fibonacci request if none is in progress
+00303         if (aChar == 'f' || aChar == 'F') 
+00304                 {
+00305                 if (!(iApplication->IsActive()))
+00306                         {
+00307                         _LIT(KTxtReturnTermNumber,"\nENTER selects num\nUP    arrow increases num\nDOWN  arrow decreases num\n\n");
+00308                         TInt iterations = GetValueFromKeyboard(5,1,2,46, KTxtReturnTermNumber, iConsole) ;
+00309                         iApplication->CalculateFibonacci(iterations);
+00310                         }
+00311                 else
+00312                         {
+00313                         _LIT(KTxtAlreadyInProgress,"[Already in progress]");
+00314                         iConsole->Printf(KTxtAlreadyInProgress);
+00315                         }
+00316                 return;
+00317                 }
+00318 
+00319       // If key is "c" or "C", cancel any outstanding request   
+00320         if (aChar == 'c' || aChar == 'C')
+00321                 {
+00322                 _LIT(KTxtCancelFibonacci,"\nCancelling Fibonacci....  \n");
+00323                 iConsole->Printf(KTxtCancelFibonacci);
+00324                 iApplication->Cancel();
+00325                 iConsole->Printf(KTxtMainInstructions);
+00326                 return;
+00327                 }
+00328         
+00329         _LIT(KTxtNotRecognised,"\nUnwanted key pressed");
+00330         iConsole->Printf(KTxtNotRecognised);
+00331         iConsole->Printf(KTxtMainInstructions);
+00332         }
+00333 
+00334 
+00336 //
+00337 // -----> CFibonacciApplication (implementation)
+00338 //
+00340 
+00341 CFibonacciApplication::CFibonacciApplication(CConsoleBase* aConsole, CFibonacciEngine* aFibonacciEngine)
+00342 //
+00343 // Constructor
+00344 //
+00345         : CActive(EPriorityStandard)
+00346         {
+00347         iConsole = aConsole ;
+00348         iFibonacciEngine = aFibonacciEngine ;
+00349         CActiveScheduler::Add(this);
+00350         __DECLARE_NAME(_S("CFibonacciApplication"));
+00351         };
+00352 
+00353 
+00354 // destructor
+00355 CFibonacciApplication::~CFibonacciApplication() 
+00356         {
+00357         // cancel any requests and tell server 
+00358         Cancel() ;
+00359         }
+00360 
+00361 
+00362 void CFibonacciApplication::DoCancel() 
+00363         {
+00364         // cancel the active object request 
+00365         iFibonacciEngine->iState = CFibonacciEngine::eInactive ;
+00366         }
+00367 
+00368 
+00369 
+00370 // initiate a request
+00371 void CFibonacciApplication::CalculateFibonacci(TInt aIterations)
+00372         {
+00373         // initialize engine
+00374         // no neeed to set iStatus to KRequestPending, as request completes below
+00375         iFibonacciEngine->StartCalculate(aIterations) ;
+00376 
+00377         // schedule the request
+00378         SetActive() ;
+00379 
+00380         // send signal that this request has completed
+00381         TRequestStatus* status = &iStatus ;
+00382         User::RequestComplete(status, KErrNone) ;
+00383         }
+00384 
+00385 
+00386 
+00387 void CFibonacciApplication::RunL() 
+00388 // implements a simple state engine: {eInactive, eCalculating, eCompleted}
+00389         {
+00390         if (iFibonacciEngine->iState == CFibonacciEngine::eInactive )
+00391                 {
+00392                 _LIT(KTxtEngineNotInitialized,"Engine not initialized");
+00393                 User::Panic(KTxtEngineNotInitialized, KErrNotReady) ;
+00394                 }
+00395         else if (iFibonacciEngine->iState == CFibonacciEngine::eCalculating )
+00396                 {               
+00397                 // unnecessary - just provides feedback on progression of the calculation
+00398                 _LIT(KTxtDot,".");
+00399                 iConsole->Printf(KTxtDot) ;
+00400 
+00401                 // no neeed to set iStatus to KRequestPending, as request completes below
+00402 
+00403                 // request next step
+00404                 iFibonacciEngine->StepCalculate() ;
+00405 
+00406                 // schedule request
+00407                 SetActive() ;
+00408 
+00409                 // send signal that this request has completed
+00410                 TRequestStatus* status = &iStatus ;
+00411                 User::RequestComplete(status, KErrNone) ;
+00412                 }
+00413         else if (iFibonacciEngine->iState == CFibonacciEngine::eCompleted )
+00414                 {
+00415                 // finished calculation: print result and reset state engine
+00416                 _LIT(KFormat2,"\n    Result : %u \n");  //not used
+00417                 iConsole->Printf(KFormat2, iFibonacciEngine->iResult) ; 
+00418                 iConsole->Printf(KTxtMainInstructions) ; 
+00419                 iFibonacciEngine->iState = CFibonacciEngine::eInactive ;
+00420                 }
+00421         }
+00422 
+00423 
+00424 
+00426 //
+00427 // -----> CFibonacciEngine (implementation)
+00428 //
+00430 CFibonacciEngine::CFibonacciEngine() 
+00431         {
+00432         iState = eInactive ;
+00433         }
+00434 
+00435 
+00436 void CFibonacciEngine::StartCalculate (TInt aTerms) 
+00437         {
+00438         // initialise all internal variables to initial state
+00439         iCurrentTotal = 1 ;
+00440         iPreviousTotal = 0 ;
+00441         iResult = 0 ;
+00442         iTermsLeftToDo = aTerms + 1 ;   // first step completed in variable initialization
+00443         iState = eCalculating ;
+00444         }
+00445 
+00446 
+00447 
+00448 void CFibonacciEngine::StepCalculate () 
+00449         {
+00450 
+00451         // if full calculation not yet complete, but in progress (i.e. not cancelled)
+00452         if (--iTermsLeftToDo > 0 && iState == eCalculating)     
+00453                 {
+00454                 // calculate next number in series
+00455                 TInt newTotal = iCurrentTotal + iPreviousTotal ;
+00456 
+00457                 // update internal variables
+00458                 iPreviousTotal = iCurrentTotal ;
+00459                 iCurrentTotal = newTotal ;
+00460 
+00461                 // introduce a delay to make us a long-running service
+00462                 User::After(1000000) ;
+00463 
+00464                 // not necessary, but allows running total to be used during the calculation
+00465                 // (say for putting values into a chart or graph)
+00466                 iResult = iCurrentTotal ;
+00467                 }
+00468         else if (iTermsLeftToDo <= 0)
+00469                 {
+00470                 // flag that calculation has finished and ensure final result is available
+00471                 iState = eCompleted ;
+00472                 iResult = iCurrentTotal ;
+00473                 }
+00474         } 
+00475 
+00476 
+00477 
+00479 // This section deals with initialisation and ensuring we have a console active
+00481 
+00482 void doExampleL () ;
+00483 
+00484 void SetupConsoleL();
+00485 
+00486 GLDEF_C TInt E32Main()                          // main function called by E32
+00487     {
+00488         CTrapCleanup* cleanup=CTrapCleanup::New();              // get clean-up stack
+00489         TRAPD(error,SetupConsoleL());                           // more initialization, then do example
+00490         _LIT(KTxtFibonacciExampleError,"Fibonacci example error");
+00491         __ASSERT_ALWAYS(!error,User::Panic(KTxtFibonacciExampleError,error));
+00492         delete cleanup;                                         // destroy clean-up stack
+00493         return 0;                                                                               // and return
+00494     }
+00495 
+00496 void SetupConsoleL()                             // initialize and call example code under cleanup stack
+00497     {
+00498         _LIT(KTxtFibActObjBackground,"Background Active Object");
+00499         console=Console::NewL(KTxtFibActObjBackground, TSize(KConsFullScreen,KConsFullScreen));
+00500         CleanupStack::PushL(console);
+00501         console->Printf(KTxtMainInstructions) ;
+00502         TRAPD(error, doExampleL());                                                     // perform example function
+00503         if (error)
+00504                 {
+00505                 _LIT(KFormat3,"failed: leave code=%d");
+00506                 console->Printf(KFormat3, error);
+00507                 }
+00508         _LIT(KTxtPressAnyKey,"[Press any key to exit]");
+00509         console->Printf(KTxtPressAnyKey);
+00510         console->Getch();                                                               // get and ignore character
+00511         CleanupStack::PopAndDestroy();                                  // close console
+00512     }
+00513 
+00514 
+00516 //
+00517 // Do the example
+00518 //
+00520 void doExampleL()
+00521     {
+00522           // Construct and install the active scheduler; push onto the cleanup stack
+00523         CExampleScheduler*  exampleScheduler = new (ELeave) CExampleScheduler;
+00524         CleanupStack::PushL(exampleScheduler);
+00525          
+00526           // Install as the active scheduler
+00527         CActiveScheduler::Install(exampleScheduler);
+00528 
+00529         // Create CFibonacciEngine active object; push onto the cleanup stack
+00530         CFibonacciEngine* fibEngine = new (ELeave) CFibonacciEngine ;
+00531     CleanupStack::PushL(fibEngine);
+00532     
+00533           // Create CFibonacciApplication handler active object; push onto the cleanup stack
+00534         CFibonacciApplication* fibApplication = new CFibonacciApplication(console, fibEngine);
+00535     CleanupStack::PushL(fibApplication);
+00536 
+00537           // Create CFibonacciKeyHandler active object; push onto the cleanup stack
+00538         CFibonacciKeyHandler* fibKeyHandler = new CFibonacciKeyHandler(console, fibApplication);
+00539     CleanupStack::PushL(fibKeyHandler);
+00540 
+00541           // issue initial request
+00542         fibKeyHandler->RequestCharacter() ;
+00543                         
+00544         // Main part of the program:
+00545         //    wait loop that cycles until ActiveScheduler::Stop called
+00546         CActiveScheduler::Start();
+00547            
+00548         // Remove items from the cleanup stack and destroy them
+00549         CleanupStack::PopAndDestroy(4); 
+00550         }
+00551 
+00552 
+
+
Generated by  + +doxygen 1.6.2
+ +