unit uutlObservable; {$mode objfpc}{$H+} interface uses Classes, SysUtils, uutlGenerics, uutlInterfaces, uutlEvent, uutlComparer; type //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TutlObservableEventType = ( oetAdd, oetRemove, oetReplace, oetClear ); TutlObservableEventArgs = class(TutlEventArgs) private fEventType: TutlObservableEventType; public property EventType: TutlObservableEventType read fEventType; constructor Create(const aEventType: TutlObservableEventType); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic TutlObservableItemEventArgs = class(TutlObservableEventArgs) private fItem: T; public property Item: T read fItem; constructor Create(const aEventType: TutlObservableEventType; constref aItem: T); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic TutlObservableReplaceEventArgs = class(TutlObservableEventArgs) private fOldItem: T; fNewItem: T; public property OldItem: T read fOldItem; property NewItem: T read fNewItem; constructor Create(const aEventType: TutlObservableEventType; constref aOldItem: T; constref aNewItem: T); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic TutlObservableCustomList = class( specialize TutlCustomList , IutlObservable) public type TItemEventArgs = class(specialize TutlObservableItemEventArgs) private fIndex: Integer; public property Index: Integer read fIndex; constructor Create(const aEventType: TutlObservableEventType; const aIndex: Integer; constref aItem: T); end; TReplaceEventArgs = class(specialize TutlObservableReplaceEventArgs) private fIndex: Integer; public property Index: Integer read fIndex; constructor Create(const aEventType: TutlObservableEventType; const aIndex: Integer; constref aOldItem: T; constref aNewItem: T); end; private fEventListener: TutlEventListenerSet; protected procedure InsertIntern(const aIndex: Integer; constref aValue: T); override; procedure DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean); override; procedure DoAddItem (const aIndex: Integer; constref aItem: T); virtual; procedure DoRemoveItem(const aIndex: Integer; constref aItem: T); virtual; procedure DoChangeItem(const aIndex: Integer; constref aOldItem: T; constref aNewItem: T); virtual; procedure DoClear (); virtual; public { IutlObservable } procedure RegisterEventListener (aListener: IutlEventListener); procedure UnregisterEventListener(aListener: IutlEventListener); protected procedure SetItem(const aIndex: Integer; aValue: T); override; public procedure Clear; override; constructor Create( aEqualityComparer: IEqualityComparer; aOwnsObjects: Boolean = true); destructor Destroy; override; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic TutlObservableList = class(specialize TutlObservableCustomList) public type TEqualityComparer = specialize TutlEqualityComparer; public constructor Create(const aOwnsObjects: Boolean); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic TutlObservableCustomHashSet = class( specialize TutlCustomHashSet , IutlObservable) public type TItemEventArgs = class(specialize TutlObservableItemEventArgs) private fIndex: Integer; public property Index: Integer read fIndex; constructor Create(const aEventType: TutlObservableEventType; const aIndex: Integer; constref aItem: T); end; TReplaceEventArgs = class(specialize TutlObservableReplaceEventArgs) private fIndex: Integer; public property Index: Integer read fIndex; constructor Create(const aEventType: TutlObservableEventType; const aIndex: Integer; constref aOldItem: T; constref aNewItem: T); end; private fEventListener: TutlEventListenerSet; protected procedure InsertIntern(const aIndex: Integer; constref aValue: T); override; procedure DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean); override; procedure SetItem (const aIndex: Integer; aValue: T); override; procedure DoAddItem (const aIndex: Integer; constref aItem: T); virtual; procedure DoRemoveItem(const aIndex: Integer; constref aItem: T); virtual; procedure DoChangeItem(const aIndex: Integer; constref aOldItem: T; constref aNewItem: T); virtual; procedure DoClear (); virtual; public { IutlObservable } procedure RegisterEventListener (aListener: IutlEventListener); procedure UnregisterEventListener(aListener: IutlEventListener); public procedure Clear; override; constructor Create(const aComparer: IComparer; const aOwnsItems: Boolean); destructor Destroy; override; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic TutlObservableHashSet = class(specialize TutlObservableCustomHashSet) public constructor Create(const aOwnsItems: Boolean); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic TutlObservableCustomMap = class( specialize TutlCustomMap , IutlObservable) public type TObservableHashSet = class(THashSet) strict private fOwner: TutlObservableCustomMap; protected procedure InsertIntern(const aIndex: Integer; constref aValue: TKeyValuePair); override; procedure DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean); override; procedure SetItem(const aIndex: Integer; aValue: TKeyValuePair); override; public procedure Clear; override; constructor Create(const aOwner: TutlObservableCustomMap; const aComparer: IComparer); reintroduce; end; TItemEventArgs = class(specialize TutlObservableItemEventArgs) private fIndex: Integer; fKey: TKey; public property Index: Integer read fIndex; property Key: TKey read fKey; constructor Create(const aEventType: TutlObservableEventType; const aIndex: Integer; constref aKey: TKey; constref aItem: TValue); end; TReplaceEventArgs = class(specialize TutlObservableReplaceEventArgs) private fIndex: Integer; fKey: TKey; public property Index: Integer read fIndex; property Key: TKey read fKey; constructor Create(const aEventType: TutlObservableEventType; const aIndex: Integer; constref aKey: TKey; constref aOldItem: TValue; constref aNewItem: TValue); end; private fEventListener: TutlEventListenerSet; protected procedure DoAddItem (const aIndex: Integer; constref aKey: TKey; constref aItem: TValue); virtual; procedure DoRemoveItem(const aIndex: Integer; constref aKey: TKey; constref aItem: TValue); virtual; procedure DoChangeItem(const aIndex: Integer; constref aKey: TKey; constref aOldItem: TValue; constref aNewItem: TValue); virtual; procedure DoClear (); virtual; public { IutlObservable } procedure RegisterEventListener (aListener: IutlEventListener); procedure UnregisterEventListener(aListener: IutlEventListener); public constructor Create(const aHashSet: TObservableHashSet; const aOwnsKeys: Boolean; const aOwnsValues: Boolean); reintroduce; destructor Destroy; override; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic TutlObservableMap = class(specialize TutlObservableCustomMap) public type TComparer = specialize TutlComparer; strict private fHashSetImpl: TObservableHashSet; public constructor Create(const aOwnsKeys: Boolean; const aOwnsValues: Boolean); destructor Destroy; override; end; implementation //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableEventArgs/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableEventArgs.Create(const aEventType: TutlObservableEventType); begin inherited Create; fEventType := aEventType; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableItemEventArgs/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableItemEventArgs.Create(const aEventType: TutlObservableEventType; constref aItem: T); begin inherited Create(aEventType); fItem := aItem; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableChangeEventArgs///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableReplaceEventArgs.Create(const aEventType: TutlObservableEventType; constref aOldItem: T; constref aNewItem: T); begin inherited Create(aEventType); fOldItem := aOldItem; fNewItem := aNewItem; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableCustomList.TChangeEventArgs///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableCustomList.TReplaceEventArgs.Create( const aEventType: TutlObservableEventType; const aIndex: Integer; constref aOldItem: T; constref aNewItem: T); begin inherited Create(aEventType, aOldItem, aNewItem); fIndex := aIndex; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableCustomList.TItemEventArgs/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableCustomList.TItemEventArgs.Create( const aEventType: TutlObservableEventType; const aIndex: Integer; constref aItem: T); begin inherited Create(aEventType, aItem); fIndex := aIndex; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableCustomList////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomList.InsertIntern(const aIndex: Integer; constref aValue: T); begin inherited InsertIntern(aIndex, aValue); DoAddItem(aIndex, aValue); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomList.DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean); begin DoRemoveItem(aIndex, GetItem(aIndex)); inherited DeleteIntern(aIndex, aFreeItem); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomList.DoAddItem(const aIndex: Integer; constref aItem: T); var e: IutlEventArgs; begin if Assigned(fEventListener) and not fEventListener.IsEmpty then begin e := TItemEventArgs.Create(oetAdd, aIndex, aItem); fEventListener.DispatchEvent(self, e); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomList.DoRemoveItem(const aIndex: Integer; constref aItem: T); var e: IutlEventArgs; begin if Assigned(fEventListener) and not fEventListener.IsEmpty then begin e := TItemEventArgs.Create(oetRemove, aIndex, aItem); fEventListener.DispatchEvent(self, e); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomList.DoChangeItem(const aIndex: Integer; constref aOldItem: T; constref aNewItem: T); var e: IutlEventArgs; begin if Assigned(fEventListener) and not fEventListener.IsEmpty then begin e := TReplaceEventArgs.Create(oetReplace, aIndex, aOldItem, aNewItem); fEventListener.DispatchEvent(self, e); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomList.DoClear; var e: IutlEventArgs; begin if Assigned(fEventListener) and not fEventListener.IsEmpty then begin e := TutlObservableEventArgs.Create(oetClear); fEventListener.DispatchEvent(self, e); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomList.RegisterEventListener(aListener: IutlEventListener); begin fEventListener.Add(aListener); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomList.UnregisterEventListener(aListener: IutlEventListener); begin fEventListener.Remove(aListener); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomList.SetItem(const aIndex: Integer; aValue: T); begin DoChangeItem(aIndex, GetItem(aIndex), aValue); inherited SetItem(aIndex, aValue); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomList.Clear; begin DoClear; inherited Clear; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableCustomList.Create(aEqualityComparer: IEqualityComparer; aOwnsObjects: Boolean); begin fEventListener := TutlEventListenerSet.Create; inherited Create(aEqualityComparer, aOwnsObjects); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TutlObservableCustomList.Destroy; begin inherited Destroy; FreeAndNil(fEventListener); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableList//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableList.Create(const aOwnsObjects: Boolean); begin inherited Create(TEqualityComparer.Create, aOwnsObjects); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableCustomHashSet.TItemEventArgs//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableCustomHashSet.TItemEventArgs.Create( const aEventType: TutlObservableEventType; const aIndex: Integer; constref aItem: T); begin inherited Create(aEventType, aItem); fIndex := aIndex; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableCustomHashSet.TReplaceEventArgs///////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableCustomHashSet.TReplaceEventArgs.Create( const aEventType: TutlObservableEventType; const aIndex: Integer; constref aOldItem: T; constref aNewItem: T); begin inherited Create(aEventType, aOldItem, aNewItem); fIndex := aIndex; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableCustomHashSet/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomHashSet.InsertIntern(const aIndex: Integer; constref aValue: T); begin inherited InsertIntern(aIndex, aValue); DoAddItem(aIndex, aValue); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomHashSet.DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean); begin DoRemoveItem(aIndex, GetItem(aIndex)); inherited DeleteIntern(aIndex, aFreeItem); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomHashSet.SetItem(const aIndex: Integer; aValue: T); begin DoChangeItem(aIndex, GetItem(aIndex), aValue); inherited SetItem(aIndex, aValue); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomHashSet.DoAddItem(const aIndex: Integer; constref aItem: T); var e: IutlEventArgs; begin if Assigned(fEventListener) and not fEventListener.IsEmpty then begin e := TItemEventArgs.Create(oetAdd, aIndex, aItem); fEventListener.DispatchEvent(self, e); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomHashSet.DoRemoveItem(const aIndex: Integer; constref aItem: T); var e: IutlEventArgs; begin if Assigned(fEventListener) and not fEventListener.IsEmpty then begin e := TItemEventArgs.Create(oetRemove, aIndex, aItem); fEventListener.DispatchEvent(self, e); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomHashSet.DoChangeItem(const aIndex: Integer; constref aOldItem: T; constref aNewItem: T); var e: IutlEventArgs; begin if Assigned(fEventListener) and not fEventListener.IsEmpty then begin e := TReplaceEventArgs.Create(oetReplace, aIndex, aOldItem, aNewItem); fEventListener.DispatchEvent(self, e); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomHashSet.DoClear; var e: IutlEventArgs; begin if Assigned(fEventListener) and not fEventListener.IsEmpty then begin e := TutlObservableEventArgs.Create(oetClear); fEventListener.DispatchEvent(self, e); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomHashSet.RegisterEventListener(aListener: IutlEventListener); begin fEventListener.Add(aListener); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomHashSet.UnregisterEventListener(aListener: IutlEventListener); begin fEventListener.Remove(aListener); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomHashSet.Clear; begin DoClear; inherited Clear; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableCustomHashSet.Create(const aComparer: IComparer; const aOwnsItems: Boolean); begin fEventListener := TutlEventListenerSet.Create; inherited Create(aComparer, aOwnsItems); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TutlObservableCustomHashSet.Destroy; begin inherited Destroy; FreeAndNil(fEventListener); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableHashSet///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableHashSet.Create(const aOwnsItems: Boolean); begin inherited Create(specialize TutlComparer.Create, aOwnsItems); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableCustomMap.TObservableHashSet//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomMap.TObservableHashSet.InsertIntern(const aIndex: Integer; constref aValue: TKeyValuePair); begin inherited InsertIntern(aIndex, aValue); fOwner.DoAddItem(aIndex, aValue.Key, aValue.Value); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomMap.TObservableHashSet.DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean); var kvp: TKeyValuePair; begin kvp := GetItem(aIndex); fOwner.DoRemoveItem(aIndex, kvp.Key, kvp.Value); inherited DeleteIntern(aIndex, aFreeItem); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomMap.TObservableHashSet.SetItem(const aIndex: Integer; aValue: TKeyValuePair); begin fOwner.DoChangeItem(aIndex, aValue.Key, GetItem(aIndex).Value, aValue.Value); inherited SetItem(aIndex, aValue); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomMap.TObservableHashSet.Clear; begin fOwner.DoClear; while (Count > 0) do Delete(Count - 1); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableCustomMap.TObservableHashSet.Create( const aOwner: TutlObservableCustomMap; const aComparer: IComparer); begin inherited Create(aOwner, aComparer); fOwner := aOwner; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableCustomMap.TItemEventArgs//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableCustomMap.TItemEventArgs.Create( const aEventType: TutlObservableEventType; const aIndex: Integer; constref aKey: TKey; constref aItem: TValue); begin inherited Create(aEventType, aItem); fIndex := aIndex; fKey := aKey; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableCustomMap.TReplaceEventArgs///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableCustomMap.TReplaceEventArgs.Create( const aEventType: TutlObservableEventType; const aIndex: Integer; constref aKey: TKey; constref aOldItem: TValue; constref aNewItem: TValue); begin inherited Create(aEventType, aOldItem, aNewItem); fIndex := aIndex; fKey := aKey; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableCustomMap/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomMap.DoAddItem( const aIndex: Integer; constref aKey: TKey; constref aItem: TValue); var e: IutlEventArgs; begin if Assigned(fEventListener) and not fEventListener.IsEmpty then begin e := TItemEventArgs.Create(oetAdd, aIndex, aKey, aItem); fEventListener.DispatchEvent(self, e); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomMap.DoRemoveItem( const aIndex: Integer; constref aKey: TKey; constref aItem: TValue); var e: IutlEventArgs; begin if Assigned(fEventListener) and not fEventListener.IsEmpty then begin e := TItemEventArgs.Create(oetRemove, aIndex, aKey, aItem); fEventListener.DispatchEvent(self, e); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomMap.DoChangeItem( const aIndex: Integer; constref aKey: TKey; constref aOldItem: TValue; constref aNewItem: TValue); var e: IutlEventArgs; begin if Assigned(fEventListener) and not fEventListener.IsEmpty then begin e := TReplaceEventArgs.Create(oetReplace, aIndex, aKey, aOldItem, aNewItem); fEventListener.DispatchEvent(self, e); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomMap.DoClear; var e: IutlEventArgs; begin if Assigned(fEventListener) and not fEventListener.IsEmpty then begin e := TutlObservableEventArgs.Create(oetClear); fEventListener.DispatchEvent(self, e); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomMap.RegisterEventListener(aListener: IutlEventListener); begin fEventListener.Add(aListener); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TutlObservableCustomMap.UnregisterEventListener(aListener: IutlEventListener); begin fEventListener.Remove(aListener); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableCustomMap.Create( const aHashSet: TObservableHashSet; const aOwnsKeys: Boolean; const aOwnsValues: Boolean); begin fEventListener := TutlEventListenerSet.Create; inherited Create(aHashSet, aOwnsKeys, aOwnsValues); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TutlObservableCustomMap.Destroy; begin inherited Destroy; FreeAndNil(fEventListener); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlObservableMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlObservableMap.Create(const aOwnsKeys: Boolean; const aOwnsValues: Boolean); begin fHashSetImpl := TObservableHashSet.Create(self, TKeyValuePairComparer.Create(TComparer.Create)); inherited Create(fHashSetImpl, aOwnsKeys, aOwnsValues); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TutlObservableMap.Destroy; begin inherited Destroy; FreeAndNil(fHashSetImpl); end; end.