📄 eventmgr.cpp
字号:
{
LISTPOSITION pos = m_pEventQueue->GetHeadPosition();
while (pos)
{
// Get the event
CRendererEvent* pEvent =
(CRendererEvent*) m_pEventQueue->GetNext(pos);
if (pEvent)
{
// Loop through our lists and test each sink
// to see if it should be passed this event
//
// XXXMEH - TODO - short-circuit the callback - if
// we find out that there are no sinks registered for
// this kind of event up front, then we shouldn't
// even fire the callback
//
if (m_pSinkList && m_pSinkList->GetCount() > 0)
{
LISTPOSITION pos = m_pSinkList->GetHeadPosition();
while (pos)
{
IHXEventSink* pSink =
(IHXEventSink*) m_pSinkList->GetNext(pos);
if (ShouldSinkGetEvent(pSink, pEvent))
{
pEvent->Fire(pSink);
}
}
}
}
// Now that we've processed the event,
// we can delete it
HX_DELETE(pEvent);
}
// Now remove everything from the queue
m_pEventQueue->RemoveAll();
}
// Unlock the mutex
if (m_pEventQueueMutex) m_pEventQueueMutex->Unlock();
return retVal;
}
STDMETHODIMP CRendererEventManager::Close()
{
HX_RESULT retVal = HXR_OK;
// Cleanup all remaining callbacks
if (m_pCallback && m_pScheduler)
{
m_pScheduler->Remove(m_pCallback->GetPendingCallback());
m_pCallback->CallbackCanceled();
}
HX_RELEASE(m_pCallback);
HX_RELEASE(m_pScheduler);
HX_RELEASE(m_pContext);
ClearSinks();
HX_DELETE(m_pSinkList);
HX_DELETE(m_pSinkToFilterMap);
ClearEventQueue();
HX_DELETE(m_pEventQueue);
HX_RELEASE(m_pEventQueueMutex);
return retVal;
}
void CRendererEventManager::ClearSinks()
{
if (m_pSinkToFilterMap)
{
// Run through the filter map and release each entry
POSITION pos = m_pSinkToFilterMap->GetStartPosition();
while (pos)
{
void* pKey = NULL;
void* pEntry = NULL;
m_pSinkToFilterMap->GetNextAssoc(pos, pKey, pEntry);
if (pEntry)
{
// Get the filter
CHXSimpleList* pFilter = (CHXSimpleList*) pEntry;
// Clear this list
ClearSinkFilterList(pFilter);
// Delete the rule list
HX_DELETE(pFilter);
}
}
m_pSinkToFilterMap->RemoveAll();
}
if (m_pSinkList)
{
// Run through the list, releasing the sinks
LISTPOSITION pos = m_pSinkList->GetHeadPosition();
while (pos)
{
IHXEventSink* pSink = (IHXEventSink*) m_pSinkList->GetNext(pos);
HX_RELEASE(pSink);
}
m_pSinkList->RemoveAll();
}
}
BOOL CRendererEventManager::IsSinkInList(IHXEventSink* pSink)
{
BOOL bRet = FALSE;
if (pSink && m_pSinkList)
{
LISTPOSITION pos = m_pSinkList->GetHeadPosition();
while (pos)
{
IHXEventSink* pListSink =
(IHXEventSink*) m_pSinkList->GetNext(pos);
if (pListSink &&
pListSink == pSink)
{
bRet = TRUE;
break;
}
}
}
return bRet;
}
void CRendererEventManager::ClearEventQueue()
{
if (m_pEventQueue && m_pEventQueue->GetCount() > 0)
{
LISTPOSITION pos = m_pEventQueue->GetHeadPosition();
while (pos)
{
CRendererEvent* pEvent =
(CRendererEvent*) m_pEventQueue->GetNext(pos);
HX_DELETE(pEvent);
}
m_pEventQueue->RemoveAll();
}
}
BOOL CRendererEventManager::ShouldSinkGetEvent(IHXEventSink* pSink,
CRendererEvent* pEvent)
{
BOOL bRet = FALSE;
if (pSink && pEvent && m_pSinkToFilterMap)
{
// Look up the filter for this sink
void* pVoid = NULL;
if (m_pSinkToFilterMap->Lookup((void*) pSink, pVoid))
{
// Get the filter
CHXSimpleList* pFilter = (CHXSimpleList*) pVoid;
// Check if the event passes the filter
bRet = PassFilter(pFilter, pEvent);
}
}
return bRet;
}
BOOL CRendererEventManager::PassFilter(CHXSimpleList* pFilter,
CRendererEvent* pEvent)
{
BOOL bRet = FALSE;
// Do we have a non-NULL filter?
if (pFilter)
{
if (pEvent)
{
// Loop through the rules until we find a rule
// that will allow this event to pass through
LISTPOSITION pos = pFilter->GetHeadPosition();
while (pos)
{
CEventSinkFilterRule* pRule =
(CEventSinkFilterRule*) pFilter->GetNext(pos);
if (PassFilterRule(pRule, pEvent))
{
bRet = TRUE;
break;
}
}
}
}
else
{
// We don't have a filter, so the event passes
bRet = TRUE;
}
return bRet;
}
BOOL CRendererEventManager::PassFilterRule(CEventSinkFilterRule* pRule,
CRendererEvent* pEvent)
{
BOOL bRet = FALSE;
if (pRule && pEvent)
{
// Do we pass all of the properties?
if (PassFilterRuleString(pRule->GetURL(), pEvent->GetURL()) &&
PassFilterRuleString(pRule->GetFragment(), pEvent->GetFragment()) &&
PassFilterRuleString(pRule->GetEventName(), pEvent->GetEventName()))
{
bRet = TRUE;
}
}
return bRet;
}
BOOL CRendererEventManager::PassFilterRuleString(const char* pszRule,
const char* pszEvent)
{
BOOL bRet = FALSE;
// If the rule string is NULL, that's an automatic pass,
// because the rule is not making any statement about this
// particular property.
// If the rule string is NOT NULL, then the two
// strings have to match exactly.
if (!pszRule || (pszEvent && !strcmp(pszRule, pszEvent)))
{
bRet = TRUE;
}
return bRet;
}
void CRendererEventManager::ClearSinkFilterList(CHXSimpleList* pList)
{
if (pList)
{
LISTPOSITION pos = pList->GetHeadPosition();
while (pos)
{
CEventSinkFilterRule* pRule =
(CEventSinkFilterRule*) pList->GetNext(pos);
HX_DELETE(pRule);
}
pList->RemoveAll();
}
}
CEventSinkFilterRule::CEventSinkFilterRule(IHXValues* pRule)
{
m_pRule = pRule;
if (m_pRule)
{
m_pRule->AddRef();
}
}
CEventSinkFilterRule::~CEventSinkFilterRule()
{
HX_RELEASE(m_pRule);
}
BOOL CEventSinkFilterRule::Same(CEventSinkFilterRule* pRule)
{
BOOL bRet = FALSE;
if (pRule)
{
if (SameString(GetURL(), pRule->GetURL()) &&
SameString(GetFragment(), pRule->GetFragment()) &&
SameString(GetEventName(), pRule->GetEventName()))
{
bRet = TRUE;
}
}
return bRet;
}
const char* CEventSinkFilterRule::GetURL() const
{
return GetString(m_pRule, FILTER_RULE_KEY_URL);
}
const char* CEventSinkFilterRule::GetFragment() const
{
return GetString(m_pRule, FILTER_RULE_KEY_FRAGMENT);
}
const char* CEventSinkFilterRule::GetEventName() const
{
return GetString(m_pRule, FILTER_RULE_KEY_EVENTNAME);
}
BOOL CEventSinkFilterRule::SameString(const char* pszA,
const char* pszB)
{
BOOL bRet = FALSE;
// If both of the strings are NULL, that's TRUE.
// If both of the strings are NOT NULL and the
// strings match, then that's TRUE.
// Anything else is FALSE.
if ((!pszA && !pszB) ||
(pszA && pszB && !strcmp(pszA, pszB)))
{
bRet = TRUE;
}
return bRet;
}
const char* CEventSinkFilterRule::GetString(IHXValues* pValues,
const char* pszName)
{
const char* pRet = NULL;
if (pValues && pszName)
{
IHXBuffer* pBuf = NULL;
pValues->GetPropertyCString(pszName, pBuf);
if (pBuf)
{
pRet = (const char*) pBuf->GetBuffer();
}
HX_RELEASE(pBuf);
}
return pRet;
}
void CRendererEventManager::RendererEventCallback(void* pParam)
{
CRendererEventManager* pObj = (CRendererEventManager*)pParam;
if (pObj)
{
pObj->Func();
}
}
CRendererEvent::CRendererEvent(IHXBuffer* pURLStr,
IHXBuffer* pFragmentStr,
IHXBuffer* pEventNameStr,
IHXValues* pOtherValues)
{
m_pURLStr = pURLStr;
m_pFragmentStr = pFragmentStr;
m_pEventNameStr = pEventNameStr;
m_pOtherValues = pOtherValues;
if (m_pURLStr) m_pURLStr->AddRef();
if (m_pFragmentStr) m_pFragmentStr->AddRef();
if (m_pEventNameStr) m_pEventNameStr->AddRef();
if (m_pOtherValues) m_pOtherValues->AddRef();
}
CRendererEvent::~CRendererEvent()
{
HX_RELEASE(m_pURLStr);
HX_RELEASE(m_pFragmentStr);
HX_RELEASE(m_pEventNameStr);
HX_RELEASE(m_pOtherValues);
}
HX_RESULT CRendererEvent::Fire(IHXEventSink* pSink)
{
HX_RESULT retVal = HXR_FAIL;
if (pSink)
{
retVal = pSink->EventFired(m_pURLStr,
m_pFragmentStr,
m_pEventNameStr,
m_pOtherValues);
}
return retVal;
}
const char* CRendererEvent::GetURL() const
{
const char* pRet = NULL;
if (m_pURLStr)
{
pRet = (const char*) m_pURLStr->GetBuffer();
}
return pRet;
}
const char* CRendererEvent::GetFragment() const
{
const char* pRet = NULL;
if (m_pFragmentStr)
{
pRet = (const char*) m_pFragmentStr->GetBuffer();
}
return pRet;
}
const char* CRendererEvent::GetEventName() const
{
const char* pRet = NULL;
if (m_pEventNameStr)
{
pRet = (const char*) m_pEventNameStr->GetBuffer();
}
return pRet;
}
#endif /* #if defined(HELIX_FEATURE_EVENTMANAGER) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -