Skip to content

Instantly share code, notes, and snippets.

@vk2gpu
Last active September 17, 2016 04:34
Show Gist options
  • Select an option

  • Save vk2gpu/dbf051ab7f6af9cfacc0dfb92a28fa0a to your computer and use it in GitHub Desktop.

Select an option

Save vk2gpu/dbf051ab7f6af9cfacc0dfb92a28fa0a to your computer and use it in GitHub Desktop.
/// Core undo/redo code.
typedef std::function< void() > ActionCallback;
struct EditorAction
{
BcU32 ID_ = 0;
const char* Name_ = nullptr;
ActionCallback Do_;
ActionCallback Undo_;
BcU32 CombinedID_ = 0;
};
EditorAction ActiveAction_;
std::deque< EditorAction > UndoStack_;
std::deque< EditorAction > RedoStack_;
void Action( BcU32 ID, const char* Name, ActionCallback Do, ActionCallback Undo, bool Commit )
{
BcU32 CombinedID = 0;
CombinedID = BcHash::GenerateCRC32( CombinedID, &ID, sizeof( ID ) );
CombinedID = BcHash::GenerateCRC32( CombinedID, Name, BcStrLength( Name ) );
if( CombinedID != ActiveAction_.CombinedID_ )
{
if( ActiveAction_.CombinedID_ != 0 )
{
CommitAction();
}
ActiveAction_.Undo_ = Undo;
}
ActiveAction_.Do_ = Do;
ActiveAction_.ID_ = ID;
ActiveAction_.Name_ = Name;
ActiveAction_.CombinedID_ = CombinedID;
Do();
RedoStack_.clear();
if( Commit )
{
CommitAction();
}
}
void CancelAction()
{
PSY_LOGSCOPEDCATEGORY( Editor );
if( ActiveAction_ .CombinedID_ != 0 )
{
PSY_LOG( "CancelAction: %u, %s", ActiveAction_.ID_, ActiveAction_.Name_ );
}
if( ActiveAction_.Undo_ )
{
ActiveAction_.Undo_();
}
ActiveAction_ = EditorAction();
}
void CommitAction()
{
PSY_LOGSCOPEDCATEGORY( Editor );
if( ActiveAction_ .CombinedID_ != 0 )
{
PSY_LOG( "CommitAction: %u, %s", ActiveAction_.ID_, ActiveAction_.Name_ );
}
if( ActiveAction_.CombinedID_ != 0 )
{
UndoStack_.push_back( ActiveAction_ );
ActiveAction_ = EditorAction();
}
}
void UndoAction()
{
PSY_LOG( "UndoAction: %u", UndoStack_.size() );
CommitAction();
if( UndoStack_.size() > 0 )
{
ActiveAction_ = UndoStack_.back();
RedoStack_.push_back( ActiveAction_ );
UndoStack_.pop_back();
CancelAction();
}
}
void RedoAction()
{
PSY_LOG( "RedoAction: %u", RedoStack_.size() );
CommitAction();
if( RedoStack_.size() > 0 )
{
ActiveAction_ = RedoStack_.back();
RedoStack_.pop_back();
ActiveAction_.Do_();
CommitAction();
}
}
/// Example usage:
Editor::Action( Idx, "Track Add Node",
// Do
[ this, Idx, Result ]()
{
GaTrackPoint NewTrack;
NewTrack.Position_ = Result.WorldPosition_;
Points_.insert( Points_.begin() + Idx + 1, NewTrack );
rebuildTrackMesh();
},
// Undo
[ this, Points = Points_ ]()
{
Points_ = Points;
rebuildTrackMesh();
} );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment