00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <e32cons.h>
00023 #include <e32base.h>
00024 #include <e32std.h>
00025
00027
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
00037
00038
00039
00041 class CActiveConsole : public CActive
00042 {
00043 public:
00044
00045 CActiveConsole(CConsoleBase* aConsole);
00046 void ConstructL();
00047
00048
00049 ~CActiveConsole();
00050
00051
00052 void RequestCharacter();
00053
00054
00055
00056
00057 void DoCancel();
00058
00059
00060
00061
00062 void RunL();
00063
00064
00065
00066 virtual void ProcessKeyPress(TChar aChar) = 0;
00067
00068 protected:
00069
00070 CConsoleBase* iConsole;
00071 };
00072
00073
00075
00076
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
00089 CActiveConsole* iActiveConsole;
00090 };
00091
00092
00093
00095
00096
00097
00098
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
00124
00125
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
00150
00151
00152
00154
00155 class CFibonacciKeyHandler : public CActiveConsole
00156 {
00157 public:
00158 CFibonacciKeyHandler( CConsoleBase* aConsole,
00159 CFibonacciApplication* aApplication) ;
00160 void ConstructL();
00161
00162
00163 static CFibonacciKeyHandler* NewLC(CConsoleBase* aConsole, CFibonacciApplication* aHandler) ;
00164
00165
00166 void ProcessKeyPress(TChar aChar) ;
00167
00168 private:
00169 CConsoleBase* iConsole ;
00170 CFibonacciApplication* iApplication ;
00171 };
00172
00173
00175
00176
00177
00179 CActiveConsole::CActiveConsole( CConsoleBase* aConsole)
00180 : CActive(CActive::EPriorityUserInput)
00181
00182 {
00183 iConsole = aConsole;
00184 __DECLARE_NAME(_S("CActiveConsole"));
00185
00186 }
00187
00188 void CActiveConsole::ConstructL()
00189 {
00190
00191 CActiveScheduler::Add(this);
00192 }
00193
00194 CActiveConsole::~CActiveConsole()
00195 {
00196
00197 Cancel();
00198 }
00199
00200 void CActiveConsole::DoCancel()
00201 {
00202 iConsole->ReadCancel();
00203 }
00204
00205 void CActiveConsole::RunL()
00206 {
00207
00208 ProcessKeyPress(TChar(iConsole->KeyCode()));
00209 }
00210
00211 void CActiveConsole::RequestCharacter()
00212 {
00213
00214
00215 iConsole->Read(iStatus);
00216 SetActive();
00217 }
00218
00219
00221
00222
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
00248
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
00275
00277
00278 CFibonacciKeyHandler::CFibonacciKeyHandler(CConsoleBase* aConsole, CFibonacciApplication* aApplication)
00279 : CActiveConsole(aConsole)
00280
00281 {
00282 iConsole = aConsole ;
00283 iApplication = aApplication ;
00284
00285 __DECLARE_NAME(_S("CFibonacciApplication"));
00286
00287 CActiveScheduler::Add(this);
00288
00289 ((CExampleScheduler*)(CActiveScheduler::Current()))->SetActiveObject(this);
00290 }
00291
00292
00293 void CFibonacciKeyHandler::ProcessKeyPress(TChar aChar)
00294 {
00295
00296 if (aChar == EKeyEscape)
00297 {
00298 CActiveScheduler::Stop();
00299 return;
00300 }
00301
00302
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
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
00338
00340
00341 CFibonacciApplication::CFibonacciApplication(CConsoleBase* aConsole, CFibonacciEngine* aFibonacciEngine)
00342
00343
00344
00345 : CActive(EPriorityStandard)
00346 {
00347 iConsole = aConsole ;
00348 iFibonacciEngine = aFibonacciEngine ;
00349 CActiveScheduler::Add(this);
00350 __DECLARE_NAME(_S("CFibonacciApplication"));
00351 };
00352
00353
00354
00355 CFibonacciApplication::~CFibonacciApplication()
00356 {
00357
00358 Cancel() ;
00359 }
00360
00361
00362 void CFibonacciApplication::DoCancel()
00363 {
00364
00365 iFibonacciEngine->iState = CFibonacciEngine::eInactive ;
00366 }
00367
00368
00369
00370
00371 void CFibonacciApplication::CalculateFibonacci(TInt aIterations)
00372 {
00373
00374
00375 iFibonacciEngine->StartCalculate(aIterations) ;
00376
00377
00378 SetActive() ;
00379
00380
00381 TRequestStatus* status = &iStatus ;
00382 User::RequestComplete(status, KErrNone) ;
00383 }
00384
00385
00386
00387 void CFibonacciApplication::RunL()
00388
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
00398 _LIT(KTxtDot,".");
00399 iConsole->Printf(KTxtDot) ;
00400
00401
00402
00403
00404 iFibonacciEngine->StepCalculate() ;
00405
00406
00407 SetActive() ;
00408
00409
00410 TRequestStatus* status = &iStatus ;
00411 User::RequestComplete(status, KErrNone) ;
00412 }
00413 else if (iFibonacciEngine->iState == CFibonacciEngine::eCompleted )
00414 {
00415
00416 _LIT(KFormat2,"\n Result : %u \n");
00417 iConsole->Printf(KFormat2, iFibonacciEngine->iResult) ;
00418 iConsole->Printf(KTxtMainInstructions) ;
00419 iFibonacciEngine->iState = CFibonacciEngine::eInactive ;
00420 }
00421 }
00422
00423
00424
00426
00427
00428
00430 CFibonacciEngine::CFibonacciEngine()
00431 {
00432 iState = eInactive ;
00433 }
00434
00435
00436 void CFibonacciEngine::StartCalculate (TInt aTerms)
00437 {
00438
00439 iCurrentTotal = 1 ;
00440 iPreviousTotal = 0 ;
00441 iResult = 0 ;
00442 iTermsLeftToDo = aTerms + 1 ;
00443 iState = eCalculating ;
00444 }
00445
00446
00447
00448 void CFibonacciEngine::StepCalculate ()
00449 {
00450
00451
00452 if (--iTermsLeftToDo > 0 && iState == eCalculating)
00453 {
00454
00455 TInt newTotal = iCurrentTotal + iPreviousTotal ;
00456
00457
00458 iPreviousTotal = iCurrentTotal ;
00459 iCurrentTotal = newTotal ;
00460
00461
00462 User::After(1000000) ;
00463
00464
00465
00466 iResult = iCurrentTotal ;
00467 }
00468 else if (iTermsLeftToDo <= 0)
00469 {
00470
00471 iState = eCompleted ;
00472 iResult = iCurrentTotal ;
00473 }
00474 }
00475
00476
00477
00479
00481
00482 void doExampleL () ;
00483
00484 void SetupConsoleL();
00485
00486 GLDEF_C TInt E32Main()
00487 {
00488 CTrapCleanup* cleanup=CTrapCleanup::New();
00489 TRAPD(error,SetupConsoleL());
00490 _LIT(KTxtFibonacciExampleError,"Fibonacci example error");
00491 __ASSERT_ALWAYS(!error,User::Panic(KTxtFibonacciExampleError,error));
00492 delete cleanup;
00493 return 0;
00494 }
00495
00496 void SetupConsoleL()
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());
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();
00511 CleanupStack::PopAndDestroy();
00512 }
00513
00514
00516
00517
00518
00520 void doExampleL()
00521 {
00522
00523 CExampleScheduler* exampleScheduler = new (ELeave) CExampleScheduler;
00524 CleanupStack::PushL(exampleScheduler);
00525
00526
00527 CActiveScheduler::Install(exampleScheduler);
00528
00529
00530 CFibonacciEngine* fibEngine = new (ELeave) CFibonacciEngine ;
00531 CleanupStack::PushL(fibEngine);
00532
00533
00534 CFibonacciApplication* fibApplication = new CFibonacciApplication(console, fibEngine);
00535 CleanupStack::PushL(fibApplication);
00536
00537
00538 CFibonacciKeyHandler* fibKeyHandler = new CFibonacciKeyHandler(console, fibApplication);
00539 CleanupStack::PushL(fibKeyHandler);
00540
00541
00542 fibKeyHandler->RequestCharacter() ;
00543
00544
00545
00546 CActiveScheduler::Start();
00547
00548
00549 CleanupStack::PopAndDestroy(4);
00550 }
00551
00552