Error from Dynamic Components plugin, in drawing with NO DCs

dc
bug
dynamiccomponents
toolsobserver

#1

I’m getting this error message when debugging a Ruby script that isn’t a tool - it just draws programmatically given inputs via a UI.inputBox.

Error: #<NoMethodError: undefined method `length' for nil:NilClass>
/users/johnwmcc/library/application support/sketchup 2017/sketchup/plugins/su_dynamiccomponents/ruby/dcobservers.rbe:563:in `onToolStateChanged'

The line number can’t be from my script, which only has lines up to 300-odd.

As far as I know, my Dynamic Components plugin (for SU 2017) is up to date.

It seems to be happening when the script has made several components, and is trying to do place_component on the first one drawn.

Is this a bug in my code triggering it, or a bug in the DC Components plugin?

If the former, where should I look? Everything runs, and the three components I make are drawn, but the place_component doesn’t happen.

  # Add reference points
  ellipse_comp.entities.add_cpoint [0,0,0]
  floors_comp.entities.add_cpoint [0,0,0]
  floor_numbers_comp.entities.add_cpoint [0,0,0]
  if y_offset > 0.0
    ellipse_comp.entities.add_cpoint [0, y_offset, 0]
  end
#   ellipse_comp.entities.add_cpoint [0, a1 * slope1, a1]
#   ellipse_comp.entities.add_cpoint [0, a2 * slope2, a2]

  ellipse_comp.name = component_name

  # puts"About to add faces to mesh"
  ellipse_comp.entities.add_faces_from_mesh mesh


  mod.place_component ellipse_comp

PS. That’s the last line in my code.

I’ve temporarily disabled the DC plugin, which stops the error


#2

that’s my take on it…

the DC observers throw many errors on a mac, even when NO DC’s are in the active_model

I run with it ‘off’ most of the time and only enable it when using DC’s or plugins that use some of it’s methods…

ACT can also cause issues…

john


#3

what is/are ACTs?


#4

Advanced Camera Tools…

john


#5

As I remember, this feature causes several tool changes “under the bonnet”, and therefore will cause the firing of callbacks in ToolsObserver subclass instances.

First it will deactivate the current tool, causing a call to #onToolStateChanged().

Then it will activate either the ComponentTool (21013), or the ComponentCSTool (21126), causing a call to #onActiveToolChanged().

I think (test to be sure, if it matters,) the MoveTool might also get activated.

Anyway, as components were placed, there would be calls to #onToolStateChanged() especially if multiple instances were inserted (a true second argument.)

This all worked fine until the 2016M0 version that overhauled the observer engine.
From the Release Notes (2016): Observer Upgrades:

Observer events are now queued up until the active operation is done.

So, with repect to the ToolsObserver, all the events are dumped to watching observers afterward, making other things a coder once took for granted, now obsolete.

For example, previously a coder might rely upon the current selection holding the new component instance (as it is attached to the cursor during placement,) … but v2016+, by the time the observer callback fires, the selection may be empty.

This (or similar) is why we are seeing more NoMethodError exceptions with messages like “undefined method 'soforth' for nil:NilClass”.


It also means basically the ToolsObserver is now about worthless.


#6

Thanks for the very clear explanation, Dan.

for me at the moment, turning off the DC plugin and ACT is sufficient to let the rest of my code work or error through my own fault!


#7

This may be,… but you still trap the error with a rescue clause
in the block where you do the place_component.

Something like:

begin
  #
  # code that breaks Dynamic Components
  #
rescue NoMethodError => e
  source = e.backtrace[0]
  pathname = source.split(':').first
  if pathname != __FILE__
    file = File.basename(pathname,".*")
    if file != "dcobservers"
      # it may be one of your files
    end
  else
    # the error is in THIS file !
  end
end

#8

Many thanks. I will include that in future versions if necessary. For the moment, and for relatively temporary use, it’s probably enough just to turn off the DC plugin.