So basically I was thinking of an undo-redo system (I've heard enough of memmento pattern and command pattern and I'm just gonna REEEEEEEEEE) where you'd make an object of this UndoRedo class inside any class that required a UR system and then every function that can be undone would start by generating a string of code that would undo the action (taking into account things like parameters passed to the function and any other related info) and push it to the undo stack of the URobject, which would handle the 2 stacks appropriately and have functions for undoing and redoing that just pop the code and eval it
Then I found this SO post about how to Eval in c# but it's useless because it's sandboxed and I need the Eval-ed code to communicate with the rest of my code and stuff.
Then, with @CodeCharmander's suggestion and @Fixation's clarification and a bit of research I managed to make it work!
For Anyone Interest in the Final Class:
using System;
using System.Collections.Generic;
class UndoRedo
{
public Stack<Action> UndoStack { get; } = new Stack<Action>();
public Stack<Action> RedoStack { get; } = new Stack<Action>();
public Stack<Action> DoStack { get; } = new Stack<Action>();
public Stack<Action> BackupStack { get; } = new Stack<Action>();
public void Do(Action DoAct, Action UndoAct, bool Entry)
{
if ( Entry )
{
DoStack.Push( DoAct );
UndoStack.Push( UndoAct );
RedoStack.Clear();
BackupStack.Clear();
}
DoAct();
}
public void Undo()
{
var undoAct = UndoStack.Pop();
undoAct();
BackupStack.Push( undoAct );
RedoStack.Push( DoStack.Pop() );
}
public void Redo()
{
var redoAct = RedoStack.Pop();
redoAct();
DoStack.Push( redoAct );
UndoStack.Push( BackupStack.Pop() );
}
}
Info:
The Do function takes 2 Lambda expressions as Delegates. (Thx to @CodeCharmander for the suggestion, @Fixation for the clarification, and Google for reminding me how Delegates work)
() => { //Code here }
The Entry parameter is for cases where the Undo action is a call to any other undoable method, it should normally be set based on what object/class/method called said other undoable method; If this isn't set up correctly it can cause issues where undoing an action adds said "undo" as another action, creating an infinite loop and clearing Redo/Backup stacks when it shouldnt