Skip to end of metadata
Go to start of metadata

Classes:

 

IUndoManager (Code\Sandbox\EditorInterface\IUndoManager.h) Stores the list of undo commands and provides all operations needed for manipulation with this list. Currently there is only one instance that can be accessed via GetIEditor()->GetIUndoManager().
CUndo (Code\Sandbox\EditorInterface\IUndoObject.h) It's a helper class for easy use of the GetIEditor()->GetIUndoManager() instance.
IUndoObject (Code\Sandbox\EditorInterface\IUndoObject.h) Interface you have to implement for individual undo steps.

Please refer the CUndoVariableChange (Code\Sandbox\EditorQt\Controls\PropertyItem.cpp).

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 
class CUndoVariableChange : public IUndoObject
{
public:
    CUndoVariableChange(IVariable* var, const char* undoDescription)
    {
        // Stores the current state of this object.
        assert(var != 0);
        m_undoDescription = undoDescription;
        m_var = var;
        m_undo = m_var->Clone(false);
    }
protected:
    virtual int GetSize()
    {
        int size = sizeof(*this);
        //if (m_var)
        //size += m_var->GetSize();
        if (m_undo)
            size += m_undo->GetSize();
        if (m_redo)
            size += m_redo->GetSize();
        return size;
    }
    virtual const char* GetDescription() { return m_undoDescription; };
    virtual void        Undo(bool bUndo)
    {
        if (bUndo)
        {
            m_redo = m_var->Clone(false);
        }
        m_var->CopyValue(m_undo);
    }
    virtual void Redo()
    {
        if (m_redo)
            m_var->CopyValue(m_redo);
    }
private:
    CString              m_undoDescription;
    TSmartPtr<IVariable> m_undo;
    TSmartPtr<IVariable> m_redo;
    TSmartPtr<IVariable> m_var;
};

 

Important: when you implement your own IUndoObject the function IUndoObject::Undo(bool bUndo) takes boolean argument - every undo object needs to remember its original state and the new state, i.e. in case of implementation of the CUndoVariableChange it has TSmartPtr<IVariable> m_undo and TSmartPtr<IVariable> m_redo variables for storing the old and new state - the m_undo variable is filled by the current m_var data (that is before the m_var is modified) in the constructor of the CUndoVariableChange. The m_redo variable needs to be filled after the value was modified, so it's filled the first time the IUndoObject::Undo(bool bUndo) function is called - when it's first time called the bUndo is true, so now you fill the m_redo variable with the current m_var data (that is after the m_var is modified from outside).

Usage

To start the undo command recording, you have to first call function IUndoManager::Begin().
To record the undo step you have to call IUndoManager::RecordUndo(pMyCommand). You can call this function multiple times if you want to group more commands together.
To finish the recording you have to call IUndoManager::Accept("Desc") or IUndoManager::Cancel() if you want to discard the commands.
There is a helper class for all these functions CUndo that calls begin/accept/cancel in its constructor/destructor and also provides a function for the recording.

The typical usage looks like this:

 

 
1
2
3
4
 
CUndo undo("Group Objects");
 
if (CUndo::IsRecording())
    CUndo::Record(new CUndoGroupObjectOpenClose(pPrefabObj));

 

Events:

When the IUndoManager undo buffer is changed, it emits several events via IUndoManager::signalBufferChanged. See its usage in Code\Sandbox\EditorQt\Undo\CommandHistory.cpp.

  • No labels