00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <e32std.h>
00038 #include <e32cons.h>
00039 #include <e32base.h>
00040
00041
00042
00043
00044 _LIT(KTxtFibThread,"FibThread");
00045
00046
00047 LOCAL_D CConsoleBase* console;
00048
00049 _LIT(KTxtMainInstructions,"\n\nPress 'F' to start\n 'ESC' to exit\n 'C' to cancel, anytime\n");
00050
00052
00053
00054
00055
00056
00058 class CActiveConsole : public CActive
00059 {
00060 public:
00061
00062 CActiveConsole(CConsoleBase* aConsole);
00063 void ConstructL();
00064
00065
00066 ~CActiveConsole();
00067
00068
00069 void RequestCharacter();
00070
00071
00072
00073
00074 void DoCancel();
00075
00076
00077
00078
00079 void RunL();
00080
00081
00082
00083 virtual void ProcessKeyPress(TChar aChar) = 0;
00084
00085 protected:
00086
00087 CConsoleBase* iConsole;
00088 };
00089
00090
00092
00093
00094
00096
00097 class CExampleScheduler : public CActiveScheduler
00098 {
00099 public:
00100 void Error (TInt aError) const;
00101 void WaitForAnyRequest();
00102 void SetActiveObject(CActiveConsole* aActiveConsole);
00103 private:
00104
00105 CActiveConsole* iActiveConsole;
00106 };
00107
00108
00110
00111
00112
00113
00114
00116
00117 class CFibonacciEngine : public CBase
00118 {
00119 public:
00120 void Calculate (TInt aTerms) ;
00121
00122 TUint iResult ;
00123 } ;
00124
00125
00127
00128
00129
00130
00131
00133
00134 class TFibonacciParameters
00135 {
00136 public:
00137 TInt iVar1 ;
00138 TAny* iVar2 ;
00139 TUint iResult ;
00140 } ;
00141
00142
00144
00145
00146
00147
00148
00150
00151 class CFibonacciThreadHandler : public CActive
00152 {
00153 public:
00154 CFibonacciThreadHandler(CConsoleBase* aConsole, CFibonacciEngine* aFibonacciEngine) ;
00155 ~CFibonacciThreadHandler() ;
00156
00157 void CalculateFibonacciL(TInt aIterations) ;
00158
00159 private:
00160 void DoCancel() ;
00161 void RunL() ;
00162 static TInt FibonacciThread(TAny* aParameters) ;
00163
00164 private:
00165 CConsoleBase* iConsole ;
00166 TFibonacciParameters iFibonacciParameters ;
00167 CFibonacciEngine* iFibonacciEngine ;
00168 };
00169
00170
00172
00173
00174
00175
00176
00178
00179 class CFibonacciKeyHandler : public CActiveConsole
00180 {
00181 public:
00182 CFibonacciKeyHandler( CConsoleBase* aConsole,
00183 CFibonacciThreadHandler* iThreadHandler) ;
00184 void ConstructL();
00185
00186
00187 static CFibonacciKeyHandler* NewLC(CConsoleBase* aConsole, CFibonacciThreadHandler* aHandler) ;
00188
00189
00190 void ProcessKeyPress(TChar aChar) ;
00191
00192 private:
00193 CConsoleBase* iConsole ;
00194 CFibonacciThreadHandler* iThreadHandler ;
00195 };
00196
00197
00198
00199
00201
00202
00203
00205 CActiveConsole::CActiveConsole( CConsoleBase* aConsole)
00206 : CActive(CActive::EPriorityUserInput)
00207
00208 {
00209 iConsole = aConsole;
00210 }
00211
00212 void CActiveConsole::ConstructL()
00213 {
00214
00215 CActiveScheduler::Add(this);
00216 }
00217
00218 CActiveConsole::~CActiveConsole()
00219 {
00220
00221 Cancel();
00222 }
00223
00224 void CActiveConsole::DoCancel()
00225 {
00226 iConsole->ReadCancel();
00227 }
00228
00229 void CActiveConsole::RunL()
00230 {
00231
00232 ProcessKeyPress(TChar(iConsole->KeyCode()));
00233 }
00234
00235 void CActiveConsole::RequestCharacter()
00236 {
00237
00238
00239 iConsole->Read(iStatus);
00240 SetActive();
00241 }
00242
00243
00245
00246
00247
00249 void CExampleScheduler::Error(TInt aError) const
00250 {
00251 _LIT(KTxtSchedulerError,"CExampleScheduler - error");
00252 User::Panic(KTxtSchedulerError,aError);
00253 }
00254
00255
00256 void CExampleScheduler::WaitForAnyRequest()
00257 {
00258 if (!(iActiveConsole->IsActive()))
00259 iActiveConsole->RequestCharacter();
00260 CActiveScheduler::WaitForAnyRequest();
00261 }
00262
00263 void CExampleScheduler::SetActiveObject(CActiveConsole* aActiveConsole)
00264 {
00265 iActiveConsole = aActiveConsole;
00266 }
00267
00268
00269
00270
00271
00273
00274
00276
00277 TInt GetValueFromKeyboard (TInt aInitial, TInt aStep, TInt lowerLimit, TInt upperLimit, const TDesC& aPrompt, CConsoleBase* aConsole)
00278 {
00279 TChar input ;
00280 TInt value = aInitial ;
00281
00282 aConsole->Printf(aPrompt) ;
00283 do
00284 {
00285 aConsole->SetPos(0);
00286 _LIT(KFormat1,"%d ");
00287 aConsole->Printf(KFormat1, value);
00288 input = aConsole->Getch() ;
00289 if (input == EKeyUpArrow && value < upperLimit) value = value + aStep ;
00290 if (input == EKeyDownArrow && value > lowerLimit) value = value - aStep ;
00291 }
00292 while (input != EKeyEnter) ;
00293
00294 return value ;
00295 }
00296
00297
00299
00300
00301
00303
00304
00305 CFibonacciKeyHandler::CFibonacciKeyHandler(CConsoleBase* aConsole, CFibonacciThreadHandler* aThreadHandler )
00306 : CActiveConsole(aConsole)
00307
00308 {
00309 iConsole = aConsole ;
00310 iThreadHandler = aThreadHandler ;
00311
00312 CActiveScheduler::Add(this);
00313
00314 ((CExampleScheduler*)(CActiveScheduler::Current()))->SetActiveObject(this);
00315 }
00316
00317
00318 void CFibonacciKeyHandler::ProcessKeyPress(TChar aChar)
00319 {
00320
00321
00322
00323 if (aChar == EKeyEscape)
00324 {
00325 CActiveScheduler::Stop();
00326 return;
00327 }
00328
00329
00330
00331
00332 if (aChar == 'f' || aChar == 'F')
00333 {
00334 _LIT(KTxtStartingFibonacci,"\nStarting Fibonacci.... \n");
00335 iConsole->Printf(KTxtStartingFibonacci);
00336 _LIT(KTxtReturnTermNumber,"\nENTER selects num\nUP arrow increases num\nDOWN arrow decreases num\n\n");
00337 TInt iterations = GetValueFromKeyboard(5,1,2,46, KTxtReturnTermNumber, iConsole) ;
00338 TRAPD(err,iThreadHandler->CalculateFibonacciL(iterations));
00339 if(err)
00340 {
00341 _LIT(KFormat4,"CalculateFibonacciL failed: leave code=%d");
00342 console->Printf(KFormat4, err);
00343 }
00344 return;
00345 }
00346
00347
00348
00349 if (aChar == 'c' || aChar == 'C')
00350 {
00351 _LIT(KTxtCancelFibonacci,"\nCancelling Fibonacci.... \n");
00352 iConsole->Printf(KTxtCancelFibonacci);
00353 iThreadHandler->Cancel();
00354 iConsole->Printf(KTxtMainInstructions);
00355 return;
00356 }
00357
00358 _LIT(KTxtNotRecognised,"\nUnwanted key pressed");
00359 iConsole->Printf(KTxtNotRecognised);
00360 iConsole->Printf(KTxtMainInstructions);
00361 }
00362
00363
00365
00366
00367
00369
00370 CFibonacciThreadHandler::CFibonacciThreadHandler(CConsoleBase* aConsole, CFibonacciEngine* aFibonacciEngine)
00371
00372
00373
00374 : CActive(EPriorityStandard)
00375 {
00376 iConsole = aConsole ;
00377 iFibonacciEngine = aFibonacciEngine ;
00378 CActiveScheduler::Add(this);
00379 };
00380
00381
00382
00383 CFibonacciThreadHandler::~CFibonacciThreadHandler()
00384 {
00385
00386 Cancel() ;
00387 }
00388
00389
00390 void CFibonacciThreadHandler::DoCancel()
00391 {
00392
00393 RThread thread ;
00394 thread.Open(KTxtFibThread) ;
00395 thread.Close() ;
00396 }
00397
00398
00399 void CFibonacciThreadHandler::RunL()
00400 {
00401
00402 _LIT(KFormat2," Result : %u \n");
00403 iConsole->Printf(KFormat2, iFibonacciParameters.iResult) ;
00404 iConsole->Printf(KTxtMainInstructions);
00405 }
00406
00407
00408
00409 void CFibonacciThreadHandler::CalculateFibonacciL(TInt aIterations)
00410 {
00411 const TInt KHeapSize = 0x800 ;
00412
00413 _LIT(KTxtFibRequested,"\nFibonacci requested ... ");
00414 iConsole->Printf(KTxtFibRequested);
00415
00416
00417 RThread thread ;
00418
00419
00420
00421 iFibonacciParameters.iVar1 = aIterations ;
00422 iFibonacciParameters.iVar2 = iFibonacciEngine ;
00423
00424
00425
00426 TInt result = thread.Create(KTxtFibThread,(TThreadFunction)FibonacciThread, KDefaultStackSize,
00427 KMinHeapSize, KHeapSize, &iFibonacciParameters, EOwnerThread) ;
00428 User::LeaveIfError(result) ;
00429
00430
00431
00432 thread.Logon(iStatus) ;
00433
00434
00435 thread.SetPriority(EPriorityMuchLess) ;
00436
00437
00438 thread.Resume() ;
00439
00440 thread.Close() ;
00441
00442
00443 SetActive() ;
00444
00445 _LIT(KTxtOK,"OK \n");
00446 iConsole->Printf(KTxtOK);
00447 }
00448
00449
00451
00453
00454 TInt CFibonacciThreadHandler::FibonacciThread(TAny* aParameters)
00455 {
00456
00457 TFibonacciParameters* parameters = (TFibonacciParameters*) aParameters ;
00458
00459
00460 TInt iterations = parameters->iVar1 ;
00461 CFibonacciEngine* fibonacciEngine = (CFibonacciEngine*)parameters->iVar2 ;
00462
00463
00464 fibonacciEngine->Calculate(iterations) ;
00465
00466
00467 parameters->iResult = fibonacciEngine->iResult ;
00468
00469 return KErrNone ;
00470 }
00471
00472
00474
00475
00476
00478
00479 void CFibonacciEngine::Calculate (TInt aTerms)
00480 {
00481 TInt iterations = aTerms ;
00482
00483 TInt currentTotal = 1 ;
00484 TInt previousTotal = 0 ;
00485 _LIT(KTxtTooManyIterations,"Too many iterations");
00486 __ASSERT_ALWAYS(iterations<47,User::Panic(KTxtTooManyIterations,iterations));
00487
00488
00489
00490 while (iterations-- > 0)
00491 {
00492
00493 TInt newTotal = currentTotal + previousTotal ;
00494
00495
00496 previousTotal = currentTotal ;
00497 currentTotal = newTotal ;
00498
00499
00500 User::After(1000000) ;
00501 }
00502
00503 iResult = currentTotal ;
00504
00505
00506 }
00507
00508
00510
00512
00513 void doExampleL () ;
00514
00515 void SetupConsoleL();
00516
00517 GLDEF_C TInt E32Main()
00518 {
00519 CTrapCleanup* cleanup=CTrapCleanup::New();
00520 TRAPD(error,SetupConsoleL());
00521 _LIT(KTxtFibonacciExampleError,"Fibonacci example error");
00522 __ASSERT_ALWAYS(!error,User::Panic(KTxtFibonacciExampleError,error));
00523 delete cleanup;
00524 return 0;
00525 }
00526
00527 void SetupConsoleL()
00528 {
00529 _LIT(KTxtFibActObjInThread,"Active Object and thread");
00530 console=Console::NewL(KTxtFibActObjInThread,TSize(KConsFullScreen,KConsFullScreen));
00531 CleanupStack::PushL(console);
00532 console->Printf(KTxtMainInstructions) ;
00533 TRAPD(error, doExampleL());
00534 if (error)
00535 {
00536 _LIT(KFormat3,"failed: leave code=%d");
00537 console->Printf(KFormat3, error);
00538 }
00539 _LIT(KTxtPressAnyKey,"[Press any key to exit]");
00540 console->Printf(KTxtPressAnyKey);
00541 console->Getch();
00542 CleanupStack::PopAndDestroy(console);
00543 }
00544
00545
00547
00548
00549
00551 void doExampleL()
00552 {
00553
00554 CExampleScheduler* exampleScheduler = new (ELeave) CExampleScheduler;
00555 CleanupStack::PushL(exampleScheduler);
00556
00557
00558 CActiveScheduler::Install(exampleScheduler);
00559
00560
00561 CFibonacciEngine* fibEngine = new (ELeave) CFibonacciEngine ;
00562 CleanupStack::PushL(fibEngine);
00563
00564
00565 CFibonacciThreadHandler* fibThreadHandler = new (ELeave) CFibonacciThreadHandler(console, fibEngine);
00566 CleanupStack::PushL(fibThreadHandler);
00567
00568
00569 CFibonacciKeyHandler* fibKeyHandler = new (ELeave) CFibonacciKeyHandler(console, fibThreadHandler);
00570 CleanupStack::PushL(fibKeyHandler);
00571
00572
00573 fibKeyHandler->RequestCharacter() ;
00574
00575
00576
00577 CActiveScheduler::Start();
00578
00579
00580 CleanupStack::PopAndDestroy(4);
00581 }
00582
00583
00584
00585