📄 hxcleng.cpp
字号:
{
delete this;
}
return 0;
}
/*
* IHXClientEngine methods
*/
/************************************************************************
* Method:
* IHXClientEngine::CreatePlayer
* Purpose:
* TBD.
*
*/
STDMETHODIMP HXClientEngine::CreatePlayer(IHXPlayer* &pPlayer)
{
if (!m_bInitialized)
{
_Initialize();
}
// 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -