examples/Base/IPC/Async/AcceptInput2/AcceptInput2.cpp

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 CKeyMessengerProcessor active object (derived from
00016 // class CActiveConsole) which accepts input from keyboard, but does not
00017 // print it.
00018 // This object contains a CMessageTimer object which it activates if the
00019 // user inputs the character "m" and cancelled if the user inputs "c" .
00020 // All keyboard requests are issued from the active scheduler.
00021 //
00022 
00023 
00024 #include "CommonFramework.h"
00025 
00026 //
00027 // Common literal text
00028 //
00029 _LIT(KTxtNewLine,"\n");
00030 
00031 
00032 // panics
00033 enum
00034         {
00035         EPanicAlreadyActive=1000,
00036         };
00037 
00038 
00040 //
00041 // -----> CTimedMessenger (definition)
00042 //
00044 class CTimedMessenger : public CTimer
00045         {
00046 public:
00047           // Construction
00048         CTimedMessenger();
00049       // Destruction
00050         ~CTimedMessenger();
00051 
00052 public:
00053           // Static construction
00054         static CTimedMessenger* NewLC(const TDesC& aGreeting,
00055                                           TInt aTicksRequested,
00056                                                                   TInt aTicksInterval
00057                                                                  );
00058         static CTimedMessenger* NewL(const TDesC& aGreeting,
00059                                          TInt aTicksRequested,
00060                                                                  TInt aTicksInterval
00061                                                                 );
00062 
00063 public:
00064           // Second phase construction
00065         void ConstructL(const TDesC& aGreeting,
00066                             TInt aTicksRequested,
00067                                         TInt aTicksInterval
00068                                    );
00069 
00070           // issue request
00071         void IssueRequest(); 
00072 
00073           // Cancel request
00074           // Defined as pure virtual by CActive;
00075           // implementation provided by this class.
00076         void DoCancel();
00077 
00078           // service completed request.
00079           // Defined as pure virtual by CActive;
00080           // implementation provided by this class.
00081         void RunL();
00082 
00083 public:
00084           // data members defined by this class
00085         TBufC<20> iGreeting;   // Text of the greeting.
00086         TInt iTicksRequested;  // Total number of greetings CTimedMessenger
00087                                // will emit.
00088         TInt iTicksInterval;   // Number of seconds between each greeting.
00089         TInt iTicksDone;       // Number of greetings issued so far.
00090         };
00091 
00092 
00094 //
00095 // -----> CExampleScheduler (definition)
00096 //
00098 class CActiveConsole;
00099 class CExampleScheduler : public CActiveScheduler
00100         {
00101 public:
00102         void Error (TInt aError) const;
00103         void WaitForAnyRequest();
00104         void SetActiveObject(CActiveConsole* aActiveConsole);
00105 private:
00106           // data members defined for this class
00107         CActiveConsole* iActiveConsole;
00108         };
00109 
00110 
00112 //
00113 // -----> CActiveConsole (definition)
00114 //
00115 // An abstract class which provides the facility to issue key requests. 
00116 //
00118 class CActiveConsole : public CActive
00119         {
00120 public:
00121           // Construction
00122         CActiveConsole(CConsoleBase* aConsole);
00123         void ConstructL();
00124 
00125           // Destruction
00126         ~CActiveConsole();
00127 
00128           // Issue request
00129         void RequestCharacter();
00130         
00131           // Cancel request.
00132           // Defined as pure virtual by CActive;
00133           // implementation provided by this class.
00134         void DoCancel();
00135 
00136           // Service completed request.
00137           // Defined as pure virtual by CActive;
00138           // implementation provided by this class,
00139         void RunL();
00140 
00141           // Called from RunL() - an implementation must be provided
00142           // by derived classes to handle the completed request
00143         virtual void ProcessKeyPress(TChar aChar) = 0; 
00144           
00145 protected:
00146           // Data members defined by this class
00147         CConsoleBase* iConsole; // A console for reading from
00148         };
00149 
00150 
00152 //
00153 // -----> CWriteKeyProcessor (definition)
00154 //
00155 // This class is derived from CActiveConsole. 
00156 // Request handling: accepts input from the keyboard and outputs it 
00157 // to the console.
00158 //
00160 class CWriteKeyProcessor : public CActiveConsole
00161         {
00162 public:
00163           // Construction
00164         CWriteKeyProcessor(CConsoleBase* aConsole);
00165 
00166 public:
00167           // Static constuction
00168         static CWriteKeyProcessor *NewLC (CConsoleBase* aConsole);
00169         static CWriteKeyProcessor *NewL(CConsoleBase* aConsole);
00170 
00171           // Service request
00172         void ProcessKeyPress(TChar aChar);
00173         };
00174 
00175 
00177 //
00178 // -----> CTimedMessenger (implementation)
00179 //
00181 CTimedMessenger::CTimedMessenger()
00182         : CTimer(CActive::EPriorityStandard)
00183           // Construct standard-priority active object
00184         {};
00185 
00186 CTimedMessenger* CTimedMessenger::NewLC(const TDesC& aGreeting,
00187                                                                                 TInt aTicksRequested,
00188                                                                                 TInt aTicksInterval
00189                                                                            )
00190         {
00191         CTimedMessenger* self=new (ELeave) CTimedMessenger;
00192         CleanupStack::PushL(self);
00193         self->ConstructL(aGreeting,aTicksRequested,aTicksInterval);
00194         return self;
00195         }
00196 
00197 CTimedMessenger* CTimedMessenger::NewL(const TDesC& aGreeting,
00198                                                                    TInt aTicksRequested,
00199                                                                            TInt aTicksInterval
00200                                                                           )
00201         {
00202         CTimedMessenger* self = NewLC(aGreeting,aTicksRequested,aTicksInterval);
00203         CleanupStack::Pop();
00204         return self;
00205         }
00206 
00207 void CTimedMessenger::ConstructL(const TDesC& aGreeting,
00208                                                                  TInt aTicksRequested,
00209                                                                  TInt aTicksInterval
00210                                                                 )
00211         {
00212           // Base class second-phase construction.
00213         CTimer::ConstructL();
00214           // Set members from arguments
00215         iGreeting       = aGreeting;       // Set greeting text.
00216         iTicksRequested = aTicksRequested; // Ticks requested
00217         iTicksInterval  = aTicksInterval;  // Interval between ticks
00218           // Add active object to active scheduler
00219         CActiveScheduler::Add(this); 
00220         }
00221 
00222 
00223 CTimedMessenger::~CTimedMessenger()
00224         {
00225           // Make sure we're cancelled
00226         Cancel();
00227         }
00228 
00229 void CTimedMessenger::DoCancel()
00230         {
00231           // Base class
00232         CTimer::DoCancel(); 
00233           // Reset this variable - needed if the object is re-activated later
00234         iTicksDone = 0;
00235           // Tell user
00236         _LIT(KTxtOutMessReqCancelled,"Outstanding Messenger request cancelled\n");
00237         console->Printf(KTxtOutMessReqCancelled); 
00238         }
00239 
00240 void CTimedMessenger::IssueRequest()
00241         {
00242           // There should never be an outstanding request at this point.
00243         _LIT(KTxtIsAlreadyActive,"Is already Active");
00244         __ASSERT_ALWAYS(!IsActive(),User::Panic(KTxtIsAlreadyActive,EPanicAlreadyActive));
00245           // Request another wait
00246         CTimer::After( iTicksInterval*1000000);
00247         }
00248 
00249 void CTimedMessenger::RunL()
00250         {
00251           // Handle request completion
00252           // One more tick done
00253         iTicksDone++;
00254           // Print greeting
00255         _LIT(KFormat1,"%S \n");
00256         console->Printf(KFormat1,&iGreeting);
00257           // Issue new request, or stop if we have reached the limit
00258         if (iTicksDone  < iTicksRequested)
00259                 {
00260                 IssueRequest();
00261                 }
00262         else
00263                 {
00264                 _LIT(KTxtMessengerFinished,"Messenger finished \n");
00265                 console->Printf(KTxtMessengerFinished);
00266                   // Reset this variable - needed if the object is re-activated later
00267                 iTicksDone=0;
00268                   // Can now stop the active scheduler
00269                 CActiveScheduler::Stop();
00270                 }
00271         }
00272 
00273 
00275 //
00276 // -----> CExampleScheduler (implementation)
00277 //
00279 void CExampleScheduler::Error(TInt aError) const
00280         {
00281         _LIT(KTxtSchedulerError,"CExampleScheduler - error");
00282         User::Panic(KTxtSchedulerError,aError);
00283         }
00284 
00285 
00286 void CExampleScheduler::WaitForAnyRequest()
00287         {
00288         if (!(iActiveConsole->IsActive()))
00289                 iActiveConsole->RequestCharacter();     
00290         CActiveScheduler::WaitForAnyRequest();
00291         }
00292 
00293 void CExampleScheduler::SetActiveObject(CActiveConsole* aActiveConsole)
00294         {
00295         iActiveConsole = aActiveConsole;
00296         }
00297 
00298 
00300 //
00301 // -----> CActiveConsole (implementation)
00302 //
00304 CActiveConsole::CActiveConsole( CConsoleBase* aConsole) 
00305         : CActive(CActive::EPriorityUserInput)
00306           // Construct high-priority active object
00307         {
00308         iConsole = aConsole;
00309         }
00310 
00311 void CActiveConsole::ConstructL()
00312         {
00313           // Add to active scheduler
00314         CActiveScheduler::Add(this);
00315         }
00316 
00317 CActiveConsole::~CActiveConsole()
00318         {
00319         // Make sure we're cancelled
00320         Cancel();
00321         }
00322 
00323 void  CActiveConsole::DoCancel()
00324         {
00325         iConsole->ReadCancel();
00326         }
00327 
00328 void  CActiveConsole::RunL()
00329         {
00330           // Handle completed request
00331         ProcessKeyPress(TChar(iConsole->KeyCode()));
00332         }
00333 
00334 void CActiveConsole::RequestCharacter()
00335         {
00336           // A request is issued to the CConsoleBase to accept a
00337           // character from the keyboard.
00338         iConsole->Read(iStatus); 
00339         SetActive();
00340         }
00341 
00342 
00344 //
00345 // -----> CWriteKeyProcessor (implementation)
00346 //
00348 CWriteKeyProcessor::CWriteKeyProcessor(CConsoleBase* aConsole)
00349         : CActiveConsole(aConsole)
00350           // Construct zero-priority active object
00351         {};
00352 
00353 CWriteKeyProcessor* CWriteKeyProcessor::NewLC(CConsoleBase* aConsole)
00354         {
00355         CWriteKeyProcessor* self=new (ELeave) CWriteKeyProcessor(aConsole);
00356         CleanupStack::PushL(self);
00357         self->ConstructL();
00358         return self;
00359         }
00360 
00361 CWriteKeyProcessor* CWriteKeyProcessor::NewL(CConsoleBase* aConsole)
00362         {
00363         CWriteKeyProcessor* self=NewLC(aConsole);
00364         CleanupStack::Pop();
00365         return self;
00366         }
00367 
00368 void CWriteKeyProcessor::ProcessKeyPress(TChar aChar)
00369         {
00370           // "Esc" character prints a new line and stops the scheduler
00371         if (aChar == EKeyEscape)
00372                 {
00373                 iConsole->Printf(KTxtNewLine);
00374                 CActiveScheduler::Stop();
00375                 return;
00376                 }
00377 
00378           // "Enter" prints a new line character
00379           // An alphabetic or space is printed as a character;
00380           // anything else is printed as an integer.
00381         if (aChar == EKeyEnter)
00382                 iConsole->Printf(KTxtNewLine);
00383         else
00384                 {
00385                 _LIT(KFormat2,"%c");
00386                 _LIT(KFormat3,"%d");
00387                 if (aChar.IsAlphaDigit()|| aChar.IsSpace())
00388                         
00389                         iConsole->Printf(KFormat2,TUint(aChar));
00390                 else
00391                         iConsole->Printf(KFormat3,TUint(aChar));
00392                 }
00393 
00394           // Issue another request 
00395         RequestCharacter();
00396         }
00397 
00398 
00400 //
00401 // -----> CMessageKeyProcessor (definition)
00402 //
00403 // This class is derived from CActiveConsole. 
00404 // Request handling:
00405 //   if key is "m", a message timer request is issued.
00406 //   if key is "c", any outstanding message timer request is cancelled.
00407 //   If key is ESC, the wait loop is terminated.
00408 //
00410 class CMessageKeyProcessor : public CActiveConsole
00411         {
00412 public:
00413           // Construction
00414         CMessageKeyProcessor(CConsoleBase* aConsole, CTimedMessenger* iMessenger);
00415         void ConstructL();
00416 
00417 public:
00418           // Static construction
00419         static CMessageKeyProcessor* NewLC(CConsoleBase* aConsole,
00420                                                CTimedMessenger* iMessenger
00421                                                                           );
00422         static CMessageKeyProcessor* NewL(CConsoleBase* aConsole,
00423                                               CTimedMessenger* iMessenger
00424                                                                          );
00425 
00426 public:
00427           // service request
00428         void ProcessKeyPress(TChar aChar);
00429 
00430 private:
00431           // Data members defined by this class
00432         CTimedMessenger* iMessenger;
00433         };
00434 
00436 //
00437 // -----> CMessageKeyProcessor (implementation)
00438 //
00440 CMessageKeyProcessor::CMessageKeyProcessor(CConsoleBase* aConsole,
00441                                                                                    CTimedMessenger* aMessenger
00442                                                                                   )
00443         : CActiveConsole(aConsole)
00444           // construct zero-priority active object
00445         {
00446         iMessenger = aMessenger;
00447         } 
00448 
00449 CMessageKeyProcessor* CMessageKeyProcessor::NewLC(CConsoleBase* aConsole,
00450                                                                                                   CTimedMessenger* aMessenger
00451                                                                                                  )
00452         {
00453         CMessageKeyProcessor* self=new (ELeave) CMessageKeyProcessor(aConsole,
00454                                                                          aMessenger
00455                                                                                                                                 );
00456         CleanupStack::PushL(self);
00457         self->ConstructL();
00458         return self;
00459         }
00460 
00461 CMessageKeyProcessor* CMessageKeyProcessor::NewL(CConsoleBase* aConsole,
00462                                                                                                  CTimedMessenger* aMessenger
00463                                                                                                 )
00464         {
00465         CMessageKeyProcessor* self = NewLC(aConsole, aMessenger);
00466         CleanupStack::Pop();
00467         return self;
00468         }
00469 
00470 void CMessageKeyProcessor::ConstructL()
00471         {
00472           // Add to active scheduler
00473         CActiveScheduler::Add(this);
00474           // Make this the active object
00475         ((CExampleScheduler*)(CActiveScheduler::Current()))->SetActiveObject(this);
00476         }
00477 
00478 void CMessageKeyProcessor::ProcessKeyPress(TChar aChar)
00479         {
00480           // if key is ESC 
00481           //   cancel any outstanding request
00482           //   stop the scheduler
00483         if (aChar == EKeyEscape)
00484                 {
00485                 iMessenger->Cancel();
00486                 CActiveScheduler::Stop();
00487                 return;
00488                 }
00489 
00490           // If key is "m" or "M"
00491           //   cancel any outstanding request
00492           //   reset the tick counter
00493           //   issue a message timer request.
00494         if (aChar == 'm' || aChar == 'M') 
00495                 {
00496                 _LIT(KTxtStartingMess,"Starting Messenger....  \n");
00497                 iConsole->Printf(KTxtStartingMess);
00498                 iMessenger->Cancel();
00499                 iMessenger ->IssueRequest();
00500                 }
00501 
00502       // If key is "c" or "C" 
00503           //    cancel any outstanding request  
00504         if (aChar == 'c' || aChar == 'C')
00505                 iMessenger->Cancel();
00506         }
00507 
00508 
00510 //
00511 // Do the example
00512 //
00514 LOCAL_C void doExampleL()
00515     {
00516           // Construct and install the active scheduler
00517         CExampleScheduler*  exampleScheduler = new (ELeave) CExampleScheduler;
00518 
00519           // Push onto the cleanup stack
00520         CleanupStack::PushL(exampleScheduler);
00521          
00522           // Install as the active scheduler
00523         CActiveScheduler::Install(exampleScheduler);
00524 
00525           // Create a CTimedMessenger active object which will emit
00526           // 3 messages with an interval of 2 seconds between messages.
00527         _LIT(KTxtGoodMorning,"Good Morning!");
00528         CTimedMessenger* messenger = CTimedMessenger::NewLC(KTxtGoodMorning, 3, 2);
00529 
00530           // Create aCMessageKeyProcessor active object.
00531         _LIT(KTxtMain1,"A single CKeyMessengerProcessor active object ");
00532         _LIT(KTxtMain2,"Active scheduler renews request.\n");
00533         _LIT(KTxtMain3,"Press 'm' to activate messenger; Press 'c' to cancel it.\n");
00534         _LIT(KTxtMain4,"Press ESC to end.\n\n");
00535         console->Printf(KTxtMain1);
00536         console->Printf(KTxtMain2);
00537         console->Printf(KTxtMain3);
00538         console->Printf(KTxtMain4);
00539         CMessageKeyProcessor::NewLC(console,messenger);
00540                         
00541           // Main part of the program is a wait loop
00542         CActiveScheduler::Start();
00543 
00544         // Remove from the cleanup stack and destroy:
00545         // 1. the CTimedMessenger active object
00546         // 2. the CMessageKeyProcessor active object.
00547         // 3. exampleScheduler
00548         CleanupStack::PopAndDestroy(3); 
00549         }
00550 
00551 
00552 

Generated by  doxygen 1.6.2