diff -r 51a74ef9ed63 -r ae94777fff8f Symbian3/SDK/Source/GUID-2161BD64-889B-5EAB-B023-1162FE9619DB.dita --- a/Symbian3/SDK/Source/GUID-2161BD64-889B-5EAB-B023-1162FE9619DB.dita Wed Mar 31 11:11:55 2010 +0100 +++ b/Symbian3/SDK/Source/GUID-2161BD64-889B-5EAB-B023-1162FE9619DB.dita Fri Jun 11 12:39:03 2010 +0100 @@ -1,160 +1,160 @@ - - - - - -How -to use multiple active objectsThis document illustrates how to use one active object to control -another. -

The following example code fragments show how to construct a program with -two active objects, where one controls the initiation and cancellation of -the other.

-

In these examples:

-

CActiveConsole is an active object and contains a pointer -to a CConsoleBase object which is a service provider. Through -this service provider, the active object provides the facility to request -a character from the keyboard.

-

RunL() delegates the handling of completed requests to -the pure virtual function ProcessKeyPress(), which must be -provided by a derived class.

-

CMessageKeyProcessor is further derived from CActiveConsole and -contains a pointer to another active object CExampleActiveObject, -which requires input from the keyboard.

-

Depending on the input character, the CMessageKeyProcessor active -object does one of the following:

- -

The implementation of the CExampleActiveObject active -object is not relevant to the example and is not shown.

-

The following diagram shows the relationship between the classes.

- - - -
Encapsulating the service provider

The class CActiveConsole encapsulates -the provision of basic keyboard services. Its iConsole data -member is a pointer to the service provider, the CConsoleBase object.

The -active object class is defined as:

class CActiveConsole : public CActive - { -public: - CActiveConsole(CConsoleBase* aConsole); - void ConstructL(); - ~CActiveConsole(); - void RequestCharacter(); - void RunL(); - void DoCancel(); - virtual void ProcessKeyPress(TChar aChar)=0; -protected: - CConsoleBase* iConsole; - };

The class constructor takes a pointer to a CConsoleBase object -as its single argument and initializes its iConsole data -member to this value:

CActiveConsole::CActiveConsole(CConsoleBase* aConsole) - : iConsole(aConsole) - {}

The ConstructL() function adds the -active object to the active scheduler:

void CActiveConsole::ConstructL() - { - CActiveScheduler::Add(this); - }

The destructor cancels any outstanding request before -destroying the active object:

CActiveConsole::~CActiveConsole() - { - Cancel(); - }

DoCancel() is implemented to cancel -the request to iConsole.

The RequestCharacter() function -makes a request for a key press to the service provider by calling iConsole->Read(iStatus) and -setting the active request flag:

void CActiveConsole::RequestCharacter() - { - iConsole->Read(iStatus); - SetActive(); - }

The RunL() function makes a call to -the ProcessKeyPress() function. This is a pure virtual function -that derived classes must implement to handle the key press and to reissue -the request:

void CActiveConsole::RunL() - { - ProcessKeyPress(TChar(iConsole->KeyCode())); - }
-
Further deriving from the active object

The class CMessageKeyProcessor is -a concrete class, derived from CActiveConsole. It provides -an implementation for theProcessKeyPress() function and can -issue or cancel requests to aCExampleActiveObject active -object.

This active object class is defined as:

class CMessageKeyProcessor : public CActiveConsole - { -public: - ... - CMessageKeyProcessor(CConsoleBase* aConsole, CExampleActiveObject* iExampleObject); - void ProcessKeyPress(TChar aChar); -private: - CExampleActiveObject* iExampleObject; - };

Notes

    -
  • The first constructor -parameter specifies a CConsoleBase which will be used to -provide asynchronous keyboard input.

  • -
  • the second constructor -parameter specifies a CExampleActiveObject which will be -controlled by this CMessageKeyProcessor.

  • -

The behaviour of the ProcessKeyPress() function -depends on the key code value:

void CMessageKeyProcessor::ProcessKeyPress(TChar aChar) - { - if (aChar == 'm' || aChar == 'M') - { - iExampleObject->Cancel(); - iExampleObject->IssueRequest(); - } - if (aChar == 'c' || aChar == 'C') - { - iExampleObject->Cancel(); - } - if (aChar != EKeyEscape) - { - RequestCharacter(); - } - else - { - iExampleObject->Cancel(); - CActiveScheduler::Stop(); - } - }
-
Enhanced framework

In the code fragment below, -an active scheduler is created to which both a CMessageKeyProcessor active -object and aCExampleActiveObject active object are added:

LOCAL_C void doExampleL() - { - CActiveScheduler* exampleScheduler=new (ELeave) CActiveScheduler; - CleanupStack::PushL(exampleScheduler); - CActiveScheduler::Install(exampleScheduler); - - CExampleActiveObject* iExampleObject = - CExampleActiveObject::NewLC(); - CMessageKeyProcessor* keyProcessor= - CMessageKeyProcessor::NewLC(console, iExampleObject); - - keyProcessor->RequestCharacter(); - CActiveScheduler::Start(); - CleanupStack::PopAndDestroy(3); - }

Notes

    -
  • An instance of the active -scheduler, exampleScheduler is pushed onto the cleanup stack -and installed as the current active scheduler.

  • -
  • An instance of the CExampleActiveObject active -object is created.

  • -
  • An instance of the CMessageKeyProcessor active -object is created and this is in control.

  • -
  • keyProcessor->RequestCharacter() issues -a request for keyboard input.

  • -
  • CActiveScheduler::Start() starts -the active scheduler. At least one outstanding request is necessary before -the wait loop is started, otherwise the thread hangs. All further request -issuing and servicing occurs within this function. The wait loop continues -until one of the active objects’ RunL() callsCActiveScheduler::Stop().

  • -
  • The active objects and -the active scheduler are popped from the cleanup stack and destroyed.

  • -
+ + + + + +How +to use multiple active objectsThis document illustrates how to use one active object to control +another. +

The following example code fragments show how to construct a program with +two active objects, where one controls the initiation and cancellation of +the other.

+

In these examples:

+

CActiveConsole is an active object and contains a pointer +to a CConsoleBase object which is a service provider. Through +this service provider, the active object provides the facility to request +a character from the keyboard.

+

RunL() delegates the handling of completed requests to +the pure virtual function ProcessKeyPress(), which must be +provided by a derived class.

+

CMessageKeyProcessor is further derived from CActiveConsole and +contains a pointer to another active object CExampleActiveObject, +which requires input from the keyboard.

+

Depending on the input character, the CMessageKeyProcessor active +object does one of the following:

+
    +
  • issues a request to +the CExampleActiveObject active object

  • +
  • cancels any outstanding +request to the CExampleActiveObject active object

  • +
  • does nothing

  • +
+

The implementation of the CExampleActiveObject active +object is not relevant to the example and is not shown.

+

The following diagram shows the relationship between the classes.

+ + + +
Encapsulating the service provider

The class CActiveConsole encapsulates +the provision of basic keyboard services. Its iConsole data +member is a pointer to the service provider, the CConsoleBase object.

The +active object class is defined as:

class CActiveConsole : public CActive + { +public: + CActiveConsole(CConsoleBase* aConsole); + void ConstructL(); + ~CActiveConsole(); + void RequestCharacter(); + void RunL(); + void DoCancel(); + virtual void ProcessKeyPress(TChar aChar)=0; +protected: + CConsoleBase* iConsole; + };

The class constructor takes a pointer to a CConsoleBase object +as its single argument and initializes its iConsole data +member to this value:

CActiveConsole::CActiveConsole(CConsoleBase* aConsole) + : iConsole(aConsole) + {}

The ConstructL() function adds the +active object to the active scheduler:

void CActiveConsole::ConstructL() + { + CActiveScheduler::Add(this); + }

The destructor cancels any outstanding request before +destroying the active object:

CActiveConsole::~CActiveConsole() + { + Cancel(); + }

DoCancel() is implemented to cancel +the request to iConsole.

The RequestCharacter() function +makes a request for a key press to the service provider by calling iConsole->Read(iStatus) and +setting the active request flag:

void CActiveConsole::RequestCharacter() + { + iConsole->Read(iStatus); + SetActive(); + }

The RunL() function makes a call to +the ProcessKeyPress() function. This is a pure virtual function +that derived classes must implement to handle the key press and to reissue +the request:

void CActiveConsole::RunL() + { + ProcessKeyPress(TChar(iConsole->KeyCode())); + }
+
Further deriving from the active object

The class CMessageKeyProcessor is +a concrete class, derived from CActiveConsole. It provides +an implementation for theProcessKeyPress() function and can +issue or cancel requests to aCExampleActiveObject active +object.

This active object class is defined as:

class CMessageKeyProcessor : public CActiveConsole + { +public: + ... + CMessageKeyProcessor(CConsoleBase* aConsole, CExampleActiveObject* iExampleObject); + void ProcessKeyPress(TChar aChar); +private: + CExampleActiveObject* iExampleObject; + };

Notes

    +
  • The first constructor +parameter specifies a CConsoleBase which will be used to +provide asynchronous keyboard input.

  • +
  • the second constructor +parameter specifies a CExampleActiveObject which will be +controlled by this CMessageKeyProcessor.

  • +

The behaviour of the ProcessKeyPress() function +depends on the key code value:

void CMessageKeyProcessor::ProcessKeyPress(TChar aChar) + { + if (aChar == 'm' || aChar == 'M') + { + iExampleObject->Cancel(); + iExampleObject->IssueRequest(); + } + if (aChar == 'c' || aChar == 'C') + { + iExampleObject->Cancel(); + } + if (aChar != EKeyEscape) + { + RequestCharacter(); + } + else + { + iExampleObject->Cancel(); + CActiveScheduler::Stop(); + } + }
+
Enhanced framework

In the code fragment below, +an active scheduler is created to which both a CMessageKeyProcessor active +object and aCExampleActiveObject active object are added:

LOCAL_C void doExampleL() + { + CActiveScheduler* exampleScheduler=new (ELeave) CActiveScheduler; + CleanupStack::PushL(exampleScheduler); + CActiveScheduler::Install(exampleScheduler); + + CExampleActiveObject* iExampleObject = + CExampleActiveObject::NewLC(); + CMessageKeyProcessor* keyProcessor= + CMessageKeyProcessor::NewLC(console, iExampleObject); + + keyProcessor->RequestCharacter(); + CActiveScheduler::Start(); + CleanupStack::PopAndDestroy(3); + }

Notes

    +
  • An instance of the active +scheduler, exampleScheduler is pushed onto the cleanup stack +and installed as the current active scheduler.

  • +
  • An instance of the CExampleActiveObject active +object is created.

  • +
  • An instance of the CMessageKeyProcessor active +object is created and this is in control.

  • +
  • keyProcessor->RequestCharacter() issues +a request for keyboard input.

  • +
  • CActiveScheduler::Start() starts +the active scheduler. At least one outstanding request is necessary before +the wait loop is started, otherwise the thread hangs. All further request +issuing and servicing occurs within this function. The wait loop continues +until one of the active objects’ RunL() callsCActiveScheduler::Stop().

  • +
  • The active objects and +the active scheduler are popped from the cleanup stack and destroyed.

  • +
\ No newline at end of file