eventmgr.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:25k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #if defined(HELIX_FEATURE_EVENTMANAGER)
  36. // include
  37. #include "hxtypes.h"
  38. #include "hxcom.h"
  39. #include "hxresult.h"
  40. #include "ihxpckts.h"
  41. #include "hxcomm.h"
  42. #include "hxengin.h"
  43. #include "hxinter.h"
  44. // pncont
  45. #include "hxslist.h"
  46. #include "hxmap.h"
  47. // rmacore
  48. #include "hxcbobj.h"
  49. #include "eventmgr.h"
  50. // pndebug
  51. #include "hxheap.h"
  52. #ifdef _DEBUG
  53. #undef HX_THIS_FILE             
  54. static const char HX_THIS_FILE[] = __FILE__;
  55. #endif
  56. CRendererEventManager::CRendererEventManager(IUnknown* pContext)
  57. {
  58.     m_lRefCount        = 0;
  59.     m_pContext         = pContext;
  60.     m_pScheduler       = NULL;
  61.     m_pSinkList        = NULL;
  62.     m_pSinkToFilterMap = NULL;
  63.     m_pCallback        = NULL;
  64.     m_pEventQueue      = NULL;
  65.     m_pEventQueueMutex = NULL;
  66.     if (m_pContext)
  67.     {
  68.         // AddRef the context
  69.         m_pContext->AddRef();
  70.         // QI for IHXCommonClassFactory
  71.         IHXCommonClassFactory* pFactory = NULL;
  72.         m_pContext->QueryInterface(IID_IHXCommonClassFactory,
  73.                                    (void**) &pFactory);
  74.         if (pFactory)
  75.         {
  76.             // Create a mutex
  77.             pFactory->CreateInstance(CLSID_IHXMutex,
  78.                                      (void**) &m_pEventQueueMutex);
  79.         }
  80.         HX_RELEASE(pFactory);
  81.     }
  82. }
  83. CRendererEventManager::~CRendererEventManager()
  84. {
  85.     Close();
  86. }
  87. STDMETHODIMP CRendererEventManager::QueryInterface(REFIID riid, void** ppvObj)
  88. {
  89.     HX_RESULT retVal = HXR_OK;
  90.     if (ppvObj)
  91.     {
  92.         QInterfaceList qiList[] =
  93.             {
  94.                 { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXEventManager*)this },
  95.                 { GET_IIDHANDLE(IID_IHXEventManager), (IHXEventManager*)this },
  96.                 { GET_IIDHANDLE(IID_IHXCallback), (IHXCallback*)this },
  97.             };
  98.         
  99.         retVal = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  100.     }
  101.     else
  102.     {
  103.         retVal = HXR_FAIL;
  104.     }
  105.     return retVal;
  106. }
  107. STDMETHODIMP_(ULONG32) CRendererEventManager::AddRef()
  108. {
  109.     return InterlockedIncrement(&m_lRefCount);
  110. }
  111. STDMETHODIMP_(ULONG32) CRendererEventManager::Release()
  112. {
  113.     if (InterlockedDecrement(&m_lRefCount) > 0)
  114.     {
  115.         return m_lRefCount;
  116.     }
  117.     delete this;
  118.     return 0;
  119. }
  120. STDMETHODIMP CRendererEventManager::AddEventSink(IHXEventSink* pSink)
  121. {
  122.     HX_RESULT retVal = HXR_FAIL;
  123.     if (pSink)
  124.     {
  125.         // Do we have a list?
  126.         if (!m_pSinkList)
  127.         {
  128.             m_pSinkList = new CHXSimpleList();
  129.         }
  130.         if (m_pSinkList)
  131.         {
  132.             // Clear the return value
  133.             retVal = HXR_OK;
  134.             // Make sure this sink is not already on the list
  135.             if (!IsSinkInList(pSink))
  136.             {
  137.                 // AddRef before we put it on the list
  138.                 pSink->AddRef();
  139.                 // Now put this sink on the tail of the list
  140.                 m_pSinkList->AddTail((void*) pSink);
  141.                 // Add an NULL entry for this sink in the map
  142.                 if (!m_pSinkToFilterMap)
  143.                 {
  144.                     m_pSinkToFilterMap = new CHXMapPtrToPtr();
  145.                 }
  146.                 if (m_pSinkToFilterMap)
  147.                 {
  148.                     m_pSinkToFilterMap->SetAt((void*) pSink, NULL);
  149.                 }
  150.             }
  151.         }
  152.     }
  153.     return retVal;
  154. }
  155. STDMETHODIMP CRendererEventManager::RemoveEventSink(IHXEventSink* pSink)
  156. {
  157.     HX_RESULT retVal = HXR_OK;
  158.     if (pSink && m_pSinkList && m_pSinkList->GetCount() > 0)
  159.     {
  160.         // Remove the sink's entry in the sink-to-filter map and
  161.         // release our ref on the filter
  162.         void* pVoid = NULL;
  163.         if (m_pSinkToFilterMap &&
  164.             m_pSinkToFilterMap->Lookup((void*) pSink, pVoid))
  165.         {
  166.             // Get the key value list
  167.             CHXSimpleList* pList = (CHXSimpleList*) pVoid;
  168.             // Clear this list
  169.             ClearSinkFilterList(pList);
  170.             // Delete the rule list
  171.             HX_DELETE(pList);
  172.             // Remove the entry from the sink-to-filter map
  173.             m_pSinkToFilterMap->RemoveKey((void*) pSink);
  174.         }
  175.         // Run through the sink list and release
  176.         // the list's ref on the sink
  177.         LISTPOSITION pos = m_pSinkList->GetHeadPosition();
  178.         while (pos)
  179.         {
  180.             IHXEventSink* pListSink =
  181.                 (IHXEventSink*) m_pSinkList->GetAt(pos);
  182.             if (pListSink && pListSink == pSink)
  183.             {
  184.                 m_pSinkList->RemoveAt(pos);
  185.                 HX_RELEASE(pListSink);
  186.                 break;
  187.             }
  188.             m_pSinkList->GetNext(pos);
  189.         }
  190.     }
  191.     return retVal;
  192. }
  193. STDMETHODIMP CRendererEventManager::AddEventSinkFilterRule(IHXEventSink* pSink,
  194.                                                            IHXValues*    pRule)
  195. {
  196.     HX_RESULT retVal = HXR_FAIL;
  197.     if (pSink && pRule && m_pSinkToFilterMap)
  198.     {
  199.         // Do we have an entry in the filter map? We definitely
  200.         // should, because it was initialized when the sink
  201.         // was added to the sink list. The entry can be NULL,
  202.         // but there has to be an entry.
  203.         void* pVoid = NULL;
  204.         if (m_pSinkToFilterMap->Lookup((void*) pSink, pVoid))
  205.         {
  206.             // Get the filter
  207.             CHXSimpleList* pFilter = (CHXSimpleList*) pVoid;
  208.             // If the filter is NULL, then that means
  209.             // we need to create the list and put it
  210.             // back into the map
  211.             if (!pFilter)
  212.             {
  213.                 pFilter = new CHXSimpleList();
  214.                 if (pFilter)
  215.                 {
  216.                     m_pSinkToFilterMap->SetAt((void*) pSink,
  217.                                               (void*) pFilter);
  218.                 }
  219.             }
  220.             if (pFilter)
  221.             {
  222.                 // Create the CEventSinkFilterRule object
  223.                 CEventSinkFilterRule* pRuleObj =
  224.                     new CEventSinkFilterRule(pRule);
  225.                 if (pRuleObj)
  226.                 {
  227.                     // Make sure this rule is not already in the list
  228.                     BOOL bPresent = FALSE;
  229.                     LISTPOSITION pos = pFilter->GetHeadPosition();
  230.                     while (pos)
  231.                     {
  232.                         CEventSinkFilterRule* pListRuleObj =
  233.                             (CEventSinkFilterRule*) pFilter->GetNext(pos);
  234.                         if (pListRuleObj &&
  235.                             pListRuleObj->Same(pRuleObj))
  236.                         {
  237.                             bPresent = TRUE;
  238.                             break;
  239.                         }
  240.                     }
  241.                     // Was the rule already present?
  242.                     if (!bPresent)
  243.                     {
  244.                         // It was NOT already present, so we
  245.                         // can append it to the list of rules
  246.                         pFilter->AddTail((void*) pRuleObj);
  247.                     }
  248.                     else
  249.                     {
  250.                         // It was already present, so we can
  251.                         // delete this object
  252.                         HX_DELETE(pRuleObj);
  253.                     }
  254.                     // Clear the return value
  255.                     retVal = HXR_OK;
  256.                 }
  257.             }
  258.         }
  259.     }
  260.     return retVal;
  261. }
  262. STDMETHODIMP CRendererEventManager::RemoveEventSinkFilterRule(IHXEventSink* pSink,
  263.                                                               IHXValues*    pRule)
  264. {
  265.     HX_RESULT retVal = HXR_FAIL;
  266.     if (pSink && pRule && m_pSinkToFilterMap)
  267.     {
  268.         // Do we have an entry in the filter map? We definitely
  269.         // should, because it was initialized when the sink
  270.         // was added to the sink list. The entry can be NULL,
  271.         // but there has to be an entry.
  272.         void* pVoid = NULL;
  273.         if (m_pSinkToFilterMap->Lookup((void*) pSink, pVoid))
  274.         {
  275.             // Get the filter
  276.             CHXSimpleList* pFilter = (CHXSimpleList*) pVoid;
  277.             // Do we have a filter for this sink yet?
  278.             if (pFilter)
  279.             {
  280.                 // Create a temp CEventSinkFilterRule object
  281.                 // just so we can use CEventSinkFilterRule::Same()
  282.                 CEventSinkFilterRule* pRuleObj =
  283.                     new CEventSinkFilterRule(pRule);
  284.                 if (pRuleObj)
  285.                 {
  286.                     // Find this rule in the list
  287.                     LISTPOSITION pos = pFilter->GetHeadPosition();
  288.                     while (pos)
  289.                     {
  290.                         CEventSinkFilterRule* pListRuleObj =
  291.                             (CEventSinkFilterRule*) pFilter->GetAt(pos);
  292.                         if (pListRuleObj &&
  293.                             pListRuleObj->Same(pRuleObj))
  294.                         {
  295.                             // Remove the rule from the list
  296.                             pFilter->RemoveAt(pos);
  297.                             // Delete the rule object
  298.                             HX_DELETE(pListRuleObj);
  299.                             // Jump out of the loop
  300.                             break;
  301.                         }
  302.                         else
  303.                         {
  304.                             pFilter->GetNext(pos);
  305.                         }
  306.                     }
  307.                     // Clear the return value
  308.                     retVal = HXR_OK;
  309.                 }
  310.                 // Delete the temporary rule
  311.                 HX_DELETE(pRuleObj);
  312.             }
  313.         }
  314.     }
  315.     return retVal;
  316. }
  317. STDMETHODIMP CRendererEventManager::FireEvent(IHXBuffer* pURLStr,
  318.                                               IHXBuffer* pFragmentStr,
  319.                                               IHXBuffer* pEventNameStr,
  320.                                               IHXValues* pOtherValues)
  321. {
  322.     HX_RESULT retVal = HXR_FAIL;
  323.     if (pURLStr && pEventNameStr)
  324.     {
  325.         // Do we have a scheduler interface?
  326.         if (!m_pScheduler && m_pContext)
  327.         {
  328.             // QI for IHXScheduler
  329.             m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler);
  330.         }
  331.         if (m_pScheduler)
  332.         {
  333.             // Do we have a callback?
  334.             if (!m_pCallback)
  335.             {
  336.                 // Create a callback object
  337.                 m_pCallback = new CHXGenericCallback((void*)this, (fGenericCBFunc)RendererEventCallback);
  338.                 if (m_pCallback)
  339.                 {
  340.                     m_pCallback->AddRef();
  341.                 }
  342.             }
  343.             if (m_pCallback)
  344.             {
  345.                 // Create the event object
  346.                 CRendererEvent* pEvent = new CRendererEvent(pURLStr,
  347.                                                             pFragmentStr,
  348.                                                             pEventNameStr,
  349.                                                             pOtherValues);
  350.                 if (pEvent)
  351.                 {
  352.                     // Do we have an event queue?
  353.                     if (!m_pEventQueue)
  354.                     {
  355.                         // Create an event queue
  356.                         m_pEventQueue = new CHXSimpleList();
  357.                     }
  358.                     if (m_pEventQueue)
  359.                     {
  360.                         // Lock the mutex
  361.                         if (m_pEventQueueMutex) m_pEventQueueMutex->Lock();
  362.                         // Put the event object on the queue
  363.                         m_pEventQueue->AddTail((void*) pEvent);
  364.                         // If we don't already have a callback scheduled
  365.                         // then schedule one
  366.                         if (!m_pCallback->GetPendingCallback())
  367.                         {
  368.                             m_pCallback->CallbackScheduled(m_pScheduler->RelativeEnter(m_pCallback, 0));
  369.                         }
  370.                         // Unlock the mutex
  371.                         if (m_pEventQueueMutex) m_pEventQueueMutex->Unlock();
  372.                         // Clear the return value
  373.                         retVal = HXR_OK;
  374.                     }
  375.                 }
  376.                 if (FAILED(retVal))
  377.                 {
  378.                     HX_DELETE(pEvent);
  379.                 }
  380.             }
  381.         }
  382.     }
  383.     return retVal;
  384. }
  385. STDMETHODIMP CRendererEventManager::Func()
  386. {
  387.     HX_RESULT retVal = HXR_OK;
  388.     // Lock the mutex
  389.     if (m_pEventQueueMutex) m_pEventQueueMutex->Lock();
  390.     // Fire off all the events in the event queue
  391.     if (m_pEventQueue && m_pEventQueue->GetCount() > 0)
  392.     {
  393.         LISTPOSITION pos = m_pEventQueue->GetHeadPosition();
  394.         while (pos)
  395.         {
  396.             // Get the event
  397.             CRendererEvent* pEvent =
  398.                 (CRendererEvent*) m_pEventQueue->GetNext(pos);
  399.             if (pEvent)
  400.             {
  401.                 // Loop through our lists and test each sink
  402.                 // to see if it should be passed this event
  403.                 //
  404.                 // XXXMEH - TODO - short-circuit the callback - if
  405.                 // we find out that there are no sinks registered for
  406.                 // this kind of event up front, then we shouldn't 
  407.                 // even fire the callback
  408.                 //
  409.                 if (m_pSinkList && m_pSinkList->GetCount() > 0)
  410.                 {
  411.                     LISTPOSITION pos = m_pSinkList->GetHeadPosition();
  412.                     while (pos)
  413.                     {
  414.                         IHXEventSink* pSink =
  415.                             (IHXEventSink*) m_pSinkList->GetNext(pos);
  416.                         if (ShouldSinkGetEvent(pSink, pEvent))
  417.                         {
  418.                             pEvent->Fire(pSink);
  419.                         }
  420.                     }
  421.                 }
  422.             }
  423.             // Now that we've processed the event,
  424.             // we can delete it
  425.             HX_DELETE(pEvent);
  426.         }
  427.         // Now remove everything from the queue
  428.         m_pEventQueue->RemoveAll();
  429.     }
  430.     // Unlock the mutex
  431.     if (m_pEventQueueMutex) m_pEventQueueMutex->Unlock();
  432.     return retVal;
  433. }
  434. STDMETHODIMP CRendererEventManager::Close()
  435. {
  436.     HX_RESULT retVal = HXR_OK;
  437.     // Cleanup all remaining callbacks
  438.     if (m_pCallback && m_pScheduler)
  439.     {
  440.         m_pScheduler->Remove(m_pCallback->GetPendingCallback());
  441.         m_pCallback->CallbackCanceled();
  442.     }
  443.     HX_RELEASE(m_pCallback);
  444.     HX_RELEASE(m_pScheduler);
  445.     HX_RELEASE(m_pContext);
  446.     ClearSinks();
  447.     HX_DELETE(m_pSinkList);
  448.     HX_DELETE(m_pSinkToFilterMap);
  449.     ClearEventQueue();
  450.     HX_DELETE(m_pEventQueue);
  451.     HX_RELEASE(m_pEventQueueMutex);
  452.     return retVal;
  453. }
  454. void CRendererEventManager::ClearSinks()
  455. {
  456.     if (m_pSinkToFilterMap)
  457.     {
  458.         // Run through the filter map and release each entry
  459.         POSITION pos = m_pSinkToFilterMap->GetStartPosition();
  460.         while (pos)
  461.         {
  462.             void* pKey   = NULL;
  463.             void* pEntry = NULL;
  464.             m_pSinkToFilterMap->GetNextAssoc(pos, pKey, pEntry);
  465.             if (pEntry)
  466.             {
  467.                 // Get the filter
  468.                 CHXSimpleList* pFilter = (CHXSimpleList*) pEntry;
  469.                 // Clear this list
  470.                 ClearSinkFilterList(pFilter);
  471.                 // Delete the rule list
  472.                 HX_DELETE(pFilter);
  473.             }
  474.         }
  475.         m_pSinkToFilterMap->RemoveAll();
  476.     }
  477.     if (m_pSinkList)
  478.     {
  479.         // Run through the list, releasing the sinks
  480.         LISTPOSITION pos = m_pSinkList->GetHeadPosition();
  481.         while (pos)
  482.         {
  483.             IHXEventSink* pSink = (IHXEventSink*) m_pSinkList->GetNext(pos);
  484.             HX_RELEASE(pSink);
  485.         }
  486.         m_pSinkList->RemoveAll();
  487.     }
  488. }
  489. BOOL CRendererEventManager::IsSinkInList(IHXEventSink* pSink)
  490. {
  491.     BOOL bRet = FALSE;
  492.     if (pSink && m_pSinkList)
  493.     {
  494.         LISTPOSITION pos = m_pSinkList->GetHeadPosition();
  495.         while (pos)
  496.         {
  497.             IHXEventSink* pListSink =
  498.                 (IHXEventSink*) m_pSinkList->GetNext(pos);
  499.             if (pListSink &&
  500.                 pListSink == pSink)
  501.             {
  502.                 bRet = TRUE;
  503.                 break;
  504.             }
  505.         }
  506.     }
  507.     return bRet;
  508. }
  509. void CRendererEventManager::ClearEventQueue()
  510. {
  511.     if (m_pEventQueue && m_pEventQueue->GetCount() > 0)
  512.     {
  513.         LISTPOSITION pos = m_pEventQueue->GetHeadPosition();
  514.         while (pos)
  515.         {
  516.             CRendererEvent* pEvent =
  517.                 (CRendererEvent*) m_pEventQueue->GetNext(pos);
  518.             HX_DELETE(pEvent);
  519.         }
  520.         m_pEventQueue->RemoveAll();
  521.     }
  522. }
  523. BOOL CRendererEventManager::ShouldSinkGetEvent(IHXEventSink*  pSink,
  524.                                                CRendererEvent* pEvent)
  525. {
  526.     BOOL bRet = FALSE;
  527.     if (pSink && pEvent && m_pSinkToFilterMap)
  528.     {
  529.         // Look up the filter for this sink
  530.         void* pVoid = NULL;
  531.         if (m_pSinkToFilterMap->Lookup((void*) pSink, pVoid))
  532.         {
  533.             // Get the filter
  534.             CHXSimpleList* pFilter = (CHXSimpleList*) pVoid;
  535.             // Check if the event passes the filter
  536.             bRet = PassFilter(pFilter, pEvent);
  537.         }
  538.     }
  539.     return bRet;
  540. }
  541. BOOL CRendererEventManager::PassFilter(CHXSimpleList*  pFilter,
  542.                                        CRendererEvent* pEvent)
  543. {
  544.     BOOL bRet = FALSE;
  545.     // Do we have a non-NULL filter?
  546.     if (pFilter)
  547.     {
  548.         if (pEvent)
  549.         {
  550.             // Loop through the rules until we find a rule
  551.             // that will allow this event to pass through
  552.             LISTPOSITION pos = pFilter->GetHeadPosition();
  553.             while (pos)
  554.             {
  555.                 CEventSinkFilterRule* pRule =
  556.                     (CEventSinkFilterRule*) pFilter->GetNext(pos);
  557.                 if (PassFilterRule(pRule, pEvent))
  558.                 {
  559.                     bRet = TRUE;
  560.                     break;
  561.                 }
  562.             }
  563.         }
  564.     }
  565.     else
  566.     {
  567.         // We don't have a filter, so the event passes
  568.         bRet = TRUE;
  569.     }
  570.     return bRet;
  571. }
  572. BOOL CRendererEventManager::PassFilterRule(CEventSinkFilterRule* pRule,
  573.                                            CRendererEvent*       pEvent)
  574. {
  575.     BOOL bRet = FALSE;
  576.     if (pRule && pEvent)
  577.     {
  578.         // Do we pass all of the properties?
  579.         if (PassFilterRuleString(pRule->GetURL(),       pEvent->GetURL())      &&
  580.             PassFilterRuleString(pRule->GetFragment(),  pEvent->GetFragment()) &&
  581.             PassFilterRuleString(pRule->GetEventName(), pEvent->GetEventName()))
  582.         {
  583.             bRet = TRUE;
  584.         }
  585.     }
  586.     return bRet;
  587. }
  588. BOOL CRendererEventManager::PassFilterRuleString(const char* pszRule,
  589.                                                  const char* pszEvent)
  590. {
  591.     BOOL bRet = FALSE;
  592.     // If the rule string is NULL, that's an automatic pass,
  593.     // because the rule is not making any statement about this
  594.     // particular property.
  595.     // If the rule string is NOT NULL, then the two
  596.     // strings have to match exactly.
  597.     if (!pszRule || (pszEvent && !strcmp(pszRule, pszEvent)))
  598.     {
  599.         bRet = TRUE;
  600.     }
  601.     return bRet;
  602. }
  603. void CRendererEventManager::ClearSinkFilterList(CHXSimpleList* pList)
  604. {
  605.     if (pList)
  606.     {
  607.         LISTPOSITION pos = pList->GetHeadPosition();
  608.         while (pos)
  609.         {
  610.             CEventSinkFilterRule* pRule =
  611.                 (CEventSinkFilterRule*) pList->GetNext(pos);
  612.             HX_DELETE(pRule);
  613.         }
  614.         pList->RemoveAll();
  615.     }
  616. }
  617. CEventSinkFilterRule::CEventSinkFilterRule(IHXValues* pRule)
  618. {
  619.     m_pRule = pRule;
  620.     if (m_pRule)
  621.     {
  622.         m_pRule->AddRef();
  623.     }
  624. }
  625. CEventSinkFilterRule::~CEventSinkFilterRule()
  626. {
  627.     HX_RELEASE(m_pRule);
  628. }
  629. BOOL CEventSinkFilterRule::Same(CEventSinkFilterRule* pRule)
  630. {
  631.     BOOL bRet = FALSE;
  632.     if (pRule)
  633.     {
  634.         if (SameString(GetURL(),       pRule->GetURL())      &&
  635.             SameString(GetFragment(),  pRule->GetFragment()) &&
  636.             SameString(GetEventName(), pRule->GetEventName()))
  637.         {
  638.             bRet = TRUE;
  639.         }
  640.     }
  641.     return bRet;
  642. }
  643. const char* CEventSinkFilterRule::GetURL() const
  644. {
  645.     return GetString(m_pRule, FILTER_RULE_KEY_URL);
  646. }
  647. const char* CEventSinkFilterRule::GetFragment() const
  648. {
  649.     return GetString(m_pRule, FILTER_RULE_KEY_FRAGMENT);
  650. }
  651. const char* CEventSinkFilterRule::GetEventName() const
  652. {
  653.     return GetString(m_pRule, FILTER_RULE_KEY_EVENTNAME);
  654. }
  655. BOOL CEventSinkFilterRule::SameString(const char* pszA,
  656.                                       const char* pszB)
  657. {
  658.     BOOL bRet = FALSE;
  659.     // If both of the strings are NULL, that's TRUE.
  660.     // If both of the strings are NOT NULL and the
  661.     // strings match, then that's TRUE.
  662.     // Anything else is FALSE.
  663.     if ((!pszA && !pszB) ||
  664.         (pszA  &&  pszB && !strcmp(pszA, pszB)))
  665.     {
  666.         bRet = TRUE;
  667.     }
  668.     return bRet;
  669. }
  670. const char* CEventSinkFilterRule::GetString(IHXValues* pValues,
  671.                                             const char* pszName)
  672. {
  673.     const char* pRet = NULL;
  674.     if (pValues && pszName)
  675.     {
  676.         IHXBuffer* pBuf = NULL;
  677.         pValues->GetPropertyCString(pszName, pBuf);
  678.         if (pBuf)
  679.         {
  680.             pRet = (const char*) pBuf->GetBuffer();
  681.         }
  682.         HX_RELEASE(pBuf);
  683.     }
  684.     return pRet;
  685. }
  686. void CRendererEventManager::RendererEventCallback(void* pParam)
  687. {
  688.     CRendererEventManager* pObj = (CRendererEventManager*)pParam;
  689.     if (pObj)
  690.     {
  691.         pObj->Func();
  692.     }
  693. }
  694. CRendererEvent::CRendererEvent(IHXBuffer* pURLStr,
  695.                                IHXBuffer* pFragmentStr,
  696.                                IHXBuffer* pEventNameStr,
  697.                                IHXValues* pOtherValues)
  698. {
  699.     m_pURLStr       = pURLStr;
  700.     m_pFragmentStr  = pFragmentStr;
  701.     m_pEventNameStr = pEventNameStr;
  702.     m_pOtherValues  = pOtherValues;
  703.     if (m_pURLStr)       m_pURLStr->AddRef();
  704.     if (m_pFragmentStr)  m_pFragmentStr->AddRef();
  705.     if (m_pEventNameStr) m_pEventNameStr->AddRef();
  706.     if (m_pOtherValues)  m_pOtherValues->AddRef();
  707. }
  708. CRendererEvent::~CRendererEvent()
  709. {
  710.     HX_RELEASE(m_pURLStr);
  711.     HX_RELEASE(m_pFragmentStr);
  712.     HX_RELEASE(m_pEventNameStr);
  713.     HX_RELEASE(m_pOtherValues);
  714. }
  715. HX_RESULT CRendererEvent::Fire(IHXEventSink* pSink)
  716. {
  717.     HX_RESULT retVal = HXR_FAIL;
  718.     if (pSink)
  719.     {
  720.         retVal = pSink->EventFired(m_pURLStr,
  721.                                    m_pFragmentStr,
  722.                                    m_pEventNameStr,
  723.                                    m_pOtherValues);
  724.     }
  725.     return retVal;
  726. }
  727. const char* CRendererEvent::GetURL() const
  728. {
  729.     const char* pRet = NULL;
  730.     if (m_pURLStr)
  731.     {
  732.         pRet = (const char*) m_pURLStr->GetBuffer();
  733.     }
  734.     return pRet;
  735. }
  736. const char* CRendererEvent::GetFragment() const
  737. {
  738.     const char* pRet = NULL;
  739.     if (m_pFragmentStr)
  740.     {
  741.         pRet = (const char*) m_pFragmentStr->GetBuffer();
  742.     }
  743.     return pRet;
  744. }
  745. const char* CRendererEvent::GetEventName() const
  746. {
  747.     const char* pRet = NULL;
  748.     if (m_pEventNameStr)
  749.     {
  750.         pRet = (const char*) m_pEventNameStr->GetBuffer();
  751.     }
  752.     return pRet;
  753. }
  754. #endif /* #if defined(HELIX_FEATURE_EVENTMANAGER) */