Undomanager performance


#1

In the undomanager the following is performed every time an action is performed.

while (nextIndex > 0 && getNumberOfUnitsTakenUpByStoredCommands() > maxNumUnitsToKeep && transactions.size() > minimumTransactionsToKeep) { transactions.remove (0); transactionNames.remove (0); --nextIndex; }

If you have a transaction made up of thousands of actions, and you are undoing the current transaction and redoing it every time the mouse moves, this can get really slow. So, now I only let the above code run if it is a new transaction. Do you see any problem with that?


#2

Not a bad idea. I guess even better than that would be if it kept a running total, so it wouldn’t have to recalculate it every time.


#3

G-Mon,

please could you paste the code you used? I think I may be getting slowed down by that in some mouse drags.

Thanks!

Bruce


#4

Ok

[code]bool UndoManager::perform (UndoableAction* const command, const String& actionName)
{
if (command != 0)
{
if (actionName.isNotEmpty())
currentTransactionName = actionName;

    if (reentrancyCheck)
    {
        jassertfalse    // don't call perform() recursively from the UndoableAction::perform() or
                        // undo() methods, or else these actions won't actually get done.

        return false;
    }
    else
    {
        bool success = false;
		bool wasNew  = newTransaction;

        JUCE_TRY
        {
            success = command->perform();
        }
        JUCE_CATCH_EXCEPTION

        jassert (success);
        if (success)
        {
            if (nextIndex > 0 && ! newTransaction)
            {
                OwnedArray<UndoableAction>* commandSet = transactions [nextIndex - 1];

                jassert (commandSet != 0);
                if (commandSet == 0)
                    return false;

                commandSet->add (command);
            }
            else
            {
                OwnedArray<UndoableAction>* commandSet = new OwnedArray<UndoableAction>();
                commandSet->add (command);
                transactions.insert (nextIndex, commandSet);
                transactionNames.insert (nextIndex, currentTransactionName);
                ++nextIndex;
            }

            newTransaction = false;
        }

        while (nextIndex < transactions.size())
        {
            transactions.removeLast();
            transactionNames.remove (transactionNames.size() - 1);
        }

		if (wasNew)
		{
			while (nextIndex > 0
				&& getNumberOfUnitsTakenUpByStoredCommands() > maxNumUnitsToKeep
				&& transactions.size() > minimumTransactionsToKeep)
			{
				transactions.remove (0);
				transactionNames.remove (0);
				--nextIndex;
			}
		}

        sendChangeMessage (this);

        return success;
    }
}

return false;

}[/code]


#5