I'm developing a sort of editor in Flutter and it should have an undo/redo functionality.
In my editor, my the different operations done by the user are done on a Design
object. I'm using freezed
(https://pub.dev/packages/freezed) for building my object model. Here's what it looks like:
@freezed
class Design with _$Design {
const factory Design({
required int id,
required String name,
required DiagramOrientation orientation,
@ColorConverter() Color? backgroundColor,
required String backgroundImage,
required String logo,
required List<DesignArea>? areas
}) = _Design;
factory Design.fromJson(Map<String, Object?> json)
=> _$DesignFromJson(json);
}
To implement undo/redo functionality I have 2 options that I have thought of.
- Create some kind of class that will hold an "operation":
class DesignOperation {
final Design design;
final String name;
const DesignOperation(required this.design, required this.name);
}
On each operation create this class with the name of the operation (for operation history displaying purposes) and insert a copy of the object into a list (managing the max number of allowed operations, removing operations when inserting new ones after undo, etc...). Undo/redo would be just to update the object to the correct place in the list.
- Use a library I found for undo/redo - https://pub.dev/packages/undo.
Looking at this library I would need to change my
Design
model to be@unfreezed
, and when callingadd
I pass 2 anonymous functions (which hold a reference to the variables in my code and basically having to be working with closures).
I'm wondering, development wise, performance and memory what would be the better approach - copies of my object or keeping anonymous functions with references to my object properties.