122 lines
4 KiB
C++
122 lines
4 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 2000 - 2000
|
|
//
|
|
// File: eventlock.h
|
|
//
|
|
// This file contains code needed to fire script event in a safer way
|
|
// Locks made on stack will postpone firing the event on particular interface
|
|
// as long as the last lock is released.
|
|
//--------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#if !defined(EVENTLOCK_H_INCLUDED)
|
|
#define EVENTLOCK_H_INCLUDED
|
|
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* CLASS: CEventBuffer
|
|
*
|
|
* PURPOSE: objects this class maintains the interface locks by exposing
|
|
* methods Lock(), Unlock() and IsLocked(); It also implements queue
|
|
* of script events accessible thru ScEmitOrPostpone(); Events in the queue
|
|
* will be automatically emited when the last lock is removed by
|
|
* calling Unlock() method.
|
|
*
|
|
* USAGE: Object of this class are constucted as global or static variables
|
|
* per each monitored interface.
|
|
* Currently it is used (as static variable) by GetEventBuffer template
|
|
* function and is accessed by CEventLock object put on the stack by
|
|
* LockComEventInterface macro
|
|
*
|
|
\***************************************************************************/
|
|
class MMCBASE_API CEventBuffer
|
|
{
|
|
// structure containing postponed script event
|
|
// since it is a dipinterface call, data consists of pointer to
|
|
// IDispatch interface , disp_id and the array of parameters
|
|
struct DispCallStr
|
|
{
|
|
IDispatchPtr spDispatch;
|
|
DISPID dispid;
|
|
std::vector<CComVariant> vars;
|
|
};
|
|
|
|
// queue of postponed events
|
|
std::queue<DispCallStr> m_postponed;
|
|
// lock count
|
|
int m_locks;
|
|
|
|
public:
|
|
// constructor. No locks initially
|
|
CEventBuffer() : m_locks(0) {}
|
|
|
|
// locking methods
|
|
void Lock() { m_locks++; }
|
|
void Unlock() { ASSERT(m_locks > 0); if (--m_locks == 0) ScFlushPostponed(); }
|
|
bool IsLocked() { return m_locks != 0; }
|
|
|
|
// event emitting / postponing
|
|
SC ScEmitOrPostpone(IDispatch *pDispatch, DISPID dispid, CComVariant *pVar, int count);
|
|
private:
|
|
// helper emiting postponed events
|
|
SC ScFlushPostponed();
|
|
};
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* FUNCTION: GetEventBuffer
|
|
*
|
|
* PURPOSE: This function provides access to static object created in it's body
|
|
* Having it as template allows us to define as many static objects as
|
|
* interfaces we have.
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
* RETURNS:
|
|
* CEventBuffer& - reference to the static object created inside
|
|
*
|
|
\***************************************************************************/
|
|
MMCBASE_API CEventBuffer& GetEventBuffer();
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* CLASS: CEventLock
|
|
*
|
|
* PURPOSE: Template class to allow simple Lock()/Unlock() functionality
|
|
* by placing instances of this class on the stack.
|
|
* Constructor will put a lock on the event interface, destructor
|
|
* will release it.
|
|
*
|
|
* USAGE: You can place the lock on stack by constructing object directly
|
|
* or by using LockComEventInterface macro (which does the same)
|
|
*
|
|
\***************************************************************************/
|
|
template <typename _dispinterface>
|
|
class MMCBASE_API CEventLock
|
|
{
|
|
public:
|
|
|
|
CEventLock() { GetEventBuffer().Lock(); }
|
|
~CEventLock() { GetEventBuffer().Unlock(); }
|
|
};
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* MACRO: LockComEventInterface
|
|
*
|
|
* PURPOSE: Constructs the object on stack which holds a lock on event interface
|
|
*
|
|
\***************************************************************************/
|
|
#define LockComEventInterface(_dispinterface) \
|
|
CEventLock<_dispinterface> _LocalEventInterfaceLock;
|
|
|
|
|
|
#endif // !defined(EVENTLOCK_H_INCLUDED)
|
|
|
|
|