]>
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 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
24 #include "wx/fl/garbagec.h"
26 /***** Implementation for class GarbageCollector *****/
28 inline static GCItem
& node_to_item( wxNode
* pNode
)
30 return *( (GCItem
*)(pNode
->GetData()) );
33 GarbageCollector::~GarbageCollector()
38 /*** GC alg. helpers ***/
40 void GarbageCollector::DestroyItemList( wxList
& lst
)
42 wxNode
* pNode
= lst
.GetFirst();
46 delete &node_to_item( pNode
);
48 pNode
= pNode
->GetNext();
54 wxNode
* GarbageCollector::FindItemNode( void* pForObj
)
56 wxNode
* pNode
= mAllNodes
.GetFirst();
60 if ( node_to_item( pNode
).mpObj
== pForObj
)
64 pNode
= pNode
->GetNext();
70 wxNode
* GarbageCollector::FindReferenceFreeItemNode()
72 wxNode
* pNode
= mAllNodes
.GetFirst();
76 if ( node_to_item( pNode
).mRefs
.GetCount() == 0 )
80 pNode
= pNode
->GetNext();
86 void GarbageCollector::RemoveReferencesToNode( wxNode
* pItemNode
)
88 wxNode
* pNode
= mAllNodes
.GetFirst();
92 wxList
& refLst
= node_to_item( pNode
).mRefs
;
93 wxNode
* pRefNode
= refLst
.GetFirst();
97 if ( pRefNode
->GetData() == (wxObject
*)pItemNode
)
99 wxNode
* pNext
= pRefNode
->GetNext();
101 refLst
.DeleteNode( pRefNode
);
107 else pRefNode
= pRefNode
->GetNext();
110 pNode
= pNode
->GetNext();
114 void GarbageCollector::ResolveReferences()
116 wxNode
* pNode
= mAllNodes
.GetFirst();
120 GCItem
& item
= node_to_item( pNode
);
122 wxNode
* pRefNode
= item
.mRefs
.GetFirst();
126 pRefNode
->SetData( (wxObject
*) FindItemNode( (void*)pRefNode
->GetData() ) );
128 pRefNode
= pRefNode
->GetNext();
131 pNode
= pNode
->GetNext();
135 void GarbageCollector::AddObject( void* pObj
, int WXUNUSED(refCnt
) )
137 // FOR NOW:: initial ref-count is not used
139 GCItem
* pItem
= new GCItem();
143 mAllNodes
.Append( (wxObject
*) pItem
);
146 void GarbageCollector::AddDependency( void* pObj
, void* pDependsOnObj
)
148 node_to_item( FindItemNode( pObj
) ).mRefs
.Append( (wxObject
*)pDependsOnObj
);
151 /*** GC alg. implementation ***/
153 void GarbageCollector::ArrangeCollection()
159 // find node, which does not depend on anything
161 wxNode
* pItemNode
= FindReferenceFreeItemNode();
165 // append it to the list, where items are contained
166 // in the increasing order of dependencies
168 mRegularLst
.Append( pItemNode
->GetData() );
170 mAllNodes
.DeleteNode( pItemNode
);
172 // remove references to this current "least-dependent" node
173 // from reference lists of all the other nodes
175 RemoveReferencesToNode( pItemNode
);
179 // otherwise, what is left - all nodes, which
180 // are involved into cycled chains (rings)
182 wxNode
* pNode
= mAllNodes
.GetFirst();
186 mCycledLst
.Append( pNode
->GetData() );
188 pNode
= pNode
->GetNext();
195 // continue search for "least-dependent" nodes
200 wxList
& GarbageCollector::GetRegularObjects()
205 wxList
& GarbageCollector::GetCycledObjects()
210 void GarbageCollector::Reset()
212 DestroyItemList( mAllNodes
);
213 DestroyItemList( mRegularLst
);
214 DestroyItemList( mCycledLst
);