Есть какие то типовые варианты создания функции отмена?

Модератор: Модераторы

Есть какие то типовые варианты создания функции отмена?

Сообщение Sharfik » 29.04.2015 12:53:36

Функция Отмена последних действий иногда очень полезная, но понятия не имею какими методами ее можно организовать в программах.
Если вся программа построена на классах наследованных от TObject например, то в каждом случае надо самому все реализовывать или есть какие то средства для "сливания" предыдущих значений памяти в хранилище отдельное?
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 759
Зарегистрирован: 20.07.2013 01:04:30

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение MiniQ » 29.04.2015 13:00:39

Реализовывать нужно самому.
Например хранить отдельно "старые" объекты и новые.
MiniQ
новенький
 
Сообщения: 81
Зарегистрирован: 28.01.2013 16:31:55

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение Sharfik » 29.04.2015 13:10:33

MiniQ писал(а):Например хранить отдельно "старые" объекты и новые.

Я что то зациклился на мысли о хранении значения переменных, полностью отдельно объект и правда проще слить. Спасибо.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 759
Зарегистрирован: 20.07.2013 01:04:30

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение zub » 29.04.2015 13:50:38

Я стараюсь хранить минимально возможный набор данных для отката - сохранять целый объект накладно, особенно при возможности массированых изменений. Вообще тема сложная и индивидуальная - единого решения нет.
Совет - undo\redo нужно вводить какможно раньше (ну или хотябы продумать как оно будет), внедрять это хозяйство в уже рабочий код - та еще каторга
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение stanilar » 29.04.2015 16:20:43

Есть такое слово, как сериализация, оно поддерживается наследниками TPersistent.
Если логика работы представлена в виде дерева наследников TPersistent, которые пишут лог своих изменений, то возможно построение функции записи макроса работы программы, и макроса текущего состояния.

Сам подумываю над таким компонентом.
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение Mirage » 30.04.2015 01:23:22

Есть паттерн, сильно облегчающий реализацию undo/redo, а также дающий доп. плюшки:
Каждый тип операции модификации данных (коих по идее немног - изменение свойств чего-то, модификация данных и т.п.) оборачивается в класс с одним методом - Perform() допустим.
Первый его вызов совершает модификацию данных, второй - отменяет. Третий опять совершает и т.д.
Как это делается - сериализацией или как-то по-другому уже другой вопрос. Зависит.
И да, желательно сразу так делать, хотя, если программа написана вменяемо, то выделить классы операций должно быть несложно и уже существующем коде.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение zub » 30.04.2015 11:54:15

>>оборачивается в класс с одним методом - Perform() допустим.
не все операции одинаково выглядят в ундо\редо, такчто метода лучше 2
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение MiniQ » 30.04.2015 12:00:03

Mirage писал(а):Первый его вызов совершает модификацию данных, второй - отменяет. Третий опять совершает и т.д.

Что-то мудрено. А если мне нужно взглянуть, как было 10 операций назад? Т.е. откатить назад 10 операций и потом вернуть все в текущее состояние.
Вот этот патерн "первый вызов, второй вызов" как будет работать?
MiniQ
новенький
 
Сообщения: 81
Зарегистрирован: 28.01.2013 16:31:55

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение Лекс Айрин » 30.04.2015 12:42:59

MiniQ писал(а):Что-то мудрено. А если мне нужно взглянуть, как было 10 операций назад?


Думаю, проще сделать ссылку на следующее/предыдущее изменение. (то есть, использовать список операций)
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение ViTality » 30.04.2015 14:26:04

помница когда писал свой текстовый супер редактор с БЖиШ везде советовали TCollection
ViTality
постоялец
 
Сообщения: 308
Зарегистрирован: 05.10.2007 15:12:02

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение Mirage » 01.05.2015 02:16:27

zub писал(а):не все операции одинаково выглядят в ундо\редо, такчто метода лучше 2


Я тоже некоторое время так думал. Но потом понял, почему все же лучше один - применить, либо отменить два и более раз подряд тогда не получится и данные не потеряются.

MiniQ писал(а):А если мне нужно взглянуть, как было 10 операций назад? Т.е. откатить назад 10 операций и потом вернуть все в текущее состояние.Вот этот патерн "первый вызов, второй вызов" как будет работать?


Собственно, для этого и делается. При применении операции вызываем Perform() и кладем её в стек. При отмене - из стека достаем, кладем в другой стек и снова вызываем Perform(). При повторении (redo) достаем из второго стека, применяем, кладем в первый.
Можно и 10 шагов откатить и накатить обратно.
Еще оба стека красиво в один массив ложатся, с индексом текущей операции. Массив просто обрезается по текущему индексу при добавлении новой операции.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение zub » 01.05.2015 10:16:46

А какие проблемы могут быть с двойным вазовом? при работе не с "командой", а со стеком это сделать не получится, даже если постараться

>>Еще оба стека красиво в один массив ложатся, с индексом текущей операции. Массив просто обрезается по текущему индексу при добавлении новой операции.
у меня в конечном итоге так и получилось
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение Mirage » 02.05.2015 01:22:19

zub писал(а): а со стеком это сделать не получится, даже если постараться


Почему это не получится? Достал экземпляр операции из стека и вызывай её метод сколько хочешь раз.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение zub » 02.05.2015 01:53:23

Если так рассуждать то можно хоть что сделать)) Множественный вызов Perform тоже ничего хорошего не сулит.
Имхо ниче доставать ненадо, надо просто делать UndoStack.Undo или UndoStack.Redo. Возня с "операцией" должна быть только на этапе ее создания и подготовки, после помещения в стек нечего к ней лезти.

Как ни крути а Perform будет универсальным (с одинаковой реализацией ундо\редо) только для простых случаев изменения данных. Например добавление\удаление элемента массива уже не такая универсальная операция.
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Есть какие то типовые варианты создания функции отмена?

Сообщение Mirage » 04.05.2015 03:32:18

zub писал(а):Множественный вызов Perform тоже ничего хорошего не сулит.


Это как раз штатная ситуация. Потерь данных точно нет. В отличии от повторного вызова Undo.

zub писал(а):Имхо ниче доставать ненадо, надо просто делать UndoStack.Undo или UndoStack.Redo. Возня с "операцией" должна быть только на этапе ее создания и подготовки, после помещения в стек нечего к ней лезти.


Можно, конечно, коллекцию (стек) нагрузить знаниями о том, что там хранятся операции и что их нельзя отдавать, и что надо контролировать чтобы они правильно вызывались. Но это как раз не "просто делать". Тут прям напрячься надо. :lol:

zub писал(а):Как ни крути а Perform будет универсальным (с одинаковой реализацией ундо\редо) только для простых случаев изменения данных. Например добавление\удаление элемента массива уже не такая универсальная операция.


То, что он универсальный это не принципиальный момент. Может и не быть универсальным. Может хранить флажок, что делаем в следующий раз: добавляем или удаляем.
Принципиально то, что все максимально просто, вся информация в самой операции и как её не мучай, потери данных не будет.
А коллекция останется коллекцией. Её можно даже будет в любой момент заменить на другую с аналогичным интерфейсом, как и должно быть с коллекциями.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

След.

Вернуться в Общие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru