LCOV - code coverage report
Current view: top level - src/gui/commands - command_history.cpp (source / functions) Coverage Total Hit
Test: merged.info Lines: 97.9 % 47 46
Test Date: 2026-06-03 09:13:19 Functions: 100.0 % 8 8

            Line data    Source code
       1              : #include "gui/commands/command_history.h"
       2              : 
       3              : namespace Amplitron {
       4              : 
       5              : /** @brief Execute cmd, attempt coalescing, push to undo stack, clear redo. */
       6          225 : void CommandHistory::execute(std::unique_ptr<Command> cmd) {
       7          225 :     if (!cmd->execute()) return; // no-op — skip history recording
       8              : 
       9              :     // Try coalescing with the top of the undo stack
      10          210 :     if (!undo_stack_.empty() && undo_stack_.back()->merge_with(*cmd)) {
      11              :         // Merged into existing top — no new entry needed
      12            0 :     } else {
      13          210 :         undo_stack_.push_back(std::move(cmd));
      14          210 :         trim();
      15              :     }
      16              : 
      17              :     // New action invalidates the redo branch
      18          210 :     redo_stack_.clear();
      19           75 : }
      20              : 
      21              : /** @brief Push an already-applied command; attempt coalescing, clear redo. */
      22           54 : void CommandHistory::push_executed(std::unique_ptr<Command> cmd) {
      23           54 :     if (!undo_stack_.empty() && undo_stack_.back()->merge_with(*cmd)) {
      24              :         // Merged into existing top — no new entry needed
      25            3 :     } else {
      26           45 :         undo_stack_.push_back(std::move(cmd));
      27           45 :         trim();
      28              :     }
      29              : 
      30              :     // New action invalidates the redo branch
      31           54 :     redo_stack_.clear();
      32           54 : }
      33              : 
      34              : /** @brief Pop the top undo command, call its undo(), and move it to redo. */
      35           99 : bool CommandHistory::undo() {
      36           99 :     if (undo_stack_.empty()) return false;
      37              : 
      38           96 :     auto cmd = std::move(undo_stack_.back());
      39           96 :     undo_stack_.pop_back();
      40              : 
      41           96 :     cmd->undo();
      42           96 :     redo_stack_.push_back(std::move(cmd));
      43           96 :     return true;
      44           97 : }
      45              : 
      46              : /** @brief Pop the top redo command, call its execute(), and move it to undo. */
      47           51 : bool CommandHistory::redo() {
      48           51 :     if (redo_stack_.empty()) return false;
      49              : 
      50           48 :     auto cmd = std::move(redo_stack_.back());
      51           48 :     redo_stack_.pop_back();
      52              : 
      53           48 :     cmd->execute();
      54           48 :     undo_stack_.push_back(std::move(cmd));
      55           48 :     return true;
      56           49 : }
      57              : 
      58              : /** @brief Discard all undo and redo history. */
      59           27 : void CommandHistory::clear() {
      60           27 :     undo_stack_.clear();
      61           27 :     redo_stack_.clear();
      62           27 : }
      63              : 
      64              : /** @brief Return the description of the top undo command, or nullptr. */
      65            9 : const char* CommandHistory::undo_description() const {
      66            9 :     if (undo_stack_.empty()) return nullptr;
      67            6 :     return undo_stack_.back()->description();
      68            3 : }
      69              : 
      70              : /** @brief Return the description of the top redo command, or nullptr. */
      71            9 : const char* CommandHistory::redo_description() const {
      72            9 :     if (redo_stack_.empty()) return nullptr;
      73            6 :     return redo_stack_.back()->description();
      74            3 : }
      75              : 
      76              : /** @brief Remove oldest undo entries until stack size <= max_depth_. */
      77          261 : void CommandHistory::trim() {
      78          297 :     while (static_cast<int>(undo_stack_.size()) > max_depth_) {
      79           36 :         undo_stack_.erase(undo_stack_.begin());
      80              :     }
      81          261 : }
      82              : 
      83              : } // namespace Amplitron
        

Generated by: LCOV version 2.0-1