31
31
using Cairo ;
32
32
using System . Diagnostics ;
33
33
using System . Reflection ;
34
+ using System . Threading ;
34
35
35
36
36
37
namespace Crow
37
38
{
38
39
public class Group : GraphicObject
39
40
{
41
+ protected ReaderWriterLockSlim childrenRWLock = new ReaderWriterLockSlim ( ) ;
42
+
40
43
#region CTOR
41
44
public Group ( ) : base ( ) { }
42
45
public Group ( Interface iface ) : base ( iface ) { }
@@ -62,10 +65,13 @@ public bool MultiSelect
62
65
set { _multiSelect = value ; }
63
66
}
64
67
public virtual void AddChild ( GraphicObject g ) {
65
- lock ( Children ) {
66
- g . Parent = this ;
67
- Children . Add ( g ) ;
68
- }
68
+ childrenRWLock . EnterWriteLock ( ) ;
69
+
70
+ g . Parent = this ;
71
+ Children . Add ( g ) ;
72
+
73
+ childrenRWLock . ExitWriteLock ( ) ;
74
+
69
75
g . RegisteredLayoutings = LayoutingType . None ;
70
76
g . LayoutChanged += OnChildLayoutChanges ;
71
77
g . RegisterForLayouting ( LayoutingType . Sizing | LayoutingType . ArrangeChildren ) ;
@@ -79,8 +85,11 @@ public virtual void RemoveChild(GraphicObject child)
79
85
CurrentInterface . HoverWidget = null ;
80
86
}
81
87
82
- lock ( Children )
83
- Children . Remove ( child ) ;
88
+ childrenRWLock . EnterWriteLock ( ) ;
89
+
90
+ Children . Remove ( child ) ;
91
+
92
+ childrenRWLock . ExitWriteLock ( ) ;
84
93
85
94
if ( child == largestChild && Width == Measure . Fit )
86
95
searchLargestChild ( ) ;
@@ -96,10 +105,13 @@ public virtual void DeleteChild(GraphicObject child)
96
105
child . Dispose ( ) ;
97
106
}
98
107
public virtual void InsertChild ( int idx , GraphicObject g ) {
99
- lock ( Children ) {
100
- g . Parent = this ;
101
- Children . Insert ( idx , g ) ;
102
- }
108
+ childrenRWLock . EnterWriteLock ( ) ;
109
+
110
+ g . Parent = this ;
111
+ Children . Insert ( idx , g ) ;
112
+
113
+ childrenRWLock . ExitWriteLock ( ) ;
114
+
103
115
g . RegisteredLayoutings = LayoutingType . None ;
104
116
g . LayoutChanged += OnChildLayoutChanges ;
105
117
g . RegisterForLayouting ( LayoutingType . Sizing | LayoutingType . ArrangeChildren ) ;
@@ -109,15 +121,17 @@ public virtual void DeleteChild (int idx) {
109
121
}
110
122
public virtual void ClearChildren ( )
111
123
{
112
- lock ( Children ) {
113
- while ( Children . Count > 0 ) {
114
- GraphicObject g = Children [ Children . Count - 1 ] ;
115
- g . LayoutChanged -= OnChildLayoutChanges ;
116
- Children . RemoveAt ( Children . Count - 1 ) ;
117
- g . Dispose ( ) ;
118
- }
124
+ childrenRWLock . EnterWriteLock ( ) ;
125
+
126
+ while ( Children . Count > 0 ) {
127
+ GraphicObject g = Children [ Children . Count - 1 ] ;
128
+ g . LayoutChanged -= OnChildLayoutChanges ;
129
+ Children . RemoveAt ( Children . Count - 1 ) ;
130
+ g . Dispose ( ) ;
119
131
}
120
132
133
+ childrenRWLock . ExitWriteLock ( ) ;
134
+
121
135
resetChildrenMaxSize ( ) ;
122
136
123
137
this . RegisterForLayouting ( LayoutingType . Sizing ) ;
@@ -128,45 +142,56 @@ public void putWidgetOnTop(GraphicObject w)
128
142
{
129
143
if ( Children . Contains ( w ) )
130
144
{
131
- lock ( Children ) {
132
- Children . Remove ( w ) ;
133
- Children . Add ( w ) ;
134
- }
145
+ childrenRWLock . EnterWriteLock ( ) ;
146
+
147
+ Children . Remove ( w ) ;
148
+ Children . Add ( w ) ;
149
+
150
+ childrenRWLock . ExitWriteLock ( ) ;
135
151
}
136
152
}
137
153
public void putWidgetOnBottom ( GraphicObject w )
138
154
{
139
155
if ( Children . Contains ( w ) )
140
156
{
141
- lock ( Children ) {
142
- Children . Remove ( w ) ;
143
- Children . Insert ( 0 , w ) ;
144
- }
157
+ childrenRWLock . EnterWriteLock ( ) ;
158
+
159
+ Children . Remove ( w ) ;
160
+ Children . Insert ( 0 , w ) ;
161
+
162
+ childrenRWLock . ExitWriteLock ( ) ;
145
163
}
146
164
}
147
165
148
166
#region GraphicObject overrides
149
167
public override void OnDataSourceChanged ( object sender , DataSourceChangeEventArgs e )
150
168
{
151
169
base . OnDataSourceChanged ( this , e ) ;
152
- lock ( Children ) {
153
- foreach ( GraphicObject g in children )
154
- if ( g . localDataSourceIsNull & g . localLogicalParentIsNull )
155
- g . OnDataSourceChanged ( g , e ) ;
156
- }
170
+
171
+ childrenRWLock . EnterReadLock ( ) ;
172
+
173
+ foreach ( GraphicObject g in children )
174
+ if ( g . localDataSourceIsNull & g . localLogicalParentIsNull )
175
+ g . OnDataSourceChanged ( g , e ) ;
176
+
177
+ childrenRWLock . ExitReadLock ( ) ;
157
178
}
158
179
public override GraphicObject FindByName ( string nameToFind )
159
180
{
160
181
if ( Name == nameToFind )
161
182
return this ;
162
183
GraphicObject tmp = null ;
163
- lock ( Children ) {
164
- foreach ( GraphicObject w in Children ) {
165
- tmp = w . FindByName ( nameToFind ) ;
166
- if ( tmp != null )
167
- break ;
168
- }
184
+
185
+ childrenRWLock . EnterReadLock ( ) ;
186
+
187
+ foreach ( GraphicObject w in Children ) {
188
+ tmp = w . FindByName ( nameToFind ) ;
189
+ if ( tmp != null )
190
+ break ;
169
191
}
192
+
193
+ childrenRWLock . ExitReadLock ( ) ;
194
+
170
195
return tmp ;
171
196
}
172
197
public override bool Contains ( GraphicObject goToFind )
@@ -207,10 +232,11 @@ public override void OnLayoutChanges (LayoutingType layoutType)
207
232
{
208
233
base . OnLayoutChanges ( layoutType ) ;
209
234
235
+ childrenRWLock . EnterReadLock ( ) ;
210
236
//position smaller objects in group when group size is fit
211
237
switch ( layoutType ) {
212
238
case LayoutingType . Width :
213
- foreach ( GraphicObject c in Children ) {
239
+ foreach ( GraphicObject c in Children ) {
214
240
if ( c . Width . Units == Unit . Percent )
215
241
c . RegisterForLayouting ( LayoutingType . Width ) ;
216
242
else
@@ -226,6 +252,7 @@ public override void OnLayoutChanges (LayoutingType layoutType)
226
252
}
227
253
break ;
228
254
}
255
+ childrenRWLock . ExitReadLock ( ) ;
229
256
}
230
257
protected override void onDraw ( Context gr )
231
258
{
@@ -239,11 +266,13 @@ protected override void onDraw (Context gr)
239
266
gr . Clip ( ) ;
240
267
}
241
268
242
- lock ( Children ) {
269
+ childrenRWLock . EnterReadLock ( ) ;
270
+
243
271
foreach ( GraphicObject g in Children ) {
244
272
g . Paint ( ref gr ) ;
245
273
}
246
- }
274
+
275
+ childrenRWLock . ExitReadLock ( ) ;
247
276
gr . Restore ( ) ;
248
277
}
249
278
protected override void UpdateCache ( Context ctx )
@@ -268,16 +297,18 @@ protected override void UpdateCache (Context ctx)
268
297
gr . Clip ( ) ;
269
298
}
270
299
271
- lock ( Children ) {
272
- foreach ( GraphicObject c in Children ) {
273
- if ( ! c . Visible )
274
- continue ;
275
- if ( Clipping . Contains ( c . Slot + ClientRectangle . Position ) == RegionOverlap . Out )
276
- continue ;
277
- c . Paint ( ref gr ) ;
278
- }
300
+ childrenRWLock . EnterReadLock ( ) ;
301
+
302
+ foreach ( GraphicObject c in Children ) {
303
+ if ( ! c . Visible )
304
+ continue ;
305
+ if ( Clipping . Contains ( c . Slot + ClientRectangle . Position ) == RegionOverlap . Out )
306
+ continue ;
307
+ c . Paint ( ref gr ) ;
279
308
}
280
309
310
+ childrenRWLock . ExitReadLock ( ) ;
311
+
281
312
#if DEBUG_CLIP_RECTANGLE
282
313
Clipping . stroke ( gr , Color . Amaranth . AdjustAlpha ( 0.8 ) ) ;
283
314
#endif
0 commit comments