svgtopt/SVG/SVGEngine/src/SVGTimer.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 14 Apr 2010 16:53:18 +0300
branchRCL_3
changeset 15 d240fe32a15c
parent 0 d46562c3d99d
permissions -rw-r--r--
Revision: 201013 Kit: 201015

/*
* Copyright (c) 2003 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:  SVG Engine source file
 *
*/


#include "SVGTimer.h"
#include "SVGEngineImpl.h"
#include "GfxAffineTransform.h"
#include "GfxPoint2D.h"
#include "SVGTimeContainer.h"

// ---------------------------------------------------------------------------
// Two phase constructor
// ---------------------------------------------------------------------------
CSvgTimer* CSvgTimer::NewLC( CSvgTimeContainer* aTimeContainer )
    {
    CSvgTimer* self = new ( ELeave ) CSvgTimer( aTimeContainer );
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }

//
// ---------------------------------------------------------------------------
// Two phase constructor
// ---------------------------------------------------------------------------
CSvgTimer* CSvgTimer::NewL( CSvgTimeContainer* aTimeContainer )
    {
    CSvgTimer* self = NewLC( aTimeContainer );
    CleanupStack::Pop();
    return self;
    }

// ---------------------------------------------------------------------------
// Private method that builds the heap objects or performs leavable actions
// during object construction
// ---------------------------------------------------------------------------
void CSvgTimer::ConstructL()
    {
    // Call the base class ConstructL
    CTimer::ConstructL();
    // Add to active scheduler
    CActiveScheduler::Add( this );
    }

//
// ---------------------------------------------------------------------------
// Constructor
// Initialized with a pointer to the time container
// ---------------------------------------------------------------------------
CSvgTimer::CSvgTimer( CSvgTimeContainer* aTimeContainer ) : 
    CTimer( CActive::EPriorityStandard ),
    iTimeContainer( aTimeContainer )
    {
    ChangeFrameDuration( KMinFrameDelay );
    SetStrictFrameDuration( EFalse );
    ResetTime();
    }

//
// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
CSvgTimer::~CSvgTimer()
    {
    Cancel();
    }

// ---------------------------------------------------------------------------
// Reset the time
// ---------------------------------------------------------------------------
void CSvgTimer::ResetTime()
    {
    iTime = 0;
    iFrames = 0;
    iFirstFrameDrawn = EFalse;
    }

// ---------------------------------------------------------------------------
// Change the duration of the timer in milliseconds
// ---------------------------------------------------------------------------
void CSvgTimer::ChangeFrameDuration( TUint32 aFrameDuration )
    {
    // If delay duration is less then minimum-delay, set to minimum-delay
    if ( aFrameDuration < KMinFrameDelay )
        {
        aFrameDuration =  KMinFrameDelay;
        }
    iFrameDuration = aFrameDuration;
    }

// ---------------------------------------------------------------------------
// Return the frames per 10-seconds
// ---------------------------------------------------------------------------
TUint CSvgTimer::Fps()
    {
	if ( iTime == 0 )
		{
		return 0;
		}
	// iTime is in milliseconds
	return ( 10000 * iFrames ) / iTime ;
    }


// ---------------------------------------------------------------------------
// Standard Active Object DoCancel
// ---------------------------------------------------------------------------
void CSvgTimer::DoCancel()
    {
    CTimer::DoCancel();
    }

// ---------------------------------------------------------------------------
// Standard Active Object RunL
// ---------------------------------------------------------------------------
void CSvgTimer::RunL()
    {
    // Check if timed entity not null
    if ( !iTimeContainer )
        {
        return;
        }
    
#if 0    
    // Check engine and document
    if ( !iSvgEngine || !iSvgEngine->Document() )
        {
        return;
        }

	// wait for images to finish decoding
    if ( !iSvgEngine->ReadyToRender() )
    	{
        CActive::Deque();
        CActiveScheduler::Add( this );
        CTimer::After( 10 * 1000 );
        return;
		}
#endif
    /********************** Generate first frame ********************/
    if ( !iFirstFrameDrawn )
    	{
        iFirstFrameDrawn = ETrue;
    	}
	else
		{
		/********************** After first frame ********************/
		TTime currentTime;
		currentTime.HomeTime();
		TUint32 elapsedTime = GetElapsedMilliseconds( iPreviousFrameTime, currentTime );

		// Cap elapsed time, if needed
		if ( iIsStrictFrameDuration &&
			 elapsedTime > iFrameDuration )
			{
			elapsedTime = iFrameDuration;
			}

		// Generate frame
		iTime += elapsedTime;
		}

    // Mark time of new frame
    iPreviousFrameTime.HomeTime();

    // Generate new frame
    TUint32 sleepTime = GenerateFrameL( iTime );

		// Sleep to next frame
	if ( 
	( iTimeContainer->Document()->Engine()->SVGEngineState() == ESVGEngineRunning ) 
	&& ( iTimeContainer->GetCurTick().iParentTcTick < iTimeContainer->Document()->AnimationDuration() ) 
	)
	
		{
        // Dequeue to move this ActiveObject to the end of the list
        // to share processor with other AOs.
		CActive::Deque();
		CActiveScheduler::Add( this );
		CTimer::After( 1000 * sleepTime );
		}
    }

// --------------------------------------------------------------------------
// void CSvgTimer::SVGStop()
// ---------------------------------------------------------------------------
void CSvgTimer::SVGStop()
    {
    if ( IsActive() )
        {
        Cancel(); // stop current timer
        }
    iFirstFrameDrawn = EFalse;
    }

// --------------------------------------------------------------------------
// void CSvgTimer::SVGResume()
// ---------------------------------------------------------------------------
void CSvgTimer::SVGResume( TInt32 aTime )
    {
    if ( !IsActive() )
        {
        if ( aTime < 0 )
            {
            // Error, ( negative time ) set to default
            aTime = 1000;
            }
            
        CTimer::After( aTime ); // invoke initial timer event
        }
    }

// --------------------------------------------------------------------------
// void CSvgTimer::SetStartTime()
// Reset animation time to zero
// ---------------------------------------------------------------------------
void CSvgTimer::SetStartTime()
    {
    SetSeekTime( 0 );
    }

// --------------------------------------------------------------------------
// void CSvgTimer::SetSeekTime( TUint32 aTime )
// ---------------------------------------------------------------------------
void CSvgTimer::SetSeekTime( TUint32 aTime )
    {
    // update the current time.
    iFirstFrameDrawn = EFalse;
#if 0
    // the current home time needs to be updated.
    if ( iSvgEngine && iSvgEngine->Document() && aTime != iTime )
        {
        TSvgTimerEvent timeEvent( aTime );
        iSvgEngine->Document()->Reset( &timeEvent );
        }
#endif
    iTime = aTime;

     if ( !IsActive() )
        {
        CTimer::After( 1000 );
        }

    }

// --------------------------------------------------------------------------
// void CSvgTimer::SetStrictFrameDuration( TBool aKeepStrictFrameDuration )
// ---------------------------------------------------------------------------
void CSvgTimer::SetStrictFrameDuration( TBool aKeepStrictFrameDuration )
    {
    iIsStrictFrameDuration = aKeepStrictFrameDuration;
    }

// --------------------------------------------------------------------------
// TUint32 CSvgTimer::GenerateFrameL( TUint32 aTime )
// ---------------------------------------------------------------------------
TUint32 CSvgTimer::GenerateFrameL( TUint32 aTime )
    {
    TTime startTime;
    startTime.HomeTime();
    TSvgTick lTick;
    lTick.iRealTimeTick = aTime;
    lTick.iParentTcTick = 0;
    
    iTimeContainer->ParentTimeContainerTick( lTick );
    
#if 0
    // Request to drawn frame at given time
    TSvgTimerEvent timeEvent( aTime );
    iSvgEngine->ProcessEventL( iSvgEngine->Document(), &timeEvent );
#endif
    TTime endTime;
    endTime.HomeTime();

    TUint32 elapsedTime = GetElapsedMilliseconds( startTime, endTime );

    // Calculate sleep time to next frame
    TUint32 sleepTime = KMinSleepDuration;
    if ( elapsedTime < iFrameDuration )
        {
        sleepTime = iFrameDuration - elapsedTime;
        if ( sleepTime < KMinSleepDuration )
            {
            sleepTime = KMinSleepDuration;
            }
        }

	iFrames++;
    return sleepTime;
    }

// --------------------------------------------------------------------------
// TUint32 CSvgTimer::GetElapsedMilliseconds( TTime& aStart, TTime& aEnd )
// ---------------------------------------------------------------------------
TUint32 CSvgTimer::GetElapsedMilliseconds( TTime& aStart, TTime& aEnd )
    {
    TTimeIntervalMicroSeconds interval64 = aEnd.MicroSecondsFrom( aStart );
    // in milliseconds
    return I64INT( interval64.Int64() ) / 1000;
    }