UndoStateChange Eventhandler custom callback hang

Hi, I wrote custom component to try to ‘catch’ user activities by getting the undo stack. So what I’m trying to do now is to attach custom callback to record it.

In the main SolveInstance:
GH_Document ghDoc = this.OnPingDocument();
ghDoc.UndoStateChanged += CustomCallback;

void CustomCallback(Object sender, GH_DocUndoEventArgs e)
_ {_
_ Rhino.RhinoApp.WriteLine(“SENDER: " + sender.ToString());_
_ Rhino.RhinoApp.WriteLine(” name: " + e.Record.Name);_
_ Rhino.RhinoApp.WriteLine(" guid: " + e.Record.Guid.ToString());_
_ Rhino.RhinoApp.WriteLine(" time: " + e.Record.Time.ToString());_
_ Rhino.RhinoApp.WriteLine(" state: " + e.Record.State.ToString());_

_ this.OnPingDocument().UndoServer.PushUndoRecord(e.Record);_

However, this causes hang when any action is done on the canvas. If I try to move any object, it cannot be dropped (seems like it’s attached to mouse click). Adding ExpireSolution doesnt help either (I think it shouldn’t expire anyway?).

I feel that I might have to add more lines in the custom callback to ‘emulate’ normal procedure, however I am not too familiar with the workflow.

Kindly advice, and thanks in advance!

If you’re adding a new undo record from within the handler which is called whenever the undo stack changes, you end up in an endlessly repeating cycle of modifying the undo stack, responding to that change, and modifying it again.

Ah, ok. thank you for your reply. I understand after your explanation. However, it seems that GH_DocUndoEventArgs e is still empty when this custom callback is triggered, while I needed the changed information.

I assume from https://www.grasshopper3d.com/forum/topics/ins-and-outs-of-undo that the record isn’t created yet, hence it is empty. However, I need the information of the name, guid, time, and the changed value information. Is there a way I can get this information when a change is triggered?

Yeah something is very wrong here too. If I try to access the name of the undo record it starts messing with the UI. Looking deeper.

Not all events are associated with a specific record though. Whenever you push a new undo record, first the redo stack is wiped clean. This causes an event without an associated record.

See attached file for how to special case events with null records: undorecorder.gh (2.8 KB)

Ah, I see. That null catch is important. The script works well. Thank you David!