]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/fl/garbagec.cpp
Updated version and other minor tweaks
[wxWidgets.git] / contrib / src / fl / garbagec.cpp
CommitLineData
8e08b761 1/////////////////////////////////////////////////////////////////////////////
4cbc57f0
JS
2// Name: garbagec.cpp
3// Purpose: Garbage collection algorithm for optimizing refresh.
8e08b761
JS
4// Author: Aleksandras Gluchovas
5// Modified by:
6// Created: 18/10/98
7// RCS-ID: $Id$
8// Copyright: (c) Aleksandras Gluchovas
4cbc57f0 9// Licence: wxWindows licence
8e08b761
JS
10/////////////////////////////////////////////////////////////////////////////
11
12
13#ifdef __GNUG__
14 #pragma implementation "garbagec.h"
15#endif
16
17// For compilers that support precompilation, includes "wx/wx.h".
18#include "wx/wxprec.h"
19
20#ifdef __BORLANDC__
21#pragma hdrstop
22#endif
23
24
25#ifndef WX_PRECOMP
26#include "wx/wx.h"
27#endif
28
29#include "wx/fl/garbagec.h"
30
31/***** Implementation for class GarbageCollector *****/
32
33inline static GCItem& node_to_item( wxNode* pNode )
34{
4cbc57f0 35 return *( (GCItem*)(pNode->Data()) );
8e08b761
JS
36}
37
38GarbageCollector::~GarbageCollector()
39{
4cbc57f0 40 Reset();
8e08b761
JS
41}
42
43/*** GC alg. helpers ***/
44
45void GarbageCollector::DestroyItemList( wxList& lst )
46{
4cbc57f0 47 wxNode* pNode = lst.First();
8e08b761 48
4cbc57f0
JS
49 while( pNode )
50 {
51 delete &node_to_item( pNode );
8e08b761 52
4cbc57f0
JS
53 pNode = pNode->Next();
54 }
8e08b761 55
4cbc57f0 56 lst.Clear();
8e08b761
JS
57}
58
59wxNode* GarbageCollector::FindItemNode( void* pForObj )
60{
4cbc57f0 61 wxNode* pNode = mAllNodes.First();
8e08b761 62
4cbc57f0
JS
63 while( pNode )
64 {
65 if ( node_to_item( pNode ).mpObj == pForObj )
8e08b761 66
4cbc57f0 67 return pNode;
8e08b761 68
4cbc57f0
JS
69 pNode = pNode->Next();
70 }
8e08b761 71
4cbc57f0
JS
72 int avoidCompilerWarning = 0;
73 wxASSERT(avoidCompilerWarning); // DBG:: item should be present
8e08b761 74
4cbc57f0 75 return 0;
8e08b761
JS
76}
77
78wxNode* GarbageCollector::FindReferenceFreeItemNode()
79{
4cbc57f0 80 wxNode* pNode = mAllNodes.First();
8e08b761 81
4cbc57f0
JS
82 while( pNode )
83 {
84 if ( node_to_item( pNode ).mRefs.Number() == 0 )
8e08b761 85
4cbc57f0 86 return pNode;
8e08b761 87
4cbc57f0
JS
88 pNode = pNode->Next();
89 }
8e08b761 90
4cbc57f0 91 return 0;
8e08b761
JS
92}
93
94void GarbageCollector::RemoveReferencesToNode( wxNode* pItemNode )
95{
4cbc57f0 96 wxNode* pNode = mAllNodes.First();
8e08b761 97
4cbc57f0
JS
98 while( pNode )
99 {
100 wxList& refLst = node_to_item( pNode ).mRefs;
101 wxNode* pRefNode = refLst.First();
8e08b761 102
4cbc57f0
JS
103 while( pRefNode )
104 {
105 if ( pRefNode->Data() == (wxObject*)pItemNode )
106 {
107 wxNode* pNext = pRefNode->Next();
8e08b761 108
4cbc57f0 109 refLst.DeleteNode( pRefNode );
8e08b761 110
4cbc57f0 111 pRefNode = pNext;
8e08b761 112
4cbc57f0
JS
113 continue;
114 }
115 else pRefNode = pRefNode->Next();
116 }
8e08b761 117
4cbc57f0
JS
118 pNode = pNode->Next();
119 }
8e08b761
JS
120}
121
122void GarbageCollector::ResolveReferences()
123{
4cbc57f0 124 wxNode* pNode = mAllNodes.First();
8e08b761 125
4cbc57f0
JS
126 while( pNode )
127 {
128 GCItem& item = node_to_item( pNode );
8e08b761 129
4cbc57f0 130 wxNode* pRefNode = item.mRefs.First();
8e08b761 131
4cbc57f0
JS
132 while( pRefNode )
133 {
134 pRefNode->SetData( (wxObject*) FindItemNode( (void*)pRefNode->Data() ) );
8e08b761 135
4cbc57f0
JS
136 pRefNode = pRefNode->Next();
137 }
8e08b761 138
4cbc57f0
JS
139 pNode = pNode->Next();
140 }
8e08b761
JS
141}
142
143void GarbageCollector::AddObject( void* pObj, int refCnt )
144{
4cbc57f0 145 // FOR NOW:: initial ref-count is not used
8e08b761 146
4cbc57f0 147 GCItem* pItem = new GCItem();
8e08b761 148
4cbc57f0 149 pItem->mpObj = pObj;
8e08b761 150
4cbc57f0 151 mAllNodes.Append( (wxObject*) pItem );
8e08b761
JS
152}
153
154void GarbageCollector::AddDependency( void* pObj, void* pDependsOnObj )
155{
4cbc57f0 156 node_to_item( FindItemNode( pObj ) ).mRefs.Append( (wxObject*)pDependsOnObj );
8e08b761
JS
157}
158
159/*** GC alg. implementation ***/
160
161void GarbageCollector::ArrangeCollection()
162{
4cbc57f0 163 ResolveReferences();
8e08b761 164
4cbc57f0
JS
165 do
166 {
167 // find node, which does not depend on anything
8e08b761 168
4cbc57f0 169 wxNode* pItemNode = FindReferenceFreeItemNode();
8e08b761 170
4cbc57f0
JS
171 if ( pItemNode )
172 {
173 // append it to the list, where items are contained
174 // in the increasing order of dependencies
8e08b761 175
4cbc57f0 176 mRegularLst.Append( pItemNode->Data() );
8e08b761 177
4cbc57f0 178 mAllNodes.DeleteNode( pItemNode );
8e08b761 179
4cbc57f0
JS
180 // remove references to this current "least-dependent" node
181 // from reference lists of all the other nodes
8e08b761 182
4cbc57f0
JS
183 RemoveReferencesToNode( pItemNode );
184 }
185 else
186 {
187 // otherwise, what is left - all nodes, which
188 // are involved into cycled chains (rings)
8e08b761 189
4cbc57f0 190 wxNode* pNode = mAllNodes.First();
8e08b761 191
4cbc57f0
JS
192 while( pNode )
193 {
194 mCycledLst.Append( pNode->Data() );
8e08b761 195
4cbc57f0
JS
196 pNode = pNode->Next();
197 }
8e08b761 198
4926b15b 199 mAllNodes.Clear();
4cbc57f0
JS
200 break;
201 }
8e08b761 202
4cbc57f0 203 // continue search for "least-dependent" nodes
8e08b761 204
4cbc57f0 205 } while(1);
8e08b761
JS
206}
207
208wxList& GarbageCollector::GetRegularObjects()
209{
4cbc57f0 210 return mRegularLst;
8e08b761
JS
211}
212
213wxList& GarbageCollector::GetCycledObjects()
214{
4cbc57f0 215 return mCycledLst;
8e08b761
JS
216}
217
218void GarbageCollector::Reset()
219{
4cbc57f0 220 DestroyItemList( mAllNodes );
4926b15b
GT
221 DestroyItemList( mRegularLst );
222 DestroyItemList( mCycledLst );
8e08b761
JS
223}
224