#ifndef __AGCEventThread_h__
#define __AGCEventThread_h__
#include <AGC.h>
#include <..\TCLib\AutoHandle.h>
#include <..\TCLib\WorkerThread.h>
#include "AGCGlobal.h"
#include "AGCEventData.h"
class CAGCEventThread :
public TCWorkerThread
{
private:
CAGCEventThread(const CAGCEventThread&); public:
CAGCEventThread(CAGCGlobal* pGlobal);
public:
void QueueEvent(HAGCLISTENERS hListeners, CAGCEventData& data);
void QueueEventSynchronous(HAGCLISTENERS hListeners, CAGCEventData& data);
protected:
virtual IUnknown* OnGetUnknown();
virtual TC_WorkItemRelProc OnGetWorkItemRelProc();
virtual void OnMessage(UINT idMsg, int cParams, LPARAM* rgParams);
protected:
static void WINAPI ArgumentReleaseProc(UINT idMsg, int cParams,
LPARAM* rgParams);
protected:
typedef CAGCGlobal::XEventSinks XEventSinks;
typedef CAGCGlobal::XEventSinksIt XEventSinksIt;
enum {e_TriggerEvent};
protected:
CAGCGlobal* m_pGlobal;
};
inline CAGCEventThread::CAGCEventThread(CAGCGlobal* pGlobal) :
m_pGlobal(pGlobal)
{
}
inline void CAGCEventThread::QueueEvent(HAGCLISTENERS hListeners,
CAGCEventData& data)
{
UINT cbData;
BYTE* pbData = data.Detach(&cbData);
PostMessage(e_TriggerEvent, 4, hListeners, cbData, pbData, NULL);
}
inline void CAGCEventThread::QueueEventSynchronous(HAGCLISTENERS hListeners,
CAGCEventData& data)
{
TCHandle shEvent = ::CreateEvent(NULL, false, false, NULL);
UINT cbData;
BYTE* pbData = data.Detach(&cbData);
PostMessage(e_TriggerEvent, 4, hListeners, cbData, pbData, shEvent.GetHandle());
WaitForSingleObject(shEvent, INFINITE);
}
inline IUnknown* CAGCEventThread::OnGetUnknown()
{
return m_pGlobal->GetUnknown();
}
inline TC_WorkItemRelProc CAGCEventThread::OnGetWorkItemRelProc()
{
return ArgumentReleaseProc;
}
inline void CAGCEventThread::OnMessage(UINT idMsg, int cParams,
LPARAM* rgParams)
{
switch (idMsg)
{
case e_TriggerEvent:
{
assert(4 <= cParams);
XEventSinks* pSinks = reinterpret_cast<XEventSinks*>(rgParams[0]);
UINT cbData = static_cast<UINT >(rgParams[1]);
BYTE* pbData = reinterpret_cast<BYTE* >(rgParams[2]);
HANDLE hevt = reinterpret_cast<HANDLE >(rgParams[3]);
CAGCEventData data(cbData, pbData);
CComObject<CAGCEvent>* pEvent = NULL;
ZSucceeded(pEvent->CreateInstance(&pEvent));
IAGCEventPtr spEvent(pEvent);
ZSucceeded(pEvent->Init(data));
for (XEventSinksIt it = pSinks->begin(); it != pSinks->end(); ++it)
{
IAGCEventSinkPtr spSink;
if (m_pGlobal->GetEventSinksAreGITCookies())
{
ZSucceeded(m_pGlobal->GetInterfaceFromGlobal(
reinterpret_cast<DWORD>(*it), IID_IAGCEventSink, (void**)&spSink));
}
else
{
spSink = *it;
}
if (hevt)
{
IAGCEventSinkSynchronousPtr spSinkSync(spSink);
if (spSinkSync != NULL)
{
spSinkSync->OnEventTriggeredSynchronous(spEvent);
continue;
}
}
spSink->OnEventTriggered(spEvent);
}
data.Detach();
return;
}
}
}
inline void WINAPI CAGCEventThread::ArgumentReleaseProc(UINT idMsg,
int cParams, LPARAM* rgParams)
{
switch (idMsg)
{
case e_TriggerEvent:
{
assert(4 <= cParams);
XEventSinks* pSinks = reinterpret_cast<XEventSinks*>(rgParams[0]);
UINT cbData = static_cast<UINT >(rgParams[1]);
BYTE* pbData = reinterpret_cast<BYTE* >(rgParams[2]);
HANDLE hevt = reinterpret_cast<HANDLE >(rgParams[3]);
CAGCGlobal::FreeListenersImpl(reinterpret_cast<HAGCLISTENERS>(pSinks));
CAGCEventData(cbData, pbData);
if (hevt)
::SetEvent(hevt);
return;
}
}
}
#endif