📄 smlelem.cpp
字号:
// 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, ifso, call insertElementWithPendingBeginOrEnd() with the earlier time, elsecall 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_RESULTCSmilElement::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) { SmilTimeValue* pTmpVal = (SmilTimeValue*)m_pEndTimeList->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->addEndTimeSyncElement(this); // /XXXEH- make sure we handle end="3s; prev.end" where
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -