Symbian 学习日志(八、Active Object )

一、CActive

可以理解为Windows的消息循环之类的东西;执行过程参照此图:

 

process

二、Symbian 的消息循环:

EventProcessingLoop()

{

      // Suspend the thread until an event occurs

      User::WaitForAnyRequest();

 

      // Thread wakes when the request semaphore is signaled

      // Inspect each active object added to the scheduler,

      // in order of decreasing priority

      // Call the event handler of the first which is active & completed

      FOREVER

      {

           // Get the next active object in the priority queue

           // the activeObject is getting from the priority queue

           if (activeObject->IsActive())

                 && (activeObject->iStatus!=KRequestPending)

           {// Found an active object ready to handle an event

                 // Reset the iActive status to indicate it is not active

                 activeObject->iActive = EFalse;

                 // Call the active object’s event handler in a TRAP

                 TRAPD(r, activeObject->RunL());

                 if (KErrNone!=r)

                 {// event handler left, call RunError() on active object

                      r = activeObject->RunError();

                      if (KErrNone!=r) // RunError() didn’t handle the error,

                            Error(r); // call CActiveScheduler::Error()

                 }

                 break; // Event handled. Break out of lookup loop & resume

           }

      } // End of FOREVER loop

}

 

三、消息循环流程

 

Symbian Event Loop

四、Symbian 操作系统定义好了以上类,只要调用以下代码就完成消息循环:

CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;

CleanupStack::PushL(scheduler);

CActiveScheduler::Install(scheduler);

 

用户可以直接使用 CActiveScheduler 也可以从其派生,定义自己的一些特性。

 

五、Cancel

执行取消必须在被调用到对应对象的 RunL之前,如果已经在调用RunL,再调用Cancel 是没有办法取消的,除非在RunL里面做判断;(自己总结的,不知道对错)

 

六、CIdle 类和CPeriodic

在空闲时刻执行和定期执行;

使用状态机,如下例:

 Symbian state machine

 

// Provides the "step" functions

class CServiceProvider : public CBase

{

public:

      static CServiceProvider* NewL();

      ~CServiceProvider() {};

public:

      void GetData(const TDesC& aSource, HBufC8*& aData,

           TRequestStatus& aStatus);

      void CancelGetData();

      TInt TranslateData(TDes8& aData);

      void SendData(const TDesC& aTarget, const TDesC8& aData,

           TRequestStatus& aStatus);

      void CancelSendData();

protected:

      CServiceProvider(){};

};

 

void CServiceProvider::GetData(const TDesC& aSource, HBufC8*& aData,

                                          TRequestStatus& aStatus)

{

      aStatus = KRequestPending;

      // Retrieves data from aSource using the asynchronous overload of

      // RFile::Read() and writing to aData (re-allocating it if

      // necessary). aStatus is completed by the file server when the

      // read has finished

      ...

}

void CServiceProvider::CancelGetData() {...}

TInt CServiceProvider::TranslateData(TDes8& aData)

{// Synchronously translates aData & writes into same descriptor

      ...

           return (translationResult);

}

void CServiceProvider::SendData(const TDesC& aTarget, const TDesC8&

                                             aData, TRequestStatus& aStatus)

{

      aStatus = KRequestPending;

      // Writes data to aTarget using the asynchronous overload of

      // RFile::Write(), which completes aStatus

      ...

}

void CServiceProvider::CancelSendData() {...}

class CStateMachine : public CActive

{

public:

      ~CStateMachine();

      static CStateMachine* NewLC();

      void SendTranslatedData(const TDesC& aSource, const TDesC& aTarget,

           TRequestStatus&);

protected:

      enum TState { EIdle, EGet, ETranslate, ESend};

protected:

      CStateMachine();

      void InitializeL(const TDesC& aTarget);

      void Cleanup();

protected:

      virtual void DoCancel(); // Inherited from CActive

      virtual void RunL();

      // The following base class method is not overridden because

      // RunL() cannot leave

      // virtual TInt RunError(TInt aError);

private:

      CServiceProvider* iService;

      TState iState;

private:

      HBufC* iTarget;

      HBufC8* iStorage;

      TRequestStatus* iClientStatus;

};

CStateMachine::CStateMachine()

: CActive(EPriorityStandard) {CActiveScheduler::Add(this);}

CStateMachine::()

{

      Cancel();

      Cleanup();

}

void CStateMachine::InitializeL(const TDesC& aTarget)

{

      // Store this to pass to CServiceProvider later

      iTarget = aTarget.AllocL();

      // To store retrieved data

      iStorage = HBufC8::NewL(KStandardDataLen);

}

void CStateMachine::Cleanup()

{// Pointers are NULL-ed because this method is called outside

      // the destructor

      iState = EIdle;

      delete iTarget;

      iTarget = NULL;

      delete iStorage;

      iStorage = NULL;

}

const TInt KStandardDataLen = 1024;

// Starts the state machine

void CStateMachine::SendTranslatedData(const TDesC& aSource,

                                                     const TDesC& aTarget, TRequestStatus& aStatus)

{

      __ASSERT_ALWAYS(!IsActive(), User::Panic(KExPanic, KErrInUse));

      ASSERT(EIdle==iState);

      // Store the client request status to complete later

      iClientStatus = &aStatus;

      iClientStatus = KRequestPending;

      TRAPD(r, InitializeL(aTarget);

      if (KErrNone!=r)

      {// Allocation of iTarget of iStorage failed

           Cleanup(); // Destroys successfully allocated member data

           User::RequestComplete(iClientStatus, r);

      }

      else

      {

           iService->GetData(aSource, iStorage, iStatus);

           iState = EGet;

           SetActive();

      }

}

 

// The state machine is driven by this method

void CStateMachine::RunL()

{// Inspects result of completion and iState

      // and submits next request (if required)

      ASSERT(EIdle!=iState);

      if (KErrNone!=iStatus.Int())

      {// An error - notify the client and stop the state machine

           User::RequestComplete(iClientStatus, iStatus.Int());

           Cleanup();

      }

      else

      {

           if (EGet==iState)

           {// Data was retrieved, now translate it synchronously

                 TPtr8 ptr(iStorage->Des());

                 iService->TranslateData(ptr);

                 iState = ETranslate;

                 // Self completion –described later

                 TRequestStatus* stat = &iStatus;

                 User::RequestComplete(stat, r);

                 SetActive();

           }

           else if (ETranslate==iState)

           {// Data was translated, now send it asynchronously

                 TInt r = iService->SendData(*iTarget, *iStorage, iStatus);

                 iState = ESend;

                 SetActive();

           }

           else

           {// All done, notify the caller

                 ASSERT(ESend==iState);

                 User::RequestComplete(iClientStatus, iStatus.Int());

                 Cleanup();

           }

      }

}

 

void CStateMachine::DoCancel()

{

      if (iService)

      {

           if (CStateMachine::EGet = =iState)

           {

                 iService->CancelGetData();

           }

           else if (CStateMachine::ESend = =iState)

           {

                 iService->CancelSendData();

           }

      }

      if (iClientStatus)

      {// Complete the caller with KErrCancel

           User::RequestComplete(iClientStatus, KErrCancel);

      }

      Cleanup();

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值