how to undo any function - java

Is there a way to undo last function/method which is just finished to work?
for example I have a function/method which is doing this:
isTrue = false
num+=5
and many more functions. Each function start to work when user presses certain button on a screen. User should have possibility to undo his last action.
Is there universal way to undo any function which just finished to work?
Of course, I can do this way:
isTrue=true
num-=5
but that to do if there is many functions? Is there easy way to undo any function (android)?

I don't know any language or platform where you can do something like that.
Any code that your application executes modifies data in memory in some way (creates or destroys objects, changes values etc.). In order to undo changes made by that code operating system should save the full history of data modifications and that is practically impossible because of limited resources.

There isn't any built-in language feature to allow undoing everything that function has changed, but there are patterns that are established in other to help in these kind of situations.
One option you have is memento pattern, where you keep copy of previous state, so that you can always comeback to it, but one drawback of this is increased memory usage for saving all excess state, or in case you are persisting state on disk then there is performance overhead for reading/writing.
Another option is using command pattern where each command knows how to undo itself, this way you don't need to keep previous state, but you need to keep track of command history, what this means is that if you have a lot of state then command pattern would be better option because you don't need to save previous state but you will have a inverse function which knows to undo change that has been made by that command, while if you have only few strings then using memento pattern would be better option, especially if you need to allow undoing actions even after app is killed and started again.
Good example of using command pattern for undo with explanation can be found here.

Related

What is the difference between Memento and Command design pattern?

I have successfully coded a solitaire game on Java, and now I have been asked to implement an undo/redo on top of my design.
My plan was to store a list or stack of moves the user executed, and if the user wants to undo, I would 1. check if the user can undo (ie. there are moves in the list or stack), then 2. reverse the last two moves I stored (ie. the "from" move where I moved the card from and the "to" move, where I moved the card to).
For redo, I would just redo the moves, depending on how far down the user did the undo action (for example, if they pressed undo twice, I would be, at least, (size of list - 4) down my list or stack).
I think they will be implemented in an interface like so:
public interface UndoRedo {
void undo();
void redo();
}
Am I implementing Memento, or Command design pattern, or neither? I'm having trouble grasping what the two design patterns look like in the context of an undo/redo for this game. I'm also a beginner with Java OOP, and design patterns in general.
From what you describe, you seem to implement the Command pattern.
Command captures all information needed to perform certain action (not necessarily to undo this action). Your moves are basically commands.
Memento is a way to store state so that it is restoreable. Assume you'd have a class like GameState which represents the current state of the game. You'd be implementing Memento if your GameState would have methods like GameStateBackup createBackup() and restoreFromBackup(GameStateBackup).
Consider a game of chess where you'd want to be able to revert last x moves.
One way to do it would be to record all moves. You could then either "undo" moves. Or simple "replay" the first n-x moves. That would be the Command approach.
Another way would be to save the last x states of the game (and be able to restore them). This is the Memento approach.
You could actually use both patterns together. For instance, when implementation of "undo" would not be feasible you could record the state of the game before/after each move to make moves undoable.
If you are undoing/redoing by executing commands on the state, that is the command pattern.
If you are undoing/redoing by replacing state from a cache of states, that is the memento.
The difference between the Command and the Memento patterns for UNDO/REDO, is that in the Command pattern, you re-execute commands in the same order that changed attributes of a state, and with the Memento, you completely replace the state by retrieving from a cache/store.
Design Patterns In Python: ASIN B08XLJ8Z2J
Neither. You're storing previous input as state and allowing actions on the data.
Memento is storing computed values for each unique input for deterministic functions and returning the stored value if the same input is seen again.
Command is bundling execution code and its input as a single object that can be executed later by passing the input to the executable.
It's close to Command, but doesn't seem like it is Command because it's not an independent asynch action.

Efficient recall of a delta-based data log in Java

My application has a number of objects in an internal list, and I need to be able to log them (e.g. once a second) and later recreate the state of the list at any time by querying the log file.
The current implementation logs the entire list every second, which is great for retrieval because I can simply load the log file, scan through it until I reach the desired time, and load the stored list.
However, the majority of my objects (~90%) rarely change, so it is wasteful in terms of disk space to continually log them at a set interval.
I am considering switching to a "delta" based log where only the changed objects are logged every second. Unfortunately this means it becomes hard to find the true state of the list at any one recorded time, without "playing back" the entire file to catch those objects that had not changed for a while before the desired recall time.
An alternative could be to store (every second) both the changed objects and the last-changed time for each unchanged object, so that a log reader would know where to look for them. I'm worried I'm reinventing the wheel here though — this must be a problem that has been encountered before.
Existing comparable techniques, I suppose, are those used in version control systems, but I'd like a native object-aware Java solution if possible — running git commit on a binary file once a second seems like it's abusing the intention of a VCS!
So, is there a standard way of solving this problem that I should be aware of? If not, any pitfalls that I might encounter when developing my own solution?

Command Pattern for undo/redo in paint application

I would like to implement undo/redo in a small paint application. It seems the Command Pattern fits the use nicely, but I am unsure how to best implement it.
As I understand the pattern, it is necessary to include in each command:
The details of the paint operation for purposes of redo (e.g. Line -> start & end points, free form line -> GeneralPath)
The state of the component prior to the change for undo. In this case, that will be a small snapshot image of the area affected by the command.
My understanding based on that is that each command needs to be 'atomic' or self contained, with all the information needed for undo/redo that operation.
Unfortunately that would require storing more information than I'd first anticipated. For a line we must also account for things like the Color, Stroke and RenderingHints used to draw it initially. This turns my 'simple little commands' into something ..more bulky in memory, and with more boiler-plate code to churn out (each will be a serializable bean1).
For reasons of memory conservation (mostly) I was wanting to 'cheat' on the specification of the commands. Perhaps take a backup of the entire drawing area every 100th update, but otherwise store no part of the changed image, and simply rebuild the last (up to) 100 commands for each new paint operation. But that seems problematic to ensure that the state of the Graphics object is right before painting each part - this part might require a line, but the RenderingHints were changed 4 commands ago, the Color was changed 98 commands ago, while the Stroke has remained the same for the last 227 commands.
Pursuing a more memory efficient command seems to throw the pattern right out the window in terms of being 'atomic'. That in turn leads to difficulties in determining the earliest command that might affect the rendering.
Should I:
Look for a new pattern?
Attempt to implement my peculiar needs by tweaking the pattern?
Toss all this in the waste bin as premature optimization and code it in the simplest (and most memory consuming) way that sticks to the command pattern as defined?
Update
"each will be a serializable bean" On 2nd thoughts, no. I did dome checks to find that a Graphics2D (which neatly encapsulates many parameters used when drawing) is not serializable. Further, a BasicStroke is serializable, but the thickness of the stroke is not stored. I could create serializable versions of many of the attributes but it seems to make for a lot more code, so I'm going to abandon that spec. as well. I will only attempt to store a reference to a BufferedImage at run-time.
I would stick with command pattern and first try a naive solution (=the most memory-hungry). For some graphical operations it may be even necessary to keep a copy of the entire image in the command object (eg. think of filters). This is a common problem also in professional image editing applications, they often have a memory or step limit of last commands that are remembered. And if the memory consumption is really large you may think of swapping the oldest entries in command-history to file system. I think user will not mind waiting a second until the change is undone.
Maybe, it would be better not to store copy of entire image in command, but store only copy of area, which is changing by command. Of course, this is not a panacea

WatchService / dectect renames and or moves

Note: Replace INSERT/DELETE with the appropriate events from WatchService...
One more question regarding the WatchService class from Java7. How can I reliably detect renames (and maybe even moves) of directories/files? On a more thorough thought it seems very hard to even detect renames, or more precisely it involes a lot of state to keep track of. I don't think it's enough to check for INSERT/DELETE or DELETE/INSERT pairs of the same file/directory identifier. I think it's not enough to keep track of only one event. It might as well interfere with other DELETEs or INSERTs of files. Thus all I can think of is a really ugly heuristic to keep track of unique identifiers and to watch for an INSERT and a subsequent DELETE which might interfere with other events or DELETE/INSERT. Thus I think I would need some kind of timeout and after it expires just insert/delete all tracked changes. Definitely error prone or a best effort to detect renames :-( I think it's possible to get the relevant info from Linux and Windows (RENAME event), but I currently don't intend to use JNI, as I've already implemented everything with WatchService (even if I've spend only a few days).
StandardWatchEventKinds.ENTRY_MODIFY is the event you are looking for.

Efficient undo/redo for Photoshop-like mobile app

I'm trying to write a painting app for a mobile device (Android) that will have a bit more functionality than MS Paint (e.g. various brushes and brush settings, selections, layers) but won't be as complex as Photoshop. I need my app to have a decent undo/redo feature. Unlimited undo/redo is probably not possible. I'd be happy with being able to undo about the last minute worth of user actions (maybe about 20 actions).
The main approaches I know of for undo/redo is:
save the whole state or just the bits that changed after each operation. Undoing involves updating the state by restoring snapshots. Pros: simple to implement Cons: memory intensive.
use the command pattern where each command has a "do action" and "undo action" method. To undo, you just call the undo action of the previous commands. Pros: memory efficient, Cons: much more complex to implement.
My pathological undo/redo scenarios I have to consider is:
the user paints over the whole canvas in one go, where you would want this whole operation to be undone when the user clicks undo. With option 1, we'd need to store a bitmap the size of the whole canvas.
the user draws something, imports image 1.jpg onto the canvas, does some more drawing, 1.jpg is then deleted/modified at some point by another application and then the user wants to undo then redo all their actions in the paint application. I'm really not sure how to undo correctly here without saving a copy of any imported image while it's on the undo stack.
Can anyone give any recommendations about how best to implement undo/redo on a mobile device where memory and processor speed are low? I like the simplicity of 1 and 3 but it seems like the only realistic option is 2. I'm not sure how to cope with my second pathological example with this option though.
On the iPhone, Core Data has built in support for undo and redo. Just make your data model reflect the objects drawn and you can easily roll it back and forward between saves. Usually you would save the procedures and objects used to create the graphic instead of the graphic itself.
Edit:
OK, but this is just a little API
support for implementing number 2 and
won't help with the examples I gave.
The key idea to making this work is that you don't configure your data model to modal and persist the graphical output of the program, you configure it to modal and persist the process of creating the graphical output.
The naive way of creating a graphical program would be to set up the data flow like:
Input_UI-->Display_UI-->Data_Model
The user manipulates the Input_UI which directly alters the onscreen graphics of the Display_UI. Only when the user saved would the Data_Model come into play. This type of data flow makes undo/redo (and other things) very hard to implement especially in a painting e.g. compositing program. Every single operation has to know how to undo itself and has to be able operate on the altered graphic.
The better way is to set up a data flow like this:
Input_UI-->Data_Model-->Display_UI
The user manipulates the Input_UI which communicates to the Data_Model which manipulations the user chose. The Data_Model records the process e.g. "add file jpg.1 at rect {0,0,100,100}". A change to the Data_Model sends a notification to the Display_UI which reads the changed data and implements the process described.
The Data_Model rolls itself back and the Display_UI simply draws what the Data_Model tells it to. The Display_UI doesn't have to understand the undo process at all.
In a drawing program you would create logical layers of individual graphical objects so that redoing is just a matter of removing layers in the reverse order they were added. For painting/composition programs, you have to start at the last save point and recreate the graphic going forward until the last-1 step.
So, in your examples for a compositing program:
The Data_Model stores the coordinates of the selected area (the entire canvas) which is still just "rect {0,0,canvas.width,canvas.height}" and then the operation "fill with black". For undo, the Display_UI whips the image back to the last save point and then invisibly applies the changes made up to last-1.
You just need to save a cache of the image up until the next save. At that point, the Data_Modal commits all the changes and exports the composition to a file. The next time the app starts, it begins with the image from the last time. If you want infinite undo, then yes you have to save the imported image permanently.
The way to approach this is to ignore the GUI and instead think about how you would design an app to be run from the command line with out any GUI input or output. The Data_Modal would work just the same. It would save the text commands and the data (e.g. imported images) for creating the output image, not just a snapshot of the image on screen.
I like the simplicity of 1 and 3 but
it seems like the only realistic
option is 2.
I'm not sure what "3" is, since you only appear to have two options in your question.
With respect to the memory consumption of #1, it's only an issue if you use memory. Only hold onto history in memory for as long as it takes an AsyncTask (or possibly a regular background thread working off a LinkedBlockingQueue) to write them to the SD card. No SD card -- no undo/redo. On an undo, if your history has already written it to disk, reload it from disk. Just be sure to clean up the SD card (delete history on a clean exit, delete all lingering files on next startup).
Bear in mind that I have never written a painting application, let alone on Android, and so there may yet be performance problems (e.g., undo may take a second to load the bitmap off of the SD card).

Categories

Resources