(my question is for a scripting component using c# , not a custom plug-in component developed via the grasshopper API)
My starting point was, to track changes of a clipping-Plane in the RhinoDocument.
This can by done via a ID/Guid Parameter set to the ClippingPlane.
But Grasshopper will not track this changes.
My (more general) question: if my c# script component subscribes:
RhinoDoc.ReplaceRhinoObject += OnReplaceObj;
where can i unsubscribe the Event, if the script is updated or unloaded / closed.
attached definition - each time you edit the script will register a new listener to the event.
When you update your script (e.g. adding a white-space in your source), the script will be recompiled and get a different component name. This means, you can’t unsubscribe it easily within the entire runtime of Rhino because you lost the reference. But it will stay in memory and cause very weird behaviour, at least if you are not aware of this.
A solution would be to store the handler reference somewhere in global accessible data store. In IronPython this is the Sticky dictionary. Not sure if you can add it there or exploit a similar store somewhere else. E.g. Userdata? You can then unsubscribe the handler before you subscribe a new one, or by another logic.
I remember not to find a good solution for this problem. So I simply created a custom plugin and prevented to perform event-handling on script components at all.
Edit:
added some Random “shortId” that will show the surviving, lost instances:
Command: _Drag
MyEventHandler.OnReplaceRhinoObject
MyEventHandler.OnReplaceRhinoObject
MyEventHandler.OnReplaceRhinoObject
MyEventHandler.OnReplaceRhinoObject
MyEventHandler.OnReplaceRhinoObject from 6053
MyEventHandler.OnReplaceRhinoObject from 1711
MyEventHandler.OnReplaceRhinoObject from 5156
the following seams to work.
I use Component.InstanceGuid as a key to store the latest / current instance of the Script_Instance in the Documents RuntimeData.
when the eventhandler runs, i check if the called instance still matches the latest one.
If not i unhook / unsubscribe the event - so this only happens once.
Yes I think this looks good. I think by the time I was writing complex scripts, there was no RuntimeData dictionary.
Still its a bit hard to understand what you are doing here, if you don’t know about the problems with event-handling in script components. Just in case you share the script to co-workers.
I still believe it would be better to not use event handling in scripts and rather think about a plugin solution. I think its dangerous if scripts alter the default intended behaviour of Grasshopper, because the “pipeline” is not designed to dynamically react to document changes.