No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 

329 líneas
15 KiB

  1. unit uutlObservableGenerics;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils,
  6. uutlGenerics;
  7. type
  8. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. generic TutlEventList<T> = class(specialize TutlHashSetBase<T>)
  10. private type
  11. TComparer = class(TInterfacedObject, IComparer)
  12. public
  13. function Compare(const i1, i2: T): Integer;
  14. end;
  15. public
  16. function RegisterEvent(const aEvent: T): Boolean;
  17. function UnregisterEvent(const aEvent: T): Boolean;
  18. constructor Create;
  19. end;
  20. TutlNotifyEventList = specialize TutlEventList<TNotifyEvent>;
  21. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  22. generic TutlObservableCustomList<T> = class(specialize TutlCustomList<T>)
  23. public type
  24. TEventList = specialize TutlEventList<TItemEvent>;
  25. private
  26. fOnAddItem: TEventList;
  27. fOnRemoveItem: TEventList;
  28. protected
  29. procedure InsertIntern(const aIndex: Integer; const aItem: T); override;
  30. procedure DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean = true); override;
  31. public
  32. property OnAddItem: TEventList read fOnAddItem;
  33. property OnRemoveItem: TEventList read fOnRemoveItem;
  34. constructor Create(aEqualityComparer: IEqualityComparer; const aOwnsObjects: Boolean = true);
  35. destructor Destroy; override;
  36. end;
  37. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  38. generic TutlObservableList<T> = class(specialize TutlObservableCustomList<T>)
  39. public type
  40. TEqualityComparer = specialize TutlEqualityComparer<T>;
  41. public
  42. constructor Create(const aOwnsObjects: Boolean = true);
  43. end;
  44. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  45. generic TutlObservableCustomHashSet<T> = class(specialize TutlCustomHashSet<T>)
  46. public type
  47. TEventList = specialize TutlEventList<THashItemEvent>;
  48. private
  49. fOnAddItem: TEventList;
  50. fOnRemoveItem: TEventList;
  51. protected
  52. procedure InsertIntern(const aIndex: Integer; const aItem: T); override;
  53. procedure DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean = true); override;
  54. public
  55. property OnAddItem: TEventList read fOnAddItem;
  56. property OnRemoveItem: TEventList read fOnRemoveItem;
  57. constructor Create(aComparer: IComparer; const aOwnsObjects: Boolean = true);
  58. destructor Destroy; override;
  59. end;
  60. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  61. generic TutlObservableHashSet<T> = class(specialize TutlObservableCustomHashSet<T>)
  62. public type
  63. TComparer = specialize TutlComparer<T>;
  64. public
  65. constructor Create(const aOwnsObjects: Boolean = true);
  66. end;
  67. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  68. generic TutlObservableCustomMap<TKey, TValue> = class(specialize TutlMapBase<TKey, TValue>)
  69. public type
  70. TEventList = specialize TutlEventList<TKeyValuePairEvent>;
  71. TObservableHashSet = class(THashSet)
  72. private
  73. fOwner: TObject;
  74. fOnAddItem: TEventList;
  75. fOnRemoveItem: TEventList;
  76. protected
  77. procedure InsertIntern(const aIndex: Integer; const aItem: TKeyValuePair); override;
  78. procedure DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean = true); override;
  79. public
  80. property OnAddItem: TEventList read fOnAddItem write fOnAddItem;
  81. property OnRemoveItem: TEventList read fOnRemoveItem write fOnRemoveItem;
  82. constructor Create(const aOwner: TObject; const aComparer: IComparer; const aOwnsObjects: Boolean = true);
  83. end;
  84. private
  85. fHashSetImpl: TObservableHashSet;
  86. fOnAddItem: TEventList;
  87. fOnRemoveItem: TEventList;
  88. public
  89. property OnAddItem: TEventList read fOnAddItem;
  90. property OnRemoveItem: TEventList read fOnRemoveItem;
  91. constructor Create(const aComparer: IComparer; const aOwnsObjects: Boolean = true);
  92. destructor Destroy; override;
  93. end;
  94. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  95. generic TutlObservableMap<TKey, TValue> = class(specialize TutlObservableCustomMap<TKey, TValue>)
  96. public type
  97. TComparer = specialize TutlComparer<TKey>;
  98. public
  99. constructor Create(const aOwnsObjects: Boolean = true);
  100. end;
  101. implementation
  102. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  103. //TutlEventList/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  104. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  105. function TutlEventList.TComparer.Compare(const i1, i2: T): Integer;
  106. var
  107. m1, m2: TMethod;
  108. begin
  109. m1 := TMethod(i1);
  110. m2 := TMethod(i2);
  111. if (m1.Data < m2.Data) then
  112. result := -1
  113. else if (m1.Data > m2.Data) then
  114. result := 1
  115. else if (m1.Code < m2.Code) then
  116. result := -1
  117. else if (m1.Code > m2.Code) then
  118. result := 1
  119. else
  120. result := 0;
  121. end;
  122. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  123. function TutlEventList.RegisterEvent(const aEvent: T): Boolean;
  124. var
  125. i: Integer;
  126. begin
  127. result := (SearchItem(0, List.Count-1, aEvent, i) < 0);
  128. if result then
  129. InsertIntern(i, aEvent);
  130. end;
  131. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  132. function TutlEventList.UnregisterEvent(const aEvent: T): Boolean;
  133. var
  134. i, tmp: Integer;
  135. begin
  136. i := SearchItem(0, List.Count-1, aEvent, tmp);
  137. result := (i >= 0);
  138. if result then
  139. DeleteIntern(i);
  140. end;
  141. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  142. constructor TutlEventList.Create;
  143. begin
  144. inherited Create(TComparer.Create, true);
  145. end;
  146. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  147. //TutlObservableCustomList//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  148. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  149. procedure TutlObservableCustomList.InsertIntern(const aIndex: Integer; const aItem: T);
  150. var
  151. e: TItemEvent;
  152. begin
  153. inherited InsertIntern(aIndex, aItem);
  154. if Assigned(fOnAddItem) then
  155. for e in fOnAddItem do
  156. e(self, aIndex, aItem);
  157. end;
  158. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  159. procedure TutlObservableCustomList.DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean);
  160. var
  161. e: TItemEvent;
  162. begin
  163. if Assigned(fOnRemoveItem) then
  164. for e in fOnRemoveItem do
  165. e(self, aIndex, GetItem(aIndex));
  166. inherited DeleteIntern(aIndex, aFreeItem);
  167. end;
  168. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  169. constructor TutlObservableCustomList.Create(aEqualityComparer: IEqualityComparer; const aOwnsObjects: Boolean);
  170. begin
  171. inherited Create(aEqualityComparer, aOwnsObjects);
  172. fOnAddItem := TEventList.Create;
  173. fOnRemoveItem := TEventList.Create;
  174. end;
  175. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  176. destructor TutlObservableCustomList.Destroy;
  177. begin
  178. FreeAndNil(fOnRemoveItem);
  179. FreeAndNil(fOnAddItem);
  180. inherited Destroy;
  181. end;
  182. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  183. //TutlObservableList////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  184. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  185. constructor TutlObservableList.Create(const aOwnsObjects: Boolean);
  186. begin
  187. inherited Create(TEqualityComparer.Create, aOwnsObjects);
  188. end;
  189. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  190. //TutlObservableCustomHashSet///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  191. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  192. procedure TutlObservableCustomHashSet.InsertIntern(const aIndex: Integer; const aItem: T);
  193. var
  194. e: THashItemEvent;
  195. begin
  196. inherited InsertIntern(aIndex, aItem);
  197. if Assigned(fOnAddItem) then
  198. for e in fOnAddItem do
  199. e(self, aItem);
  200. end;
  201. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  202. procedure TutlObservableCustomHashSet.DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean);
  203. var
  204. e: THashItemEvent;
  205. begin
  206. if Assigned(fOnRemoveItem) then
  207. for e in fOnRemoveItem do
  208. e(self, GetItem(aIndex));
  209. inherited DeleteIntern(aIndex, aFreeItem);
  210. end;
  211. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  212. constructor TutlObservableCustomHashSet.Create(aComparer: IComparer; const aOwnsObjects: Boolean);
  213. begin
  214. inherited Create(aComparer, aOwnsObjects);
  215. fOnAddItem := TEventList.Create;
  216. fOnRemoveItem := TEventList.Create;
  217. end;
  218. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  219. destructor TutlObservableCustomHashSet.Destroy;
  220. begin
  221. inherited Destroy; // calls clear -> Free EventLists after
  222. FreeAndNil(fOnAddItem);
  223. FreeAndNil(fOnRemoveItem);
  224. end;
  225. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  226. //TutlObservableHashSet/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  227. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  228. constructor TutlObservableHashSet.Create(const aOwnsObjects: Boolean);
  229. begin
  230. inherited Create(TComparer.Create, aOwnsObjects);
  231. end;
  232. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  233. //TutlObservableCustomMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  234. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  235. procedure TutlObservableCustomMap.TObservableHashSet.InsertIntern(const aIndex: Integer; const aItem: TKeyValuePair);
  236. var
  237. e: TKeyValuePairEvent;
  238. begin
  239. inherited InsertIntern(aIndex, aItem);
  240. if Assigned(fOnAddItem) then begin
  241. for e in fOnAddItem do
  242. e(fOwner, aItem.Key, aItem.Value);
  243. end;
  244. end;
  245. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  246. procedure TutlObservableCustomMap.TObservableHashSet.DeleteIntern(const aIndex: Integer; const aFreeItem: Boolean);
  247. var
  248. e: TKeyValuePairEvent;
  249. tmp: TKeyValuePair;
  250. begin
  251. if Assigned(fOnRemoveItem) then begin
  252. tmp := GetItem(aIndex);
  253. for e in fOnRemoveItem do
  254. e(fOwner, tmp.Key, tmp.Value);
  255. end;
  256. inherited DeleteIntern(aIndex, aFreeItem);
  257. end;
  258. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  259. constructor TutlObservableCustomMap.TObservableHashSet.Create(const aOwner: TObject; const aComparer: IComparer; const aOwnsObjects: Boolean);
  260. begin
  261. inherited Create(aComparer, aOwnsObjects);
  262. fOwner := aOwner;
  263. end;
  264. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  265. constructor TutlObservableCustomMap.Create(const aComparer: IComparer; const aOwnsObjects: Boolean);
  266. begin
  267. fOnAddItem := TEventList.Create;
  268. fOnRemoveItem := TEventList.Create;
  269. fHashSetImpl := TObservableHashSet.Create(self, TKeyValuePairComparer.Create(aComparer), aOwnsObjects);
  270. fHashSetImpl.OnAddItem := fOnAddItem;
  271. fHashSetImpl.OnRemoveItem := fOnRemoveItem;
  272. inherited Create(fHashSetImpl);
  273. end;
  274. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  275. destructor TutlObservableCustomMap.Destroy;
  276. begin
  277. inherited Destroy;
  278. FreeAndNil(fHashSetImpl);
  279. FreeAndNil(fOnAddItem);
  280. FreeAndNil(fOnRemoveItem);
  281. end;
  282. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  283. //TutlObservableMap/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  284. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  285. constructor TutlObservableMap.Create(const aOwnsObjects: Boolean);
  286. begin
  287. inherited Create(TComparer.Create, aOwnsObjects);
  288. end;
  289. end.