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.

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