Я пытаюсь реализовать функцию отмены / повторения в очень простом текстовом редакторе, как проект. У меня есть класс, CommandProcessor
, которая берет какие кнопки нажал пользователь, и, если она совпадает, выполняет общую команду, которая вызывает функцию execute () типа объекта, который использует эту конкретную команду, т.е.
struct UserInteraction
{
UserInteractionType type; // this is just a enum type
Command* command;
};
case 'U':
command = new MoveLeft;
return makeCommandInteraction(command);
Вот команда MoveLeft, которую она вызывает:
void MoveLeft::execute(Editor& editor)
{
// if we try to move past the amount of input, throw exception
if(editor.cursorColumn() == 1) {
throw EditorException("Already at beginning!");
} else { // otherwise, move the cursor left
editor.moveCursorLeft();
}
}
И в этом есть команда Editor, которая вызывается.
void Editor::moveCursorLeft()
{
column--;
}
Если пользователь нажимает Ctrl + Z или Ctrl + A, мы возвращаем команду отменить / повторить: return makeUndoInteraction();
или же return makeRedoInteraction();
Я использую два стека, один для отмены и один для повторения. undoStack
сохраняет последнюю команду и при вызове в процессоре вызывает функцию отмены (которая в данный момент просто перемещает курсор вправо) из MoveLeft
, толкает вершину отмены стека в redoStack, а затем выталкивает вершину отмены стека. redoStack
содержит последнюю команду отмены, и, следовательно, я храню ее в interaction
который является типом, который содержит команды. С этим я вызываю execute () из MoveLeft
и затем верните взаимодействие обратно на undoStack
Вот обе функции:
else if (interaction.type == UserInteractionType::undo)
{
try
{
interaction.command->undo(editor);
redoStack.push(undoStack.top());
undoStack.pop();
view.clearErrorMessage();
} catch (EditorException& e)
{
view.showErrorMessage(e.getReason());
}
view.refresh();
delete interaction.command; // delete command since we stored it in the stack
}
else if (interaction.type == UserInteractionType::redo)
{
try
{
interaction = redoStack.top();
interaction.command->execute(editor);
undoStack.push(interaction);
view.clearErrorMessage();
}
catch (EditorException& e)
{
view.showErrorMessage(e.getReason());
}
view.refresh();
}
Прямо сейчас я получаю «Ошибка сегментации (ядро сброшено)» в этой строке в отменить:
interaction.command-> отменить (редактор);
И если я просто проверяю повтор, я получаю ошибку сегментации в этой строке:
взаимодействие = redoStack.top ();
Оба являются первой строкой после оператора try. Что может быть причиной?
Задача ещё не решена.