This document describes how to construct an active object to encapsulate a service provider.
The following examples outline the practical framework required when implementing an active object
The following example code demonstrates how to construct the framework for a simple active object which encapsulates a service-provider.
First define and implement the service-provider class. The following code shows the typical features:
class CExampleServiceProvider { public: ... void RequestTheService(TRequestStatus& aStatus); void CancelTheRequest(); private: TInt iResult ; };
Now define and implement the active object which wraps around the service provider. The following code shows the main features of an active object class.
Provide a constructor.
Provide a RunL()
function
to handle the completion of an asynchronous request.
Provide a DoCancel()
function
to implement a cancellation request.
Provide a RunError()
function
to implement recovery and cleanup if the RunL()
function
leaves. Note that this is not available in v5.
class CExampleActiveObject : public CActive; { public: CExampleActiveObject(CExampleServiceProvider* aServiceProvider); ~CExampleActiveObject; void IssueRequest(); private: void DoCancel(); void RunL(); TInt RunError(TInt aError); private: CExampleServiceProvider* iServiceProvider ; };
When the class codes a DoCancel()
then
the destructor must call the Cancel()
member function of
the active object.
The following code shows the typical elements required when constructing an active object.
CExampleActiveObject::CExampleActiveObject(CExampleServiceProvider* aServiceProvider) : CActive(EPriorityStandard) { iServiceProvider = aServiceProvider; // Store pointer to service provider CActiveScheduler::Add(this) ; // add to active scheduler }
Set the active object’s
priority using one of the CActive::Tpriority
enumeration
values.
Retain a handle to the required service provider, so that request functions can pass on a request to the asynchronous service provider.
Use add()
to
add the active object to the active scheduler, in order to ensure that its
requests are handled.
In practice there are many variations on this basic construction theme.
Most active objects
set the priority within the constructor and this is almost always the EPriorityStandard
or
zero value. In some cases, the choice of priority value is decided by the
caller or by the constructor of a class further derived from this one.
In many situations,
the service provider is constructed by the active object itself, instead of
being passed in. Often this is done as part of a two stage construction process.
For example, the CTimer
active object has a simple constructor
and a function ConstructL()
which completes the construction
of the object:
CTimer::CTimer(TInt aPriority) : CActive(aPriority) { }
void CTimer::ConstructL() { TInt r=iTimer.CreateLocal(); if (r!=KErrNone) { User::Leave(r); } }