diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_fibonacci2_8cpp-source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_fibonacci2_8cpp-source.html Tue Mar 30 11:56:28 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,552 +0,0 @@ - -
-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 -