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