📄 hxcleng.cpp
字号:
// might be memory error in constructor... if (m_LastError) return m_LastError; HXPlayer* lpPlayer = NewPlayer(); if( !lpPlayer ) { m_LastError = HXR_OUTOFMEMORY; return m_LastError; } CHXAudioPlayer* pAudioPlayer = 0; HX_RESULT theErr = HXR_OK; UINT32 unRegistryID = 0; char szPlayerName[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */ if (!lpPlayer) { return HXR_OUTOFMEMORY; } /* Local AddRef to keep the object around */ lpPlayer->AddRef(); // create registry entry for this player SafeSprintf(szPlayerName, MAX_DISPLAY_NAME, "Statistics.Player%ld", m_ulPlayerIndex); m_ulPlayerIndex++; #if defined(HELIX_FEATURE_REGISTRY) unRegistryID = m_pRegistry->AddComp(szPlayerName);#endif /* HELIX_FEATURE_REGISTRY */#if defined(HELIX_FEATURE_AUDIO) theErr = m_pAudioSession->CreateAudioPlayer(&pAudioPlayer); if (theErr == HXR_OK) { theErr = lpPlayer->Init(this, unRegistryID, pAudioPlayer); lpPlayer->SetInterrupt(m_bUseCoreThread); /* HXPlayer will keep it around */ HX_RELEASE(pAudioPlayer); }#endif /* HELIX_FEATURE_AUDIO */ if (theErr == HXR_OK) { //Return Copy pPlayer = lpPlayer; pPlayer->AddRef(); // Keep Copy m_PlayerList.AddHead((void *) pPlayer); pPlayer->AddRef(); m_pPlayerSinkControl->PlayerCreated(pPlayer); } //Release Local Copy HX_RELEASE(lpPlayer); return theErr;}CHXAudioSession*HXClientEngine::NewAudioSession(){ return (new CHXAudioSession());}HXPlayer*HXClientEngine::NewPlayer(){ return (new HXPlayer());}HXCookies*HXClientEngine::NewCookies(){ HXCookies* pRet = NULL;#if defined(HELIX_FEATURE_COOKIES) pRet = (new HXCookies((IUnknown*) (IHXClientEngine*) this));#endif /* defined(HELIX_FEATURE_COOKIES) */ return pRet;}/************************************************************************ * Method: * IHXClientEngine::ClosePlayer * Purpose: * Called by the engine when it is done using the player... * */STDMETHODIMP HXClientEngine::ClosePlayer(IHXPlayer* pPlayer){ CHXSimpleList::Iterator lIterator = m_PlayerList.Begin(); LISTPOSITION lPosition = m_PlayerList.Find(pPlayer); if (lPosition) { m_PlayerList.RemoveAt(lPosition); HXPlayer* pHXPlayer = (HXPlayer*) pPlayer; m_pPlayerSinkControl->PlayerClosed(pPlayer); pHXPlayer->ClosePlayer(); pPlayer->Release(); return HXR_OK; } else { return HXR_INVALID_PARAMETER; }}/************************************************************************ * Method: * IHXClientEngine::GetPlayerCount * Purpose: * Returns the current number of source instances supported by * this player instance. */STDMETHODIMP_(UINT16) HXClientEngine::GetPlayerCount(){ return (UINT16)m_PlayerList.GetCount();}/************************************************************************ * Method: * IHXClientEngine::GetPlayer * Purpose: * Returns the Nth source instance supported by this player. */STDMETHODIMP HXClientEngine::GetPlayer( UINT16 nIndex, REF(IUnknown*) pUnknown){ LISTPOSITION pos = m_PlayerList.FindIndex(nIndex); if (!pos) { pUnknown = NULL; return HXR_INVALID_PARAMETER; } HXPlayer* pPlayer = (HXPlayer*)m_PlayerList.GetAt(pos); HX_ASSERT(pPlayer); return pPlayer->QueryInterface(IID_IUnknown,(void**)&pUnknown);} /************************************************************************ * Method: * IHXClientEngine::GetPlayerBySite * Purpose: * Returns the IHXPlayer instance supported by this client * engine instance that contains the specified IHXSite. */STDMETHODIMP HXClientEngine::GetPlayerBySite( IHXSite* pSite, REF(IUnknown*) pUnknown){ pUnknown = NULL; HXPlayer* pPlayer = NULL; for (int i = 0; i < m_PlayerList.GetCount(); ++i) { LISTPOSITION pos = m_PlayerList.FindIndex(i); pPlayer = (HXPlayer*)m_PlayerList.GetAt(pos); if (pPlayer->IsSitePresent(pSite)) return pPlayer->QueryInterface(IID_IUnknown,(void**)&pUnknown); } return HXR_FAIL;}/************************************************************************* Method:* IHXClientEngine::EventOccurred* Purpose:* Clients call this to pass OS events to all players. HXxEvent* defines a cross-platform event.*/STDMETHODIMP HXClientEngine::EventOccurred(HXxEvent* pEvent){#if defined(_UNIX)#if defined(HELIX_FEATURE_PLAYBACK_NET)#if defined(_UNIX_THREADED_NETWORK_IO) if( !m_bNetworkThreading ) if (!pEvent) unix_TCP::process_idle(); //XXXgfw Just keep this for unix gold. Then do it right. //This is the new unix message loop. //Check the main app thread for any messages. if(m_bNetworkThreading) { ThreadEngine* pEngine = ThreadEngine::GetThreadEngine(); HX_ASSERT( pEngine ); HXUnixThread* pMainAppThread = (HXUnixThread*)pEngine->GetMainAppThread(); HX_ASSERT( pMainAppThread ); struct HXThreadMessage msg; while(pMainAppThread->PeekMessage(&msg, 0, 0, TRUE )==HXR_OK) { if( msg.m_ulMessage != 0 ) { ThreadedConn* pThat = (ThreadedConn*)msg.m_pParam1; if (pThat != NULL) { switch(msg.m_ulMessage) { case HXMSG_ASYNC_DNS: pThat->OnAsyncDNS((BOOL)msg.m_pParam2); break; case HXMSG_ASYNC_CONNECT: pThat->OnConnect((BOOL)msg.m_pParam2); break; case HXMSG_ASYNC_READ: pThat->OnReadNotification(); break; case HXMSG_ASYNC_WRITE: pThat->OnWriteNotification(); break; case HXMSG_ASYNC_ACCEPT: pThat->OnAcceptNotification(); break; default: HX_ASSERT("Unknown message" == NULL ); break; } } } } } #else if (!pEvent) unix_TCP::process_idle();#endif //_UNIX_THREADED_NETWORK_IO #endif //HELIX_FEATURE_PLAYBACK_NET #ifdef _MAC_UNIX if (m_pCoreMutex) { m_pCoreMutex->Lock(); } LISTPOSITION lPosition = m_PlayerList.GetHeadPosition(); HXPlayer* pPlayer; while (lPosition != NULL) { pPlayer = (HXPlayer*) m_PlayerList.GetNext(lPosition); pPlayer->EventOccurred(pEvent); } #ifdef HELIX_FEATURE_VIDEO CHXSiteManager::EventOccurred(pEvent);#endif if (m_pCoreMutex) { m_pCoreMutex->Unlock(); } /* Do not pump the core on any other event since the top level * sends fake update events with doctored visualRegion. If we pump * the core on such an event, it may result in a timesync * and a draw. Since the visualRegiom may be set to a wrong value, * nothing may be displayed. */ if (pEvent->event == nullEvent) { Timeline::CallAllTimeSyncs(); } #else if (m_pSiteEventHandler) { m_pSiteEventHandler->EventOccurred(pEvent); } if (!pEvent) { Timeline::CallAllTimeSyncs(); }#endif#elif defined(__TCS__) #if defined(HELIX_FEATURE_PLAYBACK_NET) if (!pEvent) { tm1_TCP::process_idle(); }#endif //HELIX_FEATURE_PLAYBACK_NET if (m_pSiteEventHandler) { m_pSiteEventHandler->EventOccurred(pEvent); } if (!pEvent) { Timeline::CallAllTimeSyncs(); } #elif defined (_MACINTOSH) //if def _UNIX#define MINIMUM_TIME_BETWEEN_NULL_EVENTS 10 static UINT32 ulLastNullEventTime = 0; if (pEvent && pEvent->event == nullEvent) { UINT32 ulCurrentTime = HX_GET_TICKCOUNT(); static Rect sLastNullEventClipRect = {0,0,0,0}; Rect thisClipRect = {0,0,0,0};#ifdef _CARBON GrafPtr thePort = GetQDGlobalsThePort(); if (thePort) { RgnHandle clipRgn = ::NewRgn(); GetPortClipRegion(thePort, clipRgn); GetRegionBounds(clipRgn, &thisClipRect); ::DisposeRgn(clipRgn); }#else if (qd.thePort && qd.thePort->clipRgn) { thisClipRect = (**qd.thePort->clipRgn).rgnBBox; }#endif if (!::EqualRect(&sLastNullEventClipRect, &thisClipRect)) { sLastNullEventClipRect = thisClipRect; // if it's not equal to the previous clip rectangle, be sure // to pass this null event through so the clip region information // can be propogated if necessary. } else { if (CALCULATE_ELAPSED_TICKS(ulLastNullEventTime, ulCurrentTime) < MINIMUM_TIME_BETWEEN_NULL_EVENTS) { // ignore a null event.. too many of them! return HXR_OK; } } ulLastNullEventTime = ulCurrentTime; } if (m_pCoreMutex) { m_pCoreMutex->Lock(); } LISTPOSITION lPosition = m_PlayerList.GetHeadPosition(); HXPlayer* pPlayer; while (lPosition != NULL) { pPlayer = (HXPlayer*) m_PlayerList.GetNext(lPosition); pPlayer->EventOccurred(pEvent); } #ifdef HELIX_FEATURE_VIDEO extern ULONG32 gTIMELINE_MUTEX; InterlockedIncrement(&gTIMELINE_MUTEX); CHXSiteManager::EventOccurred(pEvent); InterlockedDecrement(&gTIMELINE_MUTEX);#endif static UINT32 ulLastTimeMemoryCompacted = 0; UINT32 ulTickCount = HX_GET_TICKCOUNT(); // every thirty seconds, compact memory. if ( CALCULATE_ELAPSED_TICKS( ulLastTimeMemoryCompacted, ulTickCount ) >= 30000 ) { HXMM_COMPACT(); ulLastTimeMemoryCompacted = ulTickCount; } if (m_pCoreMutex) { m_pCoreMutex->Unlock(); } /* Do not pump the core on any other event since the top level * sends fake update events with doctored visualRegion. If we pump * the core on such an event, it may result in a timesync * and a draw. Since the visualRegiom may be set to a wrong value, * nothing may be displayed. */ if (pEvent->event == nullEvent) { Timeline::CallAllTimeSyncs(); }#elif defined(_OPENWAVE) // if defined(_UNIX) if (!pEvent) { Timeline::CallAllTimeSyncs(); }#endif // _UNIX return HXR_OK;}#ifdef _UNIX/************************************************************************ * Method: * IHXClientEngine::Select * Purpose: * Top level clients under Unix should use this instead of * select() to select for events. */STDMETHODIMP_(INT32)HXClientEngine::Select(INT32 n, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout){ int s=0; //XXXgfw no need for these selects if we aren't doing network i/o. //Of course, it would be nice for those using this instead of a sleep //to time their callbacks back into the core, that it works... //I guess we can just turn this into a sleep for timeval seconds if //we are not doing any network playback. Of course, if you have a //threaded core it won't hurt to much either way.#if defined(HELIX_FEATURE_PLAYBACK_NET) fd_set real_readfds; fd_set real_writefds; fd_set real_exceptfds; struct timeval tv; static unix_TCP* un = 0; if(!un) { un = new unix_TCP; } if(readfds) { real_readfds = *readfds; } else { FD_ZERO(&real_readfds); } if(writefds) { real_writefds = *writefds; } else { FD_ZERO(&real_writefds); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -