diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_periodic_8cpp-source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_periodic_8cpp-source.html Tue Mar 30 11:56:28 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,414 +0,0 @@ - - -TB10.1 Example Applications: examples/Base/Timers/Periodic/Periodic.cpp Source File - - - - -

examples/Base/Timers/Periodic/Periodic.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 // Shows difference between CPeriodic and CHeartBeat
-00015 // CPeriodic uses repeated RTimer::After() requests to get
-00016 // a periodic tick - simple, but the time the tick is serviced lags
-00017 // increasingly.
-00018 // As a nuance of CPeriodic, it takes a TCallBack to service
-00019 // its requests.
-00020 // CHeartbeat uses repeated RTimer::Lock() requests: its
-00021 // requests complete in synchronization with the beating
-00022 // of the system clock.
-00023 // As a nuance of CHeartbeat, it takes an MBeating* mixin:
-00024 // the MBeating's Beat() function is called when completion
-00025 // occurs in sync, and Synchronize() is called when
-00026 // synchronization has been lost.
-00027 //
-00028 
-00029 
-00030 
-00031 // standard example header
-00032 #include "CommonFramework.h"
-00033 
-00034 // beginning of real example
-00035 
-00036 #include <e32math.h>
-00037 
-00038 void RandomDelay(TInt64& aSeed, TInt /*aTimerNumber*/)
-00039         {
-00040         // initialize seed first time through
-00041         if (aSeed==0)
-00042                 {
-00043                 TTime time;
-00044                 time.HomeTime();
-00045                 aSeed=time.Int64();
-00046                 }
-00047         // ok, here we go
-00048         TReal randomZeroToOne;
-00049         randomZeroToOne = Math::FRand(aSeed);
-00050         TReal realDelay;
-00051         realDelay = randomZeroToOne * randomZeroToOne * 2000000;
-00052         TInt32 intDelay;
-00053         Math::Int(intDelay, realDelay);
-00054         TTimeIntervalMicroSeconds32 delayMicroSeconds;
-00055         delayMicroSeconds=intDelay;
-00056         User::After(delayMicroSeconds);
-00057         }
-00058 
-00059 // A version of the RandomDelay function which is not random ! 
-00060 // The delay is fixed at 1000000us and may be useful to 
-00061 // experiment with. 
-00062 //
-00063 //
-00064 //void RandomDelay(TInt64& /* aSeed */, TInt aTimerNumber)
-00065 //      {
-00066 //      User::After(1000000);
-00067 //  _LIT(KFormatMisc,"Delay for timer %d: 1000000us\n");
-00068 //      console->Printf(KFormatMisc, aTimerNumber);
-00069 //      }
-00070 
-00071 
-00072 class TAppRunner
-00073         {
-00074 public:
-00075         TAppRunner();
-00076         void NotifyFinished(); // notify an active object has finished
-00077         void NotifyStarted(); // notify an active object has started
-00078 // private:
-00079         TInt iActiveObjects; // count of active objects
-00080         };
-00081 
-00082 TAppRunner::TAppRunner()
-00083         {
-00084         iActiveObjects=0;
-00085         }
-00086 
-00087 void TAppRunner::NotifyStarted()
-00088         {
-00089         iActiveObjects++;
-00090         }
-00091 
-00092 void TAppRunner::NotifyFinished()
-00093         {
-00094         iActiveObjects--;
-00095         if (iActiveObjects==0) CActiveScheduler::Stop();
-00096         }
-00097 
-00098 /*
-00099         CPeriodicRunner class
-00100 
-00101         Constructor makes a CPeriodic and sets it off with one-second ticks.
-00102         These are fielded by the callback function, the static Tick(TAny*),
-00103         which simply casts the pointer to a CPeriodicRunner* and calls
-00104         the non-static callback, DoTick().
-00105 
-00106         Processing gets behind: when the ticks left have counted down to zero,
-00107         it should be behind by a second or two.  The destructor indicates how many
-00108         seconds since the object's creation.
-00109 */
-00110 
-00111 class CPeriodicRunner : public CBase
-00112         {
-00113 public:
-00114         // construct, add CPeriodic to active scheduler, and start it
-00115         static CPeriodicRunner* NewL(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner);
-00116         ~CPeriodicRunner(); // destruct and give statistics
-00117 protected:
-00118         CPeriodicRunner(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner);
-00119 private:
-00120         void ConstructL(); // second construction phase
-00121         // functions for TCallBack protocol
-00122         static TInt Tick(TAny* aObject); // directly called
-00123         void DoTick(); // indirectly called
-00124 private:
-00125       // constructor parameters
-00126         TAppRunner& iAppRunner; // notify when started and finished
-00127         TInt iTotalTicks;       // total number of ticks requested
-00128         TInt iTickInterval;     // the tick interval in microseconds
-00129         
-00130           // things set up by ConstructL()
-00131         TTime iStartTime;       // when we were started
-00132         CPeriodic* iPeriodic;   // periodic timer active object
-00133         
-00134           // remaining ticks will be decremented as we go
-00135         TInt iTicksLeft;        // number of ticks before we expire
-00136         TInt iTimerNumber;      // indentifying number for the timer
-00137         
-00138         // seed for random delay generator
-00139         TInt64 iDelaySeed;
-00140         };
-00141 
-00142 // protected C++ constructor
-00143 CPeriodicRunner::CPeriodicRunner(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner)
-00144         : iAppRunner(aAppRunner), iTotalTicks(aTotalTicks), iTickInterval(aTickInterval)
-00145         {}
-00146 
-00147 // private second-phase constructor
-00148 void CPeriodicRunner::ConstructL()
-00149         {
-00150         iStartTime.HomeTime();
-00151         iPeriodic =CPeriodic::NewL(0); // neutral priority
-00152         iAppRunner.NotifyStarted();
-00153         iTimerNumber = iAppRunner.iActiveObjects; // set idenfifying number for timer
-00154         iTicksLeft = iTotalTicks;
-00155         // variable (actually 1 second) delay and interval 
-00156         iPeriodic->Start(iTickInterval,iTickInterval,TCallBack(Tick, this));
-00157         }
-00158 
-00159 // construct, add CPeriodic to active scheduler, and start it
-00160 CPeriodicRunner* CPeriodicRunner::NewL(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner)
-00161         {
-00162         CPeriodicRunner* self=new (ELeave) CPeriodicRunner(aTickInterval, aTotalTicks, aAppRunner);
-00163         CleanupStack::PushL(self);
-00164     self->ConstructL();
-00165         CleanupStack::Pop();
-00166     return self;
-00167         }
-00168 
-00169 // destruct and give statistics
-00170 CPeriodicRunner::~CPeriodicRunner()
-00171         {
-00172         TTimeIntervalMicroSeconds elapsedTime;
-00173         TTime currentTime;
-00174         // set current time
-00175         currentTime.HomeTime(); // set currentTime to now
-00176         // find and show elapsed time & ticks 
-00177         elapsedTime = currentTime.MicroSecondsFrom(iStartTime);
-00178         
-00179         _LIT(KFormat1,"Periodic timer %d finished after: %Ld microseconds for %d %dus ticks\n");
-00180         console->Printf(KFormat1,iTimerNumber,elapsedTime.Int64(),iTotalTicks,iTickInterval);
-00181 
-00182         
-00183         
-00184         //  cancel any outstanding request; delete owned CPeriodic object 
-00185         iPeriodic->Cancel();
-00186     delete iPeriodic;
-00187         // tell app runner we've finished (if we're last, scheduler will stop)
-00188         iAppRunner.NotifyFinished();
-00189         }
-00190 
-00191 // private
-00192 TInt CPeriodicRunner::Tick(TAny* aObject)
-00193         {
-00194         ((CPeriodicRunner*)aObject)->DoTick(); // cast, and call non-static function
-00195         return 1;
-00196         }
-00197 
-00198 // private
-00199 void CPeriodicRunner::DoTick()
-00200         {
-00201         iTicksLeft--;
-00202         _LIT(KFormat2,"Periodic timer %d: %d ticks done\n");
-00203         console->Printf(KFormat2, iTimerNumber, iTotalTicks - iTicksLeft);
-00204         if(iTicksLeft==0)
-00205                 {
-00206                 delete this;
-00207                 }
-00208         RandomDelay(iDelaySeed,iTimerNumber); // a random delay to mess up the timing
-00209         }
-00210 
-00211 /*
-00212         CHeartbeatRunner class
-00213 
-00214         This class receives beats in sync with the system clock.  It also has a much
-00215         nicer interface than for periodic timers - the MBeating mixin, which is nicely
-00216         object-oriented.
-00217 
-00218         Most of the time, the Beat() function is called which trivially updates the tick
-00219         count.  Occasionally, synchronization is lost, and the Synchronize() function
-00220         is called instead: this must find out from the system time how many ticks should
-00221         have been counted, and update things accordingly.
-00222 
-00223         The destructor gives the same comparisons as the CPeriodic's.  The discrepancy
-00224         between the number of ticks and the number of seconds since construction should
-00225         never be more than is accounted for by the last heartbeat.
-00226 */
-00227 
-00228 class CHeartbeatRunner : public CBase, public MBeating
-00229         {
-00230 public:
-00231         // construct, add CHeartbeat to active scheduler, and start it
-00232         static CHeartbeatRunner* NewL(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner);
-00233         ~CHeartbeatRunner(); // destruct and give statistics
-00234 protected:
-00235         CHeartbeatRunner(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner);
-00236 private:
-00237         void ConstructL();
-00238         // functions for MBeating protocol
-00239         void Beat(); // called when beat works ok
-00240         void Synchronize(); // called when we need to synchronize
-00241 private:
-00242         // constructor parameters
-00243         TAppRunner& iAppRunner; // notify when started and finished
-00244         TInt iTotalTicks; // number of ticks requested
-00245         TInt iTickInterval; // tick length in microseconds
-00246         // things set up by ConstructL
-00247         TTime iStartTime; // when we were started
-00248         CHeartbeat* iHeartbeat; // heartbeat active object
-00249         // ticks left decrements as we go
-00250         TInt iTicksLeft; // number of ticks before we expire
-00251         TInt iTimerNumber; // indentifying number for the timer
-00252         // seed for random delay generator
-00253         TInt64 iDelaySeed;
-00254         };
-00255 
-00256 // protected C++ constructor
-00257 CHeartbeatRunner::CHeartbeatRunner(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner)
-00258         :iAppRunner(aAppRunner), iTotalTicks(aTotalTicks), iTickInterval(aTickInterval)
-00259         {}
-00260 
-00261 // private second-phase constructor
-00262 void CHeartbeatRunner::ConstructL()
-00263         {
-00264         iStartTime.HomeTime();
-00265         iHeartbeat=CHeartbeat::NewL(0); // neutral priority
-00266         iAppRunner.NotifyStarted();
-00267         iTimerNumber = iAppRunner.iActiveObjects; // set idenfifying number for timer
-00268         iTicksLeft = iTotalTicks;
-00269         // start the heartbeat timer, beating exactly on the second
-00270         iHeartbeat->Start(ETwelveOClock,this);
-00271         }
-00272 
-00273 // construct, add CHeartbeat to active scheduler, and start it
-00274 CHeartbeatRunner* CHeartbeatRunner::NewL(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner)
-00275         {
-00276         CHeartbeatRunner* self=new (ELeave) CHeartbeatRunner(aTickInterval, aTotalTicks, aAppRunner);
-00277         CleanupStack::PushL(self);
-00278     self->ConstructL();
-00279         CleanupStack::Pop();
-00280     return self;
-00281         }
-00282 
-00283 // destruct and give statistics
-00284 CHeartbeatRunner::~CHeartbeatRunner()
-00285         {
-00286         TTimeIntervalMicroSeconds elapsedTime;
-00287         TTime currentTime;
-00288         currentTime.HomeTime(); // set current time to now
-00289         // find and show elapsed time & ticks 
-00290         elapsedTime = currentTime.MicroSecondsFrom(iStartTime); 
-00291         
-00292         _LIT(KFormat3,"Heartbeat timer %d finished after: %Ld microseonds for %d %dus ticks\n");
-00293         console->Printf(KFormat3,iTimerNumber,elapsedTime.Int64(),iTotalTicks,iTickInterval);
-00294         
-00295         //  cancel any outstanding request; delete owned CPeriodic object 
-00296         iHeartbeat->Cancel();
-00297     delete iHeartbeat;
-00298         // tell app runner we've finished (if last, scheduler will stop)
-00299         iAppRunner.NotifyFinished();
-00300         }
-00301 
-00302 // private
-00303 void CHeartbeatRunner::Beat()
-00304         {
-00305         iTicksLeft--;
-00306         if(iTicksLeft<=0)
-00307                 delete this;
-00308         else
-00309                 RandomDelay(iDelaySeed,iTimerNumber); // a random delay to mess up the timing
-00310         }
-00311 
-00312 // private
-00313 void CHeartbeatRunner::Synchronize()
-00314         {
-00315         TInt ticksMissed = 0;
-00316                  // what time in microseconds should be for this tick
-00317         TTime desiredTime = iStartTime + TTimeIntervalMicroSeconds((iTotalTicks - iTicksLeft) * iTickInterval);
-00318         TTime currentTime; // set current time to now
-00319         currentTime.HomeTime();
-00320         TTimeIntervalMicroSeconds missedTime = currentTime.MicroSecondsFrom(desiredTime);
-00321         // Calculate the ticks missed (quickly!)
-00322         TInt64 missedTimeInt = missedTime.Int64(); // convert the missed time interval to an Int64
-00323         
-00324         ticksMissed = (missedTimeInt / iTickInterval);
-00325         //ticksMissed = (missedTimeInt / iTickInterval).GetTInt();
-00326         
-00327         
-00328         // The following loop increments the ticks missed by the same amount, but takes much longer
-00329         // while (desiredTime < currentTime)
-00330         //      {
-00331         //      desiredTime = desiredTime - TTimeIntervalMicroSeconds(iTickInterval);
-00332         //      ticksMissed++;
-00333         //      }
-00334         _LIT(KFormat4,"Ticks done %d\n");
-00335         console->Printf(KFormat4, (iTotalTicks -iTicksLeft));
-00336         
-00337         iTicksLeft = iTicksLeft - ticksMissed;
-00338         TTimeIntervalMicroSeconds elapsedTime;
-00339         elapsedTime = currentTime.MicroSecondsFrom(iStartTime); // find and show elapsed time & ticks 
-00340         _LIT(KFormat5,"Elapsed time: %Ld microseconds\n");
-00341         console->Printf(KFormat5, elapsedTime.Int64());
-00342         
-00343         _LIT(KFormat6,"Synchronize heartbeat timer %d: ticks missed %d: left %d: done now %d\n");
-00344         console->Printf(KFormat6,
-00345                             iTimerNumber,
-00346                                         ticksMissed,
-00347                                         iTicksLeft,
-00348                                         ((iTotalTicks - iTicksLeft) <= iTotalTicks) ? iTotalTicks - iTicksLeft : iTotalTicks
-00349                                    );
-00350         // iTicksLeft can be less than zero
-00351         if(iTicksLeft<=0)
-00352                 {
-00353                 delete this;
-00354                 }
-00355         }
-00356 
-00357 /*
-00358         TAppRunner class
-00359 
-00360         Encapsulates logic for stopping the active scheduler
-00361 */
-00362 
-00363 
-00364 // do the example
-00365 
-00366 void doExampleL()
-00367     {
-00368           // Make and install the active scheduler
-00369         CActiveScheduler*  scheduler = new (ELeave) CActiveScheduler;
-00370         
-00371           // Push onto clean-up stack
-00372         CleanupStack::PushL(scheduler); 
-00373         
-00374           // Install as active scheduler
-00375         CActiveScheduler::Install(scheduler);
-00376 
-00377       // Controls the stopping of the scheduler
-00378         TAppRunner appRunner; 
-00379         
-00380           // Set the tick interval to 1 second.
-00381         TInt TickInterval = 1000000;
-00382 
-00383           // run each kind of timer for increasing numbers of ticks
-00384           // was 10/40/10
-00385                 
-00386         for (TInt total_ticks=4; total_ticks<=6; total_ticks+=2)
-00387                 {               
-00388                   // Create periodic timer
-00389                   //
-00390                   // [nb Comment next line out if you just want to see heart beat runner]
-00391         CPeriodicRunner::NewL(TickInterval, total_ticks, appRunner);
-00392                         
-00393                   // Create hearbeat
-00394                   //
-00395                   // [nb Comment next line out if you just want to see periodic timer]
-00396                 CHeartbeatRunner::NewL(TickInterval, total_ticks, appRunner);
-00397                 }
-00398 
-00399         CActiveScheduler::Start();
-00400         CleanupStack::PopAndDestroy(); // scheduler
-00401         }
-00402 
-

Generated on Thu Jan 21 10:32:57 2010 for TB10.1 Example Applications by  - -doxygen 1.5.3
- -