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