winamp/Src/omBrowser/flagTracker.cpp

96 lines
1.4 KiB
C++

#include "main.h"
#include "./flagTracker.h"
FlagTracker::FlagTracker()
: flags(0), cache(0), updateRef(0), eventHandler(NULL), eventParam(0)
{
InitializeCriticalSection(&lock);
}
FlagTracker::~FlagTracker()
{
DeleteCriticalSection(&lock);
}
void FlagTracker::Set(UINT nFlags, UINT nMask)
{
EnterCriticalSection(&lock);
nFlags &= nMask;
UINT clearMask = ~(nFlags ^ nMask);
flags &= clearMask;
cache &= clearMask;
if (0 != nFlags)
{
Mark(nFlags);
}
LeaveCriticalSection(&lock);
}
UINT FlagTracker::Get()
{
return flags;
}
void FlagTracker::Mark(UINT nFlags)
{
EnterCriticalSection(&lock);
flags |= nFlags;
if (0 == updateRef)
{
if (NULL != eventHandler && 0 != nFlags)
{
eventHandler(nFlags, this, eventParam);
}
}
else
{
cache |= nFlags;
}
LeaveCriticalSection(&lock);
}
ULONG FlagTracker::BeginUpdate()
{
EnterCriticalSection(&lock);
ULONG r = InterlockedIncrement((LONG*)&updateRef);
LeaveCriticalSection(&lock);
return r;
}
ULONG FlagTracker::EndUpdate()
{
EnterCriticalSection(&lock);
ULONG r;
if (0 == updateRef)
{
r = 0;
}
else
{
r = InterlockedDecrement((LONG*)&updateRef);
if (0 == r && 0 != cache)
{
Mark(cache);
cache = 0;
}
}
LeaveCriticalSection(&lock);
return r;
}
void FlagTracker::SetEventHandler(EventHandler handler, ULONG_PTR user)
{
EnterCriticalSection(&lock);
eventHandler = handler;
eventParam = user;
LeaveCriticalSection(&lock);
}