LCOV - code coverage report
Current view: top level - src/gui/commands - command_history.h (source / functions) Coverage Total Hit
Test: merged.info Lines: 100.0 % 7 7
Test Date: 2026-06-07 15:51:50 Functions: 100.0 % 5 5

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include <memory>
       4              : #include <vector>
       5              : 
       6              : #include "gui/commands/command.h"
       7              : 
       8              : namespace Amplitron {
       9              : 
      10              : /**
      11              :  * @brief Manages undo and redo stacks for Command objects.
      12              :  *
      13              :  * Provides execute(), undo(), redo(), and push_executed() operations.
      14              :  * Supports coalescing of rapid parameter changes and enforces a
      15              :  * configurable maximum history depth (default DEFAULT_MAX_DEPTH).
      16              :  */
      17           90 : class CommandHistory {
      18              :    public:
      19              :     /** @brief Default maximum number of undo entries. */
      20              :     static constexpr int DEFAULT_MAX_DEPTH = 100;
      21              : 
      22              :     /**
      23              :      * @brief Construct a CommandHistory.
      24              :      * @param max_depth Maximum undo stack size. Negative values are clamped to 0.
      25              :      */
      26          380 :     explicit CommandHistory(int max_depth = DEFAULT_MAX_DEPTH)
      27          380 :         : max_depth_(max_depth < 0 ? 0 : max_depth) {}
      28              : 
      29              :     /**
      30              :      * @brief Execute a command and push it onto the undo stack.
      31              :      *
      32              :      * Calls cmd->execute(), attempts coalescing with the stack top, and
      33              :      * clears the redo stack (new action invalidates the redo branch).
      34              :      *
      35              :      * @param cmd Owning pointer to the command to execute.
      36              :      */
      37              :     void execute(std::unique_ptr<Command> cmd);
      38              : 
      39              :     /**
      40              :      * @brief Record a command that was already applied by the caller.
      41              :      *
      42              :      * Useful for knob changes that are applied directly by the widget;
      43              :      * the command is pushed for undo without calling execute().
      44              :      *
      45              :      * @param cmd Owning pointer to the already-executed command.
      46              :      */
      47              :     void push_executed(std::unique_ptr<Command> cmd);
      48              : 
      49              :     /**
      50              :      * @brief Undo the most recent command.
      51              :      * @return true if an undo was performed, false if the stack was empty.
      52              :      */
      53              :     bool undo();
      54              : 
      55              :     /**
      56              :      * @brief Redo the most recently undone command.
      57              :      * @return true if a redo was performed, false if the stack was empty.
      58              :      */
      59              :     bool redo();
      60              : 
      61              :     /** @brief Clear both undo and redo stacks (e.g. when loading a preset). */
      62              :     void clear();
      63              : 
      64              :     /** @brief Return true if the undo stack is non-empty. */
      65            3 :     bool can_undo() const { return !undo_stack_.empty(); }
      66              : 
      67              :     /** @brief Return true if the redo stack is non-empty. */
      68            9 :     bool can_redo() const { return !redo_stack_.empty(); }
      69              : 
      70              :     /** @brief Number of commands on the undo stack. */
      71           30 :     int undo_size() const { return static_cast<int>(undo_stack_.size()); }
      72              : 
      73              :     /** @brief Number of commands on the redo stack. */
      74            3 :     int redo_size() const { return static_cast<int>(redo_stack_.size()); }
      75              : 
      76              :     /** @brief Current maximum undo depth. */
      77              :     int max_depth() const { return max_depth_; }
      78              : 
      79              :     /**
      80              :      * @brief Change the maximum undo depth and trim excess entries.
      81              :      * @param depth New maximum depth. Negative values are clamped to 0.
      82              :      */
      83              :     void set_max_depth(int depth) {
      84              :         max_depth_ = (depth < 0) ? 0 : depth;
      85              :         trim();
      86              :     }
      87              : 
      88              :     /** @brief Description string of the top undo command, or nullptr if empty. */
      89              :     const char* undo_description() const;
      90              : 
      91              :     /** @brief Description string of the top redo command, or nullptr if empty. */
      92              :     const char* redo_description() const;
      93              : 
      94              :    private:
      95              :     /** @brief Evict the oldest undo entries until the stack fits max_depth_. */
      96              :     void trim();
      97              : 
      98              :     std::vector<std::unique_ptr<Command>> undo_stack_;
      99              :     std::vector<std::unique_ptr<Command>> redo_stack_;
     100              :     int max_depth_;
     101              : };
     102              : 
     103              : }  // namespace Amplitron
        

Generated by: LCOV version 2.0-1