examples/Base/IPC/Async/AcceptPrintInput/AcceptPrintInput.cpp

00001 /*
00002 Copyright (c) 2000-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions are met:
00006 
00007 * Redistributions of source code must retain the above copyright notice, this
00008   list of conditions and the following disclaimer.
00009 * Redistributions in binary form must reproduce the above copyright notice,
00010   this list of conditions and the following disclaimer in the documentation
00011   and/or other materials provided with the distribution.
00012 * Neither the name of Nokia Corporation nor the names of its contributors
00013   may be used to endorse or promote products derived from this software
00014   without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027 Description: 
00028 Asynchronous keyboard processing with messenger program.
00029 A single CWriteKeyProcessor active object (derived from 
00030 class CActiveConsole) which accepts and prints keyboard
00031 input to a console.
00032 */
00033 
00034 
00035 #include "CommonFramework.h"
00036 
00037 // panics
00038 enum
00039         {
00040         EPanicAlreadyActive=1000,
00041         };
00042 
00044 //
00045 // -----> CTimedMessenger (definition)
00046 //
00048 class CTimedMessenger : public CTimer
00049         {
00050 public:
00051           // Construction
00052         CTimedMessenger();
00053       // Destruction
00054         ~CTimedMessenger();
00055 
00056 public:
00057           // Static construction
00058         static CTimedMessenger* NewLC(const TDesC& aGreeting,
00059                                           TInt aTicksRequested,
00060                                                                   TInt aTicksInterval
00061                                                                  );
00062         static CTimedMessenger* NewL(const TDesC& aGreeting,
00063                                          TInt aTicksRequested,
00064                                                                  TInt aTicksInterval
00065                                                                 );
00066 
00067 public:
00068           // Second phase construction
00069         void ConstructL(const TDesC& aGreeting,
00070                             TInt aTicksRequested,
00071                                         TInt aTicksInterval
00072                                    );
00073 
00074           // issue request
00075         void IssueRequest(); 
00076 
00077           // Cancel request
00078           // Defined as pure virtual by CActive;
00079           // implementation provided by this class.
00080         void DoCancel();
00081 
00082           // service completed request.
00083           // Defined as pure virtual by CActive;
00084           // implementation provided by this class.
00085         void RunL();
00086 
00087 public:
00088           // data members defined by this class
00089         TBufC<20> iGreeting;   // Text of the greeting.
00090         TInt iTicksRequested;  // Total number of greetings CTimedMessenger
00091                                // will emit.
00092         TInt iTicksInterval;   // Number of seconds between each greeting.
00093         TInt iTicksDone;       // Number of greetings issued so far.
00094         };
00095 
00096 
00098 //
00099 // -----> CExampleScheduler (definition)
00100 //
00102 class CExampleScheduler : public CActiveScheduler
00103         {
00104 public:
00105         void Error (TInt aError) const;
00106         };
00107 
00108 
00110 //
00111 // -----> CActiveConsole (definition)
00112 //
00113 // An abstract class which provides the facility to issue key requests. 
00114 //
00116 class CActiveConsole : public CActive
00117         {
00118 public:
00119           // Construction
00120         CActiveConsole(CConsoleBase* aConsole);
00121         void ConstructL();
00122 
00123           // Destruction
00124         ~CActiveConsole();
00125 
00126           // Issue request
00127         void RequestCharacter();
00128         
00129           // Cancel request.
00130           // Defined as pure virtual by CActive;
00131           // implementation provided by this class.
00132         void DoCancel();
00133 
00134           // Service completed request.
00135           // Defined as pure virtual by CActive;
00136           // implementation provided by this class,
00137         void RunL();
00138 
00139           // Called from RunL() - an implementation must be provided
00140           // by derived classes to handle the completed request
00141         virtual void ProcessKeyPress(TChar aChar) = 0; 
00142           
00143 protected:
00144           // Data members defined by this class
00145         CConsoleBase* iConsole; // A console for reading from
00146         };
00147 
00148 
00150 //
00151 // -----> CWriteKeyProcessor (definition)
00152 //
00153 // This class is derived from CActiveConsole. 
00154 // Request handling: accepts input from the keyboard and outputs it 
00155 // to the console.
00156 //
00158 class CWriteKeyProcessor : public CActiveConsole
00159         {
00160 public:
00161           // Construction
00162         CWriteKeyProcessor(CConsoleBase* aConsole);
00163 
00164 public:
00165           // Static constuction
00166         static CWriteKeyProcessor *NewLC (CConsoleBase* aConsole);
00167         static CWriteKeyProcessor *NewL(CConsoleBase* aConsole);
00168 
00169 public:
00170           // Service request
00171         void ProcessKeyPress(TChar aChar);
00172         };
00173 
00174 
00176 //
00177 // -----> CTimedMessenger (implementation)
00178 //
00180 CTimedMessenger::CTimedMessenger()
00181         : CTimer(CActive::EPriorityStandard)
00182           // Construct standard-priority active object
00183         {};
00184 
00185 CTimedMessenger* CTimedMessenger::NewLC(const TDesC& aGreeting,
00186                                                                                 TInt aTicksRequested,
00187                                                                                 TInt aTicksInterval
00188                                                                            )
00189         {
00190         CTimedMessenger* self=new (ELeave) CTimedMessenger;
00191         CleanupStack::PushL(self);
00192         self->ConstructL(aGreeting,aTicksRequested,aTicksInterval);
00193         return self;
00194         }
00195 
00196 CTimedMessenger* CTimedMessenger::NewL(const TDesC& aGreeting,
00197                                                                    TInt aTicksRequested,
00198                                                                            TInt aTicksInterval
00199                                                                           )
00200         {
00201         CTimedMessenger* self = NewLC(aGreeting,aTicksRequested,aTicksInterval);
00202         CleanupStack::Pop();
00203         return self;
00204         }
00205 
00206 void CTimedMessenger::ConstructL(const TDesC& aGreeting,
00207                                                                  TInt aTicksRequested,
00208                                                                  TInt aTicksInterval
00209                                                                 )
00210         {
00211           // Base class second-phase construction.
00212         CTimer::ConstructL();
00213           // Set members from arguments
00214         iGreeting       = aGreeting;       // Set greeting text.
00215         iTicksRequested = aTicksRequested; // Ticks requested
00216         iTicksInterval  = aTicksInterval;  // Interval between ticks
00217           // Add active object to active scheduler
00218         CActiveScheduler::Add(this); 
00219         }
00220 
00221 
00222 CTimedMessenger::~CTimedMessenger()
00223         {
00224           // Make sure we're cancelled
00225         Cancel();
00226         }
00227 
00228 void CTimedMessenger::DoCancel()
00229         {
00230           // Base class
00231         CTimer::DoCancel(); 
00232           // Reset this variable - needed if the object is re-activated later
00233         iTicksDone = 0;
00234           // Tell user
00235         _LIT(KMsgCancelled,"Outstanding Messenger request cancelled\n");
00236         console->Printf(KMsgCancelled); 
00237         }
00238 
00239 void CTimedMessenger::IssueRequest()
00240         {
00241           // There should never be an outstanding request at this point.
00242         _LIT(KMsgAlreadyActive,"Is already Active");
00243         __ASSERT_ALWAYS(!IsActive(),User::Panic(KMsgAlreadyActive,EPanicAlreadyActive));
00244           // Request another wait
00245         CTimer::After( iTicksInterval*1000000);
00246         }
00247 
00248 void CTimedMessenger::RunL()
00249         {
00250           // Handle request completion
00251           // One more tick done
00252         iTicksDone++;
00253           // Print greeting
00254         _LIT(KFormatString1,"%S \n");
00255         console->Printf(KFormatString1,&iGreeting);
00256           // Issue new request, or stop if we have reached the limit
00257         if (iTicksDone  < iTicksRequested)
00258                 {
00259                 IssueRequest();
00260                 }
00261         else
00262                 {
00263                 _LIT(KMsgFinished,"Messenger finished \n");
00264                 console->Printf(KMsgFinished);
00265                   // Reset this variable - needed if the object is re-activated later
00266                 iTicksDone=0;
00267                   // Can now stop the active scheduler
00268                 CActiveScheduler::Stop();
00269                 }
00270         }
00271 
00272 
00274 //
00275 // -----> CExampleScheduler (implementation)
00276 //
00278 void CExampleScheduler::Error(TInt aError) const
00279         {
00280         _LIT(KMsgSchedErr,"CExampleScheduler-error");
00281         User::Panic(KMsgSchedErr,aError);
00282         }
00283 
00284 
00286 //
00287 // -----> CActiveConsole (implementation)
00288 //
00290 CActiveConsole::CActiveConsole( CConsoleBase* aConsole) 
00291         : CActive(CActive::EPriorityUserInput)
00292           // Construct high-priority active object
00293         {
00294         iConsole = aConsole;
00295         }
00296 
00297 void CActiveConsole::ConstructL()
00298         {
00299           // Add to active scheduler
00300         CActiveScheduler::Add(this);
00301         }
00302 
00303 CActiveConsole::~CActiveConsole()
00304         {
00305         // Make sure we're cancelled
00306         Cancel();
00307         }
00308 
00309 void  CActiveConsole::DoCancel()
00310         {
00311         iConsole->ReadCancel();
00312         }
00313 
00314 void  CActiveConsole::RunL()
00315         {
00316           // Handle completed request
00317         ProcessKeyPress(TChar(iConsole->KeyCode()));
00318         }
00319 
00320 void CActiveConsole::RequestCharacter()
00321         {
00322           // A request is issued to the CConsoleBase to accept a
00323           // character from the keyboard.
00324         iConsole->Read(iStatus); 
00325         SetActive();
00326         }
00327 
00328 
00330 //
00331 // -----> CWriteKeyProcessor (implementation)
00332 //
00334 CWriteKeyProcessor::CWriteKeyProcessor(CConsoleBase* aConsole)
00335         : CActiveConsole(aConsole)
00336           
00337         {};
00338 
00339 CWriteKeyProcessor* CWriteKeyProcessor::NewLC(CConsoleBase* aConsole)
00340         {
00341         CWriteKeyProcessor* self=new (ELeave) CWriteKeyProcessor(aConsole);
00342         CleanupStack::PushL(self);
00343         self->ConstructL();
00344         return self;
00345         }
00346 
00347 CWriteKeyProcessor* CWriteKeyProcessor::NewL(CConsoleBase* aConsole)
00348         {
00349         CWriteKeyProcessor* self=NewLC(aConsole);
00350         CleanupStack::Pop();
00351         return self;
00352         }
00353 
00354 void CWriteKeyProcessor::ProcessKeyPress(TChar aChar)
00355         {
00356           // "Esc" character prints a new line and stops the scheduler
00357         _LIT(KTextEsc,"\n");
00358         if (aChar == EKeyEscape)
00359                 {
00360                 iConsole->Printf(KTextEsc);
00361                 CActiveScheduler::Stop();
00362                 return;
00363                 }
00364 
00365           // "Enter" prints a new line character
00366           // An alphabetic or space is printed as a character;
00367           // anything else is printed as an integer.
00368         if (aChar == EKeyEnter)
00369                 iConsole->Printf(KTextEsc);
00370         else
00371                 {
00372                 _LIT(KFormatString2,"%c");
00373                 _LIT(KFormatString3,"%d");
00374                 if (aChar.IsAlphaDigit()|| aChar.IsSpace())
00375                         iConsole->Printf(KFormatString2,TUint(aChar));
00376                 else
00377                         iConsole->Printf(KFormatString3,TUint(aChar));
00378                 }
00379 
00380           // Issue another request 
00381         RequestCharacter();
00382         }
00383 
00384 
00386 //
00387 // Do the example
00388 //
00390 LOCAL_C 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 a CWriteKeyProcessor active object
00402         _LIT(KTitleMsg,"A single CWriteKeyProcessor active object.\nIt accepts and prints keyboard input to the console.\nPress ESC to end.\n\n");
00403         console->Printf(KTitleMsg);
00404         CWriteKeyProcessor* keyProcesser = CWriteKeyProcessor::NewLC(console);
00405 
00406           // Issue the first request
00407         keyProcesser->RequestCharacter();
00408 
00409           // Main part of program is a wait loop
00410           // This function completes when the scheduler stops
00411         CActiveScheduler::Start();
00412 
00413           // Remove from the cleanup stack and destroy:
00414           // 1. the CWriteKeyProcessor active object
00415           // 2. exampleScheduler
00416         CleanupStack::PopAndDestroy(2); 
00417         }
00418 

Generated by  doxygen 1.6.2