📄 timeline.cpp
字号:
{ m_zTimerMap.RemoveKey(this); } }#endif /* _UNIX || _MACINTOSH */ return HXR_OK;}void Timeline::Done(void){ HX_RELEASE(m_pScheduler);#if defined (_MACINTOSH)#if defined (_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS) BOOL bBetterWaitForCallbacks = FALSE; if ( m_uiDeferredTaskDepth > 0 ) { char tmpStr[255]; /* Flawfinder: ignore */ sprintf(tmpStr, "m_uiDeferredTaskDepth = %u;g", m_uiDeferredTaskDepth); /* Flawfinder: ignore */// DebugStr(c2pstr(tmpStr));// don't spoil the timing by hitting MacsBug bBetterWaitForCallbacks = TRUE; }#endif m_bIsQuitting = TRUE; // sit-n-spin awaiting interrupts to finish. for ( int i = 0; i < 50; i++ ) { unsigned long dummyTix; Delay( 6, &dummyTix ); if ( !m_bAnyCallbackPending ) { i = 50; } }#if defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS) if ( bBetterWaitForCallbacks ) { if ( m_uiDeferredTaskDepth > 0 ) { DebugStr( "\pOops! After several seconds the deferred task didn't fire off;g" ); } else { DebugStr( "\pNice... the deferred task fired off and we're good to go;g" ); } }#endif m_bIsQuitting = FALSE;#endif}HX_RESULT Timeline::Resume(void){#if defined(HELIX_CONFIG_NOSTATICS) TimelineMapType& m_zTimerMap = GlobalTimelineMapType::Get(&Timeline::m_zTimerMap);#endif m_bPaused = FALSE; if (m_bIsTimerPending) { return HXR_OK; } m_ulLastCallbackTime = HX_GET_TICKCOUNT(); // Set a timer#if defined(_WINDOWS) || defined(_SYMBIAN) m_uiTimerID = HXAsyncTimer::SetTimer(m_ulGranularity, (TIMERPROC)NonMMTimerProc); if( m_bTimerFixup ) m_uiTimerIDFixup = HXAsyncTimer::SetTimer(m_ulGranularity, (TIMERPROC)NonMMTimerProc); // m_uiTimerID = SetTimer( NULL, NULL, (UINT) m_ulGranularity, // (TIMERPROC) NonMMTimerProc );// if (m_bTimerFixup)// m_uiTimerIDFixup = SetTimer( NULL, NULL, (UINT) m_ulGranularity, // (TIMERPROC) NonMMTimerProc );#elif defined(_MACINTOSH) if (m_bUseDeferredTasks) { OSErr e = noErr; if (CLOCKSET(m_tmInfo.tmTask)) { ::RmvTime((QElemPtr) &m_tmInfo); m_bAnyCallbackPending = 0; } m_tmInfo.tmTask.tmAddr = m_uppTask; m_tmInfo.tmRefCon = (long) this; m_tmInfo.tmTask.tmWakeUp = 0L; m_tmInfo.tmTask.tmReserved = 0L; ::InsTime((QElemPtr) &m_tmInfo); ::PrimeTime((QElemPtr) &m_tmInfo, m_ulGranularity); m_bAnyCallbackPending = 1; }#endif // add this timer to the static timer map#if defined(_WINDOWS) || defined(_SYMBIAN) TimerObjects* pTimerObject = new TimerObjects; if (!pTimerObject) { if (!m_bTimerFixup) // This is the "old code". Execute it just as before the // timerfixup functionality was introduced. HXAsyncTimer::KillTimer(m_uiTimerID); else { if (m_uiTimerID) HXAsyncTimer::KillTimer(m_uiTimerID); if (m_uiTimerIDFixup) HXAsyncTimer::KillTimer(m_uiTimerIDFixup); } return HXR_OUTOFMEMORY; } pTimerObject->m_pTimeline = this; pTimerObject->m_uiTimer = m_uiTimerID; m_zTimerMap.SetAt((LONG32) m_uiTimerID, (void*) pTimerObject); if (m_bTimerFixup) m_zTimerMap.SetAt((LONG32) m_uiTimerIDFixup, (void*) pTimerObject);#elif defined(_UNIX) || defined(_MACINTOSH) || defined(__TCS__) || defined(_OPENWAVE) m_zTimerMap.SetAt(this, this);#endif#if defined(_MACINTOSH) && defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS) if ( m_bIsTimerPending ) { DebugStr( "\pTimeLine::Resume -- m_bIsTimerPending already true!;g" ); }#endif m_bIsTimerPending = TRUE; return HXR_OK;}HX_RESULTTimeline::Seek(ULONG32 ulSeekTime){ if (!m_bPaused) { Pause(); Resume(); } return HXR_OK;}HX_RESULTTimeline::SetStartTime(ULONG32 ulTime){ return HXR_OK;}HX_RESULTTimeline::SetGranularity(ULONG32 ulNumMillisecs){ m_ulGranularity = ulNumMillisecs; return HXR_OK;}HX_RESULTTimeline::OnTimeSync(BOOL bAtInterrupt){#ifdef _MACINTOSH if ((InterlockedIncrement(&gTIMELINE_MUTEX) > 1) && bAtInterrupt) { InterlockedDecrement(&gTIMELINE_MUTEX); return HXR_OK; }#endif//{FILE* f1 = ::fopen("d:\\temp\\timeline.txt", "a+"); ::fprintf(f1, "%p: %lu \n", this, HX_GET_TICKCOUNT());::fclose(f1);} if (!m_bPaused) { if (m_pScheduler) { HXScheduler* pScheduler = m_pScheduler; pScheduler->AddRef(); pScheduler->OnTimeSync(bAtInterrupt); pScheduler->Release(); } }#ifdef _MACINTOSH InterlockedDecrement(&gTIMELINE_MUTEX);#endif return HXR_OK;}/* * ********* WINDOWS ONLY ***************** */#if defined(_WINDOWS) || defined(_SYMBIAN)/* * This is a Windows Timer callback proc */void CALLBACK Timeline::NonMMTimerProc( void* hwnd, // handle of window for timer messages UINT32 uMsg, // WM_TIMER message UINT32 idTimer, // timer identifier ULONG32 dwTime // current system time){#if defined(HELIX_CONFIG_NOSTATICS) TimelineMapType& m_zTimerMap = GlobalTimelineMapType::Get(&Timeline::m_zTimerMap);#endif TimerObjects* pTimerObject = NULL; if (m_zTimerMap.Lookup((LONG32) idTimer, (void*&) pTimerObject)) { // MUST call this BEFORE OnTimeSync, because OnTimeSync could // delete the object KillTimerFixup(idTimer, pTimerObject); HX_ASSERT( pTimerObject); HX_ASSERT( pTimerObject->m_pTimeline ); pTimerObject->m_pTimeline->OnTimeSync(); } return;}void Timeline::KillTimerFixup(UINT idTimer, struct TimerObjects* pTimerObject){#if defined(HELIX_CONFIG_NOSTATICS) TimelineMapType& m_zTimerMap = GlobalTimelineMapType::Get(&Timeline::m_zTimerMap);#endif if (pTimerObject->m_pTimeline->m_bTimerFixup == FALSE) return; if (pTimerObject->m_pTimeline->m_uiTimerIDFixup == 0) return; if (pTimerObject->m_pTimeline->m_uiTimerID == 0) return; if (pTimerObject->m_pTimeline->m_uiTimerID == idTimer) { HXAsyncTimer::KillTimer(pTimerObject->m_pTimeline->m_uiTimerIDFixup); m_zTimerMap.RemoveKey((LONG32) pTimerObject->m_pTimeline->m_uiTimerIDFixup); pTimerObject->m_pTimeline->m_uiTimerIDFixup = 0; } else if (pTimerObject->m_pTimeline->m_uiTimerIDFixup == idTimer) { HXAsyncTimer::KillTimer(pTimerObject->m_pTimeline->m_uiTimerID); m_zTimerMap.RemoveKey((LONG32) pTimerObject->m_pTimeline->m_uiTimerID); pTimerObject->m_pTimeline->m_uiTimerID = 0; } return;}#endif/* * ********* MAC ONLY ***************** */#ifdef _MACINTOSH/* * This is the Mac Timer callback proc (deferred task) */pascal void Timeline::MacTimerProc(TMInfoPtr task){ HXMM_INTERRUPTON(); /* * Setup and then install a deferred task */ if (task != NULL && task->tmRefCon != NULL) { Timeline* pTheTimeline = (Timeline*)task->tmRefCon;#if defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS) // m_bIsTimerPending better be true right now if ( !pTheTimeline->m_bIsTimerPending ) { DebugStr( "\pMacTimerProc -- m_bIsTimerPending is FALSE!;g" ); }#endif if (pTheTimeline->m_DeferredTaskStruct.dtAddr != NULL) {#if defined (_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS) if ( pTheTimeline->m_uiDeferredTaskDepth > 0 ) { char tmpStr[255]; /* Flawfinder: ignore */ sprintf(tmpStr, "m_uiDeferredTaskDepth = %u;g", pTheTimeline->m_uiDeferredTaskDepth); /* Flawfinder: ignore */ DebugStr(c2pstr(tmpStr)); }#endif if ( pTheTimeline->m_bIsQuitting ) { // short-circuit and don't install deferred task pTheTimeline->m_bAnyCallbackPending = 0;#if defined (_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS) DebugStr( "\pIt's quitting so we don't install deferred task;g" );#endif } else { // now that we're running on OS X, call the "deferred task" immediately. // Using a deferred thread is an artifact of OS 9: using deferred time // because it's not quite as nasty as hard interrupt time, plus there were // things that assumed they could only be interrupted "once". Those should // now all be THREAD safe (i.e. OS X) and calling deferred time oughtn't // be necessary. Timeline::DeferredTaskProc((long)pTheTimeline); } } } HXMM_INTERRUPTOFF();}pascal void Timeline::DeferredTaskProc(long param){ HXMM_INTERRUPTON(); Timeline* pTheTimeline = (Timeline*)param; if (pTheTimeline) {#ifdef THREADS_SUPPORTED if (pTheTimeline->m_pCoreMutex) pTheTimeline->m_pCoreMutex->Lock();#endif pTheTimeline->m_bAnyCallbackPending = 0; if ( !pTheTimeline->m_bIsQuitting ) { pTheTimeline->InterruptTimeSync(); }#if defined (_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS) else { DebugStr( "\pIn DeferredTaskProc, short-circuiting because we're quitting;g" ); }#endif#ifdef THREADS_SUPPORTED if (pTheTimeline->m_pCoreMutex) pTheTimeline->m_pCoreMutex->Unlock();#endif }#if defined (_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS) if ( pTheTimeline ) { if ( pTheTimeline->m_uiDeferredTaskDepth != 0 ) { char tmpStr[255]; /* Flawfinder: ignore */ sprintf(tmpStr, "m_uiDeferredTaskDepth = %u;g", pTheTimeline->m_uiDeferredTaskDepth); /* Flawfinder: ignore */ DebugStr(c2pstr(tmpStr)); } }#endif HXMM_INTERRUPTOFF();}void Timeline::InterruptTimeSync(void){ if (!m_bUseDeferredTasks) { ULONG32 ulCurTime = HX_GET_TICKCOUNT(); if ( ulCurTime > (m_ulLastCallbackTime + m_ulGranularity) ) { OnTimeSync(FALSE); } } else { if (m_pInterruptState) { m_pInterruptState->EnterInterruptState(); } OnTimeSync(TRUE); #if defined (_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS) if ( m_bIsQuitting ) { DebugStr( "\pIn InterruptTimeSync, about to ::PrimeTime, and we're QUITTING!;g" ); }#endif if ( !m_bIsQuitting ) { ::PrimeTime((QElemPtr) &m_tmInfo, m_ulGranularity); //restart timer m_bAnyCallbackPending = 1; } if (m_pInterruptState) { m_pInterruptState->LeaveInterruptState(); } }} #endif //_MACINTOSH/* * ********* MAC & UNIX ONLY ***************** */#if defined(_UNIX) || defined(_MACINTOSH) || defined(__TCS__) || defined(_OPENWAVE)voidTimeline::CallAllTimeSyncs(void){ #if defined(HELIX_CONFIG_NOSTATICS) TimelineMapType& m_zTimerMap = GlobalTimelineMapType::Get(&Timeline::m_zTimerMap);#endif CHXMapPtrToPtr::Iterator ndxTimeline = m_zTimerMap.Begin(); for (; ndxTimeline != m_zTimerMap.End(); ++ndxTimeline) { Timeline* pCurrentTimeline = (Timeline*)(*ndxTimeline); pCurrentTimeline->OnTimeSync(); }}#endif /* _UNIX || _MACINTOSH */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -