madis Posted February 20, 2011 Share Posted February 20, 2011 Every action needs associated reverse-action. Then store all the actions done in the right order. Link to comment
Deltanic Posted February 20, 2011 Author Share Posted February 20, 2011 (edited) local history = {} local h_Val = 0 --When I change something history[#history+1] = what_it_is_now -- Get the current value h_Val = #history -- Store the current history time --Now change the thing that needs to be changed -- When I press undo setting = history[h_Val] -- Get the previous history item h_Val = h_Val-1 -- backward the history time -- When I press redo setting = history[h_Val+1] -- Get the next history item h_Val = h_Val+1 -- Forward the history time Is that correct, or is this way completely inefficient? Edited February 20, 2011 by Guest Link to comment
Discord Moderators Zango Posted February 20, 2011 Discord Moderators Share Posted February 20, 2011 what if you undo + do a new change? since you do not remove the change you wanted to undo, it will add on top? Link to comment
Deltanic Posted February 20, 2011 Author Share Posted February 20, 2011 So, I should change this: --When I change something history[#history+1] = what_it_is_now -- Get the current value h_Val = #history -- Store the current history time --Now change the thing that needs to be changed Into this: --When I change something history[#h_Val+1] = what_it_is_now -- Get the current value h_Val = h_Val+1 --Now change the thing that needs to be changed Or I'm getting wtf-ed.. Link to comment
eAi Posted February 20, 2011 Share Posted February 20, 2011 Undo systems are notoriously hard to get right... Things that are hard are things like creating and destroying things. I'm sure there are articles about this on the web. Link to comment
Deltanic Posted February 21, 2011 Author Share Posted February 21, 2011 Why is it really hard to make? Almost every simple program has an undo/redo button. And I just have to store small data. Besides, after searching some articles using google, I haven't found something useful yet. It's all text, but no tutorials or examples. Link to comment
eAi Posted February 21, 2011 Share Posted February 21, 2011 Well, if it isn't hard, just do it? Link to comment
Ransom Posted February 21, 2011 Share Posted February 21, 2011 Indeed, you question why its hard yet here you are lol... There are a lot of programs out there with undo and redo that PARTIALLY work. Its rare to get something like Photoshop that can log and undo almost every single action on the GUI. Especially in any given order. You will often run into a situation where certain actions can be undone but they make it impossible to do previous undos before it. Example would be like converting a file to a different format. Then there are times you run into a situation where a popup comes and tells you something cannot be undone once done. Some programs cheat... the cheating way? Keep logging EVERYTHING at a specific point in time for x steps. If the user has a problem retreat back to this state. Basically like a save state in an emulator. This is of course highly inefficient and not suitable for something like Photoshop. Maybe you could get away with it? Link to comment
Discord Moderators Zango Posted February 21, 2011 Discord Moderators Share Posted February 21, 2011 If I am not fully mistaken, map editor has an undo/redo system? I swear I reckon some buttons in the top panel. Link to comment
madis Posted February 23, 2011 Share Posted February 23, 2011 You can think of undo/redo system a bit like revision system. Of course you need to do a lot of extra work (you need to have a reverse method), so think if you really need it. Also in MTA resource, why do you need it exactly? If it's something mutual for clients on serverside (like in the map editor?) then it adds another layer of complexity, which I would never want to deal with (programming). However, this is a very good topic. I have thought on that myself too. I'm sure there are some nice articles out there, but discussing these things by self is also fun. Link to comment
Deltanic Posted February 23, 2011 Author Share Posted February 23, 2011 It's for my handlingeditor. It would be nice to revert changes since some values can give LSOD's. Those changes just contain numbers, bools, strings, or a simple small table. So, this should be stored: oldValue["settingName"] = data --string,bool,number --or oldValue["centerOfMass"] = { x, y, z } --table for centerOfMass Nothing else, and my script can easily understand how to handle those different types of data. So that's not a problem. Link to comment
madis Posted February 23, 2011 Share Posted February 23, 2011 I'll be an ass and not read your last post, as I just got ready with an example how I would implement a draft (and later refactor it into something more re-usable). I haven't coded in Lua for half a year, so there are probably errors, but it doesn't matter. function setVehicleHeadLightColorWithUndo(vehicle, r, g, b) --get for undo local oldR, oldG, oldB = getVehicleHeadLightColor(vehicle); --keep for redo local action = setVehicleHeadLightColor(vehicle, r, g, b) local undoAction = {setVehicleHeadLightColor(vehicle, oldR, oldG, oldB)} addToActionsHistory(action, undoAction) end -- global undo table actionsHistory = {} -- ... in arguments list is a valid code in Lua, which means any extra arguments when method is called function addToActionsHistory(redoAction, undoAction) local undone = false local methodInfo = {redoAction, undoAction, undone} table.insert(actionsHistory, methodInfo) end function markAsUndone(index) local methodInfo = actionsHistory[index] -- undone = true methodInfo[3] = true -- Can't remember if it's pointer or we need to overwrite the old table element with new data in Lua... end undo(steps) { -- default value for steps if steps==nil steps=1 end for iterator, methodInfo in ipairs(steps) do local index = #actionsHistory-iterator-1 markAsUndone(index) local methodInfo = actionsHistory[index] local undoAction = methodInfo[2] -- not sure if it was that easy in Lua undoAction() end } redo(steps) { -- default value for steps if steps==nil steps=1 end --TODO: Implement it --check if undone from the end first... --local redoAction = methodInfo[1] --redoAction() } Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now