Adding InstanceObserver to each instance definition in Ruby

Hello :slight_smile:

I have trouble adding an observer per instance to get notified when the definition changes.(when the user double clicks on the instance and makes changes) I believe this would be onOpen and onClose. from the Class: Sketchup::InstanceObserver — SketchUp Ruby API Documentation

class MyExtSketchupDefObserver < Sketchup::DefinitionObserver
  def onComponentInstanceAdded(definition, instance)
    puts "onComponentInstanceAdded(#{definition}, #{instance})"
  end

  def onComponentInstanceRemoved(definition, instance)
    puts "onComponentInstanceRemoved(#{definition}, #{instance})"
  end
end

I have a class MyExtSketchupDefObserver < Sketchup::DefinitionObserver that works. I get a notification for copy paste (onComponentInstanceAdded) and delete (onComponentInstanceRemoved)

class MyExtSketchupInstanceObserver < Sketchup::InstanceObserver
  def onOpen(instance)
    puts "onOpen: #{instance}"
  end
  def onClose(instance)
    puts "onClose: #{instance}"
  end
end

I also have a class MyExtSketchupInstanceObserver < Sketchup::InstanceObserver defined but I do not get the onOpen or onClose.

This is how I add the observers:

 Sketchup.active_model.definitions.each { |d| 
 d.add_observer(MyExtSketchupDefObserver.new)
 d.instances.each { |inst| inst.add_observer(MyExtSketchupInstanceObserver.new)}

note: separately I am also using a Sketchup::EntitiesObserver and a Sketchup::DefinitionsObserver these don’t get notified for editing an instance.

Is there a way to track the changes on the component definition level?

The documentation mentions that the DefinitionObserver and InstanceObserver classes inherit #onChangeEntity from EntityObserver superclass. But since the SU2016 overhaul there are no longer empty callbacks to inherit.

Still this does mean that the SketchUp engine is supposed to call #onChangeEntity callbacks for these observers. So you should try adding this callback when you want to react to changes made to a definition or an instance. (Keep in mind that changes to a definition’s entities collection are notified via EntitiesObserver objects attached to the definition’s entities collection.)


P.S. - Also it is not necessary to create a separate observer instance for every object it is attached to, as often the collection object and the instance object reference are passed into the observer callbacks.

This means that usually a single observer instance per model can be used to watch collections and entities. The references for the various observers on a model can be kept inside the model observer instance object as instance variables.

A component/group might be changed without opening it. Solid Tools operations for instance. Many extensions will allow groups/components to be changed without opening them.

What are the high level task you are trying to do?

I would like to get notified when the instance/definition is changed. I can also do this on the layer level instead of per component. This might be easier to do? As long as the layer notifies me something has changed/added/removed on it I think it should be enough.

SketchUp Layers (aka Tags) do not have entities collections, so nothing is actually “on it”.
A layer assignment is a display property of an entity.

As said above, try using an #onChangeEntity callback method. The documentation indicates both types of observers should send change events to this callback (aka event handler.)

I did try these and unfortunately they do not fire

got it so that would not be an option I see… thanks