examples/Base/IPC/Async/AcceptPrintInput/AcceptPrintInput.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 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 

Generated by  doxygen 1.6.2