⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smltime.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

// system
#include <time.h>
// include
#include "hxtypes.h"
#include "hxwintyp.h"
#include "hxcom.h"
#include "hxxml.h"
#include "smiltype.h"
// pncont
#include "hxslist.h"
#include "hxmap.h"
// pnmisc
#include "hxwinver.h"
// rnxmllib
#include "hxxmlprs.h"
// rmasmil
#include "smlelem.h"
#include "smlparse.h"
#include "smltime.h"
#include "smlprstime.h"
// pndebug
#include "debugout.h"
#include "hxassert.h"
#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE		
static const char HX_THIS_FILE[] = __FILE__;
#endif

// /#define XXXEH_DEBUGOUT_ADDDURATION
#if defined(XXXEH_DEBUGOUT_ADDDURATION)
#define ADDDURATION_DEBUGOUT_STR_NEW_FILE   "w"
#define ADDDURATION_DEBUGOUT_STR_APPEND_TO_FILE   "a+"
static BOOL bFirstTimeAddDurDebugout = TRUE;
#endif

/*
 * CSmilTimelineElementManager methods
 */

CSmilTimelineElementManager::CSmilTimelineElementManager():
    m_pElementMap(NULL),
    m_pNotifierMap(NULL)
{
}

CSmilTimelineElementManager::~CSmilTimelineElementManager()
{
    HX_DELETE(m_pElementMap);
    if(m_pNotifierMap)
    {
	CHXMapStringToOb::Iterator i = m_pNotifierMap->Begin();
	for(; i != m_pNotifierMap->End(); ++i)
	{
	    CHXSimpleList* pList = (CHXSimpleList*)(*i);
	    delete pList;
	}
	HX_DELETE(m_pNotifierMap);
    }
}

void
CSmilTimelineElementManager::addTimelineElement(CSmilTimelineElement* pElement)
{
    if(!m_pElementMap)
    {
	m_pElementMap = new CHXMapStringToOb;
    }
    (*m_pElementMap)[pElement->m_pID] = pElement;
}

CSmilTimelineElement*
CSmilTimelineElementManager::getTimelineElement(const char* pID)
{
    CSmilTimelineElement* pElement = NULL;
    if(m_pElementMap)
    {
	m_pElementMap->Lookup(pID, (void*&)pElement);
    }
    return pElement;
}

void
CSmilTimelineElementManager::addNotification(const char* pID,
					     CSmilTimelineElement* pElement)
{
    if(!m_pNotifierMap)
    {
	m_pNotifierMap = new CHXMapStringToOb;
    }

    CHXSimpleList* pNotifyList = NULL;
    if(!m_pNotifierMap->Lookup(pID, (void*&)pNotifyList))
    {
	pNotifyList = new CHXSimpleList;
	(*m_pNotifierMap)[pID] = pNotifyList;
    }
    pNotifyList->AddTail(pElement);
}

void
CSmilTimelineElementManager::notify(const char* pID)
{
    CHXSimpleList* pNotifyList = NULL;
    if(m_pNotifierMap)
    {
	if(m_pNotifierMap->Lookup(pID, (void*&)pNotifyList))
	{
	    CSmilTimelineElement* pDependentElement = NULL;
	    if(m_pElementMap->Lookup(pID, (void*&)pDependentElement))
	    {
		CHXSimpleList::Iterator i = pNotifyList->Begin();
		for(; i != pNotifyList->End(); ++i)
		{
		    CSmilTimelineElement* pElement = 
			(CSmilTimelineElement*)(*i);
		    pElement->elementResolved(pDependentElement);
		}
	    }
	}
    }
}

void
CSmilTimelineElementManager::resetTimeline()
{
    if(m_pElementMap)
    {
	CHXMapStringToOb::Iterator i = m_pElementMap->Begin();
	for(; i != m_pElementMap->End(); ++i)
	{
	    CSmilTimelineElement* pElement = 
		(CSmilTimelineElement*)(*i);
	    pElement->reset();
	}
    }
}	
/*
 * CSmilTimelineElement methods
 */

CSmilTimelineElement::CSmilTimelineElement(CSmilElement* pSourceElement,
					   CSmilParser* pParser):
    m_pSourceElement(pSourceElement),
    m_pParser(pParser),
    m_bDurationSet(FALSE),
    m_bMaxDurationSet(FALSE),
    m_bDelaySet(FALSE),
    m_bDontResetDuration(FALSE),
    m_bNonEventDelaySet(FALSE),
    m_ulNonEventDelay((UINT32)-1),
    m_bDelayEvent(FALSE),
    m_bDurationEvent(FALSE),
    m_pChildDurAddedMap(NULL),
    m_bHasChildWithScheduledBegin(FALSE),
    m_bInElementResolved(FALSE),
    m_pParent(NULL),
    m_pChildren(NULL),
    m_pDependent(NULL)
{
    m_pID = new char[pSourceElement->m_pNode->m_id.GetLength() + 1];
    strcpy(m_pID, (const char*)m_pSourceElement->m_pNode->m_id); /* Flawfinder: ignore */

    //[SMIL 1.0 Compliance] Helps fix PR 26471:
    // /XXXEH- TODO: this is probably one of the places where
    // endsync="media" is handled.  We probably don't want to do the
    // following if() statement if endsync is NOT media on the parent
    // of an anchor|area element:
    if (SMILAnchor != m_pSourceElement->m_pNode->m_tag  &&
	    SMILArea != m_pSourceElement->m_pNode->m_tag)
    {
	m_pParser->m_pTimelineElementManager->addTimelineElement(this);
    }

    if(pSourceElement->m_nBeginEventSourceTag == SMILEventSourceBegin ||
	pSourceElement->m_nBeginEventSourceTag == SMILEventSourceEnd ||
	pSourceElement->m_nBeginEventSourceTag == SMILEventSourceClock)
    {
	m_pParser->m_pTimelineElementManager->addNotification(pSourceElement->m_BeginEventSourceID,
	    this);
	// /If we've already got a resolved begin, then we don't want to claim
	// that we're awaiting this sync-arc begin (as can happen if
	// begin="0s; x.begin+4s")
	if (!pSourceElement->m_bBeginOffsetSet)
	{
	    m_bDelayEvent = TRUE;
	}
    }

    if(pSourceElement->m_nEndEventSourceTag == SMILEventSourceBegin ||
	pSourceElement->m_nEndEventSourceTag == SMILEventSourceEnd ||
	pSourceElement->m_nEndEventSourceTag == SMILEventSourceClock)
    {
	m_pParser->m_pTimelineElementManager->addNotification(pSourceElement->m_EndEventSourceID,
	    this);
	// /If we've already got a resolved end, then we don't want to claim
	// that we're awaiting this sync-arc end (as can happen if
	// end="10s; x.begin+14s")
	if (!pSourceElement->m_bEndOffsetSet)
	{
	    m_bDurationEvent = TRUE;
	}
    }

    if(pSourceElement->m_nEndsyncEventSourceTag == SMILEventSourceID)
    {
	m_pParser->m_pTimelineElementManager->addNotification(pSourceElement->m_EndsyncEventSourceID,
	    this);
	m_bDurationEvent = TRUE;
    }

    m_pChildDurAddedMap = new CHXMapStringToOb();

    // /XXXEH- TODO: make sure this is what we want to do:
    // /Get next resolved time, if any.  If none are found in a non-empty
    // begin-time list, then treat this as a delayed event:
    if (NULL != pSourceElement->m_pBeginTimeList  &&
	    !pSourceElement->m_pBeginTimeList->IsEmpty())
    {
	SmilTimeValue* pNextResolvedTimeValue = NULL;

	HX_RESULT rettimeval = HXR_OK;
	rettimeval = pSourceElement->getNextResolvedTimeValue(
		pNextResolvedTimeValue,
		// /XXXEH- TODO: make sure we don't want to input cur time here;
		// is it possible that we'd get here after time 0 in the parent
		// timeline???  I don't think so...:
		SMILTIME_NEGATIVE_INFINITY,
		SMILTIME_NEGATIVE_INFINITY,
		SmilBeginTimeList,
		/* Don't need list of resolved times:*/ NULL);
	if (!SUCCEEDED(rettimeval)  ||  NULL == pNextResolvedTimeValue)
	{
	    // /Has no resolved time yet so must be awaiting an event:
	    m_bDelayEvent = TRUE;
	}
    }
}

CSmilTimelineElement::~CSmilTimelineElement()
{
    delete m_pChildren;
    delete[] m_pID;
    HX_DELETE(m_pChildDurAddedMap);
}

void
CSmilTimelineElement::reset()
{
    m_bDelaySet = FALSE;
    m_bNonEventDelaySet = FALSE;
    m_ulNonEventDelay = (UINT32)-1;
    m_bDurationSet = FALSE;
    m_bMaxDurationSet = FALSE;
    // /XXXEH- do we really want to do this? Find a way to test this:
#if defined(XXXEH_NEEDS_TESTING)
    HX_DELETE(m_pChildDurAddedMap); // /start fresh
#endif
}

void
CSmilTimelineElement::prepForRestart()
{
    m_bDelaySet = FALSE;
    m_bNonEventDelaySet = FALSE;
    m_ulNonEventDelay = (UINT32)-1;

#if XXXEH_OLD_WAY_THAT_DIDNT_LET_SETDURATION_TAKE_CARE_OF_NEW_DUR
    if (((UINT32)-1) != m_pSourceElement->m_ulOriginalDuration)
    {
	resetDuration(m_pSourceElement->m_ulOriginalDuration);
    }
    // /Note: leave m_bDurationSet & m_bMaxDurationSet alone for restart
#else
    //...But if we're restarting, our duration may be different and this
    // gets handled in CSmilTimelineElement::setDuration():
    m_bDurationSet = FALSE;
    // /Fixes PR 54704: if we don't reset this in concert with resetting
    // m_bDurationSet, above, then ancestorEventsAreResolved() will fail
    // when a re-insertTimelineElement() call on this occurs:
    m_bDurationEvent = FALSE;
#endif

}


void 
CSmilTimelineElement::setDelay(UINT32 ulDelay, BOOL bSetByParent)
{
    ULONG32 ulPreviouslySetDelay = m_pSourceElement->m_ulDelay;
    ULONG32 ulPreviouslySetPureDuration = m_pSourceElement->getPureDuration();

#if defined(_DEBUG)  &&  defined(XXXEH_DEBUGOUT_ADDDURATION)
    {
	FILE* f1 = ::fopen("c:\\smil2AddDuration.txt", bFirstTimeAddDurDebugout?
		ADDDURATION_DEBUGOUT_STR_NEW_FILE :
		ADDDURATION_DEBUGOUT_STR_APPEND_TO_FILE );
	::fprintf(f1, "CSmilTimelineElement{%s}::setDelay(delay=%lu, "
		"bSetByParent=%sE), prior delay=%lu, m_bDelaySet=%sE\n",
		(const char*)m_pID, ulDelay,
		bSetByParent?"TRU":"FALS",
		ulPreviouslySetDelay,
		m_bDelaySet?"TRU":"FALS");
	::fclose(f1);
	bFirstTimeAddDurDebugout = FALSE;
    }
#endif

    if(!m_bDelaySet)
    {
	// /For PR 59584: if we're just resolving this to let the
	// group duration "resolve" to unresolved, don't count begin:
	if(WAY_IN_THE_FUTURE <= ulDelay)
	{
	    HX_ASSERT(WAY_IN_THE_FUTURE >= ulDelay);
	}
	else if(!m_bDelayEvent)
	{
	    BOOL bDelayClippedDueToNegOffset = FALSE;
	    if(m_pSourceElement->m_bBeginOffsetSet)
	    {
		m_pSourceElement->m_ulDelay = ulDelay;

		// /Handle all cases so that we don't overflow:
		UINT32 ulPosOffset = m_pSourceElement->m_lBeginOffset > 0?
			m_pSourceElement->m_lBeginOffset : 0;
		UINT32 ulNegOffset = m_pSourceElement->m_lBeginOffset < 0?

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -