From 0c4454f623630ba75c32b5b152150d868a17b017 Mon Sep 17 00:00:00 2001 From: falsycat Date: Sat, 27 Aug 2022 12:04:28 +0900 Subject: [PATCH] fix nf7::GenericHistory destruction to delete commands orderedly --- common/aggregate_command.hh | 71 ++++++++++++++++++------------------- common/generic_history.hh | 8 +++-- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/common/aggregate_command.hh b/common/aggregate_command.hh index fcd5192..9c739c3 100644 --- a/common/aggregate_command.hh +++ b/common/aggregate_command.hh @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -13,45 +14,48 @@ class AggregateCommand : public nf7::History::Command { public: using CommandList = std::vector>; - AggregateCommand(CommandList&& commands) noexcept : - commands_(std::move(commands)) { + AggregateCommand(CommandList&& commands, bool applied = false) noexcept : + commands_(std::move(commands)), applied_(applied) { } ~AggregateCommand() noexcept { - for (auto itr = commands_.rbegin(); itr < commands_.rend(); ++itr) { - *itr = nullptr; + if (applied_) { + for (auto itr = commands_.begin(); itr < commands_.end(); ++itr) { + *itr = nullptr; + } + } else { + for (auto itr = commands_.rbegin(); itr < commands_.rend(); ++itr) { + *itr = nullptr; + } } } void Apply() override { - auto itr = commands_.begin(); - try { - try { - while (itr < commands_.end()) { - (*itr)->Apply(); - ++itr; - } - } catch (History::CorruptException&) { - throw History::CorruptException("failed to apply AggregateCommand"); - } - } catch (History::CorruptException&) { - try { - while (itr > commands_.begin()) { - --itr; - (*itr)->Revert(); - } - } catch (History::CorruptException&) { - throw History::CorruptException( - "AggregateCommand gave up recovering from failure of apply"); - } - throw; - } + Exec(commands_.begin(), commands_.end(), + [](auto& a) { a->Apply(); }, + [](auto& a) { a->Revert(); }); + applied_ = true; } void Revert() override { - auto itr = commands_.rbegin(); + Exec(commands_.rbegin(), commands_.rend(), + [](auto& a) { a->Revert(); }, + [](auto& a) { a->Apply(); }); + applied_ = false; + } + + std::span> commands() const noexcept { return commands_; } + + private: + CommandList commands_; + + bool applied_; + + + static void Exec(auto begin, auto end, const auto& apply, const auto& revert) { + auto itr = begin; try { try { - while (itr < commands_.rend()) { - (*itr)->Revert(); + while (itr < end) { + apply(*itr); ++itr; } } catch (History::CorruptException&) { @@ -59,9 +63,9 @@ class AggregateCommand : public nf7::History::Command { } } catch (History::CorruptException&) { try { - while (itr > commands_.rbegin()) { + while (itr > begin) { --itr; - (*itr)->Apply(); + revert(*itr); } } catch (History::CorruptException&) { throw History::CorruptException( @@ -70,11 +74,6 @@ class AggregateCommand : public nf7::History::Command { throw; } } - - std::span> commands() const noexcept { return commands_; } - - private: - CommandList commands_; }; } // namespace nf7 diff --git a/common/generic_history.hh b/common/generic_history.hh index c8f2bba..ca06e35 100644 --- a/common/generic_history.hh +++ b/common/generic_history.hh @@ -28,8 +28,12 @@ class GenericHistory : public nf7::History { return *cmds_.back(); } void Clear() noexcept { - for (auto itr = cmds_.rbegin(); itr < cmds_.rend(); ++itr) { - *itr = nullptr; + for (size_t i = 0; i < cursor_; ++i) { + cmds_[i] = nullptr; + } + for (size_t i = cmds_.size(); i > cursor_;) { + --i; + cmds_[i] = nullptr; } cmds_.clear(); }