smltime.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,795 行 · 第 1/5 页
CPP
1,795 行
/* ***** BEGIN LICENSE BLOCK *****
* Source last modified: $Id: smltime.cpp,v 1.3.4.2 2004/07/13 23:02:47 ehodge Exp $
*
* Portions Copyright (c) 1995-2004 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 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the current version of the RealNetworks Community
* Source License (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.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL") in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your version of
* this file only under the terms of the GPL, and not to allow others
* to use your version of this file under the terms of either the RPSL
* or RCSL, indicate your decision by deleting the provisions above
* and replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient may
* use your version of this file under the terms of any one of the
* RPSL, the RCSL or the GPL.
*
* 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)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?