diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_fibonacci1_8cpp_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_fibonacci1_8cpp_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,411 @@ + + +
+ +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. +00015 // Calculates Fibonacci number as chosen by the user. Note that, in this +00016 // example, the calculation is done as part of the console active object's +00017 // RunL() and can take a long time to complete. It also means that nothing +00018 // else can happen (including responding to keyboard events) until the +00019 // calculation is complete. +00020 // +00021 +00022 +00023 +00024 #include <e32base.h> +00025 #include <e32cons.h> +00026 #include <e32std.h> +00027 +00028 +00029 LOCAL_D CConsoleBase* console; +00030 +00031 _LIT(KTxtMainInstructions,"\n\nPress 'F' to start\n 'ESC' to exit.\n"); +00032 +00034 // +00035 // -----> CActiveConsole (definition) +00036 // +00037 // An abstract class which provides the facility to issue key requests. +00038 // +00040 +00041 class CActiveConsole : public CActive +00042 { +00043 public: +00044 // Construction +00045 CActiveConsole(CConsoleBase* aConsole); +00046 void ConstructL(); +00047 +00048 // Destruction +00049 ~CActiveConsole(); +00050 +00051 // Issue request +00052 void RequestCharacter(); +00053 +00054 // Cancel request. +00055 // Defined as pure virtual by CActive; +00056 // implementation provided by this class. +00057 void DoCancel(); +00058 +00059 // Service completed request. +00060 // Defined as pure virtual by CActive; +00061 // implementation provided by this class, +00062 void RunL(); +00063 +00064 // Called from RunL() - an implementation must be provided +00065 // by derived classes to handle the completed request +00066 virtual void ProcessKeyPress(TChar aChar) = 0; +00067 +00068 protected: +00069 // Data members defined by this class +00070 CConsoleBase* iConsole; // A console for reading from +00071 }; +00072 +00073 +00075 // +00076 // -----> CExampleScheduler (definition) +00077 // +00079 +00080 class CExampleScheduler : public CActiveScheduler +00081 { +00082 public: +00083 void Error (TInt aError) const; +00084 void WaitForAnyRequest(); +00085 void SetActiveObject(CActiveConsole* aActiveConsole); +00086 private: +00087 // data members defined for this class +00088 CActiveConsole* iActiveConsole; +00089 }; +00090 +00091 +00093 // +00094 // -----> TFibonacciEngine (definition) +00095 // +00096 // This class provides the fibonacci calculation engine +00097 // +00099 +00100 class TFibonacciEngine +00101 { +00102 public: +00103 void Calculate (TInt aTerms) ; +00104 +00105 TInt iResult ; +00106 } ; +00107 +00108 +00110 // +00111 // -----> CFibonacciApplication (definition) +00112 // +00113 // This class encapsulates the fibonacci calculation engine +00114 // +00116 +00117 class CFibonacciApplication : public CActiveConsole +00118 { +00119 public: +00120 CFibonacciApplication(CConsoleBase* aConsole) ; +00121 void ConstructL(); +00122 +00123 // Static construction +00124 static CFibonacciApplication* NewLC(CConsoleBase* aConsole) ; +00125 +00126 // service request +00127 void ProcessKeyPress(TChar aChar) ; +00128 +00129 private: +00130 CConsoleBase* iConsole ; +00131 TFibonacciEngine iFibonacciEngine ; +00132 }; +00133 +00134 +00136 // +00137 // -----> CActiveConsole (implementation) +00138 // +00140 +00141 CActiveConsole::CActiveConsole( CConsoleBase* aConsole) +00142 : CActive(CActive::EPriorityUserInput) +00143 // Construct high-priority active object +00144 { +00145 iConsole = aConsole; +00146 __DECLARE_NAME(_S("CActiveConsole")); +00147 +00148 } +00149 +00150 void CActiveConsole::ConstructL() +00151 { +00152 // Add to active scheduler +00153 CActiveScheduler::Add(this); +00154 } +00155 +00156 CActiveConsole::~CActiveConsole() +00157 { +00158 // Make sure we're cancelled +00159 Cancel(); +00160 } +00161 +00162 void CActiveConsole::DoCancel() +00163 { +00164 iConsole->ReadCancel(); +00165 } +00166 +00167 void CActiveConsole::RunL() +00168 { +00169 // Handle completed request +00170 ProcessKeyPress(TChar(iConsole->KeyCode())); +00171 } +00172 +00173 void CActiveConsole::RequestCharacter() +00174 { +00175 // A request is issued to the CConsoleBase to accept a +00176 // character from the keyboard. +00177 iConsole->Read(iStatus); +00178 SetActive(); +00179 } +00180 +00181 +00183 // +00184 // -----> CExampleScheduler (implementation) +00185 // +00187 +00188 void CExampleScheduler::Error(TInt aError) const +00189 { +00190 _LIT(KTxtSchedulerError,"CExampleScheduler - error"); +00191 User::Panic(KTxtSchedulerError,aError); +00192 } +00193 +00194 void CExampleScheduler::WaitForAnyRequest() +00195 { +00196 if (!(iActiveConsole->IsActive())) +00197 iActiveConsole->RequestCharacter(); +00198 CActiveScheduler::WaitForAnyRequest(); +00199 } +00200 +00201 void CExampleScheduler::SetActiveObject(CActiveConsole* aActiveConsole) +00202 { +00203 iActiveConsole = aActiveConsole; +00204 } +00205 +00206 +00208 // CFibonacciApplication support routine +00209 // uses up arrow & down arrow to change number, Enter to select +00211 +00212 TInt GetValueFromKeyboard (TInt aInitial, TInt aStep, TInt lowerLimit, TInt upperLimit, const TDesC& aPrompt, CConsoleBase* aConsole) +00213 { +00214 TChar input ; +00215 TInt value = aInitial ; +00216 +00217 aConsole->Printf(aPrompt) ; +00218 do +00219 { +00220 aConsole->SetPos(0); +00221 _LIT(KFormat1,"%d "); +00222 aConsole->Printf(KFormat1, value); +00223 input = aConsole->Getch() ; +00224 if (input == EKeyUpArrow && value < upperLimit) value = value + aStep ; +00225 if (input == EKeyDownArrow && value > lowerLimit) value = value - aStep ; +00226 if (input == 'c') value = -1; +00227 } +00228 while (input != EKeyEnter && input != 'c') ; +00229 +00230 return value ; +00231 } +00232 +00233 +00235 // +00236 // -----> CFibonacciApplication (implementation) +00237 // +00239 +00240 CFibonacciApplication::CFibonacciApplication(CConsoleBase* aConsole ) +00241 : CActiveConsole(aConsole) +00242 // construct zero-priority active object +00243 { +00244 iConsole = aConsole ; +00245 __DECLARE_NAME(_S("CFibonacciApplication")); +00246 } +00247 +00248 +00249 CFibonacciApplication* CFibonacciApplication::NewLC(CConsoleBase* aConsole ) +00250 { +00251 CFibonacciApplication* self=new (ELeave) CFibonacciApplication(aConsole); +00252 CleanupStack::PushL(self); +00253 self->ConstructL(); +00254 return self; +00255 } +00256 +00257 +00258 void CFibonacciApplication::ConstructL() +00259 { +00260 // Add to active scheduler +00261 CActiveScheduler::Add(this); +00262 // Make this the active object +00263 ((CExampleScheduler*)(CActiveScheduler::Current()))->SetActiveObject(this); +00264 } +00265 +00266 +00267 void CFibonacciApplication::ProcessKeyPress(TChar aChar) +00268 { +00269 // if key is ESC +00270 // cancel any outstanding request +00271 // stop the scheduler +00272 if (aChar == EKeyEscape) +00273 { +00274 CActiveScheduler::Stop(); +00275 return; +00276 } +00277 +00278 // If key is "f" or "F" +00279 // cancel any outstanding request +00280 // issue a fibonacci request. +00281 if (aChar == 'f' || aChar == 'F') +00282 { +00283 _LIT(KTxtStartingFibonacci,"\nStarting Fibonacci.... \n"); +00284 _LIT(KTxtReturnTermNumber,"\nENTER selects number, and starts calculation\nUP arrow increases num\nDOWN arrow decreases num\nC cancels\n\n"); +00285 _LIT(KTxtCalculating,"\nCalculating...\n"); +00286 _LIT(KFormat2,"\nResult : %u \n"); +00287 _LIT(KTxtCancelled,"Cancelled"); +00288 +00289 iConsole->Printf(KTxtStartingFibonacci); +00290 +00291 TInt iterations = GetValueFromKeyboard(5,1,2,46, KTxtReturnTermNumber, iConsole) ; +00292 if (iterations == -1) // convenient if awkward but allows us to indicate a request to cancel. +00293 { +00294 iConsole->Printf(KTxtCancelled); +00295 iConsole->Printf(KTxtMainInstructions); +00296 return; +00297 } +00298 +00299 iConsole->Printf(KTxtCalculating); +00300 iFibonacciEngine.Calculate(iterations); +00301 +00302 iConsole->Printf(KFormat2, iFibonacciEngine.iResult) ; +00303 iConsole->Printf(KTxtMainInstructions); +00304 return; +00305 } +00306 +00307 // any other key ignore +00308 _LIT(KTxtNotRecognised,"\nUnwanted key pressed"); +00309 iConsole->Printf(KTxtNotRecognised); +00310 iConsole->Printf(KTxtMainInstructions); +00311 } +00312 +00314 // +00315 // -----> TFibonacciEngine (implementation) +00316 // +00318 +00319 void TFibonacciEngine::Calculate (TInt aTerms) +00320 { +00321 TInt iterations = aTerms ; +00322 +00323 TInt currentTotal = 1 ; +00324 TInt previousTotal = 0 ; +00325 _LIT(KTxtTooManyIterations,"Too many iterations"); +00326 __ASSERT_ALWAYS(iterations<47,User::Panic(KTxtTooManyIterations,iterations)); +00327 +00328 // if limit not yet reached +00329 while (iterations-- > 0) +00330 { +00331 // calculate next number in series +00332 TInt newTotal = currentTotal + previousTotal ; +00333 +00334 // update variables +00335 previousTotal = currentTotal ; +00336 currentTotal = newTotal ; +00337 +00338 // introduce a delay +00339 User::After(1000000) ; +00340 } +00341 +00342 iResult = currentTotal ; +00343 +00344 } +00345 +00346 +00348 // This section deals with initialisation and ensuring we have a console active +00350 +00351 void doExampleL () ; +00352 +00353 void SetupConsoleL(); +00354 +00355 GLDEF_C TInt E32Main() // main function called by E32 +00356 { +00357 CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack +00358 TRAPD(error,SetupConsoleL()); // more initialization, then do example +00359 _LIT(KTxtFibonacciExampleError,"Fibonacci example error"); +00360 __ASSERT_ALWAYS(!error,User::Panic(KTxtFibonacciExampleError,error)); +00361 delete cleanup; // destroy clean-up stack +00362 return 0; // and return +00363 } +00364 +00365 void SetupConsoleL() // initialize and call example code under cleanup stack +00366 { +00367 _LIT(KTxtFibSingActObj,"Single Active Object"); +00368 console=Console::NewL(KTxtFibSingActObj, TSize(KConsFullScreen,KConsFullScreen)); +00369 CleanupStack::PushL(console); +00370 +00371 console->Printf(KTxtMainInstructions) ; +00372 TRAPD(error, doExampleL()); // perform example function +00373 if (error) +00374 { +00375 _LIT(KFormat3,"failed: leave code=%d"); +00376 console->Printf(KFormat3, error); +00377 } +00378 _LIT(KTxtPressAnyKey,"[Press any key to exit]"); +00379 console->Printf(KTxtPressAnyKey); +00380 console->Getch(); // get and ignore character +00381 CleanupStack::PopAndDestroy(); // close console +00382 } +00383 +00384 +00386 // +00387 // Do the example +00388 // +00390 void doExampleL() +00391 { +00392 // Construct and install the active scheduler +00393 CExampleScheduler* exampleScheduler = new (ELeave) CExampleScheduler; +00394 +00395 // Push onto the cleanup stack +00396 CleanupStack::PushL(exampleScheduler); +00397 +00398 // Install as the active scheduler +00399 CActiveScheduler::Install(exampleScheduler); +00400 +00401 // Create CFibonacciApplication active object. +00402 CFibonacciApplication* fibonacci = CFibonacciApplication::NewLC(console); +00403 +00404 // issue initial request +00405 fibonacci->RequestCharacter() ; +00406 +00407 // Main part of the program: +00408 // wait loop that cycles until ActiveScheduler::Stop called +00409 CActiveScheduler::Start(); +00410 +00411 // Remove from the cleanup stack and destroy: +00412 // 1. the CFibonacciApplication active object. +00413 // 2. exampleScheduler +00414 CleanupStack::PopAndDestroy(); +00415 CleanupStack::PopAndDestroy(); +00416 } +00417 +