-
Notifications
You must be signed in to change notification settings - Fork 2
/
mmanager.cpp
109 lines (96 loc) · 2.29 KB
/
mmanager.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "engine.h"
#include <algorithm>
using namespace std;
IMMObject *IMMObject::liveObjects=0;
IMMObject *IMMObject::deadObjects=0;
std::list<IMMObject *> IMMObject::heapObjects;
IMMObject::IMMObject()
{
nextObject=prevObject=0;
refCount=0;
std::list<IMMObject*>::iterator it=std::find(heapObjects.begin(),heapObjects.end(),this);
if(it==heapObjects.end())
{
bIsStackAllocated=true;
}else{
bIsStackAllocated=false;
heapObjects.erase(it);
}
if(!bIsStackAllocated)
{
//start on the deadObjects list
nextObject=deadObjects;
if(deadObjects)deadObjects->prevObject=this;
deadObjects=this;
}
}
IMMObject::~IMMObject()
{
}
void IMMObject::CollectGarbage()
{
while(deadObjects)
{
IMMObject *nObj=deadObjects->nextObject;
delete deadObjects;
deadObjects=nObj;
}
}
void IMMObject::AddRef()
{
refCount++;
if(!bIsStackAllocated&&(refCount==1))
{
//move to the liveObjects list
if(prevObject)prevObject->nextObject=nextObject;
if(nextObject)nextObject->prevObject=prevObject;
if(deadObjects==this)deadObjects=nextObject;
prevObject=0;
nextObject=liveObjects; if(liveObjects)liveObjects->prevObject=this;
liveObjects=this;
}
}
void IMMObject::Release()
{
refCount--;
if(!bIsStackAllocated&&(refCount<=0))
{
//remove self from live list
if(prevObject)prevObject->nextObject=nextObject;
if(nextObject)nextObject->prevObject=prevObject;
if(liveObjects==this)liveObjects=nextObject;
prevObject=0;
//add self to dead list
nextObject=deadObjects;
if(deadObjects)deadObjects->prevObject=this;
deadObjects=this;
}
}
void IMMObject::CollectRemainingObjects(bool bEmitWarnings)
{
CollectGarbage();
while(liveObjects)
{
IMMObject *o=liveObjects->nextObject;
if(bEmitWarnings)
{
//copy the object to a temporary buffer so that our '10 bytes' message doesn't
//cause an access violation
char szBuf[11]; ZeroMemory(szBuf,11);
memcpy(szBuf,liveObjects,min<long>(liveObjects->size(),10));
CLog::Get().Write(LOG_APP,IDS_UNRELEASED_OBJECT,liveObjects,liveObjects->size(),szBuf);
}
delete liveObjects;
liveObjects=o;
}
}
void* IMMObject::operator new(size_t objsize)
{
void *newObj=malloc(objsize);
heapObjects.push_back((IMMObject*)newObj);
return newObj;
}
void IMMObject::operator delete(void* obj)
{
if(!((IMMObject*)obj)->bIsStackAllocated)free(obj);
}