Advanced Undo

Introduction

This topic describes advanced mechanisms for storing undo history. This is meant mostly
for developers of custom user interfaces and libraries.

When Advanced Undo is Needed

In FlexSim, for the most part, undo/redo just works. You don't need to worry much about
what is being recorded to the undo history, because it's all automatic. However, there are
some instances where you might need to customize the undo history recording to suit your
needs. Some examples of when you might want to customize undo history recording are:

When you have created a customized object, and that object changes certain variable
values as the object is dragged around in the model, i.e. in its OnPreDraw or OnDrag
functionality. You may want those values to go back to their original state before the
object was dragged.

If you have custom functionality in a user library's drop script that you do NOT
want recorded in the undo history. By default, whenever the user does a drag/drop
operation from the library icon grid, FlexSim will automatically start an "aggregated
undo" operation, which essentially retools several low-level commands to record changes
that are made. We'll talk about this in more detail later, but for some dropscripts, you
may need to temporarily "turn off" undo recording, then execute your functionality, then
turn it back on. For example if you are performing functionality that opens a
window.

If you create a tool window that is used to modify the model, like the Edit Selected
Objects tool windows, then you'll need to add code to the buttons of those windows that
explicitly does undo recording. In FlexSim, all things that are done in a 3D view, a
tree view, or a table view, as well as all operations done in tool windows that focus
around those views, are undo-able, so if you design a tool window that is used with one
of these views, you'll need to make it undo-capable.

Creating an Undo Record Explicitly

To create an undo record before executing a piece of code, call beginaggregatedundo().
Pass in the view that this undo is associated with. If you pass in NULL as the view, then it
will be associated with FlexSim's global undo history (MAIN:/project/undo/). Pass in a
description of the operation being done ("ChangeColor"). The beginaggregatedundo() command
will return back a unique id for the undo record that you've created. Then execute the code
that you want to be undo-able, then call endaggregatedundo(), passing in the view and the
undo id.

When you call beginaggregatedundo(), FlexSim will retool several low-level commands, so
that subsequent calls that you make to those commands, or calls to those commands by other
commands that you call, will record changes to the undo history. The commands that are
retooled are as follows:

nodeadddata()

setnodenum()/set()

setnodestr()/sets()

nodedeldata()

nodeinsertinto()

nodeinsertafter()

nodejoin()

nodepoint()

nodebreak()

setname()

clearcontents()

createcopy()

createinstance()

switch_cppfunc(),switch_flexscript()... (all switch_... commands)

transfernode()

transfernodeobj()

moveobject()

setrank()

destroyobject()

destroynode()

Ignoring Undo

If you are inside of an aggregated undo and you want FlexSim to ignore a set of commands,
call beginignoreundo(), execute the commands, then call endignoreundo(). This is especially
useful in dropscripts of a user library. FlexSim automatically creates an aggregated undo
record that applies to all functionality executed as part a drag/drop operation from the
library icon grid, so all code that executes in a drop script is being recorded as part of
an undo record. To bypass this for certain functionality, surround it with beginignoreundo()
and endignoreundo()

Undo Tracking on a Custom Object's Drag

You may also want FlexSim to track changes to a custom object's variable value, or the
location, rotation and scale of an object that the custom object changes as it is dragged.
One example of this being used is in the Crane object in FlexSim's standard library. When
you drag on one of the Crane's sizers, there are actually several objects behind the scenes
that the Crane resizes as you drag. Also, the Crane has three variable values defining the
x, y, and z location of the Crane's frame that change as you drag the Crane to a different
position in the model. In order for undo functionality to work on the Crane, it must tell
FlexSim to track undo information on those objects that it is changing as the user
drags.

To add undo tracking to an object or number variable, call
applicationcommand("addundotracking", view, obj_or_variable). The Crane performs this as
part of its OnClick event, when the user clicks on the Crane.