You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

708 lines
32 KiB

  1. unit uutlObservable;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils,
  6. uutlGenerics, uutlInterfaces, uutlEvent, uutlComparer;
  7. type
  8. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. TutlObservableEventType = (
  10. oetAdd,
  11. oetRemove,
  12. oetReplace,
  13. oetClear
  14. );
  15. TutlObservableEventArgs = class(TutlEventArgs)
  16. private
  17. fEventType: TutlObservableEventType;
  18. public
  19. property EventType: TutlObservableEventType read fEventType;
  20. constructor Create(const aEventType: TutlObservableEventType);
  21. end;
  22. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  23. generic TutlObservableItemEventArgs<T> = class(TutlObservableEventArgs)
  24. private
  25. fItem: T;
  26. public
  27. property Item: T read fItem;
  28. constructor Create(const aEventType: TutlObservableEventType; constref aItem: T);
  29. end;
  30. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  31. generic TutlObservableReplaceEventArgs<T> = class(TutlObservableEventArgs)
  32. private
  33. fOldItem: T;
  34. fNewItem: T;
  35. public
  36. property OldItem: T read fOldItem;
  37. property NewItem: T read fNewItem;
  38. constructor Create(const aEventType: TutlObservableEventType; constref aOldItem: T; constref aNewItem: T);
  39. end;
  40. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  41. generic TutlObservableCustomList<T> = class(
  42. specialize TutlCustomList<T>
  43. , IutlObservable)
  44. public type
  45. TItemEventArgs = class(specialize TutlObservableItemEventArgs<T>)
  46. private
  47. fIndex: Integer;
  48. public
  49. property Index: Integer read fIndex;
  50. constructor Create(const aEventType: TutlObservableEventType; const aIndex: Integer; constref aItem: T);
  51. end;
  52. TReplaceEventArgs = class(specialize TutlObservableReplaceEventArgs<T>)
  53. private
  54. fIndex: Integer;
  55. public
  56. property Index: Integer read fIndex;
  57. constructor Create(const aEventType: TutlObservableEventType; const aIndex: Integer; constref aOldItem: T; constref aNewItem: T);
  58. end;
  59. private
  60. fEventListener: TutlEventListenerSet;
  61. protected
  62. procedure InsertIntern(const aIndex: Integer; constref aValue: T); override;
  63. procedure DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean); override;
  64. procedure DoAddItem (const aIndex: Integer; constref aItem: T); virtual;
  65. procedure DoRemoveItem(const aIndex: Integer; constref aItem: T); virtual;
  66. procedure DoChangeItem(const aIndex: Integer; constref aOldItem: T; constref aNewItem: T); virtual;
  67. procedure DoClear (); virtual;
  68. public { IutlObservable }
  69. procedure RegisterEventListener (aListener: IutlEventListener);
  70. procedure UnregisterEventListener(aListener: IutlEventListener);
  71. protected
  72. procedure SetItem(const aIndex: Integer; aValue: T); override;
  73. public
  74. procedure Clear; override;
  75. constructor Create(
  76. aEqualityComparer: IEqualityComparer;
  77. aOwnsObjects: Boolean = true);
  78. destructor Destroy; override;
  79. end;
  80. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  81. generic TutlObservableList<T> = class(specialize TutlObservableCustomList<T>)
  82. public type
  83. TEqualityComparer = specialize TutlEqualityComparer<T>;
  84. public
  85. constructor Create(const aOwnsObjects: Boolean);
  86. end;
  87. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  88. generic TutlObservableCustomHashSet<T> = class(
  89. specialize TutlCustomHashSet<T>
  90. , IutlObservable)
  91. public type
  92. TItemEventArgs = class(specialize TutlObservableItemEventArgs<T>)
  93. private
  94. fIndex: Integer;
  95. public
  96. property Index: Integer read fIndex;
  97. constructor Create(const aEventType: TutlObservableEventType; const aIndex: Integer; constref aItem: T);
  98. end;
  99. TReplaceEventArgs = class(specialize TutlObservableReplaceEventArgs<T>)
  100. private
  101. fIndex: Integer;
  102. public
  103. property Index: Integer read fIndex;
  104. constructor Create(const aEventType: TutlObservableEventType; const aIndex: Integer; constref aOldItem: T; constref aNewItem: T);
  105. end;
  106. private
  107. fEventListener: TutlEventListenerSet;
  108. protected
  109. procedure InsertIntern(const aIndex: Integer; constref aValue: T); override;
  110. procedure DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean); override;
  111. procedure SetItem (const aIndex: Integer; aValue: T); override;
  112. procedure DoAddItem (const aIndex: Integer; constref aItem: T); virtual;
  113. procedure DoRemoveItem(const aIndex: Integer; constref aItem: T); virtual;
  114. procedure DoChangeItem(const aIndex: Integer; constref aOldItem: T; constref aNewItem: T); virtual;
  115. procedure DoClear (); virtual;
  116. public { IutlObservable }
  117. procedure RegisterEventListener (aListener: IutlEventListener);
  118. procedure UnregisterEventListener(aListener: IutlEventListener);
  119. public
  120. procedure Clear; override;
  121. constructor Create(const aComparer: IComparer; const aOwnsItems: Boolean);
  122. destructor Destroy; override;
  123. end;
  124. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  125. generic TutlObservableHashSet<T> = class(specialize TutlObservableCustomHashSet<T>)
  126. public
  127. constructor Create(const aOwnsItems: Boolean);
  128. end;
  129. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  130. generic TutlObservableCustomMap<TKey, TValue> = class(
  131. specialize TutlCustomMap<TKey, TValue>
  132. , IutlObservable)
  133. public type
  134. TObservableHashSet = class(THashSet)
  135. strict private
  136. fOwner: TutlObservableCustomMap;
  137. protected
  138. procedure InsertIntern(const aIndex: Integer; constref aValue: TKeyValuePair); override;
  139. procedure DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean); override;
  140. procedure SetItem(const aIndex: Integer; aValue: TKeyValuePair); override;
  141. public
  142. procedure Clear; override;
  143. constructor Create(const aOwner: TutlObservableCustomMap; const aComparer: IComparer); reintroduce;
  144. end;
  145. TItemEventArgs = class(specialize TutlObservableItemEventArgs<TValue>)
  146. private
  147. fIndex: Integer;
  148. fKey: TKey;
  149. public
  150. property Index: Integer read fIndex;
  151. property Key: TKey read fKey;
  152. constructor Create(const aEventType: TutlObservableEventType; const aIndex: Integer; constref aKey: TKey; constref aItem: TValue);
  153. end;
  154. TReplaceEventArgs = class(specialize TutlObservableReplaceEventArgs<TValue>)
  155. private
  156. fIndex: Integer;
  157. fKey: TKey;
  158. public
  159. property Index: Integer read fIndex;
  160. property Key: TKey read fKey;
  161. constructor Create(const aEventType: TutlObservableEventType; const aIndex: Integer; constref aKey: TKey; constref aOldItem: TValue; constref aNewItem: TValue);
  162. end;
  163. private
  164. fEventListener: TutlEventListenerSet;
  165. protected
  166. procedure DoAddItem (const aIndex: Integer; constref aKey: TKey; constref aItem: TValue); virtual;
  167. procedure DoRemoveItem(const aIndex: Integer; constref aKey: TKey; constref aItem: TValue); virtual;
  168. procedure DoChangeItem(const aIndex: Integer; constref aKey: TKey; constref aOldItem: TValue; constref aNewItem: TValue); virtual;
  169. procedure DoClear (); virtual;
  170. public { IutlObservable }
  171. procedure RegisterEventListener (aListener: IutlEventListener);
  172. procedure UnregisterEventListener(aListener: IutlEventListener);
  173. public
  174. constructor Create(const aHashSet: TObservableHashSet; const aOwnsKeys: Boolean; const aOwnsValues: Boolean); reintroduce;
  175. destructor Destroy; override;
  176. end;
  177. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  178. generic TutlObservableMap<TKey, TValue> = class(specialize TutlObservableCustomMap<TKey, TValue>)
  179. public type
  180. TComparer = specialize TutlComparer<TKey>;
  181. strict private
  182. fHashSetImpl: TObservableHashSet;
  183. public
  184. constructor Create(const aOwnsKeys: Boolean; const aOwnsValues: Boolean);
  185. destructor Destroy; override;
  186. end;
  187. implementation
  188. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  189. //TutlObservableEventArgs///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  190. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  191. constructor TutlObservableEventArgs.Create(const aEventType: TutlObservableEventType);
  192. begin
  193. inherited Create;
  194. fEventType := aEventType;
  195. end;
  196. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  197. //TutlObservableItemEventArgs///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  198. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  199. constructor TutlObservableItemEventArgs.Create(const aEventType: TutlObservableEventType; constref aItem: T);
  200. begin
  201. inherited Create(aEventType);
  202. fItem := aItem;
  203. end;
  204. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  205. //TutlObservableChangeEventArgs/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  206. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  207. constructor TutlObservableReplaceEventArgs.Create(const aEventType: TutlObservableEventType; constref aOldItem: T; constref aNewItem: T);
  208. begin
  209. inherited Create(aEventType);
  210. fOldItem := aOldItem;
  211. fNewItem := aNewItem;
  212. end;
  213. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  214. //TutlObservableCustomList.TChangeEventArgs/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  215. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  216. constructor TutlObservableCustomList.TReplaceEventArgs.Create(
  217. const aEventType: TutlObservableEventType;
  218. const aIndex: Integer;
  219. constref aOldItem: T;
  220. constref aNewItem: T);
  221. begin
  222. inherited Create(aEventType, aOldItem, aNewItem);
  223. fIndex := aIndex;
  224. end;
  225. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  226. //TutlObservableCustomList.TItemEventArgs///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  227. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  228. constructor TutlObservableCustomList.TItemEventArgs.Create(
  229. const aEventType: TutlObservableEventType;
  230. const aIndex: Integer;
  231. constref aItem: T);
  232. begin
  233. inherited Create(aEventType, aItem);
  234. fIndex := aIndex;
  235. end;
  236. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  237. //TutlObservableCustomList//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  238. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  239. procedure TutlObservableCustomList.InsertIntern(const aIndex: Integer; constref aValue: T);
  240. begin
  241. inherited InsertIntern(aIndex, aValue);
  242. DoAddItem(aIndex, aValue);
  243. end;
  244. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  245. procedure TutlObservableCustomList.DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean);
  246. begin
  247. DoRemoveItem(aIndex, GetItem(aIndex));
  248. inherited DeleteIntern(aIndex, aFreeItem);
  249. end;
  250. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  251. procedure TutlObservableCustomList.DoAddItem(const aIndex: Integer; constref aItem: T);
  252. var
  253. e: IutlEventArgs;
  254. begin
  255. if Assigned(fEventListener) and not fEventListener.IsEmpty then begin
  256. e := TItemEventArgs.Create(oetAdd, aIndex, aItem);
  257. fEventListener.DispatchEvent(self, e);
  258. end;
  259. end;
  260. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  261. procedure TutlObservableCustomList.DoRemoveItem(const aIndex: Integer; constref aItem: T);
  262. var
  263. e: IutlEventArgs;
  264. begin
  265. if Assigned(fEventListener) and not fEventListener.IsEmpty then begin
  266. e := TItemEventArgs.Create(oetRemove, aIndex, aItem);
  267. fEventListener.DispatchEvent(self, e);
  268. end;
  269. end;
  270. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  271. procedure TutlObservableCustomList.DoChangeItem(const aIndex: Integer; constref aOldItem: T; constref aNewItem: T);
  272. var
  273. e: IutlEventArgs;
  274. begin
  275. if Assigned(fEventListener) and not fEventListener.IsEmpty then begin
  276. e := TReplaceEventArgs.Create(oetReplace, aIndex, aOldItem, aNewItem);
  277. fEventListener.DispatchEvent(self, e);
  278. end;
  279. end;
  280. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  281. procedure TutlObservableCustomList.DoClear;
  282. var
  283. e: IutlEventArgs;
  284. begin
  285. if Assigned(fEventListener) and not fEventListener.IsEmpty then begin
  286. e := TutlObservableEventArgs.Create(oetClear);
  287. fEventListener.DispatchEvent(self, e);
  288. end;
  289. end;
  290. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  291. procedure TutlObservableCustomList.RegisterEventListener(aListener: IutlEventListener);
  292. begin
  293. fEventListener.Add(aListener);
  294. end;
  295. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  296. procedure TutlObservableCustomList.UnregisterEventListener(aListener: IutlEventListener);
  297. begin
  298. fEventListener.Remove(aListener);
  299. end;
  300. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  301. procedure TutlObservableCustomList.SetItem(const aIndex: Integer; aValue: T);
  302. begin
  303. DoChangeItem(aIndex, GetItem(aIndex), aValue);
  304. inherited SetItem(aIndex, aValue);
  305. end;
  306. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  307. procedure TutlObservableCustomList.Clear;
  308. begin
  309. DoClear;
  310. inherited Clear;
  311. end;
  312. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  313. constructor TutlObservableCustomList.Create(aEqualityComparer: IEqualityComparer; aOwnsObjects: Boolean);
  314. begin
  315. fEventListener := TutlEventListenerSet.Create;
  316. inherited Create(aEqualityComparer, aOwnsObjects);
  317. end;
  318. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  319. destructor TutlObservableCustomList.Destroy;
  320. begin
  321. inherited Destroy;
  322. FreeAndNil(fEventListener);
  323. end;
  324. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  325. //TutlObservableList////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  326. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  327. constructor TutlObservableList.Create(const aOwnsObjects: Boolean);
  328. begin
  329. inherited Create(TEqualityComparer.Create, aOwnsObjects);
  330. end;
  331. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  332. //TutlObservableCustomHashSet.TItemEventArgs////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  333. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  334. constructor TutlObservableCustomHashSet.TItemEventArgs.Create(
  335. const aEventType: TutlObservableEventType;
  336. const aIndex: Integer;
  337. constref aItem: T);
  338. begin
  339. inherited Create(aEventType, aItem);
  340. fIndex := aIndex;
  341. end;
  342. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  343. //TutlObservableCustomHashSet.TReplaceEventArgs/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  344. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  345. constructor TutlObservableCustomHashSet.TReplaceEventArgs.Create(
  346. const aEventType: TutlObservableEventType;
  347. const aIndex: Integer;
  348. constref aOldItem: T;
  349. constref aNewItem: T);
  350. begin
  351. inherited Create(aEventType, aOldItem, aNewItem);
  352. fIndex := aIndex;
  353. end;
  354. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  355. //TutlObservableCustomHashSet///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  356. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  357. procedure TutlObservableCustomHashSet.InsertIntern(const aIndex: Integer; constref aValue: T);
  358. begin
  359. inherited InsertIntern(aIndex, aValue);
  360. DoAddItem(aIndex, aValue);
  361. end;
  362. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  363. procedure TutlObservableCustomHashSet.DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean);
  364. begin
  365. DoRemoveItem(aIndex, GetItem(aIndex));
  366. inherited DeleteIntern(aIndex, aFreeItem);
  367. end;
  368. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  369. procedure TutlObservableCustomHashSet.SetItem(const aIndex: Integer; aValue: T);
  370. begin
  371. DoChangeItem(aIndex, GetItem(aIndex), aValue);
  372. inherited SetItem(aIndex, aValue);
  373. end;
  374. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  375. procedure TutlObservableCustomHashSet.DoAddItem(const aIndex: Integer; constref aItem: T);
  376. var
  377. e: IutlEventArgs;
  378. begin
  379. if Assigned(fEventListener) and not fEventListener.IsEmpty then begin
  380. e := TItemEventArgs.Create(oetAdd, aIndex, aItem);
  381. fEventListener.DispatchEvent(self, e);
  382. end;
  383. end;
  384. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  385. procedure TutlObservableCustomHashSet.DoRemoveItem(const aIndex: Integer; constref aItem: T);
  386. var
  387. e: IutlEventArgs;
  388. begin
  389. if Assigned(fEventListener) and not fEventListener.IsEmpty then begin
  390. e := TItemEventArgs.Create(oetRemove, aIndex, aItem);
  391. fEventListener.DispatchEvent(self, e);
  392. end;
  393. end;
  394. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  395. procedure TutlObservableCustomHashSet.DoChangeItem(const aIndex: Integer; constref aOldItem: T; constref aNewItem: T);
  396. var
  397. e: IutlEventArgs;
  398. begin
  399. if Assigned(fEventListener) and not fEventListener.IsEmpty then begin
  400. e := TReplaceEventArgs.Create(oetReplace, aIndex, aOldItem, aNewItem);
  401. fEventListener.DispatchEvent(self, e);
  402. end;
  403. end;
  404. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  405. procedure TutlObservableCustomHashSet.DoClear;
  406. var
  407. e: IutlEventArgs;
  408. begin
  409. if Assigned(fEventListener) and not fEventListener.IsEmpty then begin
  410. e := TutlObservableEventArgs.Create(oetClear);
  411. fEventListener.DispatchEvent(self, e);
  412. end;
  413. end;
  414. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  415. procedure TutlObservableCustomHashSet.RegisterEventListener(aListener: IutlEventListener);
  416. begin
  417. fEventListener.Add(aListener);
  418. end;
  419. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  420. procedure TutlObservableCustomHashSet.UnregisterEventListener(aListener: IutlEventListener);
  421. begin
  422. fEventListener.Remove(aListener);
  423. end;
  424. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  425. procedure TutlObservableCustomHashSet.Clear;
  426. begin
  427. DoClear;
  428. inherited Clear;
  429. end;
  430. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  431. constructor TutlObservableCustomHashSet.Create(const aComparer: IComparer; const aOwnsItems: Boolean);
  432. begin
  433. fEventListener := TutlEventListenerSet.Create;
  434. inherited Create(aComparer, aOwnsItems);
  435. end;
  436. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  437. destructor TutlObservableCustomHashSet.Destroy;
  438. begin
  439. inherited Destroy;
  440. FreeAndNil(fEventListener);
  441. end;
  442. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  443. //TutlObservableHashSet/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  444. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  445. constructor TutlObservableHashSet.Create(const aOwnsItems: Boolean);
  446. begin
  447. inherited Create(specialize TutlComparer<T>.Create, aOwnsItems);
  448. end;
  449. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  450. //TutlObservableCustomMap.TObservableHashSet////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  451. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  452. procedure TutlObservableCustomMap.TObservableHashSet.InsertIntern(const aIndex: Integer; constref aValue: TKeyValuePair);
  453. begin
  454. inherited InsertIntern(aIndex, aValue);
  455. fOwner.DoAddItem(aIndex, aValue.Key, aValue.Value);
  456. end;
  457. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  458. procedure TutlObservableCustomMap.TObservableHashSet.DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean);
  459. var
  460. kvp: TKeyValuePair;
  461. begin
  462. kvp := GetItem(aIndex);
  463. fOwner.DoRemoveItem(aIndex, kvp.Key, kvp.Value);
  464. inherited DeleteIntern(aIndex, aFreeItem);
  465. end;
  466. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  467. procedure TutlObservableCustomMap.TObservableHashSet.SetItem(const aIndex: Integer; aValue: TKeyValuePair);
  468. begin
  469. fOwner.DoChangeItem(aIndex, aValue.Key, GetItem(aIndex).Value, aValue.Value);
  470. inherited SetItem(aIndex, aValue);
  471. end;
  472. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  473. procedure TutlObservableCustomMap.TObservableHashSet.Clear;
  474. begin
  475. fOwner.DoClear;
  476. while (Count > 0) do
  477. Delete(Count - 1);
  478. end;
  479. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  480. constructor TutlObservableCustomMap.TObservableHashSet.Create(
  481. const aOwner: TutlObservableCustomMap;
  482. const aComparer: IComparer);
  483. begin
  484. inherited Create(aOwner, aComparer);
  485. fOwner := aOwner;
  486. end;
  487. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  488. //TutlObservableCustomMap.TItemEventArgs////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  489. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  490. constructor TutlObservableCustomMap.TItemEventArgs.Create(
  491. const aEventType: TutlObservableEventType;
  492. const aIndex: Integer;
  493. constref aKey: TKey;
  494. constref aItem: TValue);
  495. begin
  496. inherited Create(aEventType, aItem);
  497. fIndex := aIndex;
  498. fKey := aKey;
  499. end;
  500. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  501. //TutlObservableCustomMap.TReplaceEventArgs/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  502. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  503. constructor TutlObservableCustomMap.TReplaceEventArgs.Create(
  504. const aEventType: TutlObservableEventType;
  505. const aIndex: Integer;
  506. constref aKey: TKey;
  507. constref aOldItem: TValue;
  508. constref aNewItem: TValue);
  509. begin
  510. inherited Create(aEventType, aOldItem, aNewItem);
  511. fIndex := aIndex;
  512. fKey := aKey;
  513. end;
  514. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  515. //TutlObservableCustomMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  516. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  517. procedure TutlObservableCustomMap.DoAddItem(
  518. const aIndex: Integer;
  519. constref aKey: TKey;
  520. constref aItem: TValue);
  521. var
  522. e: IutlEventArgs;
  523. begin
  524. if Assigned(fEventListener) and not fEventListener.IsEmpty then begin
  525. e := TItemEventArgs.Create(oetAdd, aIndex, aKey, aItem);
  526. fEventListener.DispatchEvent(self, e);
  527. end;
  528. end;
  529. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  530. procedure TutlObservableCustomMap.DoRemoveItem(
  531. const aIndex: Integer;
  532. constref aKey: TKey;
  533. constref aItem: TValue);
  534. var
  535. e: IutlEventArgs;
  536. begin
  537. if Assigned(fEventListener) and not fEventListener.IsEmpty then begin
  538. e := TItemEventArgs.Create(oetRemove, aIndex, aKey, aItem);
  539. fEventListener.DispatchEvent(self, e);
  540. end;
  541. end;
  542. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  543. procedure TutlObservableCustomMap.DoChangeItem(
  544. const aIndex: Integer;
  545. constref aKey: TKey;
  546. constref aOldItem: TValue;
  547. constref aNewItem: TValue);
  548. var
  549. e: IutlEventArgs;
  550. begin
  551. if Assigned(fEventListener) and not fEventListener.IsEmpty then begin
  552. e := TReplaceEventArgs.Create(oetReplace, aIndex, aKey, aOldItem, aNewItem);
  553. fEventListener.DispatchEvent(self, e);
  554. end;
  555. end;
  556. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  557. procedure TutlObservableCustomMap.DoClear;
  558. var
  559. e: IutlEventArgs;
  560. begin
  561. if Assigned(fEventListener) and not fEventListener.IsEmpty then begin
  562. e := TutlObservableEventArgs.Create(oetClear);
  563. fEventListener.DispatchEvent(self, e);
  564. end;
  565. end;
  566. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  567. procedure TutlObservableCustomMap.RegisterEventListener(aListener: IutlEventListener);
  568. begin
  569. fEventListener.Add(aListener);
  570. end;
  571. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  572. procedure TutlObservableCustomMap.UnregisterEventListener(aListener: IutlEventListener);
  573. begin
  574. fEventListener.Remove(aListener);
  575. end;
  576. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  577. constructor TutlObservableCustomMap.Create(
  578. const aHashSet: TObservableHashSet;
  579. const aOwnsKeys: Boolean;
  580. const aOwnsValues: Boolean);
  581. begin
  582. fEventListener := TutlEventListenerSet.Create;
  583. inherited Create(aHashSet, aOwnsKeys, aOwnsValues);
  584. end;
  585. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  586. destructor TutlObservableCustomMap.Destroy;
  587. begin
  588. inherited Destroy;
  589. FreeAndNil(fEventListener);
  590. end;
  591. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  592. //TutlObservableMap/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  593. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  594. constructor TutlObservableMap.Create(const aOwnsKeys: Boolean; const aOwnsValues: Boolean);
  595. begin
  596. fHashSetImpl := TObservableHashSet.Create(self, TKeyValuePairComparer.Create(TComparer.Create));
  597. inherited Create(fHashSetImpl, aOwnsKeys, aOwnsValues);
  598. end;
  599. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  600. destructor TutlObservableMap.Destroy;
  601. begin
  602. inherited Destroy;
  603. FreeAndNil(fHashSetImpl);
  604. end;
  605. end.