Создайте отмену и повтор, сделав «снимок состояния» - PullRequest
2 голосов
/ 10 июля 2019

Я хотел бы создать класс Undo & Redo для редактора изображений без создания всего шаблона команды.

На самом деле в моем коде я использую шаблон MVC, и поэтому я получил набор атрибутов, которые обновляются каждый раз, когда я запускаю действие:

    class model{
    ...code...

public:
        bool is_Flipped_V = false;
        bool is_Flipped_H = false;
        bool is_Rotated = false;
        bool is_Blurred = false;
        bool is_Sharpened = false;
        bool is_Grayscale = false;
        bool is_Sepia = false;
        bool is_Loaded = false;
        bool is_Saved = false;


        int exposure_Val;
        double contrast_Val;
        int red_Val;
        int green_Val;
        int blue_Val;

        int hue_Val;
        int saturation_Val;
        int luminance_Val;

        int angle_Val;
    }

Моя идея состоит в том, чтобы создать список, чтобы каждый раз, когда наблюдатель получал уведомление, он записывал фактическое состояние всех верхних атрибутов. Поэтому, когда я хочу что-то «отменить», я могу просто обновить свое изображение, передав предыдущие состояния атрибутов.

Кто-нибудь когда-нибудь делал что-то подобное? Как я могу сохранить состояния атрибутов в списке? Есть ли другой, но лучший способ реализовать это?

Ответы [ 2 ]

2 голосов
/ 10 июля 2019

Предпочтительным способом реализации Undo / Redo является следование Memento Pattern . Он хранит каждую отменяемую операцию и позволяет перейти к любой случайной точке в истории. Это простой и понятный шаблон, который помогает реализовать эту функцию.

Шаблон Memento использует три класса актеров. Memento содержит фактическое состояние объекта, который будет восстановлен. Originator создает и сохраняет состояния в Memento объектах, а объект Caretaker отвечает за восстановление состояния объекта из коллекции Memento объектов.

1 голос
/ 10 июля 2019

В качестве отправной точки наивной реализацией может быть помещение всех ваших атрибутов в одну структуру State и наличие std::stack<State> undo и std::stack<State> redo в вашем классе Undo / Redo. Затем, когда вы выталкиваете стек undo, чтобы отменить State, вы нажимаете тот же State, который вы вставили в стек redo. Вы делаете то же самое в обратном порядке, когда вы повторяете State. Вы вставляете стек redo и помещаете вытолкнутый State обратно в стек undo.

Также не забудьте очистить стек redo при добавлении нового изменения в стек undo.

...