]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/fl/garbagec.cpp
Version number updates
[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{
8495ba53 35 return *( (GCItem*)(pNode->GetData()) );
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{
8495ba53 47 wxNode* pNode = lst.GetFirst();
8e08b761 48
4cbc57f0
JS
49 while( pNode )
50 {
51 delete &node_to_item( pNode );
8e08b761 52
8495ba53 53 pNode = pNode->GetNext();
4cbc57f0 54 }
8e08b761 55
4cbc57f0 56 lst.Clear();
8e08b761
JS
57}
58
59wxNode* GarbageCollector::FindItemNode( void* pForObj )
60{
8495ba53 61 wxNode* pNode = mAllNodes.GetFirst();
8e08b761 62
4cbc57f0
JS
63 while( pNode )
64 {
65 if ( node_to_item( pNode ).mpObj == pForObj )
8e08b761 66
4cbc57f0 67 return pNode;
8e08b761 68
8495ba53 69 pNode = pNode->GetNext();
4cbc57f0 70 }
8e08b761 71
8552e6f0 72 return NULL;
8e08b761
JS
73}
74
75wxNode* GarbageCollector::FindReferenceFreeItemNode()
76{
8495ba53 77 wxNode* pNode = mAllNodes.GetFirst();
8e08b761 78
4cbc57f0
JS
79 while( pNode )
80 {
8495ba53 81 if ( node_to_item( pNode ).mRefs.GetCount() == 0 )
8e08b761 82
4cbc57f0 83 return pNode;
8e08b761 84
8495ba53 85 pNode = pNode->GetNext();
4cbc57f0 86 }
8e08b761 87
4cbc57f0 88 return 0;
8e08b761
JS
89}
90
91void GarbageCollector::RemoveReferencesToNode( wxNode* pItemNode )
92{
8495ba53 93 wxNode* pNode = mAllNodes.GetFirst();
8e08b761 94
4cbc57f0
JS
95 while( pNode )
96 {
97 wxList& refLst = node_to_item( pNode ).mRefs;
8495ba53 98 wxNode* pRefNode = refLst.GetFirst();
8e08b761 99
4cbc57f0
JS
100 while( pRefNode )
101 {
8495ba53 102 if ( pRefNode->GetData() == (wxObject*)pItemNode )
4cbc57f0 103 {
8495ba53 104 wxNode* pNext = pRefNode->GetNext();
8e08b761 105
4cbc57f0 106 refLst.DeleteNode( pRefNode );
8e08b761 107
4cbc57f0 108 pRefNode = pNext;
8e08b761 109
4cbc57f0
JS
110 continue;
111 }
8495ba53 112 else pRefNode = pRefNode->GetNext();
4cbc57f0 113 }
8e08b761 114
8495ba53 115 pNode = pNode->GetNext();
4cbc57f0 116 }
8e08b761
JS
117}
118
119void GarbageCollector::ResolveReferences()
120{
8495ba53 121 wxNode* pNode = mAllNodes.GetFirst();
8e08b761 122
4cbc57f0
JS
123 while( pNode )
124 {
125 GCItem& item = node_to_item( pNode );
8e08b761 126
8495ba53 127 wxNode* pRefNode = item.mRefs.GetFirst();
8e08b761 128
4cbc57f0
JS
129 while( pRefNode )
130 {
8495ba53 131 pRefNode->SetData( (wxObject*) FindItemNode( (void*)pRefNode->GetData() ) );
8e08b761 132
8495ba53 133 pRefNode = pRefNode->GetNext();
4cbc57f0 134 }
8e08b761 135
8495ba53 136 pNode = pNode->GetNext();
4cbc57f0 137 }
8e08b761
JS
138}
139
196be0f1 140void GarbageCollector::AddObject( void* pObj, int WXUNUSED(refCnt) )
8e08b761 141{
4cbc57f0 142 // FOR NOW:: initial ref-count is not used
8e08b761 143
4cbc57f0 144 GCItem* pItem = new GCItem();
8e08b761 145
4cbc57f0 146 pItem->mpObj = pObj;
8e08b761 147
4cbc57f0 148 mAllNodes.Append( (wxObject*) pItem );
8e08b761
JS
149}
150
151void GarbageCollector::AddDependency( void* pObj, void* pDependsOnObj )
152{
4cbc57f0 153 node_to_item( FindItemNode( pObj ) ).mRefs.Append( (wxObject*)pDependsOnObj );
8e08b761
JS
154}
155
156/*** GC alg. implementation ***/
157
158void GarbageCollector::ArrangeCollection()
159{
4cbc57f0 160 ResolveReferences();
8e08b761 161
4cbc57f0
JS
162 do
163 {
164 // find node, which does not depend on anything
8e08b761 165
4cbc57f0 166 wxNode* pItemNode = FindReferenceFreeItemNode();
8e08b761 167
4cbc57f0
JS
168 if ( pItemNode )
169 {
170 // append it to the list, where items are contained
171 // in the increasing order of dependencies
8e08b761 172
8495ba53 173 mRegularLst.Append( pItemNode->GetData() );
8e08b761 174
4cbc57f0 175 mAllNodes.DeleteNode( pItemNode );
8e08b761 176
4cbc57f0
JS
177 // remove references to this current "least-dependent" node
178 // from reference lists of all the other nodes
8e08b761 179
4cbc57f0
JS
180 RemoveReferencesToNode( pItemNode );
181 }
182 else
183 {
184 // otherwise, what is left - all nodes, which
185 // are involved into cycled chains (rings)
8e08b761 186
8495ba53 187 wxNode* pNode = mAllNodes.GetFirst();
8e08b761 188
4cbc57f0
JS
189 while( pNode )
190 {
8495ba53 191 mCycledLst.Append( pNode->GetData() );
8e08b761 192
8495ba53 193 pNode = pNode->GetNext();
4cbc57f0 194 }
8e08b761 195
4926b15b 196 mAllNodes.Clear();
4cbc57f0
JS
197 break;
198 }
8e08b761 199
4cbc57f0 200 // continue search for "least-dependent" nodes
8e08b761 201
4cbc57f0 202 } while(1);
8e08b761
JS
203}
204
205wxList& GarbageCollector::GetRegularObjects()
206{
4cbc57f0 207 return mRegularLst;
8e08b761
JS
208}
209
210wxList& GarbageCollector::GetCycledObjects()
211{
4cbc57f0 212 return mCycledLst;
8e08b761
JS
213}
214
215void GarbageCollector::Reset()
216{
4cbc57f0 217 DestroyItemList( mAllNodes );
4926b15b
GT
218 DestroyItemList( mRegularLst );
219 DestroyItemList( mCycledLst );
8e08b761
JS
220}
221