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 // Asynchronous keyboard processing with messenger program. 00015 // A single CWriteKeyProcessor active object (derived from 00016 // class CActiveConsole) which accepts and prints keyboard 00017 // input to a console. 00018 // 00019 00020 #include "CommonFramework.h" 00021 00022 // panics 00023 enum 00024 { 00025 EPanicAlreadyActive=1000, 00026 }; 00027 00029 // 00030 // -----> CTimedMessenger (definition) 00031 // 00033 class CTimedMessenger : public CTimer 00034 { 00035 public: 00036 // Construction 00037 CTimedMessenger(); 00038 // Destruction 00039 ~CTimedMessenger(); 00040 00041 public: 00042 // Static construction 00043 static CTimedMessenger* NewLC(const TDesC& aGreeting, 00044 TInt aTicksRequested, 00045 TInt aTicksInterval 00046 ); 00047 static CTimedMessenger* NewL(const TDesC& aGreeting, 00048 TInt aTicksRequested, 00049 TInt aTicksInterval 00050 ); 00051 00052 public: 00053 // Second phase construction 00054 void ConstructL(const TDesC& aGreeting, 00055 TInt aTicksRequested, 00056 TInt aTicksInterval 00057 ); 00058 00059 // issue request 00060 void IssueRequest(); 00061 00062 // Cancel request 00063 // Defined as pure virtual by CActive; 00064 // implementation provided by this class. 00065 void DoCancel(); 00066 00067 // service completed request. 00068 // Defined as pure virtual by CActive; 00069 // implementation provided by this class. 00070 void RunL(); 00071 00072 public: 00073 // data members defined by this class 00074 TBufC<20> iGreeting; // Text of the greeting. 00075 TInt iTicksRequested; // Total number of greetings CTimedMessenger 00076 // will emit. 00077 TInt iTicksInterval; // Number of seconds between each greeting. 00078 TInt iTicksDone; // Number of greetings issued so far. 00079 }; 00080 00081 00083 // 00084 // -----> CExampleScheduler (definition) 00085 // 00087 class CExampleScheduler : public CActiveScheduler 00088 { 00089 public: 00090 void Error (TInt aError) const; 00091 }; 00092 00093 00095 // 00096 // -----> CActiveConsole (definition) 00097 // 00098 // An abstract class which provides the facility to issue key requests. 00099 // 00101 class CActiveConsole : public CActive 00102 { 00103 public: 00104 // Construction 00105 CActiveConsole(CConsoleBase* aConsole); 00106 void ConstructL(); 00107 00108 // Destruction 00109 ~CActiveConsole(); 00110 00111 // Issue request 00112 void RequestCharacter(); 00113 00114 // Cancel request. 00115 // Defined as pure virtual by CActive; 00116 // implementation provided by this class. 00117 void DoCancel(); 00118 00119 // Service completed request. 00120 // Defined as pure virtual by CActive; 00121 // implementation provided by this class, 00122 void RunL(); 00123 00124 // Called from RunL() - an implementation must be provided 00125 // by derived classes to handle the completed request 00126 virtual void ProcessKeyPress(TChar aChar) = 0; 00127 00128 protected: 00129 // Data members defined by this class 00130 CConsoleBase* iConsole; // A console for reading from 00131 }; 00132 00133 00135 // 00136 // -----> CWriteKeyProcessor (definition) 00137 // 00138 // This class is derived from CActiveConsole. 00139 // Request handling: accepts input from the keyboard and outputs it 00140 // to the console. 00141 // 00143 class CWriteKeyProcessor : public CActiveConsole 00144 { 00145 public: 00146 // Construction 00147 CWriteKeyProcessor(CConsoleBase* aConsole); 00148 00149 public: 00150 // Static constuction 00151 static CWriteKeyProcessor *NewLC (CConsoleBase* aConsole); 00152 static CWriteKeyProcessor *NewL(CConsoleBase* aConsole); 00153 00154 public: 00155 // Service request 00156 void ProcessKeyPress(TChar aChar); 00157 }; 00158 00159 00161 // 00162 // -----> CTimedMessenger (implementation) 00163 // 00165 CTimedMessenger::CTimedMessenger() 00166 : CTimer(CActive::EPriorityStandard) 00167 // Construct standard-priority active object 00168 {}; 00169 00170 CTimedMessenger* CTimedMessenger::NewLC(const TDesC& aGreeting, 00171 TInt aTicksRequested, 00172 TInt aTicksInterval 00173 ) 00174 { 00175 CTimedMessenger* self=new (ELeave) CTimedMessenger; 00176 CleanupStack::PushL(self); 00177 self->ConstructL(aGreeting,aTicksRequested,aTicksInterval); 00178 return self; 00179 } 00180 00181 CTimedMessenger* CTimedMessenger::NewL(const TDesC& aGreeting, 00182 TInt aTicksRequested, 00183 TInt aTicksInterval 00184 ) 00185 { 00186 CTimedMessenger* self = NewLC(aGreeting,aTicksRequested,aTicksInterval); 00187 CleanupStack::Pop(); 00188 return self; 00189 } 00190 00191 void CTimedMessenger::ConstructL(const TDesC& aGreeting, 00192 TInt aTicksRequested, 00193 TInt aTicksInterval 00194 ) 00195 { 00196 // Base class second-phase construction. 00197 CTimer::ConstructL(); 00198 // Set members from arguments 00199 iGreeting = aGreeting; // Set greeting text. 00200 iTicksRequested = aTicksRequested; // Ticks requested 00201 iTicksInterval = aTicksInterval; // Interval between ticks 00202 // Add active object to active scheduler 00203 CActiveScheduler::Add(this); 00204 } 00205 00206 00207 CTimedMessenger::~CTimedMessenger() 00208 { 00209 // Make sure we're cancelled 00210 Cancel(); 00211 } 00212 00213 void CTimedMessenger::DoCancel() 00214 { 00215 // Base class 00216 CTimer::DoCancel(); 00217 // Reset this variable - needed if the object is re-activated later 00218 iTicksDone = 0; 00219 // Tell user 00220 _LIT(KMsgCancelled,"Outstanding Messenger request cancelled\n"); 00221 console->Printf(KMsgCancelled); 00222 } 00223 00224 void CTimedMessenger::IssueRequest() 00225 { 00226 // There should never be an outstanding request at this point. 00227 _LIT(KMsgAlreadyActive,"Is already Active"); 00228 __ASSERT_ALWAYS(!IsActive(),User::Panic(KMsgAlreadyActive,EPanicAlreadyActive)); 00229 // Request another wait 00230 CTimer::After( iTicksInterval*1000000); 00231 } 00232 00233 void CTimedMessenger::RunL() 00234 { 00235 // Handle request completion 00236 // One more tick done 00237 iTicksDone++; 00238 // Print greeting 00239 _LIT(KFormatString1,"%S \n"); 00240 console->Printf(KFormatString1,&iGreeting); 00241 // Issue new request, or stop if we have reached the limit 00242 if (iTicksDone < iTicksRequested) 00243 { 00244 IssueRequest(); 00245 } 00246 else 00247 { 00248 _LIT(KMsgFinished,"Messenger finished \n"); 00249 console->Printf(KMsgFinished); 00250 // Reset this variable - needed if the object is re-activated later 00251 iTicksDone=0; 00252 // Can now stop the active scheduler 00253 CActiveScheduler::Stop(); 00254 } 00255 } 00256 00257 00259 // 00260 // -----> CExampleScheduler (implementation) 00261 // 00263 void CExampleScheduler::Error(TInt aError) const 00264 { 00265 _LIT(KMsgSchedErr,"CExampleScheduler-error"); 00266 User::Panic(KMsgSchedErr,aError); 00267 } 00268 00269 00271 // 00272 // -----> CActiveConsole (implementation) 00273 // 00275 CActiveConsole::CActiveConsole( CConsoleBase* aConsole) 00276 : CActive(CActive::EPriorityUserInput) 00277 // Construct high-priority active object 00278 { 00279 iConsole = aConsole; 00280 } 00281 00282 void CActiveConsole::ConstructL() 00283 { 00284 // Add to active scheduler 00285 CActiveScheduler::Add(this); 00286 } 00287 00288 CActiveConsole::~CActiveConsole() 00289 { 00290 // Make sure we're cancelled 00291 Cancel(); 00292 } 00293 00294 void CActiveConsole::DoCancel() 00295 { 00296 iConsole->ReadCancel(); 00297 } 00298 00299 void CActiveConsole::RunL() 00300 { 00301 // Handle completed request 00302 ProcessKeyPress(TChar(iConsole->KeyCode())); 00303 } 00304 00305 void CActiveConsole::RequestCharacter() 00306 { 00307 // A request is issued to the CConsoleBase to accept a 00308 // character from the keyboard. 00309 iConsole->Read(iStatus); 00310 SetActive(); 00311 } 00312 00313 00315 // 00316 // -----> CWriteKeyProcessor (implementation) 00317 // 00319 CWriteKeyProcessor::CWriteKeyProcessor(CConsoleBase* aConsole) 00320 : CActiveConsole(aConsole) 00321 00322 {}; 00323 00324 CWriteKeyProcessor* CWriteKeyProcessor::NewLC(CConsoleBase* aConsole) 00325 { 00326 CWriteKeyProcessor* self=new (ELeave) CWriteKeyProcessor(aConsole); 00327 CleanupStack::PushL(self); 00328 self->ConstructL(); 00329 return self; 00330 } 00331 00332 CWriteKeyProcessor* CWriteKeyProcessor::NewL(CConsoleBase* aConsole) 00333 { 00334 CWriteKeyProcessor* self=NewLC(aConsole); 00335 CleanupStack::Pop(); 00336 return self; 00337 } 00338 00339 void CWriteKeyProcessor::ProcessKeyPress(TChar aChar) 00340 { 00341 // "Esc" character prints a new line and stops the scheduler 00342 _LIT(KTextEsc,"\n"); 00343 if (aChar == EKeyEscape) 00344 { 00345 iConsole->Printf(KTextEsc); 00346 CActiveScheduler::Stop(); 00347 return; 00348 } 00349 00350 // "Enter" prints a new line character 00351 // An alphabetic or space is printed as a character; 00352 // anything else is printed as an integer. 00353 if (aChar == EKeyEnter) 00354 iConsole->Printf(KTextEsc); 00355 else 00356 { 00357 _LIT(KFormatString2,"%c"); 00358 _LIT(KFormatString3,"%d"); 00359 if (aChar.IsAlphaDigit()|| aChar.IsSpace()) 00360 iConsole->Printf(KFormatString2,TUint(aChar)); 00361 else 00362 iConsole->Printf(KFormatString3,TUint(aChar)); 00363 } 00364 00365 // Issue another request 00366 RequestCharacter(); 00367 } 00368 00369 00371 // 00372 // Do the example 00373 // 00375 LOCAL_C void doExampleL() 00376 { 00377 // Construct and install the active scheduler 00378 CExampleScheduler* exampleScheduler = new (ELeave) CExampleScheduler; 00379 00380 // Push onto the cleanup stack 00381 CleanupStack::PushL(exampleScheduler); 00382 00383 // Install as the active scheduler 00384 CActiveScheduler::Install(exampleScheduler); 00385 00386 // Create a CWriteKeyProcessor active object 00387 _LIT(KTitleMsg,"A single CWriteKeyProcessor active object.\nIt accepts and prints keyboard input to the console.\nPress ESC to end.\n\n"); 00388 console->Printf(KTitleMsg); 00389 CWriteKeyProcessor* keyProcesser = CWriteKeyProcessor::NewLC(console); 00390 00391 // Issue the first request 00392 keyProcesser->RequestCharacter(); 00393 00394 // Main part of program is a wait loop 00395 // This function completes when the scheduler stops 00396 CActiveScheduler::Start(); 00397 00398 // Remove from the cleanup stack and destroy: 00399 // 1. the CWriteKeyProcessor active object 00400 // 2. exampleScheduler 00401 CleanupStack::PopAndDestroy(2); 00402 } 00403
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.