@@ -33,6 +33,7 @@ interface
3333 SysUtils,
3434 TypInfo,
3535 Spring,
36+ Spring.Events.Base,
3637 Spring.Collections,
3738 Spring.Collections.Events,
3839 Spring.Collections.HashTable;
@@ -374,8 +375,7 @@ TCollectionBase<T> = class abstract(TEnumerableBase<T>)
374375 private
375376 fOnChanged: TCollectionChangedEventImpl<T>;
376377 fNotify: TNotify;
377- procedure InitializeEvent ;
378- procedure UpdateNotify (Sender: TObject);
378+ procedure EventChanged (Sender: TObject);
379379 protected
380380 { $REGION 'Property Accessors'}
381381 function GetIsReadOnly : Boolean;
@@ -645,6 +645,8 @@ TArrayHelper = record
645645 EmptyBucket = -1 ; // must be negative, note choice of BucketSentinelFlag
646646 UsedBucket = -2 ; // likewise
647647
648+ procedure UpdateNotify (actualClass, baseClass: TClass; const event: TEventBase; var code);
649+
648650implementation
649651
650652uses
@@ -657,9 +659,24 @@ implementation
657659 Posix.Pthread,
658660{ $ENDIF}
659661 Spring.Collections.Lists,
660- Spring.Events.Base,
661662 Spring.ResourceStrings;
662663
664+ procedure UpdateNotify (actualClass, baseClass: TClass; const event: TEventBase; var code);
665+ const
666+ ChangedVirtualIndex = 1 ;
667+ var
668+ baseAddress, actualAddress: Pointer;
669+ begin
670+ { $POINTERMATH ON}
671+ baseAddress := PPointer(baseClass)[ChangedVirtualIndex];
672+ actualAddress := PPointer(actualClass)[ChangedVirtualIndex];
673+ { $POINTERMATH OFF}
674+ if (Assigned(event) and event.CanInvoke) or (actualAddress <> baseAddress) then
675+ Pointer(code) := actualAddress
676+ else
677+ Pointer(code) := nil ;
678+ end ;
679+
663680
664681{ $REGION 'TArrayHelper'}
665682
@@ -1782,7 +1799,7 @@ function TSourceIterator<T>.GetElementType: PTypeInfo;
17821799constructor TCollectionBase<T>.Create;
17831800begin
17841801 inherited Create;
1785- UpdateNotify(Self );
1802+ UpdateNotify(ClassType, TCollectionBase<T>, fOnChanged, fNotify );
17861803end ;
17871804
17881805destructor TCollectionBase<T>.Destroy;
@@ -1791,24 +1808,9 @@ destructor TCollectionBase<T>.Destroy;
17911808 inherited Destroy;
17921809end ;
17931810
1794- procedure TCollectionBase <T>.InitializeEvent;
1795- var
1796- onChanged: TCollectionChangedEventImpl<T>;
1811+ procedure TCollectionBase <T>.EventChanged(Sender: TObject);
17971812begin
1798- if not Assigned(fOnChanged) then
1799- begin
1800- onChanged := TCollectionChangedEventImpl<T>.Create;
1801- onChanged.OnChanged := UpdateNotify;
1802- if AtomicCmpExchange(Pointer(fOnChanged), Pointer(onChanged), nil ) <> nil then
1803- onChanged.Free
1804- else
1805- begin
1806- { $IFDEF AUTOREFCOUNT}
1807- onChanged.__ObjAddRef;
1808- { $ENDIF AUTOREFCOUNT}
1809- UpdateNotify(Self);
1810- end ;
1811- end ;
1813+ UpdateNotify(ClassType, TCollectionBase<T>, fOnChanged, fNotify);
18121814end ;
18131815
18141816procedure TCollectionBase <T>.DoNotify(const item: T;
@@ -1902,8 +1904,24 @@ function TCollectionBase<T>.GetIsReadOnly: Boolean;
19021904end ;
19031905
19041906function TCollectionBase <T>.GetOnChanged: ICollectionChangedEvent<T>;
1907+ var
1908+ onChanged: TCollectionChangedEventImpl<T>;
19051909begin
1906- InitializeEvent;
1910+ if not Assigned(fOnChanged) then
1911+ begin
1912+ onChanged := TCollectionChangedEventImpl<T>.Create;
1913+ if AtomicCmpExchange(Pointer(fOnChanged), Pointer(onChanged), nil ) <> nil then
1914+ onChanged.Free
1915+ else
1916+ begin
1917+ { $IFDEF AUTOREFCOUNT}
1918+ onChanged.__ObjAddRef;
1919+ { $ENDIF AUTOREFCOUNT}
1920+ fOnChanged.OnChanged := EventChanged;
1921+ EventChanged(fOnChanged);
1922+ end ;
1923+ end ;
1924+
19071925 Result := fOnChanged;
19081926end ;
19091927
@@ -1943,18 +1961,6 @@ function TCollectionBase<T>.QueryInterface(const IID: TGUID; out obj): HResult;
19431961 Result := inherited QueryInterface(IID, obj);
19441962end ;
19451963
1946- procedure TCollectionBase <T>.UpdateNotify(Sender: TObject);
1947- var
1948- event: procedure(const item: T; action: TCollectionChangedAction) of object ;
1949- begin
1950- event := Changed;
1951- if (Assigned(fOnChanged) and fOnChanged.CanInvoke)
1952- or (TMethod(event).Code <> @TCollectionBase<T>.Changed) then
1953- fNotify := TMethod(event).Code
1954- else
1955- fNotify := nil ;
1956- end ;
1957-
19581964function TCollectionBase <T>.RemoveAll(const match: Predicate<T>): Integer;
19591965begin
19601966 Result := RemoveRange(IEnumerable<T>(this).Where(match).ToArray);
@@ -2622,7 +2628,7 @@ function TListBase<T>.IndexOf(const item: T): Integer;
26222628var
26232629 count: Integer;
26242630begin
2625- count := IEnumerable <T>(this).Count;
2631+ count := IList <T>(this).Count;
26262632 if count > 0 then
26272633 Result := IList<T>(this).IndexOf(item, 0 , count)
26282634 else
@@ -2633,7 +2639,7 @@ function TListBase<T>.IndexOf(const item: T; index: Integer): Integer;
26332639var
26342640 count: Integer;
26352641begin
2636- count := IEnumerable <T>(this).Count;
2642+ count := IList <T>(this).Count;
26372643 if count > 0 then
26382644 Result := IList<T>(this).IndexOf(item, index, count - index)
26392645 else
@@ -2644,7 +2650,7 @@ function TListBase<T>.LastIndexOf(const item: T): Integer;
26442650var
26452651 count: Integer;
26462652begin
2647- count := IEnumerable <T>(this).Count;
2653+ count := IList <T>(this).Count;
26482654 if count > 0 then
26492655 Result := IList<T>(this).LastIndexOf(item, count - 1 , count)
26502656 else
@@ -2655,7 +2661,7 @@ function TListBase<T>.LastIndexOf(const item: T; index: Integer): Integer;
26552661var
26562662 count: Integer;
26572663begin
2658- count := IEnumerable <T>(this).Count;
2664+ count := IList <T>(this).Count;
26592665 if count > 0 then
26602666 Result := IList<T>(this).LastIndexOf(item, index, index + 1 )
26612667 else
@@ -2679,17 +2685,17 @@ procedure TListBase<T>.Reverse;
26792685
26802686procedure TListBase <T>.Sort;
26812687begin
2682- IList<T>(this).Sort(fComparer, 0 , IEnumerable <T>(this).Count);
2688+ IList<T>(this).Sort(fComparer, 0 , IList <T>(this).Count);
26832689end ;
26842690
26852691procedure TListBase <T>.Sort(const comparer: IComparer<T>);
26862692begin
2687- IList<T>(this).Sort(comparer, 0 , IEnumerable <T>(this).Count);
2693+ IList<T>(this).Sort(comparer, 0 , IList <T>(this).Count);
26882694end ;
26892695
26902696procedure TListBase <T>.Sort(const comparer: TComparison<T>);
26912697begin
2692- IList<T>(this).Sort(IComparer<T>(PPointer(@comparer)^), 0 , IEnumerable <T>(this).Count);
2698+ IList<T>(this).Sort(IComparer<T>(PPointer(@comparer)^), 0 , IList <T>(this).Count);
26932699end ;
26942700
26952701procedure TListBase <T>.Sort(const comparer: TComparison<T>; index, count: Integer);
0 commit comments