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