Files
sbox-public/game/editor/ShaderGraph/Code/UndoStack.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

115 lines
2.1 KiB
C#

namespace Editor.ShaderGraph;
public class UndoOp
{
public string name;
public string undoBuffer;
public string redoBuffer;
}
public class UndoStack
{
private readonly List<UndoOp> _undoStack = new();
private int _undoLevel = 0;
private bool _redoPending = false;
public bool CanUndo => _undoLevel != 0 && !_redoPending;
public bool CanRedo => _undoLevel != _undoStack.Count && !_redoPending;
public string UndoName => CanUndo ? $"Undo {_undoStack[_undoLevel - 1].name}" : null;
public string RedoName => CanRedo ? $"Redo {_undoStack[_undoLevel].name}" : null;
public int UndoLevel => _undoLevel;
public IEnumerable<string> Names => _undoStack.Select( x => x.name );
public void PushUndo( string name, string buffer )
{
Assert.False( _redoPending, $"Pending Redo ({UndoName})" );
_redoPending = true;
if ( _undoStack.Count > _undoLevel )
{
var count = _undoStack.Count - _undoLevel;
_undoStack.RemoveRange( _undoStack.Count - count, count );
}
_undoStack.Add( new() { name = name, undoBuffer = buffer } );
_undoLevel++;
}
public void PushRedo( string buffer )
{
Assert.True( _redoPending );
_redoPending = false;
_undoStack[_undoLevel - 1].redoBuffer = buffer;
}
public UndoOp Undo()
{
if ( _redoPending )
{
Log.Warning( "Pending Redo!" );
return null;
}
if ( _undoStack.Count > 0 && _undoLevel > 0 )
{
_undoLevel--;
return _undoStack[_undoLevel];
}
return null;
}
public UndoOp Redo()
{
if ( _redoPending )
{
Log.Warning( "Pending Redo!" );
return null;
}
if ( _undoStack.Count > 0 && _undoLevel <= _undoStack.Count - 1 )
{
_undoLevel++;
return _undoStack[_undoLevel - 1];
}
return null;
}
public UndoOp SetUndoLevel( int undoLevel )
{
if ( _redoPending )
{
Log.Warning( "Pending Redo!" );
return null;
}
if ( _undoLevel == undoLevel + 1 )
return null;
if ( _undoStack.Count > 0 && undoLevel <= _undoStack.Count - 1 )
{
_undoLevel = undoLevel + 1;
return _undoStack[_undoLevel - 1];
}
return null;
}
public void Clear()
{
_undoStack.Clear();
_undoLevel = 0;
_redoPending = false;
}
}