|
|
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
Не совсем вопрос по Delphi, скорее общий вопрос проектирования, но вот интересно мнение тех, кто уже либо делал или совершенно точно знает, как сделать это правильно :-) Само по себе Undo/Redo для абстрактоного набора редактируемых классов с современным-то RTTI реализовать не представляется уж очень большой проблемой. Вопрос возникает о том, как "помечать" объекты для отката их вставки/удаления? Вижу пока два способа и оба неправильные: Генерировать текстовый "путь" до объекта изменения. Примерно как Parent.GetPathToMe(Self). И по путю к нему можно легко будет найти изменённый объект. Что-нибудь вроде: "Child[4].Properties.Setting1". Минус такого подхода вижу в возне со строками: на каждый чих генерировать такую ерунду. Не то чтобы это должно что-то замедлить или съесть много памяти, но всё равно "программист" во мне говорит, что это неправильно. Генерировать целочисленные ID (или даже GUID) для объектов и хранить карту объектов (TDictionary). Вроде как проблему мгновенного нахождения обьекта решает, но возникает некоторое количество других вопросов: Нужно централизовано генерить ID, если ID это не GUID, нужно держать карту объектов обновлённой. Т.е. если что-то восстановил через Undo, то нужно регистрировать заново все восстановленные объекты в карте. Тоже самое относится к вставке из буфера обмена - нужно генерировать новые ID и регистрировать вставленные объекты. Какие есть ещё варианты? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 17:23 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
Dimonka, журналирование (это вы почти описали в п. 1) персистентные структуры данных (это то, что вы пытаетесь сформулировать в п.2) первый способ проще ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 17:37 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan)Dimonka, журналирование (это вы почти описали в п. 1) персистентные структуры данных (это то, что вы пытаетесь сформулировать в п.2) первый способ проще А можно ответ как-то развернуть или хотя бы ссылкой-другой броситься? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 17:43 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
Dimonka> А можно ответ как-то развернуть или хотя бы ссылкой-другой броситься? Я думаю, нужно четче и подробнее изложить задачу. Потому что если вопрос просто в том, как хранить ссылки/идентификаторы объектов и навигация по ним - это вопрос очень простой и известный. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 18:04 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
Отличные статьи от российского onlyoffice: https://habrahabr.ru/company/teamlab/blog/169841/ https://habrahabr.ru/company/teamlab/blog/327454/ Статьи от DevExpress про реализацию undo/redo: https://habrahabr.ru/company/devexpress/blog/104163/ https://habrahabr.ru/company/devexpress/blog/104168/ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 18:18 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
Гаджимурадов РустамЯ думаю, нужно четче и подробнее изложить задачу. Потому что если вопрос просто в том, как хранить ссылки/идентификаторы объектов и навигация по ним - это вопрос очень простой и известный. Ну вот захотелось узнать это простое - ткните носом, а то пока по ссылкам ни тема идентификаторов и тема навигации совсем не раскрыта. Про навигацию я тоже совсем забыл.. Пользователь-то должен видеть, что откатывается назад. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 19:24 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
Dimonka, журналирование надеюсь понятно, выше ссылки дали как оно может реализовываться с персистентными структурами если на пальцах: в любой момент можно сделать полноценный клон объекта. Например , есть словарь (используется Path coping) Код: pascal 1. для реализации UNDO\REDO достаточно сохранить клон объекта и при необходимости заменить текущий на сохранённый вариант ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 19:37 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan)журналирование надеюсь понятно, выше ссылки дали как оно может реализовываться По ссылкам выше разбираются разные вопросы, но я в упор не увидел, где разбирается вопрос "локализации" объекта в структуре. Тупой пример: Есть TObjectList_1 у него десятый элемент TObjectList_2, а у того есть четвёртый элемент TObjectList_3. Как сохранить ссылку на откат, если я удалю TObjectList_3, а потом ещё TObjectList_2, а заодно и TObjectList_1? kealon(Ruslan)для реализации UNDO\REDO достаточно сохранить клон объекта и при необходимости заменить текущий на сохранённый вариант Это неинтересный вариант. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 19:52 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
Dimonka, >>Как сохранить ссылку на откат, если я удалю TObjectList_3, а потом ещё TObjectList_2, а заодно и TObjectList_1? написать для каждого такого действия ручками код UNDO\REDO >>Это неинтересный вариант. почему? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 20:03 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan)Dimonka, >>Как сохранить ссылку на откат, если я удалю TObjectList_3, а потом ещё TObjectList_2, а заодно и TObjectList_1? написать для каждого такого действия ручками код UNDO\REDO Покажи пример этого кода, хотя бы псевдокодом. Опиши хоть в общих словах какие действия этих специализированные UNDO/REDO "ручками" должны выполнять? kealon(Ruslan)>>Это неинтересный вариант. почему? Потому что дублировать сотни раз одни и те же не изменяющиеся состояния бессмысленно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 20:14 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
Dimonka, а зачем их дублировать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 20:17 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan)Dimonka, а зачем их дублировать? Объясни тогда логику это метода, может быть я что-то не понял. На примере с тремя TObjectList. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 20:22 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
Dimonka, Можешь посмотреть реализацию многоуровневого Undo/Redo: https://github.com/Makhaon/TCoolMemo Код из старой версии нашего ПО. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 20:29 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
DimonkaОбъясни тогда логику это метода, может быть я что-то не понял. На примере с тремя TObjectList. TObjectList не относится к персистентным структурам в том и сложность, нужно что бы всё текущее состояние документа было сохранено в 1-й персистентной структуре, тогда ты её можешь спокойно клонировать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 20:33 |
|
||
|
Логика Undo/Redo
|
|||
|---|---|---|---|
|
#18+
Выдавил из себя пока нечто такое: TUndoObjectPathRec(ObjType: integer; ObjIndex: integer;) будет достаточно, чтобы идентифицировать положение объекта относительно родительского объекта. Конечное нахождение объекта делать из цепочки TUndoObjectPathRec - TUndoObjectPath. Красивее и универсальнее способа пока не придумал.. Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269. 270. 271. 272. 273. 274. 275. 276. 277. 278. 279. 280. 281. 282. 283. 284. 285. 286. 287. 288. 289. 290. 291. 292. 293. 294. 295. 296. 297. 298. 299. 300. 301. 302. 303. 304. 305. 306. 307. 308. 309. 310. 311. 312. 313. 314. 315. 316. 317. 318. 319. 320. 321. 322. 323. 324. 325. 326. 327. 328. 329. 330. 331. 332. 333. 334. 335. 336. 337. 338. 339. 340. 341. 342. 343. 344. 345. 346. 347. 348. 349. 350. 351. 352. 353. 354. 355. 356. 357. 358. 359. 360. 361. 362. 363. 364. 365. 366. 367. Из минусов - куча интерфайсных методов, ещё нужно учитывать, что TInterfacedObject может неожиданно самоосвободиться, если ему не отключить подсчёт RefCount. Покритикуйте, если не лень. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.02.2018, 14:02 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=39606356&tid=2041200]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
165ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
66ms |
get tp. blocked users: |
1ms |
| others: | 290ms |
| total: | 562ms |

| 0 / 0 |
