Add to undoManager without performing?


#1

Is there any way to add an UndoableAction to the UndoManager without performing the action? In my case I am doing a heavy operation on a 3d mesh, but then for redo functionality(perform funciton) I just need to set the mesh to the stored copy. Right now there is an extra copy happening the first time. Beacause I do the operation, store the copy, then call UndoManager::perform which does another copy.


#2

No, there's no way to do that, but it sounds like the wrong way to solve the problem to me..

If the operation is very slow then it should probably be invoked as a normal undomanager operation but performed lazily on a thread or something?


#3

Hi Jules, I am not sure what you mean, here is more detail on what I am saying.  This is how I am adding to the the UndoManager, say "subdivide" is the heavy operation. On the line undoManager.perform , an unnecessary copy is being made.
 

 

    auto past = *mesh;
    mesh.subdivide(params); // this function is non const
    auto future = *mesh
    auto operation = new NTOperation<NTMesh>(move(past),move(future),mesh.get());
    undoManager.perform(operation, "Subdivide"); // this line does an unnecessary copy

 

and NTOperation looks like this. it stores copies of past and future ,and sets them to the current. On undo it sets current to past and on redo it sets current to future.

 

template <class T>
class NTOperation:public juce::UndoableAction {
public:
    NTOperation(const T&& past,const T&& future, T* current){
        mPast = std::move(past);
        mFuture = std::move(future);
        mCurrent = current;
    }

    virtual bool perform() override {
        *mCurrent = mFuture;
        return true;
    }

     virtual bool undo() override {
        *mCurrent = mPast;
        return true;
    }
private:
    T mFuture;
    T mPast;
    T* mCurrent;
};
    

 

Can you please explain how I would get rid of the copy extra copy? Are you saying just move the "subdivide" into the perform function? Wouldnt that be slow compared to just storing a copy of the future mesh? Thanks !

 

 

 


#4

I still don't quite understand your problem.. If you have lumps of data that are too large to copy around, then why not pass them by a reference-counted pointer or something? Certainly trying to hack around the way that undo actions are run sounds like a bad idea to me!


#5

Yeah I could use reference counted ptrs instead Thanks.  Just one question when add a juce::UndoableAction to an undomanager , you dont delete the juce::UndoableAction, because the undomanger takes owenership?


#6

Yes - I think that should be explained in the comments for the perform() method