RhinoDoc.ReplaceRhinoObject event: detecting when multiple objects are moved at once

I’m writing a plugin using RhinoCommon that utilises a set of Rhino objects as ‘handles’ that the user can drag around to manipulate some data. To do this, I’m adding a handler for the RhinoDoc.ReplaceRhinoObject event and, when that fires, updating the backing data according to the object’s new location.

This works fine. However, I want different things to happen depending on whether the user is moving one single object at a time or multiple objects at once. In particular, I need to deal with updates to certain types of geometry before others when they are moved together (i.e. all points first, then all lines, etc.). However, when multiple objects are moved at once there does not seem to be any easy method to tell that this is the case from RhinoCommon - ReplaceRhinoObject just fires for each object one after the other and there seems to be no way to find out directly what other objects are also being moved as part of the same operation.

My current solution to this is to defer dealing with the update until all of those events have fired by, in the handling function, adding the RhinoReplaceObjectEventArgs to a ‘waiting list’ collection and starting/resetting a Timer. Once the timer has elapsed, then I process the waiting list and deal with the update of all the objects together. This works, but could potentially lead to some race conditions and has some unwanted side effects (because they happen after the viewport has already been redrawn, changes are not shown immediately, there seem to be some problems with undoing the movement, etc.) These may be fixable issues, but before I spend too much time trying to work around them I wanted to make sure there wasn’t a simpler approach I’m missing.

So, my question is: is there (or could there be) a better way of detecting and dealing with multiple objects being transformed at the same time? Or, alternately, is there a better way of figuring out when a Rhino operation (a drag, for example) has completed (without using the Timer)?

I think your current solution is what I would do as well. The only variable is the length of the timer, although you could maybe wait for the RhinoApp.Idle event to fire before handling the list of changes. This only fires after all moves have been completed, and all views have been redrawn.

To redraw the viewports after your changes, just call RhinoDoc.ActiveDoc.Views.RedrawViews() (which will fire the Idle event again, so take care :smile:)

Thanks Menno - RhinoApp.Idle looks like it’s pretty much what I wanted. I may just have to do a bit of testing on it to make sure it’s fired reliably.

It never failed me so far.