// -----------------------------------------------------------------------------
// CPhSrvComHandRequestManager::NegotiatorRequestCancel
// 
// Cancel a pending command handler request.
// -----------------------------------------------------------------------------
//
void CPhSrvComHandRequestManager::NegotiatorRequestCancel( 
    CPhSrvSubSessionBase& aSubSession )
    {
    // Obtain the subsessions handle
    const TInt handle = aSubSession.SubSessionUniqueHandle();

    // Now look for any pending requests that match.
    const TInt count = iOutstandingComHandRequests->Count();
    for( TInt i = 0; i < count; i++ )
        {
        CPhSrvComHandRequest* entry = ( *iOutstandingComHandRequests )[i];
        if ( entry->SubSessionHandle() == handle )
            {
            if ( entry == iActiveRequest )
                {
                // This request is active, so inform that it is deleted.
                iActiveRequest = NULL;
                }

            // Found matching entry, so cancel it and clean up
            if ( i == 0 ) // 0 stands for emergency request
                {
                entry->Cancel();
                entry->ClearEmergencyRequest();
                }
            else
                {
                iOutstandingComHandRequests->Remove( i );
                entry->Cancel();
                delete entry;
                }
            }
        }
    UpdateQueue();
    }
Ejemplo n.º 2
0
void ProductionWnd::Update() {
    // useful when empire hasn't changed, but production status of it might have
    UpdateInfoPanel();
    UpdateQueue();

    m_build_designator_wnd->Update();
}
Ejemplo n.º 3
0
void ProductionWnd::Reset() {
    //std::cout << "ProductionWnd::Reset()" << std::endl;
    UpdateInfoPanel();
    UpdateQueue();
    m_queue_lb->BringRowIntoView(m_queue_lb->begin());
    m_build_designator_wnd->Reset();
}
Ejemplo n.º 4
0
void ProductionWnd::Update() {
    //std::cout << "ProductionWnd::Update()" << this << std::endl;
    UpdateInfoPanel();
    UpdateQueue();

    m_build_designator_wnd->Update();
}
Ejemplo n.º 5
0
void Scheduler(char* filename,Task* tasks, int num,int (*staticComparer)(const void*,const void*), int isDynamic, int (*dynamicComparer)(const void*,const void*)){
	FILE* output;
	float currentTime, finishTime, nextTime;
	int missedTaskID;
	RunTask* taskQueue = NULL,*currentTask = NULL;
	currentTime = 0.0;
	finishTime = lcmPeriod(tasks,num);

	taskQueue = (RunTask*)malloc( sizeof(RunTask)*(num + 1) ); /*PLUS ONE FOR IDLE*/
	CreateTaskQueue(&taskQueue,tasks,num,staticComparer);
	
	output = fopen(filename,"w");
	printTitles(output,num);

	while(currentTime < finishTime){
		PickTask(taskQueue,num, &currentTask);
		nextTime = CalculateNext(&taskQueue,num,currentTask,currentTime);
		missedTaskID = CheckDeadLineMiss(taskQueue,num,nextTime);
		UpdateQueue(&taskQueue, num, currentTask,currentTime,nextTime,isDynamic,tasks,dynamicComparer,output);
		if (missedTaskID){
			fprintf(output," T%d missed it's deadline.", missedTaskID);
			break;
		}
		currentTime = nextTime;
		fprintf(output,"\n");
	}
	fclose(output);
	free(taskQueue);
}
Ejemplo n.º 6
0
void ResearchWnd::Reset()
{
    m_tech_tree_wnd->Reset();
    UpdateQueue();
    UpdateInfoPanel();
    m_queue_lb->BringRowIntoView(m_queue_lb->begin());
}
Ejemplo n.º 7
0
void Monster::FindPath(Tile* p_start, Tile* p_goal)
{
    Tile* toCheck[4];

    vector<AstarItem> queue;
    vector<AstarItem> visited;

    AstarItem first;
    first.toStart = 0;
    TilePosition startdif = p_goal->getTilePosition() - p_start->getTilePosition();
    first.toGoal = abs(startdif.x) + abs(startdif.y);
    first.tile = p_start;
    first.parent = NULL;
    queue.push_back(first);
    while (queue.size() > 0 && queue.back().tile != p_goal)
    {
        visited.push_back(queue.back());
        TilePosition p = queue.back().tile->getTilePosition();
        queue.pop_back();
        toCheck[0] = m_map->getTile(p + TilePosition(0, 1));
        toCheck[1] = m_map->getTile(p + TilePosition(0, -1));
        toCheck[2] = m_map->getTile(p + TilePosition(1, 0));
        toCheck[3] = m_map->getTile(p + TilePosition(-1, 0));
        for (int i = 0; i < 4; i++)
        {
            if (toCheck[i])
            {
                bool skip = !toCheck[i]->isFree();
                for (unsigned int j = 0; j < visited.size(); j++)
                {
                    if (visited[j].tile == toCheck[i])
                        skip = true;
                }
                if (!skip)
                {
                    int toStart = visited.back().toStart+1;
                    TilePosition dif = p_goal->getTilePosition() - toCheck[i]->getTilePosition();
                    int toGoal = abs(dif.x) + abs(dif.y);
                    UpdateQueue(toCheck[i], visited.size()-1, toStart, toGoal, queue);
                }
            }
        }
    }

    if (queue.size() == 0)
        return;

    m_path.clear();
    m_path.push_back(queue.back().tile);
    int parent = queue.back().parent;
    while (m_path.back() != p_start)
    {
        AstarItem asi = visited[parent];
        m_path.push_back(asi.tile);
        parent = asi.parent;
    }

    return;
}
Ejemplo n.º 8
0
QueueView::QueueView( hb_handle_t * handle )
    : BView( BRect( 0,0,500,300 ), NULL, B_FOLLOW_NONE, B_WILL_DRAW )
{
    fHandle = handle;

    BRect b = Bounds(), r;

    r = BRect( b.right-90,b.bottom-35,b.right-10,b.bottom-10 );
    BButton * button = new BButton( r, NULL, "Close", new BMessage( MSG_CLOSE ) );
    AddChild( button );

    fScrollView = NULL;
    UpdateQueue();
}
// -----------------------------------------------------------------------------
// CPhSrvComHandRequestManager::SetNegotiatorReadyRequestL
// 
// Updates the negotiator so that it knows if the notifier
// session is able to perform the request.
// Does not leave.
// -----------------------------------------------------------------------------
//
void CPhSrvComHandRequestManager::SetNegotiatorReadyRequestL(
    MPhSrvComHandInitiator& aInitiator )
    {
    // There mustn't already be a command handler initiator, or the existing 
    // initiator must be the same as the new one (otherwise, panic).
    __ASSERT_ALWAYS( !iComHandInitiator || &aInitiator == iComHandInitiator, 
        PhoneServerUtils::Panic( 
        EPhoneServerPanicExistingComHandInitiatorFault ) );

    // Update our pointer
    iComHandInitiator = &aInitiator;

    UpdateQueue();
    }
Ejemplo n.º 10
0
void ProductionWnd::Refresh() {
    // useful at start of turn or when loading empire from save.
    // since empire object is recreated based on turn update from server, 
    // connections of signals emitted from the empire must be remade
    m_empire_connection.disconnect();
    EmpireManager& manager = HumanClientApp::GetApp()->Empires();
    if (Empire* empire = manager.Lookup(HumanClientApp::GetApp()->EmpireID()))
        m_empire_connection = GG::Connect(empire->GetProductionQueue().ProductionQueueChangedSignal,
                                          &ProductionWnd::ProductionQueueChangedSlot, this);
    UpdateInfoPanel();
    UpdateQueue();

    m_build_designator_wnd->Refresh();
}
Ejemplo n.º 11
0
void ProductionWnd::Refresh() {
    // useful at start of turn or when loading empire from save, or when
    // the selected empire shown has changed.
    // because empire object is recreated based on turn update from server,
    // connections of signals emitted from the empire must be remade after
    // getting a turn update
    m_empire_connection.disconnect();
    if (Empire* empire = GetEmpire(m_empire_shown_id))
        m_empire_connection = GG::Connect(empire->GetProductionQueue().ProductionQueueChangedSignal,
                                          &ProductionWnd::ProductionQueueChangedSlot, this);

    UpdateInfoPanel();
    UpdateQueue();

    m_build_designator_wnd->Refresh();
}
Ejemplo n.º 12
0
void ResearchWnd::ResearchQueueChangedSlot() {
    UpdateQueue();
    UpdateInfoPanel();
    m_tech_tree_wnd->Update();
}
Ejemplo n.º 13
0
void ResearchWnd::Update() {
    m_tech_tree_wnd->Update();
    UpdateQueue();
    UpdateInfoPanel();
}
Ejemplo n.º 14
0
DWORD CXySubPicQueue::ThreadProc()
{
    SetThreadName(DWORD(-1), "Subtitle Renderer Thread");
    SetThreadPriority(m_hThread, THREAD_PRIORITY_ABOVE_NORMAL);

    bool bAgain = true;
    for (;;) {
        DWORD Ret = WaitForMultipleObjects(EVENT_COUNT, m_ThreadEvents, FALSE, bAgain ? 0 : INFINITE);
        bAgain = false;

        if (Ret == WAIT_TIMEOUT) {
            ;
        } else if ((Ret - WAIT_OBJECT_0) != EVENT_TIME) {
            break;
        }
        double fps = m_fps;
        REFERENCE_TIME rtTimePerFrame = (REFERENCE_TIME)(10000000.0 / fps);
        REFERENCE_TIME rtNow = UpdateQueue();

        int nMaxSubPic = m_nMaxSubPic;

        CComPtr<ISubPicProvider> pSubPicProvider;
        GetSubPicProvider(&pSubPicProvider);
        CComQIPtr<IXyCompatProvider> pXySubPicProvider = pSubPicProvider;
        if (pXySubPicProvider && SUCCEEDED(pSubPicProvider->Lock())) {
            for (REFERENCE_TIME rtStart = rtNow; !m_fBreakBuffering && GetQueueCount() < nMaxSubPic; rtStart += rtTimePerFrame) {
                REFERENCE_TIME rtStop = rtStart + rtTimePerFrame;

                if (m_rtNow >= rtStart) {
                    if (m_rtNow >= rtStop) {
                        continue;
                    }
                }

                if (rtStart >= m_rtNow + 60 * 10000000i64) {    // we are already one minute ahead, this should be enough
                    break;
                }

                if (m_rtNow > rtStop) {
                    TRACE(_T("BEHIND\n"));
                }

                HRESULT hr = pXySubPicProvider->RequestFrame(rtStart, rtStop, INFINITE);
                if (SUCCEEDED(hr)) {
                    ULONGLONG id;
                    hr = pXySubPicProvider->GetID(&id);
                    if (SUCCEEDED(hr)) {
                        SIZE    MaxTextureSize, VirtualSize;
                        POINT   VirtualTopLeft;
                        HRESULT hr2;

                        if (SUCCEEDED(hr2 = pSubPicProvider->GetTextureSize(0, MaxTextureSize, VirtualSize, VirtualTopLeft))) {
                            m_pAllocator->SetMaxTextureSize(MaxTextureSize);
                        }

                        if (m_llSubId == id && !m_Queue.IsEmpty()) { // same subtitle as last time
                            CComPtr<ISubPic> pSubPic = m_Queue.GetTail();
                            pSubPic->SetStop(rtStop);
#if SUBPIC_TRACE_LEVEL > 1
                            CRect r;
                            pSubPic->GetDirtyRect(&r);
                            TRACE(_T("Skip:   %f->%f      %dx%d\n"), double(pSubPic->GetStart()) / 10000000.0, double(pSubPic->GetStop()) / 10000000.0, r.Width(), r.Height());
#endif
                            continue;
                        } else {
                            CComPtr<ISubPic> pStatic;
                            if (FAILED(m_pAllocator->GetStatic(&pStatic))) {
                                break;
                            }

                            pStatic->SetInverseAlpha(true);
                            hr = RenderTo(pStatic, rtStart, rtStop, fps, true);
#if SUBPIC_TRACE_LEVEL > 0
                            CRect r;
                            pStatic->GetDirtyRect(&r);
                            TRACE(_T("Render: %f->%f      %dx%d\n"), double(rtStart) / 10000000.0, double(rtStop) / 10000000.0, r.Width(), r.Height());
#endif
                            if (FAILED(hr)) {
                                break;
                            }

                            CComPtr<ISubPic> pDynamic;
                            if (FAILED(m_pAllocator->AllocDynamic(&pDynamic))
                                    || FAILED(pStatic->CopyTo(pDynamic))) {
                                break;
                            }

                            if (SUCCEEDED(hr2)) {
                                pDynamic->SetVirtualTextureSize(VirtualSize, VirtualTopLeft);
                            }

                            RelativeTo relativeTo;
                            if (SUCCEEDED(pSubPicProvider->GetRelativeTo(0, relativeTo))) {
                                pDynamic->SetRelativeTo(relativeTo);
                            }

                            AppendQueue(pDynamic);
                            m_llSubId = id;
                            bAgain = true;
                        }
                    }
                }
            }

            pSubPicProvider->Unlock();
        }

        if (m_fBreakBuffering) {
            bAgain = true;
            CAutoLock cQueueLock(&m_csQueueLock);

            REFERENCE_TIME rtInvalidate = m_rtInvalidate;

            POSITION Iter = m_Queue.GetHeadPosition();
            while (Iter) {
                POSITION ThisPos = Iter;
                ISubPic* pSubPic = m_Queue.GetNext(Iter);

                REFERENCE_TIME rtStart = pSubPic->GetStart();
                REFERENCE_TIME rtStop = pSubPic->GetStop();

                if (rtStop > rtInvalidate) {
#if SUBPIC_TRACE_LEVEL >= 0
                    TRACE(_T("Removed subtitle because of invalidation: %f->%f\n"), double(rtStart) / 10000000.0, double(rtStop) / 10000000.0);
#endif
                    m_Queue.RemoveAt(ThisPos);
                    continue;
                }
            }

            /*
            while (GetCount() && GetTail()->GetStop() > rtInvalidate)
            {
                if (GetTail()->GetStart() < rtInvalidate) GetTail()->SetStop(rtInvalidate);
                else
                {
                    RemoveTail();
                }
            }
            */

            m_fBreakBuffering = false;
        }
    }

    return 0;
}
Ejemplo n.º 15
0
void ProductionWnd::ProductionQueueChangedSlot() {
    UpdateInfoPanel();
    UpdateQueue();
    m_build_designator_wnd->Update();
}
Ejemplo n.º 16
0
DWORD CSubPicQueue::ThreadProc()
{	
    BOOL bDisableAnim = m_bDisableAnim;
    SetThreadPriority(m_hThread, bDisableAnim ? THREAD_PRIORITY_LOWEST : THREAD_PRIORITY_ABOVE_NORMAL/*THREAD_PRIORITY_BELOW_NORMAL*/);

    bool bAgain = true;
    while(1)
    {
        DWORD Ret = WaitForMultipleObjects(EVENT_COUNT, m_ThreadEvents, FALSE, bAgain ? 0 : INFINITE);
        bAgain = false;

        if (Ret == WAIT_TIMEOUT)
            ;
        else if ((Ret - WAIT_OBJECT_0) != EVENT_TIME)
            break;
        double fps = m_fps;
        REFERENCE_TIME rtTimePerFrame = max(10000000.0/fps*1.5, 1000000); //1.5 to reduce flick
        REFERENCE_TIME rtNow = UpdateQueue();

        int nMaxSubPic = m_nMaxSubPic;

        CComPtr<ISubPicProvider> pSubPicProvider;
        if(SUCCEEDED(GetSubPicProvider(&pSubPicProvider)) && pSubPicProvider
            && SUCCEEDED(pSubPicProvider->Lock()) && SUCCEEDED(m_pAllocator->Lock()))
        {
            for(POSITION pos = pSubPicProvider->GetStartPosition(rtNow, fps); 
                pos && !m_fBreakBuffering && GetQueueCount() < (size_t)nMaxSubPic; 
                pos = pSubPicProvider->GetNext(pos))
            {
                REFERENCE_TIME rtStart = pSubPicProvider->GetStart(pos, fps);
                REFERENCE_TIME rtStop = pSubPicProvider->GetStop(pos, fps);

                if(m_rtNow >= rtStart)
                {
                    //						m_fBufferUnderrun = true;
                    if(m_rtNow >= rtStop) continue;
                }

                if(rtStart >= m_rtNow + 60*10000000i64) // we are already one minute ahead, this should be enough
                    break;

                if(rtNow < rtStop)
                {
                    REFERENCE_TIME rtCurrent = max(rtNow, rtStart);
                    bool bIsAnimated = pSubPicProvider->IsAnimated(pos) && !bDisableAnim;
                    while (rtCurrent < rtStop)
                    {

                        SIZE	MaxTextureSize, VirtualSize;
                        POINT	VirtualTopLeft;
                        HRESULT	hr2;
                        if (SUCCEEDED (hr2 = pSubPicProvider->GetTextureSize(pos, MaxTextureSize, VirtualSize, VirtualTopLeft)))
                            m_pAllocator->SetMaxTextureSize(MaxTextureSize);

                        CComPtr<ISubPic> pStatic;
                        if(FAILED(m_pAllocator->GetStatic(&pStatic)))
                            break;

                        HRESULT hr;
                        if (bIsAnimated)
                        {
                            //if (rtCurrent < m_rtNow + rtTimePerFrame)
                             //   rtCurrent = min(m_rtNow + rtTimePerFrame, rtStop-1);

                            REFERENCE_TIME rtEndThis = min(rtCurrent + rtTimePerFrame, rtStop);
                            hr = RenderTo(pStatic, rtCurrent, rtEndThis, fps, bIsAnimated);
                            pStatic->SetSegmentStart(rtStart);
                            pStatic->SetSegmentStop(rtStop);
#if DSubPicTraceLevel > 0
                            CRect r;
                            pStatic->GetDirtyRect(&r);
                            TRACE("Render: %f %f %f->%f    %f->%f      %dx%d\n",m_fps ,(double)rtTimePerFrame/ 10000000.0 , double(rtCurrent) / 10000000.0, double(rtEndThis) / 10000000.0, double(rtStart) / 10000000.0, double(rtStop) / 10000000.0, r.Width(), r.Height());
#endif
                            rtCurrent = rtEndThis;


                        }
                        else
                        {
                            hr = RenderTo(pStatic, rtStart, rtStop, fps, bIsAnimated);
                            rtCurrent = rtStop;
                        }			
#if DSubPicTraceLevel > 0
                        if (m_rtNow > rtCurrent)
                        {
                            TRACE("BEHIND\n");
                        }
#endif

                        if(FAILED(hr))
                            break;

                        if(S_OK != hr) // subpic was probably empty
                            continue;

                        CComPtr<ISubPic> pDynamic;
                        if(FAILED(m_pAllocator->AllocDynamic(&pDynamic))
                            || FAILED(pStatic->CopyTo(pDynamic)))
                            break;

                        if (SUCCEEDED (hr2))
                            pDynamic->SetVirtualTextureSize (VirtualSize, VirtualTopLeft);

                        AppendQueue(pDynamic);
                        bAgain = true;

                        if (GetQueueCount() >= (size_t)nMaxSubPic)
                            break;
                    }
                }
            }

            pSubPicProvider->Unlock();
            m_pAllocator->Unlock();
        }

        if(m_fBreakBuffering)
        {
            bAgain = true;
            CAutoLock cQueueLock(&m_csQueueLock);

            REFERENCE_TIME rtInvalidate = m_rtInvalidate;

            POSITION Iter = m_Queue.GetHeadPosition();
            while(Iter)
            {
                POSITION ThisPos = Iter;
                ISubPic *pSubPic = m_Queue.GetNext(Iter);

                REFERENCE_TIME rtStart = pSubPic->GetStart();
                REFERENCE_TIME rtStop = pSubPic->GetStop();

                if (rtStop > rtInvalidate)
                {
#if DSubPicTraceLevel >= 0
                    TRACE(("Removed subtitle because of invalidation: %f->%f\n"), double(rtStart) / 10000000.0, double(rtStop) / 10000000.0);
#endif
                    m_Queue.RemoveAt(ThisPos);
                    continue;
                }
            }

            /*
            while(GetCount() && GetTail()->GetStop() > rtInvalidate)
            {
            if(GetTail()->GetStart() < rtInvalidate) GetTail()->SetStop(rtInvalidate);
            else 
            {
            RemoveTail();
            }
            }
            */

            m_fBreakBuffering = false;
        }
    }

    return(0);
}
Ejemplo n.º 17
0
DWORD CSubPicQueue::ThreadProc()
{
    BOOL bDisableAnim = m_bDisableAnim;
    SetThreadName(DWORD(-1), "Subtitle Renderer Thread");
    SetThreadPriority(m_hThread, bDisableAnim ? THREAD_PRIORITY_LOWEST : THREAD_PRIORITY_ABOVE_NORMAL);

    bool bAgain = true;
    for (;;) {
        DWORD Ret = WaitForMultipleObjects(EVENT_COUNT, m_ThreadEvents, FALSE, bAgain ? 0 : INFINITE);
        bAgain = false;

        if (Ret == WAIT_TIMEOUT) {
            ;
        } else if ((Ret - WAIT_OBJECT_0) != EVENT_TIME) {
            break;
        }
        double fps = m_fps;
        REFERENCE_TIME rtTimePerFrame = (REFERENCE_TIME)(10000000.0 / fps);
        REFERENCE_TIME rtNow = UpdateQueue();

        int nMaxSubPic = m_nMaxSubPic;

        CComPtr<ISubPicProvider> pSubPicProvider;
        if (SUCCEEDED(GetSubPicProvider(&pSubPicProvider)) && pSubPicProvider
                && SUCCEEDED(pSubPicProvider->Lock())) {
            for (POSITION pos = pSubPicProvider->GetStartPosition(rtNow, fps);
                    pos && !m_fBreakBuffering && GetQueueCount() < nMaxSubPic;
                    pos = pSubPicProvider->GetNext(pos)) {
                REFERENCE_TIME rtStart = pSubPicProvider->GetStart(pos, fps);
                REFERENCE_TIME rtStop = pSubPicProvider->GetStop(pos, fps);

                if (m_rtNow >= rtStart) {
                    if (m_rtNow >= rtStop) {
                        continue;
                    }
                }

                if (rtStart >= m_rtNow + 60 * 10000000i64) {    // we are already one minute ahead, this should be enough
                    break;
                }

                if (rtNow < rtStop) {
                    REFERENCE_TIME rtCurrent = std::max(rtNow, rtStart);
                    bool bIsAnimated = pSubPicProvider->IsAnimated(pos) && !bDisableAnim;
                    while (rtCurrent < rtStop) {
                        SIZE    MaxTextureSize, VirtualSize;
                        POINT   VirtualTopLeft;
                        HRESULT hr2;

                        if (SUCCEEDED(hr2 = pSubPicProvider->GetTextureSize(pos, MaxTextureSize, VirtualSize, VirtualTopLeft))) {
                            m_pAllocator->SetMaxTextureSize(MaxTextureSize);
                        }

                        CComPtr<ISubPic> pStatic;
                        if (FAILED(m_pAllocator->GetStatic(&pStatic))) {
                            break;
                        }

                        HRESULT hr;
                        if (bIsAnimated) {
                            REFERENCE_TIME rtEndThis = std::min(rtCurrent + rtTimePerFrame, rtStop);
                            hr = RenderTo(pStatic, rtCurrent, rtEndThis, fps, bIsAnimated);
                            pStatic->SetSegmentStart(rtStart);
                            pStatic->SetSegmentStop(rtStop);
#if SUBPIC_TRACE_LEVEL > 0
                            CRect r;
                            pStatic->GetDirtyRect(&r);
                            TRACE(_T("Render: %f->%f    %f->%f      %dx%d\n"), double(rtCurrent) / 10000000.0, double(rtEndThis) / 10000000.0, double(rtStart) / 10000000.0, double(rtStop) / 10000000.0, r.Width(), r.Height());
#endif
                            rtCurrent = rtEndThis;
                        } else {
                            hr = RenderTo(pStatic, rtStart, rtStop, fps, bIsAnimated);
                            // Non-animated subtitles aren't part of a segment
                            pStatic->SetSegmentStart(0);
                            pStatic->SetSegmentStop(0);
                            rtCurrent = rtStop;
                        }
#if SUBPIC_TRACE_LEVEL > 0
                        if (m_rtNow > rtCurrent) {
                            TRACE(_T("BEHIND\n"));
                        }
#endif

                        if (FAILED(hr)) {
                            break;
                        }

                        if (S_OK != hr) { // subpic was probably empty
                            continue;
                        }

                        CComPtr<ISubPic> pDynamic;
                        if (FAILED(m_pAllocator->AllocDynamic(&pDynamic))
                                || FAILED(pStatic->CopyTo(pDynamic))) {
                            break;
                        }

                        if (SUCCEEDED(hr2)) {
                            pDynamic->SetVirtualTextureSize(VirtualSize, VirtualTopLeft);
                        }

                        RelativeTo relativeTo;
                        if (SUCCEEDED(pSubPicProvider->GetRelativeTo(pos, relativeTo))) {
                            pDynamic->SetRelativeTo(relativeTo);
                        }

                        AppendQueue(pDynamic);
                        bAgain = true;

                        if (GetQueueCount() >= nMaxSubPic) {
                            break;
                        }
                    }
                }
            }

            pSubPicProvider->Unlock();
        }

        if (m_fBreakBuffering) {
            bAgain = true;
            CAutoLock cQueueLock(&m_csQueueLock);

            REFERENCE_TIME rtInvalidate = m_rtInvalidate;

            POSITION Iter = m_Queue.GetHeadPosition();
            while (Iter) {
                POSITION ThisPos = Iter;
                ISubPic* pSubPic = m_Queue.GetNext(Iter);

                REFERENCE_TIME rtStart = pSubPic->GetStart();
                REFERENCE_TIME rtStop = pSubPic->GetStop();
                REFERENCE_TIME rtSegmentStop = pSubPic->GetSegmentStop();

                if (rtSegmentStop > rtInvalidate) {
#if SUBPIC_TRACE_LEVEL >= 0
                    TRACE(_T("Removed subtitle because of invalidation: %f -> %f (%f)\n"),
                          double(rtStart) / 10000000.0, double(rtStop) / 10000000.0, double(rtSegmentStop) / 10000000.0);
#endif
                    m_Queue.RemoveAt(ThisPos);
                    continue;
                }
            }

            /*
            while (GetCount() && GetTail()->GetStop() > rtInvalidate)
            {
                if (GetTail()->GetStart() < rtInvalidate) GetTail()->SetStop(rtInvalidate);
                else
                {
                    RemoveTail();
                }
            }
            */

            m_fBreakBuffering = false;
        }
    }

    return 0;
}