On 20/01/2017 at 01:53, xxxxxxxx wrote:
User Information:
Cinema 4D Version: R18
Platform: Windows ;
Language(s) : C++ ;
---------
I am having trouble understanding the undo/redo stack. Have found quite some articles in the forum handling this topic, still I can't seem to wrap my head around it.
Well, let me clarify that. I understand the concept, I just can't seem to get how to deal with processing things when user presses undo/redo.
For instance, I have this MessageData plugin, where I listen to changes, resulting from user selecting polygons. Each time a different polygon is selected I perform an action.
However, when user presses undo or redo, I want to avoid performing the action, since this might internally add something onto the undo stack. This resulting in asymmetrical undo/redo steps (i.e 2 undos to get from state B to state A, and from state A I need 4 redos to get back to state B)
I understand that this asymmetrical undo/redo is the result of adding undos onto the stack while performing an undo. So, how to detect when the plugin is trigger while an undo-action is executed?
class TestMessageData : public MessageData
{
public:
virtual Bool CoreMessage(Int32 id, const BaseContainer &bc);
UInt32 mLastDirtyChecksum;
};
Bool TestMessageData::CoreMessage(Int32 id, const BaseContainer &bc)
{
// to detect if user has changed polygon selection we listen to EVMSG_CHANGE,
// and skip processing any other message
if (id != EVMSG_CHANGE)
return true;
BaseDocument* doc = GetActiveDocument();
if (!doc)
return true;
BaseObject* object = doc->GetActiveObject();
if (!object || !object->IsInstanceOf(Opolygon))
{
mLastDirtyChecksum = 0;
return true;
}
// !!! simplified detection of change of polygon selection !!!
UInt32 objectDirty = object->GetDirty(DIRTYFLAGS_SELECT);
if (mLastDirtyChecksum != objectDirty)
{
mLastDirtyChecksum = objectDirty;
// if 'undo' then bail out, else perform the action ...