00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <e32std.h>
00023 #include <e32cons.h>
00024 #include <e32base.h>
00025
00026
00027
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
00039
00040
00041
00043 class CActiveConsole : public CActive
00044 {
00045 public:
00046
00047 CActiveConsole(CConsoleBase* aConsole);
00048 void ConstructL();
00049
00050
00051 ~CActiveConsole();
00052
00053
00054 void RequestCharacter();
00055
00056
00057
00058
00059 void DoCancel();
00060
00061
00062
00063
00064 void RunL();
00065
00066
00067
00068 virtual void ProcessKeyPress(TChar aChar) = 0;
00069
00070 protected:
00071
00072 CConsoleBase* iConsole;
00073 };
00074
00075
00077
00078
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
00090 CActiveConsole* iActiveConsole;
00091 };
00092
00093
00095
00096
00097
00098
00099
00101
00102 class CFibonacciEngine : public CBase
00103 {
00104 public:
00105 void Calculate (TInt aTerms) ;
00106
00107 TUint iResult ;
00108 } ;
00109
00110
00112
00113
00114
00115
00116
00118
00119 class TFibonacciParameters
00120 {
00121 public:
00122 TInt iVar1 ;
00123 TAny* iVar2 ;
00124 TUint iResult ;
00125 } ;
00126
00127
00129
00130
00131
00132
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
00159
00160
00161
00163
00164 class CFibonacciKeyHandler : public CActiveConsole
00165 {
00166 public:
00167 CFibonacciKeyHandler( CConsoleBase* aConsole,
00168 CFibonacciThreadHandler* iThreadHandler) ;
00169 void ConstructL();
00170
00171
00172 static CFibonacciKeyHandler* NewLC(CConsoleBase* aConsole, CFibonacciThreadHandler* aHandler) ;
00173
00174
00175 void ProcessKeyPress(TChar aChar) ;
00176
00177 private:
00178 CConsoleBase* iConsole ;
00179 CFibonacciThreadHandler* iThreadHandler ;
00180 };
00181
00182
00183
00184
00186
00187
00188
00190 CActiveConsole::CActiveConsole( CConsoleBase* aConsole)
00191 : CActive(CActive::EPriorityUserInput)
00192
00193 {
00194 iConsole = aConsole;
00195 }
00196
00197 void CActiveConsole::ConstructL()
00198 {
00199
00200 CActiveScheduler::Add(this);
00201 }
00202
00203 CActiveConsole::~CActiveConsole()
00204 {
00205
00206 Cancel();
00207 }
00208
00209 void CActiveConsole::DoCancel()
00210 {
00211 iConsole->ReadCancel();
00212 }
00213
00214 void CActiveConsole::RunL()
00215 {
00216
00217 ProcessKeyPress(TChar(iConsole->KeyCode()));
00218 }
00219
00220 void CActiveConsole::RequestCharacter()
00221 {
00222
00223
00224 iConsole->Read(iStatus);
00225 SetActive();
00226 }
00227
00228
00230
00231
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
00259
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
00286
00288
00289
00290 CFibonacciKeyHandler::CFibonacciKeyHandler(CConsoleBase* aConsole, CFibonacciThreadHandler* aThreadHandler )
00291 : CActiveConsole(aConsole)
00292
00293 {
00294 iConsole = aConsole ;
00295 iThreadHandler = aThreadHandler ;
00296
00297 CActiveScheduler::Add(this);
00298
00299 ((CExampleScheduler*)(CActiveScheduler::Current()))->SetActiveObject(this);
00300 }
00301
00302
00303 void CFibonacciKeyHandler::ProcessKeyPress(TChar aChar)
00304 {
00305
00306
00307
00308 if (aChar == EKeyEscape)
00309 {
00310 CActiveScheduler::Stop();
00311 return;
00312 }
00313
00314
00315
00316
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
00333
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
00352
00354
00355 CFibonacciThreadHandler::CFibonacciThreadHandler(CConsoleBase* aConsole, CFibonacciEngine* aFibonacciEngine)
00356
00357
00358
00359 : CActive(EPriorityStandard)
00360 {
00361 iConsole = aConsole ;
00362 iFibonacciEngine = aFibonacciEngine ;
00363 CActiveScheduler::Add(this);
00364 };
00365
00366
00367
00368 CFibonacciThreadHandler::~CFibonacciThreadHandler()
00369 {
00370
00371 Cancel() ;
00372 }
00373
00374
00375 void CFibonacciThreadHandler::DoCancel()
00376 {
00377
00378 RThread thread ;
00379 thread.Open(KTxtFibThread) ;
00380 thread.Close() ;
00381 }
00382
00383
00384 void CFibonacciThreadHandler::RunL()
00385 {
00386
00387 _LIT(KFormat2," Result : %u \n");
00388 iConsole->Printf(KFormat2, iFibonacciParameters.iResult) ;
00389 iConsole->Printf(KTxtMainInstructions);
00390 }
00391
00392
00393
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
00405
00406 iFibonacciParameters.iVar1 = aIterations ;
00407 iFibonacciParameters.iVar2 = iFibonacciEngine ;
00408
00409
00410
00411 TInt result = thread.Create(KTxtFibThread,(TThreadFunction)FibonacciThread, KDefaultStackSize,
00412 KMinHeapSize, KHeapSize, &iFibonacciParameters, EOwnerThread) ;
00413 User::LeaveIfError(result) ;
00414
00415
00416
00417 thread.Logon(iStatus) ;
00418
00419
00420 thread.SetPriority(EPriorityMuchLess) ;
00421
00422
00423 thread.Resume() ;
00424
00425 thread.Close() ;
00426
00427
00428 SetActive() ;
00429
00430 _LIT(KTxtOK,"OK \n");
00431 iConsole->Printf(KTxtOK);
00432 }
00433
00434
00436
00438
00439 TInt CFibonacciThreadHandler::FibonacciThread(TAny* aParameters)
00440 {
00441
00442 TFibonacciParameters* parameters = (TFibonacciParameters*) aParameters ;
00443
00444
00445 TInt iterations = parameters->iVar1 ;
00446 CFibonacciEngine* fibonacciEngine = (CFibonacciEngine*)parameters->iVar2 ;
00447
00448
00449 fibonacciEngine->Calculate(iterations) ;
00450
00451
00452 parameters->iResult = fibonacciEngine->iResult ;
00453
00454 return KErrNone ;
00455 }
00456
00457
00459
00460
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
00475 while (iterations-- > 0)
00476 {
00477
00478 TInt newTotal = currentTotal + previousTotal ;
00479
00480
00481 previousTotal = currentTotal ;
00482 currentTotal = newTotal ;
00483
00484
00485 User::After(1000000) ;
00486 }
00487
00488 iResult = currentTotal ;
00489
00490
00491 }
00492
00493
00495
00497
00498 void doExampleL () ;
00499
00500 void SetupConsoleL();
00501
00502 GLDEF_C TInt E32Main()
00503 {
00504 CTrapCleanup* cleanup=CTrapCleanup::New();
00505 TRAPD(error,SetupConsoleL());
00506 _LIT(KTxtFibonacciExampleError,"Fibonacci example error");
00507 __ASSERT_ALWAYS(!error,User::Panic(KTxtFibonacciExampleError,error));
00508 delete cleanup;
00509 return 0;
00510 }
00511
00512 void SetupConsoleL()
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());
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();
00527 CleanupStack::PopAndDestroy(console);
00528 }
00529
00530
00532
00533
00534
00536 void doExampleL()
00537 {
00538
00539 CExampleScheduler* exampleScheduler = new (ELeave) CExampleScheduler;
00540 CleanupStack::PushL(exampleScheduler);
00541
00542
00543 CActiveScheduler::Install(exampleScheduler);
00544
00545
00546 CFibonacciEngine* fibEngine = new (ELeave) CFibonacciEngine ;
00547 CleanupStack::PushL(fibEngine);
00548
00549
00550 CFibonacciThreadHandler* fibThreadHandler = new (ELeave) CFibonacciThreadHandler(console, fibEngine);
00551 CleanupStack::PushL(fibThreadHandler);
00552
00553
00554 CFibonacciKeyHandler* fibKeyHandler = new (ELeave) CFibonacciKeyHandler(console, fibThreadHandler);
00555 CleanupStack::PushL(fibKeyHandler);
00556
00557
00558 fibKeyHandler->RequestCharacter() ;
00559
00560
00561
00562 CActiveScheduler::Start();
00563
00564
00565 CleanupStack::PopAndDestroy(4);
00566 }
00567
00568
00569
00570