The editor has a history (undo/redo) system that allows us to register editing actions and be able to undo/redo them at any time.
You also need to make sure you encapsulate the data and the undo/redo procedure inside the undo/redo functions.
Do not do any modification of the scene or data outside those functions, because it will break the reproduction of undo/redo for that operation.
The redo
function is called inside the history:commitAction, so no need
to call it yourself.
If you add a function that is also adding a history action, it will be better to call it: addSomeThingWithUndo(.….) the postfix WithUndo will hint everyone, that the function is also registering undo operations. The other functions, by default will be considered without undo support. That function can be on the API side or on UI, as long as it has that postfix to be easily understood what it does.
Action names should be PascalCase, without the Action as
postfix, and should be unique globally, \"AddSomeThing\"
instead of
just "Add"
.
Check the history API for more complex usage or transactions of actions and so forth. See History Class
To create an undoable action you need to write two functions, like so:
-- undo the action of naming an object
local function setObjectNameUndo(actionData)
local obj = scenetree.findObjectById(actionData.objectId)
if obj then
-- for undo, we set the old name
obj:setName(actionData.oldName)
end
end
-- redo the action of naming an object
local function setObjectNameRedo(actionData)
local obj = scenetree.findObjectById(actionData.objectId)
if obj then
-- for redo we set the new name
obj:setName(actionData.newName)
end
end
-- our GUI-side and undo enabled editor function that sets the name of an object
local function setObjectNameWithUndo(objectId, name)
local obj = scenetree.findObjectById(objectId)
local oldName = ""
if obj then
oldName = obj:getName(objectId)
end
-- add the action to the history, first argument is the name of the action,
-- second is the action data where you store your undo/redo info
-- last arguments are the undo redo functions
editor.history:commitAction("SetObjectName", {objectId = objectId, newName = name, oldName = oldName}, setObjectNameUndo, setObjectNameRedo)
-- the redo function WILL BE EXECUTED in the addAction function right away
-- thus doing the actual operation
end
The function is added to the editor table (see Extending Editor
), and we can call from anywhere:
editor.setObjectNameWithUndo(3422, "MyName")
. After that, anytime
we call editor.undo()
the old name will be set, and if we call
editor.redo()
the new name will be restored.