Skip to content

Commit 764a55d

Browse files
committed
event optimizations
1 parent a23d896 commit 764a55d

File tree

9 files changed

+1172
-689
lines changed

9 files changed

+1172
-689
lines changed

Source/Base/Collections/Spring.Collections.Events.pas

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ interface
3737

3838
type
3939
TCollectionChangedEventImpl<T> = class(TEventBase, IEvent, ICollectionChangedEvent<T>)
40-
private
41-
procedure InvokeSafe(Sender: TObject; const Item: T;
42-
Action: TCollectionChangedAction);
4340
public
4441
procedure AfterConstruction; override;
4542
{$IFNDEF AUTOREFCOUNT}
@@ -52,6 +49,9 @@ TCollectionChangedEventImpl<T> = class(TEventBase, IEvent, ICollectionChangedE
5249

5350
implementation
5451

52+
uses
53+
Spring.HazardEra;
54+
5555

5656
{$REGION 'TCollectionChangedEventImpl<T>'}
5757

@@ -75,41 +75,35 @@ procedure TCollectionChangedEventImpl<T>.Free;
7575
procedure TCollectionChangedEventImpl<T>.Add(
7676
handler: TCollectionChangedEvent<T>);
7777
begin
78-
inherited Add(TMethodPointer(handler));
78+
inherited Add(TMethod(handler));
7979
end;
8080

8181
procedure TCollectionChangedEventImpl<T>.Invoke(Sender: TObject;
8282
const Item: T; Action: TCollectionChangedAction);
8383
var
84+
handlers: PMethodArray;
8485
i: Integer;
8586
begin
8687
// If you get exception at this location on NextGen and the handler is nil
8788
// it is highly possible that the owner of the collection already released
8889
// its weak references. To fix this, free the collection prior to freeing
8990
// the object owning it (even if you're using interfaces).
9091
if CanInvoke then
91-
if ThreadSafe then
92-
InvokeSafe(Sender, Item, Action)
93-
else
94-
for i := 0 to Count - 1 do
95-
TCollectionChangedEvent<T>(fHandlers[i])(Sender, Item, Action);
96-
end;
97-
98-
procedure TCollectionChangedEventImpl<T>.InvokeSafe(Sender: TObject;
99-
const Item: T; Action: TCollectionChangedAction);
100-
var
101-
handlers: TArray<TMethodPointer>;
102-
i: Integer;
103-
begin
104-
handlers := Self.Handlers;
105-
for i := 0 to Count - 1 do
106-
TCollectionChangedEvent<T>(handlers[i])(Sender, Item, Action);
92+
begin
93+
handlers := GetHandlers;
94+
try
95+
for i := 0 to DynArrayHigh(handlers) do
96+
TCollectionChangedEvent<T>(handlers[i])(Sender, Item, Action);
97+
finally
98+
ReleaseGuard;
99+
end;
100+
end;
107101
end;
108102

109103
procedure TCollectionChangedEventImpl<T>.Remove(
110104
handler: TCollectionChangedEvent<T>);
111105
begin
112-
inherited Remove(TMethodPointer(handler));
106+
inherited Remove(TMethod(handler));
113107
end;
114108

115109
{$ENDREGION}

0 commit comments

Comments
 (0)