Listening to custom events from a Rhino plug-in in Grasshopper

event_handling

#1

I am curious as to what may be the best strategy for raising an event from a Rhino plug-in and listening for it in a Grasshopper component. The various native Rhino events work great, but I would like to know if anyone has recommendations for best practices when I use an event of my own creation (say, for example, I am passing the value of custom string DataKey from Rhino to Grasshopper).

I have created and am using a static class for this now, and it seems to work fine in nearly all cases, but I understand that this isn’t a threadsafe approach, and that there are almost certainly better solutions out there.


(David Rutten) #2

If you have a static class that both the rhino plugin and grasshopper component are able to access, why not have an actual event that both have access to as well? Or were you specifically asking how that is supposed to work in C#?


#3

Yes, I suppose that’s what I’m asking. Here’s how it looks now:

/// <summary>
/// Static class for raising events in user string modification
/// </summary>
public static class ModifyUserString
{
    public static EventHandler<ModifyUserStringEventArgs> OnModify;

    public static void RaiseEvent(string[] dataKey)
    {
        EventHandler<ModifyUserStringEventArgs> modifyEvent = OnModify;
        if (OnModify != null)
        {
            modifyEvent(null, new ModifyUserStringEventArgs(dataKey));
        }
    }
}

/// <summary>
/// Event args
/// </summary>
public class ModifyUserStringEventArgs : EventArgs
{
    private string[] _dataKey;
    
    public ModifyUserStringEventArgs(string[] dataKey)
    {
        _dataKey = dataKey;
    }

    public string[] DataKey
    {
        get { return _dataKey; }
    }
}

Then I add my handlers in the GH_Component to OnModify. This all works fine…I’m getting the keys in GH and expiring the components as I’d like to, but I am just wondering if there’s a better way since most of what I read tells me that static events are to be avoided when possible. Thanks!


(David Rutten) #4

No this is pretty good. There’s no risk of stuff getting overwritten in the middle of a read (which is what I thought you were worried about re. thread safety). My only quibble would be that the event should be called UserStringModified and the method which raises it OnUserStringModified. The class of course can be named something a bit more generic, as you may elect in the future to add more events.

If the event is raised from multiple threads, then your handler will also be invoked from multiple threads. Thus, if there’s a risk of threads overwriting data by other threads, your thread handling should go into the method which responds to the event. You can either use Concurrent collections to make sure stuff doesn’t go out of whack, or you can redirect all your calls into a single thread, thus insuring stuff happens consecutively, rather than simultaneously.


#5

Good to know…and thanks for help. I’ll be sure to implement your advice on the class setup too.