home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / atl / connect / random.cpp < prev    next >
C/C++ Source or Header  |  1998-03-26  |  3KB  |  131 lines

  1. // Random.cpp : Implementation of CConnectApp and DLL registration.
  2. //
  3. // This is a part of the Active Template Library.
  4. // Copyright (C) 1996-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Active Template Library Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Active Template Library product.
  12.  
  13. #include "preconn.h"
  14. #include "Connect.h"
  15. #include "Random.h"
  16.  
  17. /////////////////////////////////////////////////////////////////////////////
  18. //
  19.  
  20. STDMETHODIMP CRandom::InterfaceSupportsErrorInfo(REFIID riid)
  21. {
  22.     if (riid == IID_IRandom)
  23.         return S_OK;
  24.     return S_FALSE;
  25. }
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28. //
  29.  
  30. DWORD WINAPI RandomSessionThreadEntry(void* pv)
  31. {
  32.     CRandom::RandomSessionData* pS = (CRandom::RandomSessionData*)pv;
  33.     CRandom* p = pS->pRandom;
  34.     while (WaitForSingleObject(pS->m_hEvent, 0) != WAIT_OBJECT_0)
  35.         p->Fire(pS->m_nID);
  36.     return 0;
  37. }
  38.  
  39. CRandom::~CRandom()
  40. {
  41.     StopAll();
  42. }
  43.  
  44. void CRandom::CreateRandomSession(RandomSessionData& rs)
  45. {
  46.     DWORD dwThreadID = 0;
  47.     ATLASSERT(rs.m_hEvent == NULL);
  48.     ATLASSERT(rs.m_hThread == NULL);
  49.     rs.pRandom = this;
  50.     rs.m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  51.     rs.m_hThread = CreateThread(NULL, 0, &RandomSessionThreadEntry, &rs, 0, &dwThreadID);
  52. }
  53.  
  54. STDMETHODIMP CRandom::Start(long* pnID)
  55. {
  56.     if (pnID == NULL)
  57.         return E_POINTER;
  58.     *pnID = 0;
  59.     HRESULT hRes = S_OK;
  60.     m_cs.Lock();
  61.     for (long i=0;i<nMaxSessions;i++)
  62.     {
  63.         if (m_rsArray[i].m_hEvent == NULL)
  64.         {
  65.             m_rsArray[i].m_nID = i;
  66.             CreateRandomSession(m_rsArray[i]);
  67.             *pnID = i;
  68.             break;
  69.         }
  70.     }
  71.     if (i == nMaxSessions) //fell through
  72.         hRes = E_FAIL;
  73.     m_cs.Unlock();
  74.     return hRes;
  75. }
  76.  
  77.  
  78. STDMETHODIMP CRandom::Stop(long nID)
  79. {
  80.     HRESULT hRes = S_OK;
  81.     m_cs.Lock();
  82.     if (m_rsArray[nID].m_hEvent != NULL)
  83.     {
  84.         SetEvent(m_rsArray[nID].m_hEvent);
  85.         WaitForSingleObject(m_rsArray[nID].m_hThread, INFINITE);
  86.         CloseHandle(m_rsArray[nID].m_hThread);
  87.         memset(&m_rsArray[nID], 0, sizeof(RandomSessionData));
  88.     }
  89.     else
  90.         hRes = E_INVALIDARG;
  91.     m_cs.Unlock();
  92.     return hRes;
  93. }
  94.  
  95. STDMETHODIMP CRandom::StopAll()
  96. {
  97.     m_cs.Lock();
  98.     for (long i=0;i<nMaxSessions;i++)
  99.     {
  100.         if (m_rsArray[i].m_hEvent != NULL)
  101.         {
  102.             SetEvent(m_rsArray[i].m_hEvent);
  103.             WaitForSingleObject(m_rsArray[i].m_hThread, INFINITE);
  104.             CloseHandle(m_rsArray[i].m_hThread);
  105.             memset(&m_rsArray[i], 0, sizeof(RandomSessionData));
  106.         }
  107.     }
  108.     m_cs.Unlock();
  109.     return S_OK;
  110. }
  111.  
  112. // broadcast to all the objects
  113. HRESULT CRandom::Fire(long nID)
  114. {
  115.     IConnectionPointImpl<CRandom, &IID_IRandomEvent, CComDynamicUnkArray>* p = this;
  116.     Lock();
  117.     HRESULT hr = S_OK;
  118.     IUnknown** pp = p->m_vec.begin();
  119.     while (pp < p->m_vec.end() && hr == S_OK)
  120.     {
  121.         if (*pp != NULL)
  122.         {
  123.             IRandomEvent* pIRandomEvent = (IRandomEvent*)*pp;
  124.             hr = pIRandomEvent->Fire(nID);
  125.         }
  126.         pp++;
  127.     }
  128.     Unlock();
  129.     return hr;
  130. }
  131.