How to check existing observers?

My plugin is heavily based on observers, it perform calculation and geometry generation whenever a user changes (move/scale) an entity. when I was testing the code, it will all observers to the same entity every time I reload the code module.
QUESTION IS: is there a way to know how many observers does an entity have? and what r the observers already added?

typo, “it will all observers to the same entity every time I reload the code module.”
I mean : “it will add observers to the same entity every time I reload the code module.”

Is this thread in the right place? Should it be in Extensions?

Moving this to the Ruby API section.

I don’t think you can see if an observer is already attached. However, before attaching an observer you can first try to remove it to make sure it is only attached ones. This is a quite old workaround and when I think of it I’m not sure it is needed anymore, or if the API itself prevents the same observer object from being added twice.

Are you creating a new observer object each time your code tries to attach it or do you initialize the object once and re-use it? I think the latter is preferred to avoid duplications.

thank you for moving the post to the right place, and thank you for the answer.

yes, every time I reload my codes, a new instance of the modified observer will be created and loaded into an entity. I haven’t found a away to avoid the duplication, so every time I reload my codes, I have to open a saved model to make sure the entities don’t have any observers.

You can use an instance or class variable for the oberver object and then just attach the same observer object again and again like so:

@observer ||= MyObserver.new
entity.attach_observer(@observer)

In my code I typically also call remove_observer before attaching it, but I’m not sure this is actually needed. Much code in the community is quite old and has workarounds for problems in old SU versions.

2 Likes

With certain API objects you have to take the same carefulness like when you want to avoid memory leaks: When you reload a file, variables might be overwritten and you lose the reference to the already existing object, which makes it impossible to access or delete the old object.

Ensure that your extension and SketchUp are always in a proper, well-defined state (good if you know what a state machine is):

  • Add an observer at most once (either don’t add it again if already added, or remove the previous observer).
  • The extension/tool should shutdown properly when you deactivate it. It should remove all observers that it has added.
  • Think about what happens when a method raises an exception: the method is not completed! So you don’t know whether SketchUp is still in a well-defined state, whether the observer was added or not. Handle such cases with rescue blocks to clean up and remove the observer.
2 Likes

This is also what I do. I keep instance variable references to my observers, and if the observer is not nil, I call remove_observer before I call add_observer - making sure I don’t end up with duplicate callbacks.

1 Like