]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/fl/garbagec.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Garbage collection algorithm for optimizing refresh.
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
14 #pragma implementation "garbagec.h"
17 // For compilers that support precompilation, includes "wx/wx.h".
18 #include "wx/wxprec.h"
29 #include "wx/fl/garbagec.h"
31 /***** Implementation for class GarbageCollector *****/
33 inline static GCItem
& node_to_item( wxNode
* pNode
)
35 return *( (GCItem
*)(pNode
->Data()) );
38 GarbageCollector::~GarbageCollector()
43 /*** GC alg. helpers ***/
45 void GarbageCollector::DestroyItemList( wxList
& lst
)
47 wxNode
* pNode
= lst
.First();
51 delete &node_to_item( pNode
);
53 pNode
= pNode
->Next();
59 wxNode
* GarbageCollector::FindItemNode( void* pForObj
)
61 wxNode
* pNode
= mAllNodes
.First();
65 if ( node_to_item( pNode
).mpObj
== pForObj
)
69 pNode
= pNode
->Next();
72 int avoidCompilerWarning
= 0;
73 wxASSERT(avoidCompilerWarning
); // DBG:: item should be present
78 wxNode
* GarbageCollector::FindReferenceFreeItemNode()
80 wxNode
* pNode
= mAllNodes
.First();
84 if ( node_to_item( pNode
).mRefs
.Number() == 0 )
88 pNode
= pNode
->Next();
94 void GarbageCollector::RemoveReferencesToNode( wxNode
* pItemNode
)
96 wxNode
* pNode
= mAllNodes
.First();
100 wxList
& refLst
= node_to_item( pNode
).mRefs
;
101 wxNode
* pRefNode
= refLst
.First();
105 if ( pRefNode
->Data() == (wxObject
*)pItemNode
)
107 wxNode
* pNext
= pRefNode
->Next();
109 refLst
.DeleteNode( pRefNode
);
115 else pRefNode
= pRefNode
->Next();
118 pNode
= pNode
->Next();
122 void GarbageCollector::ResolveReferences()
124 wxNode
* pNode
= mAllNodes
.First();
128 GCItem
& item
= node_to_item( pNode
);
130 wxNode
* pRefNode
= item
.mRefs
.First();
134 pRefNode
->SetData( (wxObject
*) FindItemNode( (void*)pRefNode
->Data() ) );
136 pRefNode
= pRefNode
->Next();
139 pNode
= pNode
->Next();
143 void GarbageCollector::AddObject( void* pObj
, int refCnt
)
145 // FOR NOW:: initial ref-count is not used
147 GCItem
* pItem
= new GCItem();
151 mAllNodes
.Append( (wxObject
*) pItem
);
154 void GarbageCollector::AddDependency( void* pObj
, void* pDependsOnObj
)
156 node_to_item( FindItemNode( pObj
) ).mRefs
.Append( (wxObject
*)pDependsOnObj
);
159 /*** GC alg. implementation ***/
161 void GarbageCollector::ArrangeCollection()
167 // find node, which does not depend on anything
169 wxNode
* pItemNode
= FindReferenceFreeItemNode();
173 // append it to the list, where items are contained
174 // in the increasing order of dependencies
176 mRegularLst
.Append( pItemNode
->Data() );
178 mAllNodes
.DeleteNode( pItemNode
);
180 // remove references to this current "least-dependent" node
181 // from reference lists of all the other nodes
183 RemoveReferencesToNode( pItemNode
);
187 // otherwise, what is left - all nodes, which
188 // are involved into cycled chains (rings)
190 wxNode
* pNode
= mAllNodes
.First();
194 mCycledLst
.Append( pNode
->Data() );
196 pNode
= pNode
->Next();
203 // continue search for "least-dependent" nodes
208 wxList
& GarbageCollector::GetRegularObjects()
213 wxList
& GarbageCollector::GetCycledObjects()
218 void GarbageCollector::Reset()
220 DestroyItemList( mAllNodes
);
221 DestroyItemList( mRegularLst
);
222 DestroyItemList( mCycledLst
);