Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / libs / c5 / C5 / Events.cs @ 3

1
/*
2
 Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft
3
 Permission is hereby granted, free of charge, to any person obtaining a copy
4
 of this software and associated documentation files (the "Software"), to deal
5
 in the Software without restriction, including without limitation the rights
6
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
 copies of the Software, and to permit persons to whom the Software is
8
 furnished to do so, subject to the following conditions:
9
 
10
 The above copyright notice and this permission notice shall be included in
11
 all copies or substantial portions of the Software.
12
 
13
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
 SOFTWARE.
20
*/
21

    
22
using System;
23
using System.Diagnostics;
24
using SCG = System.Collections.Generic;
25

    
26
namespace C5
27
{
28
  /// <summary>
29
  /// 
30
  /// </summary>
31
  [Flags]
32
  public enum EventTypeEnum
33
  {
34
    /// <summary>
35
    /// 
36
    /// </summary>
37
    None = 0x00000000,
38
    /// <summary>
39
    /// 
40
    /// </summary>
41
    Changed = 0x00000001,
42
    /// <summary>
43
    /// 
44
    /// </summary>
45
    Cleared = 0x00000002,
46
    /// <summary>
47
    /// 
48
    /// </summary>
49
    Added = 0x00000004,
50
    /// <summary>
51
    /// 
52
    /// </summary>
53
    Removed = 0x00000008,
54
    /// <summary>
55
    /// 
56
    /// </summary>
57
    Basic = 0x0000000f,
58
    /// <summary>
59
    /// 
60
    /// </summary>
61
    Inserted = 0x00000010,
62
    /// <summary>
63
    /// 
64
    /// </summary>
65
    RemovedAt = 0x00000020,
66
    /// <summary>
67
    /// 
68
    /// </summary>
69
    All = 0x0000003f
70
  }
71

    
72
  /// <summary>
73
  /// Holds the real events for a collection
74
  /// </summary>
75
  /// <typeparam name="T"></typeparam>
76
  [Serializable]
77
  internal sealed class EventBlock<T>
78
  {
79
    internal EventTypeEnum events;
80

    
81
    event CollectionChangedHandler<T> collectionChanged;
82
    internal event CollectionChangedHandler<T> CollectionChanged
83
    {
84
      add
85
      {
86
        collectionChanged += value;
87
        events |= EventTypeEnum.Changed;
88
      }
89
      remove
90
      {
91
        collectionChanged -= value;
92
        if (collectionChanged == null)
93
          events &= ~EventTypeEnum.Changed;
94
      }
95
    }
96
    internal void raiseCollectionChanged(object sender)
97
    { if (collectionChanged != null) collectionChanged(sender); }
98

    
99
    event CollectionClearedHandler<T> collectionCleared;
100
    internal event CollectionClearedHandler<T> CollectionCleared
101
    {
102
      add
103
      {
104
        collectionCleared += value;
105
        events |= EventTypeEnum.Cleared;
106
      }
107
      remove
108
      {
109
        collectionCleared -= value;
110
        if (collectionCleared == null)
111
          events &= ~EventTypeEnum.Cleared;
112
      }
113
    }
114
    internal void raiseCollectionCleared(object sender, bool full, int count)
115
    { if (collectionCleared != null) collectionCleared(sender, new ClearedEventArgs(full, count)); }
116
    internal void raiseCollectionCleared(object sender, bool full, int count, int? start)
117
    { if (collectionCleared != null) collectionCleared(sender, new ClearedRangeEventArgs(full, count, start)); }
118

    
119
    event ItemsAddedHandler<T> itemsAdded;
120
    internal event ItemsAddedHandler<T> ItemsAdded
121
    {
122
      add
123
      {
124
        itemsAdded += value;
125
        events |= EventTypeEnum.Added;
126
      }
127
      remove
128
      {
129
        itemsAdded -= value;
130
        if (itemsAdded == null)
131
          events &= ~EventTypeEnum.Added;
132
      }
133
    }
134
    internal void raiseItemsAdded(object sender, T item, int count)
135
    { if (itemsAdded != null) itemsAdded(sender, new ItemCountEventArgs<T>(item, count)); }
136

    
137
    event ItemsRemovedHandler<T> itemsRemoved;
138
    internal event ItemsRemovedHandler<T> ItemsRemoved
139
    {
140
      add
141
      {
142
        itemsRemoved += value;
143
        events |= EventTypeEnum.Removed;
144
      }
145
      remove
146
      {
147
        itemsRemoved -= value;
148
        if (itemsRemoved == null)
149
          events &= ~EventTypeEnum.Removed;
150
      }
151
    }
152
    internal void raiseItemsRemoved(object sender, T item, int count)
153
    { if (itemsRemoved != null) itemsRemoved(sender, new ItemCountEventArgs<T>(item, count)); }
154

    
155
    event ItemInsertedHandler<T> itemInserted;
156
    internal event ItemInsertedHandler<T> ItemInserted
157
    {
158
      add
159
      {
160
        itemInserted += value;
161
        events |= EventTypeEnum.Inserted;
162
      }
163
      remove
164
      {
165
        itemInserted -= value;
166
        if (itemInserted == null)
167
          events &= ~EventTypeEnum.Inserted;
168
      }
169
    }
170
    internal void raiseItemInserted(object sender, T item, int index)
171
    { if (itemInserted != null) itemInserted(sender, new ItemAtEventArgs<T>(item, index)); }
172

    
173
    event ItemRemovedAtHandler<T> itemRemovedAt;
174
    internal event ItemRemovedAtHandler<T> ItemRemovedAt
175
    {
176
      add
177
      {
178
        itemRemovedAt += value;
179
        events |= EventTypeEnum.RemovedAt;
180
      }
181
      remove
182
      {
183
        itemRemovedAt -= value;
184
        if (itemRemovedAt == null)
185
          events &= ~EventTypeEnum.RemovedAt;
186
      }
187
    }
188
    internal void raiseItemRemovedAt(object sender, T item, int index)
189
    { if (itemRemovedAt != null) itemRemovedAt(sender, new ItemAtEventArgs<T>(item, index)); }
190
  }
191

    
192
  /// <summary>
193
  /// Tentative, to conserve memory in GuardedCollectionValueBase
194
  /// This should really be nested in Guarded collection value, only have a guardereal field
195
  /// </summary>
196
  /// <typeparam name="T"></typeparam>
197
  [Serializable]
198
  internal sealed class ProxyEventBlock<T>
199
  {
200
    ICollectionValue<T> proxy, real;
201

    
202
    internal ProxyEventBlock(ICollectionValue<T> proxy, ICollectionValue<T> real)
203
    { this.proxy = proxy; this.real = real; }
204

    
205
    event CollectionChangedHandler<T> collectionChanged;
206
    CollectionChangedHandler<T> collectionChangedProxy;
207
    internal event CollectionChangedHandler<T> CollectionChanged
208
    {
209
      add
210
      {
211
        if (collectionChanged == null)
212
        {
213
          if (collectionChangedProxy == null)
214
            collectionChangedProxy = delegate(object sender) { collectionChanged(proxy); };
215
          real.CollectionChanged += collectionChangedProxy;
216
        }
217
        collectionChanged += value;
218
      }
219
      remove
220
      {
221
        collectionChanged -= value;
222
        if (collectionChanged == null)
223
          real.CollectionChanged -= collectionChangedProxy;
224
      }
225
    }
226

    
227
    event CollectionClearedHandler<T> collectionCleared;
228
    CollectionClearedHandler<T> collectionClearedProxy;
229
    internal event CollectionClearedHandler<T> CollectionCleared
230
    {
231
      add
232
      {
233
        if (collectionCleared == null)
234
        {
235
          if (collectionClearedProxy == null)
236
            collectionClearedProxy = delegate(object sender, ClearedEventArgs e) { collectionCleared(proxy, e); };
237
          real.CollectionCleared += collectionClearedProxy;
238
        }
239
        collectionCleared += value;
240
      }
241
      remove
242
      {
243
        collectionCleared -= value;
244
        if (collectionCleared == null)
245
          real.CollectionCleared -= collectionClearedProxy;
246
      }
247
    }
248

    
249
    event ItemsAddedHandler<T> itemsAdded;
250
    ItemsAddedHandler<T> itemsAddedProxy;
251
    internal event ItemsAddedHandler<T> ItemsAdded
252
    {
253
      add
254
      {
255
        if (itemsAdded == null)
256
        {
257
          if (itemsAddedProxy == null)
258
            itemsAddedProxy = delegate(object sender, ItemCountEventArgs<T> e) { itemsAdded(proxy, e); };
259
          real.ItemsAdded += itemsAddedProxy;
260
        }
261
        itemsAdded += value;
262
      }
263
      remove
264
      {
265
        itemsAdded -= value;
266
        if (itemsAdded == null)
267
          real.ItemsAdded -= itemsAddedProxy;
268
      }
269
    }
270

    
271
    event ItemInsertedHandler<T> itemInserted;
272
    ItemInsertedHandler<T> itemInsertedProxy;
273
    internal event ItemInsertedHandler<T> ItemInserted
274
    {
275
      add
276
      {
277
        if (itemInserted == null)
278
        {
279
          if (itemInsertedProxy == null)
280
            itemInsertedProxy = delegate(object sender, ItemAtEventArgs<T> e) { itemInserted(proxy, e); };
281
          real.ItemInserted += itemInsertedProxy;
282
        }
283
        itemInserted += value;
284
      }
285
      remove
286
      {
287
        itemInserted -= value;
288
        if (itemInserted == null)
289
          real.ItemInserted -= itemInsertedProxy;
290
      }
291
    }
292

    
293
    event ItemsRemovedHandler<T> itemsRemoved;
294
    ItemsRemovedHandler<T> itemsRemovedProxy;
295
    internal event ItemsRemovedHandler<T> ItemsRemoved
296
    {
297
      add
298
      {
299
        if (itemsRemoved == null)
300
        {
301
          if (itemsRemovedProxy == null)
302
            itemsRemovedProxy = delegate(object sender, ItemCountEventArgs<T> e) { itemsRemoved(proxy, e); };
303
          real.ItemsRemoved += itemsRemovedProxy;
304
        }
305
        itemsRemoved += value;
306
      }
307
      remove
308
      {
309
        itemsRemoved -= value;
310
        if (itemsRemoved == null)
311
          real.ItemsRemoved -= itemsRemovedProxy;
312
      }
313
    }
314

    
315
    event ItemRemovedAtHandler<T> itemRemovedAt;
316
    ItemRemovedAtHandler<T> itemRemovedAtProxy;
317
    internal event ItemRemovedAtHandler<T> ItemRemovedAt
318
    {
319
      add
320
      {
321
        if (itemRemovedAt == null)
322
        {
323
          if (itemRemovedAtProxy == null)
324
            itemRemovedAtProxy = delegate(object sender, ItemAtEventArgs<T> e) { itemRemovedAt(proxy, e); };
325
          real.ItemRemovedAt += itemRemovedAtProxy;
326
        }
327
        itemRemovedAt += value;
328
      }
329
      remove
330
      {
331
        itemRemovedAt -= value;
332
        if (itemRemovedAt == null)
333
          real.ItemRemovedAt -= itemRemovedAtProxy;
334
      }
335
    }
336
  }
337

    
338
  /// <summary>
339
  /// 
340
  /// </summary>
341
  /// <typeparam name="T"></typeparam>
342
  public class ItemAtEventArgs<T> : EventArgs
343
  {
344
    /// <summary>
345
    /// 
346
    /// </summary>
347
    public readonly T Item;
348
    /// <summary>
349
    /// 
350
    /// </summary>
351
    public readonly int Index;
352
    /// <summary>
353
    /// 
354
    /// </summary>
355
    /// <param name="item"></param>
356
    /// <param name="index"></param>
357
    public ItemAtEventArgs(T item, int index) { Item = item; Index = index; }
358
    /// <summary>
359
    /// 
360
    /// </summary>
361
    /// <returns></returns>
362
    public override string ToString()
363
    {
364
      return String.Format("(ItemAtEventArgs {0} '{1}')", Index, Item);
365
    }
366
  }
367

    
368
  /// <summary>
369
  /// 
370
  /// </summary>
371
  /// <typeparam name="T"></typeparam>
372
  public class ItemCountEventArgs<T> : EventArgs
373
  {
374
    /// <summary>
375
    /// 
376
    /// </summary>
377
    public readonly T Item;
378
    /// <summary>
379
    /// 
380
    /// </summary>
381
    public readonly int Count;
382
    /// <summary>
383
    /// 
384
    /// </summary>
385
    /// <param name="count"></param>
386
    /// <param name="item"></param>
387
    public ItemCountEventArgs(T item, int count) { Item = item; Count = count; }
388
    /// <summary>
389
    /// 
390
    /// </summary>
391
    /// <returns></returns>
392
    public override string ToString()
393
    {
394
      return String.Format("(ItemCountEventArgs {0} '{1}')", Count, Item);
395
    }
396
  }
397

    
398

    
399

    
400
  /// <summary>
401
  /// 
402
  /// </summary>
403
  public class ClearedEventArgs : EventArgs
404
  {
405
    /// <summary>
406
    /// 
407
    /// </summary>
408
    public readonly bool Full;
409
    /// <summary>
410
    /// 
411
    /// </summary>
412
    public readonly int Count;
413
    /// <summary>
414
    /// 
415
    /// </summary>
416
    /// 
417
    /// <param name="full">True if the operation cleared all of the collection</param>
418
    /// <param name="count">The number of items removed by the clear.</param>
419
    public ClearedEventArgs(bool full, int count) { Full = full; Count = count; }
420
    /// <summary>
421
    /// 
422
    /// </summary>
423
    /// <returns></returns>
424
    public override string ToString()
425
    {
426
      return String.Format("(ClearedEventArgs {0} {1})", Count, Full);
427
    }
428
  }
429

    
430
  /// <summary>
431
  /// 
432
  /// </summary>
433
  public class ClearedRangeEventArgs : ClearedEventArgs
434
  {
435
    //WE could let this be of type int? to  allow 
436
    /// <summary>
437
    /// 
438
    /// </summary>
439
    public readonly int? Start;
440
    /// <summary>
441
    /// 
442
    /// </summary>
443
    /// <param name="full"></param>
444
    /// <param name="count"></param>
445
    /// <param name="start"></param>
446
    public ClearedRangeEventArgs(bool full, int count, int? start) : base(full,count) { Start = start; }
447
    /// <summary>
448
    /// 
449
    /// </summary>
450
    /// <returns></returns>
451
    public override string ToString()
452
    {
453
      return String.Format("(ClearedRangeEventArgs {0} {1} {2})", Count, Full, Start);
454
    }
455
  }
456

    
457
  /// <summary>
458
  /// The type of event raised after an operation on a collection has changed its contents.
459
  /// Normally, a multioperation like AddAll, 
460
  /// <see cref="M:C5.IExtensible`1.AddAll(System.Collections.Generic.IEnumerable{`0})"/> 
461
  /// will only fire one CollectionChanged event. Any operation that changes the collection
462
  /// must fire CollectionChanged as its last event.
463
  /// </summary>
464
  public delegate void CollectionChangedHandler<T>(object sender);
465

    
466
  /// <summary>
467
  /// The type of event raised after the Clear() operation on a collection.
468
  /// <para/>
469
  /// Note: The Clear() operation will not fire ItemsRemoved events. 
470
  /// </summary>
471
  /// <param name="sender"></param>
472
  /// <param name="eventArgs"></param>
473
  public delegate void CollectionClearedHandler<T>(object sender, ClearedEventArgs eventArgs);
474

    
475
  /// <summary>
476
  /// The type of event raised after an item has been added to a collection.
477
  /// The event will be raised at a point of time, where the collection object is 
478
  /// in an internally consistent state and before the corresponding CollectionChanged 
479
  /// event is raised.
480
  /// <para/>
481
  /// Note: an Update operation will fire an ItemsRemoved and an ItemsAdded event.
482
  /// <para/>
483
  /// Note: When an item is inserted into a list (<see cref="T:C5.IList`1"/>), both
484
  /// ItemInserted and ItemsAdded events will be fired.
485
  /// </summary>
486
  /// <param name="sender"></param>
487
  /// <param name="eventArgs">An object with the item that was added</param>
488
  public delegate void ItemsAddedHandler<T>(object sender, ItemCountEventArgs<T> eventArgs);
489

    
490
  /// <summary>
491
  /// The type of event raised after an item has been removed from a collection.
492
  /// The event will be raised at a point of time, where the collection object is 
493
  /// in an internally consistent state and before the corresponding CollectionChanged 
494
  /// event is raised.
495
  /// <para/>
496
  /// Note: The Clear() operation will not fire ItemsRemoved events. 
497
  /// <para/>
498
  /// Note: an Update operation will fire an ItemsRemoved and an ItemsAdded event.
499
  /// <para/>
500
  /// Note: When an item is removed from a list by the RemoveAt operation, both an 
501
  /// ItemsRemoved and an ItemRemovedAt event will be fired.
502
  /// </summary>
503
  /// <param name="sender"></param>
504
  /// <param name="eventArgs">An object with the item that was removed</param>
505
  public delegate void ItemsRemovedHandler<T>(object sender, ItemCountEventArgs<T> eventArgs);
506

    
507
  /// <summary>
508
  /// The type of event raised after an item has been inserted into a list by an Insert, 
509
  /// InsertFirst or InsertLast operation.
510
  /// The event will be raised at a point of time, where the collection object is 
511
  /// in an internally consistent state and before the corresponding CollectionChanged 
512
  /// event is raised.
513
  /// <para/>
514
  /// Note: an ItemsAdded event will also be fired.
515
  /// </summary>
516
  /// <param name="sender"></param>
517
  /// <param name="eventArgs"></param>
518
  public delegate void ItemInsertedHandler<T>(object sender, ItemAtEventArgs<T> eventArgs);
519

    
520
  /// <summary>
521
  /// The type of event raised after an item has been removed from a list by a RemoveAt(int i)
522
  /// operation (or RemoveFirst(), RemoveLast(), Remove() operation).
523
  /// The event will be raised at a point of time, where the collection object is 
524
  /// in an internally consistent state and before the corresponding CollectionChanged 
525
  /// event is raised.
526
  /// <para/>
527
  /// Note: an ItemRemoved event will also be fired.
528
  /// </summary>
529
  /// <param name="sender"></param>
530
  /// <param name="eventArgs"></param>
531
  public delegate void ItemRemovedAtHandler<T>(object sender, ItemAtEventArgs<T> eventArgs);
532
}