Add document undo history tests
This commit is contained in:
@@ -231,4 +231,91 @@ pp::foundation::Status CanvasDocument::set_active_frame(std::size_t index) noexc
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Result<DocumentHistory> DocumentHistory::create(
|
||||
CanvasDocument initial_document,
|
||||
std::size_t max_entries)
|
||||
{
|
||||
if (max_entries < min_document_history_entries) {
|
||||
return pp::foundation::Result<DocumentHistory>::failure(
|
||||
pp::foundation::Status::invalid_argument("document history must keep at least two entries"));
|
||||
}
|
||||
|
||||
if (max_entries > max_document_history_entries) {
|
||||
return pp::foundation::Result<DocumentHistory>::failure(
|
||||
pp::foundation::Status::out_of_range("document history entry limit exceeds the configured limit"));
|
||||
}
|
||||
|
||||
DocumentHistory history;
|
||||
history.max_entries_ = max_entries;
|
||||
history.entries_.reserve(max_entries);
|
||||
history.entries_.push_back(initial_document);
|
||||
return pp::foundation::Result<DocumentHistory>::success(history);
|
||||
}
|
||||
|
||||
const CanvasDocument& DocumentHistory::current() const noexcept
|
||||
{
|
||||
return entries_[current_index_];
|
||||
}
|
||||
|
||||
std::size_t DocumentHistory::size() const noexcept
|
||||
{
|
||||
return entries_.size();
|
||||
}
|
||||
|
||||
std::size_t DocumentHistory::current_index() const noexcept
|
||||
{
|
||||
return current_index_;
|
||||
}
|
||||
|
||||
bool DocumentHistory::can_undo() const noexcept
|
||||
{
|
||||
return current_index_ > 0;
|
||||
}
|
||||
|
||||
bool DocumentHistory::can_redo() const noexcept
|
||||
{
|
||||
return current_index_ + 1U < entries_.size();
|
||||
}
|
||||
|
||||
pp::foundation::Status DocumentHistory::apply(CanvasDocument next_document)
|
||||
{
|
||||
if (entries_.empty()) {
|
||||
return pp::foundation::Status::invalid_argument("document history is not initialized");
|
||||
}
|
||||
|
||||
if (can_redo()) {
|
||||
entries_.erase(entries_.begin() + static_cast<std::ptrdiff_t>(current_index_ + 1U), entries_.end());
|
||||
}
|
||||
|
||||
entries_.push_back(next_document);
|
||||
if (entries_.size() > max_entries_) {
|
||||
entries_.erase(entries_.begin());
|
||||
} else {
|
||||
++current_index_;
|
||||
}
|
||||
|
||||
current_index_ = entries_.size() - 1U;
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status DocumentHistory::undo() noexcept
|
||||
{
|
||||
if (!can_undo()) {
|
||||
return pp::foundation::Status::out_of_range("document history has no undo entry");
|
||||
}
|
||||
|
||||
--current_index_;
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status DocumentHistory::redo() noexcept
|
||||
{
|
||||
if (!can_redo()) {
|
||||
return pp::foundation::Status::out_of_range("document history has no redo entry");
|
||||
}
|
||||
|
||||
++current_index_;
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ constexpr std::uint32_t max_canvas_dimension = 131072;
|
||||
constexpr std::uint32_t max_layer_count = 1024;
|
||||
constexpr std::uint32_t max_frame_count = 100000;
|
||||
constexpr std::uint32_t min_frame_duration_ms = 1;
|
||||
constexpr std::size_t min_document_history_entries = 2;
|
||||
constexpr std::size_t max_document_history_entries = 10000;
|
||||
|
||||
struct DocumentConfig {
|
||||
std::uint32_t width = 0;
|
||||
@@ -64,4 +66,26 @@ private:
|
||||
std::vector<AnimationFrame> frames_;
|
||||
};
|
||||
|
||||
class DocumentHistory {
|
||||
public:
|
||||
[[nodiscard]] static pp::foundation::Result<DocumentHistory> create(
|
||||
CanvasDocument initial_document,
|
||||
std::size_t max_entries = 256);
|
||||
|
||||
[[nodiscard]] const CanvasDocument& current() const noexcept;
|
||||
[[nodiscard]] std::size_t size() const noexcept;
|
||||
[[nodiscard]] std::size_t current_index() const noexcept;
|
||||
[[nodiscard]] bool can_undo() const noexcept;
|
||||
[[nodiscard]] bool can_redo() const noexcept;
|
||||
|
||||
[[nodiscard]] pp::foundation::Status apply(CanvasDocument next_document);
|
||||
[[nodiscard]] pp::foundation::Status undo() noexcept;
|
||||
[[nodiscard]] pp::foundation::Status redo() noexcept;
|
||||
|
||||
private:
|
||||
std::size_t max_entries_ = 0;
|
||||
std::size_t current_index_ = 0;
|
||||
std::vector<CanvasDocument> entries_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user