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

Generated by  doxygen 1.6.2