Undo manager

This commit is contained in:
Emmanuel BENOîT 2017-11-22 10:01:37 +01:00
parent e2beaed115
commit 4569bb30f4
5 changed files with 110 additions and 0 deletions

View file

@ -44,6 +44,7 @@ DEMO = \
demo.cc \ demo.cc \
main.cc \ main.cc \
syncview.cc \ syncview.cc \
undo.cc \
# END DEMO # END DEMO
PARSERCHECK = \ PARSERCHECK = \

View file

@ -9,6 +9,7 @@
#include "shaders.hh" #include "shaders.hh"
#include "sync.hh" #include "sync.hh"
#include "texture.hh" #include "texture.hh"
#include "undo.hh"
#include "window.hh" #include "window.hh"
@ -20,6 +21,7 @@ T_OwnPtr< T_TextureManager > Globals::textures_;
T_OwnPtr< T_ShaderManager > Globals::shaders_; T_OwnPtr< T_ShaderManager > Globals::shaders_;
T_OwnPtr< T_OutputDebugger > Globals::odbg_; T_OwnPtr< T_OutputDebugger > Globals::odbg_;
T_OwnPtr< T_ScriptManager > Globals::ops_; T_OwnPtr< T_ScriptManager > Globals::ops_;
T_OwnPtr< T_UndoManager > Globals::undo_;
void Globals::Init( ) void Globals::Init( )
@ -32,10 +34,12 @@ void Globals::Init( )
shaders_ = NewOwned< T_ShaderManager >( ); shaders_ = NewOwned< T_ShaderManager >( );
odbg_ = NewOwned< T_OutputDebugger >( ); odbg_ = NewOwned< T_OutputDebugger >( );
ops_ = NewOwned< T_ScriptManager >( ); ops_ = NewOwned< T_ScriptManager >( );
undo_ = NewOwned< T_UndoManager >( );
} }
void Globals::Shutdown( ) void Globals::Shutdown( )
{ {
undo_.clear( );
ops_.clear( ); ops_.clear( );
odbg_.clear( ); odbg_.clear( );
shaders_.clear( ); shaders_.clear( );

View file

@ -12,6 +12,7 @@ struct T_ShaderManager;
struct T_OutputDebugger; struct T_OutputDebugger;
struct T_SyncManager; struct T_SyncManager;
struct T_ScriptManager; struct T_ScriptManager;
class T_UndoManager;
struct Globals struct Globals
@ -27,6 +28,7 @@ struct Globals
static T_ShaderManager& Shaders( ) { return *shaders_; } static T_ShaderManager& Shaders( ) { return *shaders_; }
static T_OutputDebugger& ODbg( ) { return *odbg_; } static T_OutputDebugger& ODbg( ) { return *odbg_; }
static T_ScriptManager& Ops( ) { return *ops_; } static T_ScriptManager& Ops( ) { return *ops_; }
static T_UndoManager& Undo( ) { return *undo_; }
private: private:
static T_OwnPtr< T_FilesWatcher > watcher_; static T_OwnPtr< T_FilesWatcher > watcher_;
@ -37,4 +39,5 @@ struct Globals
static T_OwnPtr< T_TextureManager > textures_; static T_OwnPtr< T_TextureManager > textures_;
static T_OwnPtr< T_OutputDebugger > odbg_; static T_OwnPtr< T_OutputDebugger > odbg_;
static T_OwnPtr< T_ScriptManager > ops_; static T_OwnPtr< T_ScriptManager > ops_;
static T_OwnPtr< T_UndoManager > undo_;
}; };

45
undo.cc Normal file
View file

@ -0,0 +1,45 @@
#include "externals.hh"
#include "undo.hh"
/*= A_UndoAction ===============================================================*/
A_UndoAction::~A_UndoAction( )
{}
/*= T_UndoManager ==============================================================*/
void T_UndoManager::undo( ) noexcept
{
if ( pos_ > 0 ) {
pos_ --;
actions_[ ( start_ + pos_ ) % MaxUndo ]->undo( );
}
}
void T_UndoManager::redo( ) noexcept
{
if ( pos_ < count_ ) {
pos_ ++;
actions_[ ( start_ + pos_ ) % MaxUndo ]->redo( );
}
}
void T_UndoManager::addAction(
P_UndoAction action ) noexcept
{
assert( action );
while ( pos_ < count_ ) {
count_ --;
actions_[ ( start_ + count_ ) % MaxUndo ].clear( );
}
if ( count_ == MaxUndo ) {
actions_[ start_ ] = std::move( action );
start_ = ( start_ + 1 ) % MaxUndo;
} else {
actions_[ ( start_ + pos_ ) % MaxUndo ] = std::move( action );
count_ ++;
pos_ ++;
}
}

57
undo.hh Normal file
View file

@ -0,0 +1,57 @@
#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;
// Add an action using a pointer
void addAction( P_UndoAction action ) noexcept;
// Construct and add an action
template<
typename T ,
typename... Args
> void add( Args&&... args ) noexcept;
};
template<
typename T ,
typename... Args
> inline void T_UndoManager::add(
Args&&... args ) noexcept
{
addAction( NewOwned< T >( std::forward< Args >( args ) ... ) );
}