I have never designed an undo system before, so I just wanted to brainstorm if there were any "general" solutions which were able to save states prior to a change actioned by the IfcOpenShell Python API, and then optionally store it in an ordered list, and then restore that state if the user selects it.
Actions may be:
- Editing: element.Name = 'foo'
- Adding: ifc_file.create_entity("IfcFoo")
- Removal: ifc_file.remove(element)
Complex actions (remove_deep, copy_deep, etc) are basically just the three fundamental actions just repeated.
Naturally, the undo stack should store the final result of the element, such that if I do ifc_file.createIfcRootedFoo(ifcopenshell.guid.new(), ...) - the GlobalId does not change. Similarly, since STEP IDs are used to sync objects in the Blender client to the the IFC dataset, STEP IDs should be preserved.
Not an urgent issue to solve, but something I probably can't ignore forever :)
A naive suggestion would be that a flag can be set to start recording state changes. e.g. ifc_file.begin_transaction(). Then, the transaction consists of an ordered list. Each item in the list is either an "edit", an "add", or a "remove". The "edit" will store the element prior to the edit, the "add" will store the new element, and the remove will store the old element. Then, when all the operations are finished, state recording finishes e.g. undo = ifc_file.end_transaction(). This undo object can then call undo.restore() or something.
In theory this could be implemented in Python by wrapping all calls. This is however just my naive Wednesday morning idea of how undo systems work. I should probably do more research on it.
Thoughts?
Edit: Here's a TODO list to track undo support for operations.
I have never designed an undo system before, so I just wanted to brainstorm if there were any "general" solutions which were able to save states prior to a change actioned by the IfcOpenShell Python API, and then optionally store it in an ordered list, and then restore that state if the user selects it.
Actions may be:
Complex actions (remove_deep, copy_deep, etc) are basically just the three fundamental actions just repeated.
Naturally, the undo stack should store the final result of the element, such that if I do ifc_file.createIfcRootedFoo(ifcopenshell.guid.new(), ...) - the GlobalId does not change. Similarly, since STEP IDs are used to sync objects in the Blender client to the the IFC dataset, STEP IDs should be preserved.
Not an urgent issue to solve, but something I probably can't ignore forever :)
A naive suggestion would be that a flag can be set to start recording state changes. e.g. ifc_file.begin_transaction(). Then, the transaction consists of an ordered list. Each item in the list is either an "edit", an "add", or a "remove". The "edit" will store the element prior to the edit, the "add" will store the new element, and the remove will store the old element. Then, when all the operations are finished, state recording finishes e.g. undo = ifc_file.end_transaction(). This undo object can then call undo.restore() or something.
In theory this could be implemented in Python by wrapping all calls. This is however just my naive Wednesday morning idea of how undo systems work. I should probably do more research on it.
Thoughts?
Edit: Here's a TODO list to track undo support for operations.