148 lines
3.7 KiB
C++
148 lines
3.7 KiB
C++
/***************************************************************************\
|
|
*
|
|
* File: GdiCache.cpp
|
|
*
|
|
* Description:
|
|
* GdiCache.cpp implements the process-wide GDI cache that manages cached and
|
|
* temporary GDI objects.
|
|
*
|
|
*
|
|
* History:
|
|
* 1/18/2000: JStall: Created
|
|
*
|
|
* Copyright (C) 2000 by Microsoft Corporation. All rights reserved.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "Services.h"
|
|
#include "GdiCache.h"
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class ObjectCache
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
ObjectCache::Destroy()
|
|
{
|
|
//
|
|
// Remove all temporary regions. These MUST all be released by this point.
|
|
//
|
|
AssertMsg(m_arAll.GetSize() == m_arFree.GetSize(), "All objects should be free");
|
|
|
|
#if ENABLE_DUMPCACHESTATS
|
|
AutoTrace("%s ObjectCache statistics: %d items\n", m_szName, m_arAll.GetSize());
|
|
#endif // ENABLE_DUMPCACHESTATS
|
|
|
|
int cObjs = m_arAll.GetSize();
|
|
for (int idx = 0; idx < cObjs; idx++) {
|
|
DestroyObject(m_arAll[idx]);
|
|
}
|
|
m_arAll.RemoveAll();
|
|
m_arFree.RemoveAll();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void *
|
|
ObjectCache::Pop()
|
|
{
|
|
void * pObj;
|
|
|
|
//
|
|
// Check if any objects are already freed.
|
|
//
|
|
|
|
if (!m_arFree.IsEmpty()) {
|
|
int idxObj = m_arFree.GetSize() - 1;
|
|
pObj = m_arFree[idxObj];
|
|
Verify(m_arFree.RemoveAt(idxObj));
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// No cached regions, so create a new one.
|
|
//
|
|
|
|
pObj = Build();
|
|
if (pObj == NULL) {
|
|
AssertMsg(0, "Could not create a new object- something is probably wrong");
|
|
goto Exit;
|
|
}
|
|
|
|
{
|
|
int idxAdd = m_arAll.Add(pObj);
|
|
if (idxAdd == -1) {
|
|
AssertMsg(0, "Could not add object to array- something is probably wrong");
|
|
DestroyObject(pObj);
|
|
pObj = NULL;
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
return pObj;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
ObjectCache::Push(void * pObj)
|
|
{
|
|
#if DBG
|
|
//
|
|
// Ensure this object was previously given out, but is not currently listed
|
|
// as free.
|
|
//
|
|
|
|
{
|
|
BOOL fValid;
|
|
int cItems, idx;
|
|
|
|
fValid = FALSE;
|
|
cItems = m_arAll.GetSize();
|
|
for (idx = 0; idx < cItems; idx++) {
|
|
if (m_arAll[idx] == pObj) {
|
|
fValid = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
AssertMsg(fValid, "Object not in list of all temporary regions");
|
|
|
|
cItems = m_arFree.GetSize();
|
|
for (idx = 0; idx < cItems; idx++) {
|
|
AssertMsg(m_arFree[idx] != pObj, "Object must not be free object list");
|
|
}
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
//
|
|
// Add this object to the list of free objects.
|
|
//
|
|
|
|
if (m_arFree.GetSize() < m_cMaxFree) {
|
|
VerifyMsg(m_arFree.Add(pObj) >= 0, "Should be able to add object to list");
|
|
} else {
|
|
DestroyObject(pObj);
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class GdiCache
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|