📄 smlelem.cpp
字号:
HX_ASSERT(pSyncAncestor);
// make sure that we do not have an illegal begin value
// if we have a seq for a parent.
// /Note: we want to use our sync ancestor, not our parent, because
// our parent could be a non-time-container like <a>, <switch>,
// or <priorityClass>:
if ((pSyncAncestor && SMILSeq == pSyncAncestor->m_tag &&
// /OK if parent seq was created to expand for repeat purposes:
!m_pNode->m_bRepeatHandled) &&
( (!SUCCEEDED(rettimeval) || NULL==pNextResolvedTimeValue) ||
(pNextResolvedTimeValue->m_type != SmilTimeOffset &&
pNextResolvedTimeValue->m_type != SmilTimeClockValue) ) )
{
// only offsets are legal values...
ret = HXR_INVALID_PARAMETER;
goto cleanup;
}
// /For excl descendants, we don't want to declare that a begin time
// has been set, because we need to figure out whether or not to
// schedule it based on when other excl children begin (which we may
// not know yet):
if (SUCCEEDED(rettimeval) && NULL != pNextResolvedTimeValue)
{
if (pListOfAllResolvedBeginTimes)
{
// /Go through this list and insert each into the pending list:
LISTPOSITION lPosTmp =
pListOfAllResolvedBeginTimes->GetHeadPosition();
while (lPosTmp)
{
SmilTimeValue* pTmpVal = (SmilTimeValue*)
pListOfAllResolvedBeginTimes->GetAt(lPosTmp);
if (pTmpVal && pTmpVal->isTimeResolved() &&
pTmpVal->m_pElement)
{
if (pTmpVal != pNextResolvedTimeValue ||
bIsDescendantOfExcl)
{
// /(?XXXEH- TODO: insert into list based on resolved
// time? note that begin="20s;0s" works OK, so...?)
if (pParser->EstablishBeginTimeList())
{
CHXSimpleList* pList =
pParser->GetPendingBeginTimeList();
// /Don't add if it's a duplicate:
if (!pParser->isDuplicateEntry(pList, pTmpVal))
{
pList->AddTail(pTmpVal);
}
}
}
}
else
{
HX_ASSERT(0 && "timeval invalid");
}
pListOfAllResolvedBeginTimes->GetNext(lPosTmp);
} // /end while(lPos...).
}
HX_DELETE(pListOfAllResolvedBeginTimes);
if (!bIsDescendantOfExcl)
{
bBeginTimeHasBeenSet = TRUE;
HX_ASSERT(pNextResolvedTimeValue->isTimeResolved());
switch (pNextResolvedTimeValue->m_type)
{
case SmilTimeOffset:
case SmilTimeClockValue:
{
// /XXXEH- is this what we really want to do?
// Alternatively, we could have resolved-to "base" time
// as 0 and then m_lOffset is added to get resolved-to
// "offset" time:
m_lBeginOffset = pNextResolvedTimeValue->getTimeOffset();
m_bBeginOffsetSet = TRUE;
// /Handle this now for time containers who never get
// called with a TrackDurationSet():
m_bCurBeginIsOffsetFromSyncBase = TRUE;
m_ulBeginOffsetFromSyncBase = m_lBeginOffset;
#if defined(_DEBUG) // /XXXEH- testing!:
LONG32 lResolvedToTime = 0;
HX_RESULT tmprslt =
pNextResolvedTimeValue->getEffectiveResolvedTime(
lResolvedToTime);
HX_ASSERT(tmprslt==HXR_OK &&
m_lBeginOffset == lResolvedToTime);
#endif
}
break;
case SmilTimeEvent:
#if defined(ENABLE_SYNC_TO_PREV)
case SmilTimeSyncToPrev:
#endif
case SmilTimeSyncBase:
{
// /NOTE: this's time must be *resolved* already which
// shouldn't happen yet:
HX_ASSERT(!pNextResolvedTimeValue->isTimeResolved());
}
break;
case SmilTimeMediaMarker:
{
HX_ASSERT(!pNextResolvedTimeValue->isTimeResolved());
}
break;
case SmilTimeWallclock:
{
// /XXXEH- wouldn't it be better to use
// getEffectiveResolvedTime() here(?) so as to treat all time
// types consistently?
m_lBeginOffset = pNextResolvedTimeValue->getTimeOffset();
m_bBeginOffsetSet = TRUE;
// /Handle this now for time containers who never get
// called with a TrackDurationSet():
m_bCurBeginIsOffsetFromSyncBase = TRUE;
m_ulBeginOffsetFromSyncBase = m_lBeginOffset;
m_bWallClockBegin = TRUE;
}
break;
default:
HX_ASSERT(0);
break;
} // /end of "switch(pNextResolvedTimeValue->m_type)".
} // /end of "if (!bIsDescendantOfExcl)".
}
// /Now, go through all unresolved begin times and add this element to
// the appropriate list(s) for each unresolved time value found:
if (m_pBeginTimeList)
{
lPos = m_pBeginTimeList->GetHeadPosition();
}
if (NULL == lPos) // /list is empty.
{
goto cleanup;
}
while (lPos && HXR_OK == ret)
{
SmilTimeValue* pTmpVal = (SmilTimeValue*)m_pBeginTimeList->GetAt(lPos);
if (pTmpVal && !pTmpVal->isTimeResolved())
{
switch (pTmpVal->m_type)
{
case SmilTimeOffset:
case SmilTimeClockValue:
{
// /We shouldn't ever get here because clock times are
// always resolved:
HX_ASSERT(pTmpVal->isTimeResolved());
}
break;
case SmilTimeSyncBase:
{
pParser->addBeginTimeSyncElement(this);
if (!bBeginTimeHasBeenSet)
{
m_BeginEventSourceID = pTmpVal->m_idRef;
m_nBeginEventSourceTag = pTmpVal->m_position;
// /NOTE: this is unresolved:
m_lBeginEventClockValue =
pTmpVal->getTimeOffset();
}
// /Fixes BUG-20010521_syncArcToElementWith...smil
// where begin="0s;x.end" and x.end was being ignored:
else
{
if (!m_BeginEventSourceID.GetLength())
{
m_BeginEventSourceID = pTmpVal->m_idRef;
m_nBeginEventSourceTag = pTmpVal->m_position;
// /NOTE: this is unresolved:
m_lBeginEventClockValue = pTmpVal->getTimeOffset();
}
else
{
HX_ASSERT(0 &&
"XXXEHodge: need to handle multiple sync-arc begins");
// /XXXEH- TODO: if m_BeginEventSourceID is already
// set due to another sync-arc begin time, we need
// to have a list of m_BeginEventSourceID's & ...etc.
// Currently, just the first one wins. We could
// treat this sync-arc as a beginEvent event-arc...
// (We also need to handle this in SetEndTime().)
}
}
}
break;
#if defined(ENABLE_SYNC_TO_PREV)
case SmilTimeSyncToPrev:
{
// /XXXEH- shouldn't we treat this just like we treat the
// sync base case above by doing the following?:
// pParser->addBeginTimeSyncElement(this);
// /XXXEH- make sure we handle begin="3s; prev.end" where
// both are valid times; the following doesn't handle this
// case:
if (!bBeginTimeHasBeenSet)
{
SMILNode* pSibling =
m_pNode->m_pParent->getFirstChild();
// /Spec says to use parent time container's begin if
// m_pNode is the first child (and has no prev
// sibling):
SMILNode* pLastNode = m_pNode->m_pParent;
while (pSibling)
{
if (pSibling->m_id == m_pNode->m_id)
{
// we found our boy...
break;
}
pLastNode = pSibling;
// /XXXEH- TODO: skip over children that aren't
// *timed* elements, e.g., <a> tags; maybe we
// are supposed to use a non-timed-prev-element's
// last timed child, if any, and, if none exists,
// use it's prev timed sibling???:
pSibling = m_pNode->m_pParent->getNextChild();
}
HX_ASSERT(pSibling && pLastNode);
if (pSibling && pLastNode)
{
// /First, if we had no prev sibling, then
// we need to use our parent time container's
// begin time as our sync base:
if (pLastNode == m_pNode->m_pParent)
{
SMILNode* pFirstTimeContainerAncestor =
pParser->getSyncAncestor(m_pNode);
// /There should ALWAYS be a time container
// ancestor, even if it's the implied seq
// that we create when no time container
// exists as the 1st timed child of the body:
HX_ASSERT(pFirstTimeContainerAncestor);
if (pFirstTimeContainerAncestor)
{
#if XXXEH_
/* /Need to figure out if this is earlier than any current times and, if
so, call insertElementWithPendingBeginOrEnd() with the earlier time, else
call insertElementWithPendingBeginOrEnd() with this (pTmpVal) time:
*/
#endif
// /For parent as prev, we can just treat
// this as a SmilTimeOffset value since
// they're essentially the same thing:
pLastNode = pFirstTimeContainerAncestor;
m_lBeginOffset= pTmpVal->getTimeOffset();
pTmpVal->m_type = SmilTimeOffset;
pTmpVal->setIsTimeResolved(TRUE);
m_bBeginOffsetSet = TRUE;
}
// /else give up; can't do anything here.
}
else // /Use prev sibling time:
{
m_BeginEventSourceID = pLastNode->m_id;
// /XXXEH- wouldn't it be better to use
// getEffectiveResolvedTime() here(?) so as
// to treat all time types consistently?
m_lBeginEventClockValue =
pTmpVal->getTimeOffset();
m_nBeginEventSourceTag =
pTmpVal->m_position;
}
}
else
{
ret = HXR_FAIL;
}
}
}
break;
#endif
case SmilTimeEvent:
{
pParser->addBeginEventElement(pTmpVal);
}
break;
case SmilTimeMediaMarker:
{
pParser->addBeginMediaMarkerSyncElement(pTmpVal);
}
break;
case SmilTimeWallclock:
{
// /We shouldn't ever get here because wallclock times
// are always resolved:
HX_ASSERT(pTmpVal->isTimeResolved());
}
break;
default:
HX_ASSERT(0);
break;
} // /end switch(pTmpVal->m_type).
}
m_pBeginTimeList->GetNext(lPos);
} // /end while (lPos ...).
// else time must already be set.
cleanup:
return ret;
}
HX_RESULT
CSmilElement::setEndTime(CSmilParser* pParser)
{
HX_RESULT ret = HXR_OK;
BOOL bEndTimeHasBeenSet = FALSE;
UINT32 ulOffset = 0;
SmilTimeValue* pNextResolvedTimeValue = NULL;
LISTPOSITION lPos = NULL;
CHXSimpleList* pListOfAllResolvedEndTimes = new CHXSimpleList;
// /Looks at all resolved end times in the list and
// returns the SmilTimeValue with the closest time at or
// later than the time passed in:
HX_RESULT rettimeval = HXR_OK;
rettimeval = getNextResolvedTimeValue(pNextResolvedTimeValue,
SMILTIME_NEGATIVE_INFINITY, SMILTIME_NEGATIVE_INFINITY,
SmilEndTimeList, pListOfAllResolvedEndTimes);
// /NOTE: ret!=HXR_OK is NOT an error condition; it means
// that no value in the end time list was found that was
// resolved.
if (SUCCEEDED(rettimeval) && NULL != pNextResolvedTimeValue)
{
if (pListOfAllResolvedEndTimes)
{
// /Go through this list and insert each into the pending list:
LISTPOSITION lPosTmp =
pListOfAllResolvedEndTimes->GetHeadPosition();
while (lPosTmp)
{
SmilTimeValue* pTmpVal = (SmilTimeValue*)
pListOfAllResolvedEndTimes->GetAt(lPosTmp);
if (pTmpVal && pTmpVal->isTimeResolved() &&
pTmpVal->m_pElement)
{
if (pTmpVal != pNextResolvedTimeValue)
{
// /(?XXXEH- TODO: insert into list based on resolved
// time? end="20s;0s" works OK, so...?)
if (pParser->EstablishEndTimeList())
{
CHXSimpleList* pList =
pParser->GetPendingEndTimeList();
// /Don't add if it's a duplicate:
if (!pParser->isDuplicateEntry(pList, pTmpVal))
{
pList->AddTail(pTmpVal);
}
}
}
}
else
{
HX_ASSERT(0 && "timeval invalid");
}
pListOfAllResolvedEndTimes->GetNext(lPosTmp);
} // /end while(lPos...).
}
HX_DELETE(pListOfAllResolvedEndTimes);
bEndTimeHasBeenSet = TRUE;
HX_ASSERT(pNextResolvedTimeValue->isTimeResolved());
switch (pNextResolvedTimeValue->m_type)
{
case SmilTimeOffset:
case SmilTimeClockValue:
{
// /XXXEH- is this what we really want to do?
// Alternatively, we could have resolved-to "base" time
// as 0 and then m_lOffset is added to get resolved-to
// "offset" time:
m_lEndOffset = pNextResolvedTimeValue->getTimeOffset();
m_bEndOffsetSet = TRUE;
#if defined(_DEBUG) // /XXXEH- testing!:
LONG32 lResolvedToTime = 0;
HX_RESULT tmprslt =
pNextResolvedTimeValue->getEffectiveResolvedTime(
lResolvedToTime);
HX_ASSERT(tmprslt==HXR_OK &&
m_lEndOffset == lResolvedToTime);
#endif
}
break;
case SmilTimeSyncBase:
#if defined(ENABLE_SYNC_TO_PREV)
case SmilTimeSyncToPrev:
#endif
case SmilTimeEvent:
{
// /NOTE: this's time must be *resolved* already which
// shouldn't happen yet:
HX_ASSERT(!pNextResolvedTimeValue->isTimeResolved());
}
break;
case SmilTimeMediaMarker:
{
//XXXEH- TODO: handle media markers:
HX_ASSERT(0);
//pParser->addEndMediaMarkerSyncElement(this);
}
break;
case SmilTimeWallclock:
{
// /XXXEH- wouldn't it be better to use
// getEffectiveResolvedTime() here(?) so as to treat all time
// types consistently?
m_lEndOffset = pNextResolvedTimeValue->getTimeOffset();
m_bEndOffsetSet = TRUE;
m_bWallClockEnd = TRUE;
}
break;
case SmilTimeNone:
break;
} // /end switch(pNextResolvedTimeValue->m_type).
}
// /Now, go through all unresolved end times and add this element to
// the appropriate list(s) for each unresolved time value found:
if (m_pEndTimeList)
{
lPos = m_pEndTimeList->GetHeadPosition();
}
if (NULL == lPos) // /list is empty.
{
goto cleanup;
}
while (lPos && HXR_OK == ret)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -