Books
in black and white
Main menu
Share a book About us Home
Books
Biology Business Chemistry Computers Culture Economics Fiction Games Guide History Management Mathematical Medicine Mental Fitnes Physics Psychology Scince Sport Technics
Ads

Symbian os Expleined effective C++ programming for smartphones - Batchelor D.

Batchelor D. Symbian os Expleined effective C++ programming for smartphones - Wiley publishing , 2005. - 394 p.
ISBN 0-470-02130-6
Download (direct link): symbianosexpltivec++2005.pdf
Previous << 1 .. 59 60 61 62 63 64 < 65 > 66 67 68 69 70 71 .. 151 >> Next

Here's some example code for another background recalculation task class. In fact, I've slightly reworked the class from the example above to be driven by Cldle. You'll notice that there's no "boilerplate" active object code required, unlike the code in the CBackgroundRecalc class, because Cldle provides that functionality.
class CLongRunningCalculation : public CBase {
public:
static CLongRunningCalculation* NewLC(TRequestStatus& aStatus); protected:
static Tint TaskStep(TAny* aLongCalc); // Callback function protected:
void StartTask(); // Initialization before starting the task TBool DoTaskStep(); // Does a step of the task void EndTask(); // Destroys intermediate data
protected:
CLongRunningCalculation(TRequestStatus& aStatus); private:
TBool iMoreToDo; // Flag tracks the progress of the task // To notify the caller when the calc is complete TRequestStatus* iCallerStatus;
};
CLongRunningCalculation* CLongRunningCalculation::NewLC(TRequestStatus& aStatus)
{
CLongRunningCalculation* me = new (ELeave) CLongRunningCalculation(aStatus);
CleanupStack::PushL(me); // ... 2nd phase construction code omitted return (me);
}
CLongRunningCalculation::CLongRunningCalculation(TRequestStatusk aStatus)
: iCallerStatus(kaStatus) {}
TBool CLongRunningCalculation::DoTaskStep()
{// Does a short task step, returning ETrue if it has more to do ... // Omitted }
void CLongRunningCalculation::StartTask()
{// Prepares the task iMoreToDo = ETrue;
}
148
ACTIVE OBJECTS UNDER THE HOOD
// Error handling omitted
void CLongRunningCalculation::EndTask()
{// Performs cleanup when the task has completed ASSERT(!iMoreToDo);
User::RequestComplete(iCallerStatus, KErrNone);
}
Tint CLongRunningCalculation::TaskStep(TAny* aLongCalc)
{
ASSERT(aLongCalc);
CLongRunningCalculation* longCalc =
static_cast<CLongRunningCalculation*>(aLongCalc); if (!longCalc->iMoreToDo) longCalc->EndTask();
else
longCalc->iMoreToDo = longCalc->DoTaskStep();
return (longCalc->iMoreToDo);
}
Code which uses the idle object will look something like the following example, which creates the Cldle object and a CLongRunningCalculation object that drives the task:
Cldle* idle = CIdle::NewL(EPriorityIdle);
CleanupStack::PushL(idle);
// Create the object that runs the task, passing in a TRequestStatusk CLongRunningCalculation* longCalc =
CLongRunningCalculation::NewLC(iStatus);
TCallBack callback(CLongRunningCalculation::TaskStep, longCalc); idle->Start(callback);
... // Completion of the task completes iStatus
9.13 Class CPeriodic
CPeriodic is another useful CActive-derived class for running incremental task steps. It uses a timer object to generate regular timer events, handling a single step of the task for each timer event. CPeriodic is useful for performing regular task steps such as flashing a cursor or for controlling time-outs.
Like Cldle, CPeriodic is initialized with a priority value and the task is initiated by a call to Start(), passing settings for the timer as well as a callback to perform increments of the task. When the timer period elapses, the CPeriodic object generates an event that is detected by the active scheduler. When there are no active objects of higher priority requiring event handling, the active scheduler calls the RunL() event
COMMON MISTAKES
149
handler of the CPeriodic object, which in turn calls its task-processing callback function. Thus, the callback may not be as exactly regular as the periodic value passed to the Start() request. If the timer completes but other, higher-priority, active objects have completed events, they are processed first. Alternatively, the RunL() method of another active object may be running when the timer elapses and a running active object cannot be pre-empted even if it has a lower priority than the CPeriodic object.
The response of signal and callback processing can be improved by ensuring that all active objects in the thread perform short, efficient RunL() methods and that the CPeriodic object has a higher priority than other active objects.
9.14 Common Mistakes
I've described the dos and don'ts of active objects fairly comprehensively in this chapter and the previous one. The most commonly encountered problem when writing active object code is the infamous "stray signal" panic (E32USER-CBASE 46), which occurs when the active scheduler receives a completion event but cannot find an active object to handle it (i.e. one which is currently active and has a completed iStatus result, indicated by a value other than KRequestPending). Stray signals can arise for the following reasons:
• CActiveScheduler::Add() was not called when the active object was constructed
• SetActive() was not called following the submission of a request to the asynchronous service provider
• the asynchronous service provider completed the TRequestStatus of an active object more than once - either because of a programming error in the asynchronous service provider (for example, when an already-completed request is cancelled) or because more than one request was submitted simultaneously on the same active object.
Previous << 1 .. 59 60 61 62 63 64 < 65 > 66 67 68 69 70 71 .. 151 >> Next