2017-11-22 10:01:37 +01:00
|
|
|
#pragma once
|
|
|
|
#ifndef REAL_BUILD
|
|
|
|
# include "externals.hh"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// Interface for undo actions
|
|
|
|
class A_UndoAction
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual ~A_UndoAction( ) = 0;
|
|
|
|
virtual void undo( ) const noexcept = 0;
|
|
|
|
virtual void redo( ) const noexcept = 0;
|
|
|
|
};
|
|
|
|
using P_UndoAction = T_OwnPtr< A_UndoAction >;
|
|
|
|
|
|
|
|
|
|
|
|
// Undo manager
|
|
|
|
class T_UndoManager
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
static constexpr uint32_t MaxUndo = 1024;
|
|
|
|
|
|
|
|
ebcl::T_StaticArray< P_UndoAction , MaxUndo > actions_;
|
|
|
|
uint32_t start_{ 0 };
|
|
|
|
uint32_t count_{ 0 };
|
|
|
|
uint32_t pos_{ 0 };
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_UndoManager( ) noexcept = default;
|
|
|
|
DEF_MOVE( T_UndoManager );
|
|
|
|
NO_COPY( T_UndoManager );
|
|
|
|
|
|
|
|
// Undo last action
|
|
|
|
void undo( ) noexcept;
|
|
|
|
// Redo last undone action
|
|
|
|
void redo( ) noexcept;
|
|
|
|
|
2017-11-22 10:42:28 +01:00
|
|
|
// Check if it is possible to undo or redo
|
|
|
|
bool canUndo( ) const noexcept
|
|
|
|
{ return pos_ > 0; }
|
|
|
|
bool canRedo( ) const noexcept
|
|
|
|
{ return pos_ < count_; }
|
|
|
|
|
2017-11-22 10:01:37 +01:00
|
|
|
// Add an action using a pointer
|
2017-11-22 10:42:28 +01:00
|
|
|
A_UndoAction& addAction( P_UndoAction action ) noexcept;
|
2017-11-22 10:01:37 +01:00
|
|
|
|
|
|
|
// Construct and add an action
|
|
|
|
template<
|
|
|
|
typename T ,
|
|
|
|
typename... Args
|
2017-11-22 10:42:28 +01:00
|
|
|
> A_UndoAction& add( Args&&... args ) noexcept;
|
2017-11-22 10:01:37 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template<
|
|
|
|
typename T ,
|
|
|
|
typename... Args
|
2017-11-22 10:42:28 +01:00
|
|
|
> inline A_UndoAction& T_UndoManager::add(
|
2017-11-22 10:01:37 +01:00
|
|
|
Args&&... args ) noexcept
|
|
|
|
{
|
2017-11-22 10:42:28 +01:00
|
|
|
return addAction( NewOwned< T >( std::forward< Args >( args ) ... ) );
|
2017-11-22 10:01:37 +01:00
|
|
|
}
|