first of all .. sorry if my english was bad. its my 3rd language
im working on a paint software that draw over images and save them again ( for commenting propose )
Also, keep in mind that Python's functions are first-class objects, which can make implementing the Command pattern very smooth:
actions = []
def do_action1(arg1, arg2):
# .. do the action ..
# remember we did the action:
actions.append(do_action1, (arg1, arg2))
def do_action2(arg1, arg2):
# .. do the action ..
actions.append(do_action2, (arg1, arg2))
def replay_actions():
for fn, args in actions:
fn(*args)
The canonical strategy is to use the Command pattern. You'll represent the things you can do as Command objects, and each object is placed on a stack. The state of the application is then defined by an initial state plus everything that the stack has. Thus, the "undo" operation is then just popping the top stack item and reapplying the remaining items to the initial state.
In practice, sometimes it's expensive to keep applying those operations to the initial state to generate the current state. For example, this might be true with something like a complex series of image adjustments, like you might find in Photoshop. In cases like that, it's common to keep an alternating state-stack series in memory:
+---------+
| state_0 |
+---------+ +---------+
| next -------> | stack_0 |
+---------+ +---------+
| data | +---------+
| next -------> | state_1 |
+---------+ +---------+
| next ----- ...
+---------+
Each stack_i
holds commands until it exceeds some pre-set complexity (e.g., the commands exceed computational cost X
) or ordinal (e.g. the stack holds X
or more commands) limit. At that point, a new intermediate state object state_i+1
is created to encapsulate the state, and a new, empty stack stack_i+1
is created to hold new commands.
In this way, you only have to apply a small sequence of commands to the last snapshotted state to get the current state. This comes at the expense of memorizing entire states, which may not be feasible for very large applications, but you can choose to snapshot only a set of the state to optimize.