diff -r e52958d06c29 -r 5fd161fa28b6 svgtviewer/SvgtViewerPlugin/UIControlSrc/SvgtEventHandlerAO.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svgtviewer/SvgtViewerPlugin/UIControlSrc/SvgtEventHandlerAO.cpp Thu Sep 09 11:17:40 2010 +0300 @@ -0,0 +1,319 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This class handles the event list & process the events +* while progressive rendering +* +*/ + + +#include "SvgtEventHandlerAO.h" +#include +#include +#include "SvgtEvent.h" + +const TInt KTimerIntervalInMiliSeconds = 1000; + +const TInt KInitialTimeInterval = 100; +const TInt KMaxTimeInterval = 2000; +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::NewL +// Two phase construction +// ----------------------------------------------------------------------------- +// +CSvgtEventHandlerAO* CSvgtEventHandlerAO::NewL(MSvgtAppObserver* aAppObserverUtil, + CSVGTCustControl* aCustControl , + const TThreadId aMainThreadId ) + { + CSvgtEventHandlerAO* self = new ( ELeave ) CSvgtEventHandlerAO( aAppObserverUtil , + aCustControl, + aMainThreadId); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::CSvgtEventHandlerAO +// Constructor +// ----------------------------------------------------------------------------- +// +CSvgtEventHandlerAO::CSvgtEventHandlerAO(MSvgtAppObserver* aAppObserverUtil, + CSVGTCustControl* aCustControl, + const TThreadId aMainThreadId): + CActive( CActive::EPriorityStandard ), + iCustControl(aCustControl), + iMainThreadId( aMainThreadId ), + iIsDocumentComplete( EFalse ), + iStepCount( 1 ), + iSvgTimeBetweenRedraw( KInitialTimeInterval ) + { + iAppObserverUtil = static_cast(aAppObserverUtil); + } + +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::ConstructL +// 2nd phase constructor +// ----------------------------------------------------------------------------- +// +void CSvgtEventHandlerAO::ConstructL() + { + iPreviousRedrawClock.HomeTime(); + // Add to active scheduler + CActiveScheduler::Add( this ); + // Set the status as pending + iStatus = KRequestPending; + // Set the active object as Active + SetActive(); + // Create the critical section IPC for sync. the RequestComplete Calls + iCritSection.CreateLocal(); + } + +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::~CSvgtEventHandlerAO +// Destructor +// ----------------------------------------------------------------------------- +// +CSvgtEventHandlerAO::~CSvgtEventHandlerAO() + { + Cancel(); + iEventList.ResetAndDestroy(); + iEventList.Close(); + iCritSection.Close(); + } + +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::AddEventToList +// It adds the event (except redraw event) to the event queue. +// ----------------------------------------------------------------------------- +// +TBool CSvgtEventHandlerAO::AddEventToList( CSvgtEvent* aEvent) + { + iEventList.Append( aEvent ); + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::AddRedrawEventToList +// It adds the redraw event to the event queue. +// ----------------------------------------------------------------------------- +// +TBool CSvgtEventHandlerAO::AddRedrawEventToList( const TBool aForceAdd ) + { + TBool isEventAdded = EFalse; + if(aForceAdd || IsRedrawTimeElapsed()) + { + CSvgtEvent* redrawEvent = new CSvgtEventRedraw; + iEventList.Append( redrawEvent ); + isEventAdded = ETrue; + } + + return isEventAdded; + } + +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::MakeRequestComplete +// It make the request complete. +// ----------------------------------------------------------------------------- +// +void CSvgtEventHandlerAO::MakeRequestComplete( TInt aError ) + { + // The Asynchronouse service provider must only call the RequestComplete() + // once for each request. Multiple completion events on a single active + // object result in a stray signal panic. + // Hence use a critical section to synchronize access to RequestComplete() + iCritSection.Wait(); + if( ( IsActive() ) && ( iStatus == KRequestPending ) ) + { + // The asynchronous service provider is the loading thread and since + // this is called from both loading thread as well as main thread + // use the RThread object to complete the request for active + // object present in the main thread's active scheduler + TRequestStatus* status = &iStatus; + RThread mainThread; + + if( mainThread.Open( iMainThreadId) ) + { + // Problem opening thread, ignore error and return : Should not happen. + return; + } + + mainThread.RequestComplete( status, aError ); + mainThread.Close(); + } + iCritSection.Signal(); + } + +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::AddEventToList +// It indicates that document is document loading completed. +// ----------------------------------------------------------------------------- +// +void CSvgtEventHandlerAO::SetDocumentComplete() + { + iIsDocumentComplete = ETrue; + } + +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::RunL +// Handles an active object's request completion event. +// ----------------------------------------------------------------------------- +// +void CSvgtEventHandlerAO::RunL() + { + // Set the Active Object Active always + if( !IsActive() ) + { + iStatus = KRequestPending; + SetActive(); + } + + if(iEventList.Count()) + { + CSvgtEvent* event = iEventList[0]; + iEventList.Remove( 0 ); + switch(event->EventType()) + { + case CSvgtEvent::ESvgtEventEmbededImage: + { + CSvgtEventEmbededImage* svgEvent = + static_cast(event); + iAppObserverUtil->AssignEmbededDataL( svgEvent->ImageUri() ); + } + break; + + case CSvgtEvent::ESvgtEventFetchImage: + { + CSvgtEventFetchImage* fetchEvent = + static_cast(event); + iAppObserverUtil->NewFetchImageData(fetchEvent->ImageUri()); + } + break; + case CSvgtEvent::ESvgtEventLinkActivated: + { + CSvgtEventLinkActivated* linkEvent = + static_cast(event); + iAppObserverUtil->LinkActivated(linkEvent->ImageUri()); + } + break; + case CSvgtEvent::ESvgtEventLinkActivatedWithShow: + { + CSvgtEventLinkActivatedWithShow* linkShowEvent = + static_cast(event); + iAppObserverUtil->LinkActivatedWithShow(linkShowEvent->ImageUri(), + linkShowEvent->Show()); + } + break; + case CSvgtEvent::ESvgtEventRedraw: + { + //DO REDRAW + iCustControl->PerformEngineRedraw(); + iCustControl->DrawNow(); + } + break; + + default: + break; + } + + delete event; + } + + + if( iEventList.Count() ) + { + // Pending events in the list, reschedule active + // object + MakeRequestComplete( KErrNone ); + } + } + +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::DoCancel +// Cancels all the pending request +// ----------------------------------------------------------------------------- +// +void CSvgtEventHandlerAO::DoCancel() + { + // The service provided for this active object is the + // loading thread. Since the loading thread is already indicated to stop + // generating requests, need to terminate the request + // pending in the main thread + DoTerminate(); + } + +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::RunError +// Handles a leave occurring in the request completion event handler RunL(). +// ----------------------------------------------------------------------------- +// +TInt CSvgtEventHandlerAO::RunError( TInt aError ) + { + // When an error occurs, call base class error handler + // Note that active object should not be Cancel() here + // as Loading thread could still be alive and do a + // MakeRequestComplete. This would generate a stray + // signal. + return ( CActive::RunError( aError ) ); + } + +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::IsRedrawTimeElapsed +// It determines whether the time elapsed or not. +// ----------------------------------------------------------------------------- +// +TBool CSvgtEventHandlerAO::IsRedrawTimeElapsed() + { + TBool isTimeElapsed = EFalse; + TTime currentClock; + currentClock.HomeTime(); + + TTimeIntervalMicroSeconds time64; + time64 = currentClock.MicroSecondsFrom( iPreviousRedrawClock ); + + TUint32 timeDelta = I64INT( time64.Int64() ) / KTimerIntervalInMiliSeconds; + // milliseconds + + if ( timeDelta > iSvgTimeBetweenRedraw )//KSvgTimeBetweenRedraw=500 + { + if( iSvgTimeBetweenRedraw < KMaxTimeInterval ) + { + iSvgTimeBetweenRedraw *= ++iStepCount; + } + isTimeElapsed = ETrue; + // Save the current time to calculate interframe delay + iPreviousRedrawClock.HomeTime(); + } + + return isTimeElapsed; + } + +// ----------------------------------------------------------------------------- +// CSvgtEventHandlerAO::DoTerminate +// Cancels the pending async request +// ----------------------------------------------------------------------------- +// +void CSvgtEventHandlerAO::DoTerminate() + { + // Post a pseudo complete, so that Cancel() is done + // successfully. The Loading thread which is the actual service + // provider is by now already stopped. + // The Asynchronous service provider should complete the + // request with KErrCancel as quickly as possible, because CActive::Cancel + // blocks until completion occurs. + MakeRequestComplete( KErrCancel ); + } + + +//End of file