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