TSE3 documentation | Version 0.3.1 | Index API Version Structure

# TSE3 Commands

The `TSE3::Cmd` namespace contains classes that implement a GoF Command pattern. You can use this in applications that use the TSE3 library to provide a command history with undo/redo facilities.

However, in order to use these classes there are a number of provisos that you must take care to note:

- The commands
  There is a `TSE3::Cmd` class for every useful operation on the `Song` data structure and it's subcomponents. There are not commands for alterations to the state of objects like `Transport` and `Metronome` since they are system wide settings, not `Song` alterations.
- The `CommandHistory` class
  The `CommandHistory` class holds the list of commands. For any operation, you create a `Command` object for it (with `new`), call `execute()` on the command, and then `add` it to the `CommandHistory` class. For now on you can call `undo` and `redo` on the `CommandHistory` to undo/redo the history of operations. Remember that your application will be kept up to date with the resulting changes to the `Song` through the `Notifier` interface mechanism.
- Multiple `Song`s
  If you support multiple `Song` objects in your application you can either use one `CommandHistory` class for all operations, or create a separate `CommandHistory` for each `Song`. It is this latter operation that is the most logical, and the `TSE3_Application::Application` class contains support for it.
- If you use commands, don't directly use the TSE3 API
  If you are using TSE3 Commands then any change to a `Song` or it's subcomponents must be done through commands. Otherwise, if the state of the `Song` changes between a command being `execute`d and `undo`ne unpredicatable results may occur.
- Writing your own commands
  If you implement your own commands that are creational or destrutional (if that is a word ;-) you must take care. If you, for example, create a new `Part` in `execute` you should not delete it in `undo` and then create a different `Part` in a subsequent call to `execute`. Why? If any subsequent commands act on that `Part` and take a `Part*` parameter to identify it, by deleting the `Part` and creating a new different one on a 'redo' you will cause the later command to be invalid.
  Creational patterns should create objects in the constructors, put them into the `Song` in undo, and delete the object in the destructor only if the object is deleted after having been undone.
  Destructional commands should merely remove the object in `execute` and put the same object back in in `undo`. The object may only be deleted in the destructor if the command has not been undone.

However, despite these provisos and the extra care that you must take when using the command pattern in your application, the benefits are great: the undo/redo facility is a really user-friendly useful facility that sets a good application appart from a great one.

© Pete Goodliffe, 2001-2003 | Copyright | Psalm 150