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 #include <e32cons.h>
00037 #include <e32base.h>
00038 #include <e32std.h>
00039
00041
00042
00043
00044 LOCAL_D CConsoleBase* console;
00045
00046 _LIT(KTxtMainInstructions,"\n\nPress 'F' to start\n 'ESC' to exit\n 'C' to cancel, anytime\n");
00047
00049
00050
00051
00052
00053
00055 class CActiveConsole : public CActive
00056 {
00057 public:
00058
00059 CActiveConsole(CConsoleBase* aConsole);
00060 void ConstructL();
00061
00062
00063 ~CActiveConsole();
00064
00065
00066 void RequestCharacter();
00067
00068
00069
00070
00071 void DoCancel();
00072
00073
00074
00075
00076 void RunL();
00077
00078
00079
00080 virtual void ProcessKeyPress(TChar aChar) = 0;
00081
00082 protected:
00083
00084 CConsoleBase* iConsole;
00085 };
00086
00087
00089
00090
00091
00093 class CActiveConsole;
00094
00095 class CExampleScheduler : public CActiveScheduler
00096 {
00097 public:
00098 void Error (TInt aError) const;
00099 void WaitForAnyRequest();
00100 void SetActiveObject(CActiveConsole* aActiveConsole);
00101 private:
00102
00103 CActiveConsole* iActiveConsole;
00104 };
00105
00106
00107
00109
00110
00111
00112
00113
00115
00116 class CFibonacciEngine : public CBase
00117 {
00118 public:
00119 CFibonacciEngine() ;
00120 void StartCalculate (TInt aTerms) ;
00121 void StepCalculate () ;
00122
00123 TUint iResult ;
00124
00125 enum TEngineState {eInactive, eCalculating, eCompleted} ;
00126 TEngineState iState ;
00127
00128 private:
00129 TUint iCurrentTotal ;
00130 TUint iPreviousTotal ;
00131 TInt iTermsLeftToDo ;
00132 } ;
00133
00134
00136
00137
00138
00139
00140
00142
00143 class CFibonacciApplication : public CActive
00144 {
00145 public:
00146 CFibonacciApplication(CConsoleBase* aConsole, CFibonacciEngine* aFibonacciEngine) ;
00147 ~CFibonacciApplication() ;
00148
00149 void CalculateFibonacci(TInt aIterations) ;
00150
00151 private:
00152 void DoCancel() ;
00153 void RunL() ;
00154
00155 private:
00156 CConsoleBase* iConsole ;
00157 CFibonacciEngine* iFibonacciEngine ;
00158 } ;
00159
00160
00162
00163
00164
00165
00166
00168
00169 class CFibonacciKeyHandler : public CActiveConsole
00170 {
00171 public:
00172 CFibonacciKeyHandler( CConsoleBase* aConsole,
00173 CFibonacciApplication* aApplication) ;
00174 void ConstructL();
00175
00176
00177 static CFibonacciKeyHandler* NewLC(CConsoleBase* aConsole, CFibonacciApplication* aHandler) ;
00178
00179
00180 void ProcessKeyPress(TChar aChar) ;
00181
00182 private:
00183 CConsoleBase* iConsole ;
00184 CFibonacciApplication* iApplication ;
00185 };
00186
00187
00189
00190
00191
00193 CActiveConsole::CActiveConsole( CConsoleBase* aConsole)
00194 : CActive(CActive::EPriorityUserInput)
00195
00196 {
00197 iConsole = aConsole;
00198 __DECLARE_NAME(_S("CActiveConsole"));
00199
00200 }
00201
00202 void CActiveConsole::ConstructL()
00203 {
00204
00205 CActiveScheduler::Add(this);
00206 }
00207
00208 CActiveConsole::~CActiveConsole()
00209 {
00210
00211 Cancel();
00212 }
00213
00214 void CActiveConsole::DoCancel()
00215 {
00216 iConsole->ReadCancel();
00217 }
00218
00219 void CActiveConsole::RunL()
00220 {
00221
00222 ProcessKeyPress(TChar(iConsole->KeyCode()));
00223 }
00224
00225 void CActiveConsole::RequestCharacter()
00226 {
00227
00228
00229 iConsole->Read(iStatus);
00230 SetActive();
00231 }
00232
00233
00235
00236
00237
00239 void CExampleScheduler::Error(TInt aError) const
00240 {
00241 _LIT(KTxtSchedulerError,"CExampleScheduler - error");
00242 User::Panic(KTxtSchedulerError,aError);
00243 }
00244
00245
00246 void CExampleScheduler::WaitForAnyRequest()
00247 {
00248 if (!(iActiveConsole->IsActive()))
00249 iActiveConsole->RequestCharacter();
00250 CActiveScheduler::WaitForAnyRequest();
00251 }
00252
00253 void CExampleScheduler::SetActiveObject(CActiveConsole* aActiveConsole)
00254 {
00255 iActiveConsole = aActiveConsole;
00256 }
00257
00258
00259
00261
00262
00264
00265 TInt GetValueFromKeyboard (TInt aInitial, TInt aStep, TInt lowerLimit, TInt upperLimit, const TDesC& aPrompt, CConsoleBase* aConsole)
00266 {
00267 TChar input ;
00268 TInt value = aInitial ;
00269
00270 aConsole->Printf(aPrompt) ;
00271 do
00272 {
00273 aConsole->SetPos(0);
00274 _LIT(KFormat1,"%d ");
00275 aConsole->Printf(KFormat1, value);
00276 input = aConsole->Getch() ;
00277 if (input == EKeyUpArrow && value < upperLimit) value = value + aStep ;
00278 if (input == EKeyDownArrow && value > lowerLimit) value = value - aStep ;
00279 }
00280 while (input != EKeyEnter) ;
00281
00282 return value ;
00283 }
00284
00285
00287
00288
00289
00291
00292 CFibonacciKeyHandler::CFibonacciKeyHandler(CConsoleBase* aConsole, CFibonacciApplication* aApplication)
00293 : CActiveConsole(aConsole)
00294
00295 {
00296 iConsole = aConsole ;
00297 iApplication = aApplication ;
00298
00299 __DECLARE_NAME(_S("CFibonacciApplication"));
00300
00301 CActiveScheduler::Add(this);
00302
00303 ((CExampleScheduler*)(CActiveScheduler::Current()))->SetActiveObject(this);
00304 }
00305
00306
00307 void CFibonacciKeyHandler::ProcessKeyPress(TChar aChar)
00308 {
00309
00310 if (aChar == EKeyEscape)
00311 {
00312 CActiveScheduler::Stop();
00313 return;
00314 }
00315
00316
00317 if (aChar == 'f' || aChar == 'F')
00318 {
00319 if (!(iApplication->IsActive()))
00320 {
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 iApplication->CalculateFibonacci(iterations);
00324 }
00325 else
00326 {
00327 _LIT(KTxtAlreadyInProgress,"[Already in progress]");
00328 iConsole->Printf(KTxtAlreadyInProgress);
00329 }
00330 return;
00331 }
00332
00333
00334 if (aChar == 'c' || aChar == 'C')
00335 {
00336 _LIT(KTxtCancelFibonacci,"\nCancelling Fibonacci.... \n");
00337 iConsole->Printf(KTxtCancelFibonacci);
00338 iApplication->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 CFibonacciApplication::CFibonacciApplication(CConsoleBase* aConsole, CFibonacciEngine* aFibonacciEngine)
00356
00357
00358
00359 : CActive(EPriorityStandard)
00360 {
00361 iConsole = aConsole ;
00362 iFibonacciEngine = aFibonacciEngine ;
00363 CActiveScheduler::Add(this);
00364 __DECLARE_NAME(_S("CFibonacciApplication"));
00365 };
00366
00367
00368
00369 CFibonacciApplication::~CFibonacciApplication()
00370 {
00371
00372 Cancel() ;
00373 }
00374
00375
00376 void CFibonacciApplication::DoCancel()
00377 {
00378
00379 iFibonacciEngine->iState = CFibonacciEngine::eInactive ;
00380 }
00381
00382
00383
00384
00385 void CFibonacciApplication::CalculateFibonacci(TInt aIterations)
00386 {
00387
00388
00389 iFibonacciEngine->StartCalculate(aIterations) ;
00390
00391
00392 SetActive() ;
00393
00394
00395 TRequestStatus* status = &iStatus ;
00396 User::RequestComplete(status, KErrNone) ;
00397 }
00398
00399
00400
00401 void CFibonacciApplication::RunL()
00402
00403 {
00404 if (iFibonacciEngine->iState == CFibonacciEngine::eInactive )
00405 {
00406 _LIT(KTxtEngineNotInitialized,"Engine not initialized");
00407 User::Panic(KTxtEngineNotInitialized, KErrNotReady) ;
00408 }
00409 else if (iFibonacciEngine->iState == CFibonacciEngine::eCalculating )
00410 {
00411
00412 _LIT(KTxtDot,".");
00413 iConsole->Printf(KTxtDot) ;
00414
00415
00416
00417
00418 iFibonacciEngine->StepCalculate() ;
00419
00420
00421 SetActive() ;
00422
00423
00424 TRequestStatus* status = &iStatus ;
00425 User::RequestComplete(status, KErrNone) ;
00426 }
00427 else if (iFibonacciEngine->iState == CFibonacciEngine::eCompleted )
00428 {
00429
00430 _LIT(KFormat2,"\n Result : %u \n");
00431 iConsole->Printf(KFormat2, iFibonacciEngine->iResult) ;
00432 iConsole->Printf(KTxtMainInstructions) ;
00433 iFibonacciEngine->iState = CFibonacciEngine::eInactive ;
00434 }
00435 }
00436
00437
00438
00440
00441
00442
00444 CFibonacciEngine::CFibonacciEngine()
00445 {
00446 iState = eInactive ;
00447 }
00448
00449
00450 void CFibonacciEngine::StartCalculate (TInt aTerms)
00451 {
00452
00453 iCurrentTotal = 1 ;
00454 iPreviousTotal = 0 ;
00455 iResult = 0 ;
00456 iTermsLeftToDo = aTerms + 1 ;
00457 iState = eCalculating ;
00458 }
00459
00460
00461
00462 void CFibonacciEngine::StepCalculate ()
00463 {
00464
00465
00466 if (--iTermsLeftToDo > 0 && iState == eCalculating)
00467 {
00468
00469 TInt newTotal = iCurrentTotal + iPreviousTotal ;
00470
00471
00472 iPreviousTotal = iCurrentTotal ;
00473 iCurrentTotal = newTotal ;
00474
00475
00476 User::After(1000000) ;
00477
00478
00479
00480 iResult = iCurrentTotal ;
00481 }
00482 else if (iTermsLeftToDo <= 0)
00483 {
00484
00485 iState = eCompleted ;
00486 iResult = iCurrentTotal ;
00487 }
00488 }
00489
00490
00491
00493
00495
00496 void doExampleL () ;
00497
00498 void SetupConsoleL();
00499
00500 GLDEF_C TInt E32Main()
00501 {
00502 CTrapCleanup* cleanup=CTrapCleanup::New();
00503 TRAPD(error,SetupConsoleL());
00504 _LIT(KTxtFibonacciExampleError,"Fibonacci example error");
00505 __ASSERT_ALWAYS(!error,User::Panic(KTxtFibonacciExampleError,error));
00506 delete cleanup;
00507 return 0;
00508 }
00509
00510 void SetupConsoleL()
00511 {
00512 _LIT(KTxtFibActObjBackground,"Background Active Object");
00513 console=Console::NewL(KTxtFibActObjBackground, TSize(KConsFullScreen,KConsFullScreen));
00514 CleanupStack::PushL(console);
00515 console->Printf(KTxtMainInstructions) ;
00516 TRAPD(error, doExampleL());
00517 if (error)
00518 {
00519 _LIT(KFormat3,"failed: leave code=%d");
00520 console->Printf(KFormat3, error);
00521 }
00522 _LIT(KTxtPressAnyKey,"[Press any key to exit]");
00523 console->Printf(KTxtPressAnyKey);
00524 console->Getch();
00525 CleanupStack::PopAndDestroy();
00526 }
00527
00528
00530
00531
00532
00534 void doExampleL()
00535 {
00536
00537 CExampleScheduler* exampleScheduler = new (ELeave) CExampleScheduler;
00538 CleanupStack::PushL(exampleScheduler);
00539
00540
00541 CActiveScheduler::Install(exampleScheduler);
00542
00543
00544 CFibonacciEngine* fibEngine = new (ELeave) CFibonacciEngine ;
00545 CleanupStack::PushL(fibEngine);
00546
00547
00548 CFibonacciApplication* fibApplication = new CFibonacciApplication(console, fibEngine);
00549 CleanupStack::PushL(fibApplication);
00550
00551
00552 CFibonacciKeyHandler* fibKeyHandler = new CFibonacciKeyHandler(console, fibApplication);
00553 CleanupStack::PushL(fibKeyHandler);
00554
00555
00556 fibKeyHandler->RequestCharacter() ;
00557
00558
00559
00560 CActiveScheduler::Start();
00561
00562
00563 CleanupStack::PopAndDestroy(4);
00564 }
00565
00566