Flip Programming Guide

 

Using the Undo/Redo system

This chapter will describe how to set up and use an automatic undo/redo system with the Flip framework.

Overview

The Flip framework offers a complete automatic undo/redo system. Instead of maintaining one action class per user action, adding a name (or more generally metadatas) to a transaction is sufficient for the undo/redo system to work.

Each time the client manipulate the model, a transaction is made and record all the change to the models in some kind of simple assembler. This transaction which is also a program is then sent to the server. Because the transaction might need to be rollbacked, the program and its associated assembler were made to be reversible.

The undo/redo system use exactly this system. Because the programs can be read in whatever direction, undoing is just about reading the program backward.

More subtleties were added to the undo/redo system. In particular, it tries to autocorrect the program when it is being executed to try to avoid structural problems that would make the transaction being refused by the server.

Setting Up

The Flip framework offers a class, RootBase which automatically had the undo system to the root flip class. Instead of inheriting from flip::Object , the root class will inherit from flip::RootBase .

Doing so limits just offer a single name for the stored transactions, which is very likely to be exactly what you want. If you want more metadatas to be stored along a single transaction, you may study the flip::RootBase and visit the flip::Scribe reference for more informations.

The following listing illustrate how your root class Root should be declared.

class Root
:  public ohm::flip::RootBase // instead of ohm::flip::Object
{
};

At this point, the root Flip class will have a fully functionning undo/redo system.

Adding Metadata to a Transaction

The following listing illustrate the use of the undo/redo system in a tx_ prefixed model function.

void  MyClass::tx_set_value (float val)
{
   Root & root = get_ancestor <Root> ();
   _tx_session_guard.prepare_record (root.use_scribe ());   // 1.
   if (!_tx_session_guard.start ()) return;
   ext_set_value (val);
   root.set_scribe_metadata ("Change Value");               // 2.
   _tx_session_guard.commit ();
}
  1. Prepare the Scribe to record : it will check-in automatically to the document
  2. Set the metadata for the transaction. Here this is a string that will be displayed to the user

For the undo/redo system not to record a transaction, the line 1. and 2. above just need to be removed.

Invoking the Undo/Redo System

Invoking the undo/redo system is done through the RootBase class. The Scribe maintains a pile of undo and redo transaction. Those piles are handled automatically and as the user wants it.

The same similar function are available for redo .