The answer is likely to be that you use an observer similar to any other extension that you might have that watches the model for edit path changes.
The slight difference with Overlays is that your model observer should honor the toggle state of your extension’s overlay(s). To do this, when your extension instantiates the overlay for a model, pass a reference of the model into the overlay’s constructor and keep an
@model reference inside it.
Sidenote: I’ve asked for the API to set an internal model reference automatically when the overlay is attached to the model via
OverlaysManager#add, but it did not make it into the release. (Hoping for in the future.)
Now, I want to remind (or inform) here that generally the API’s various
#add_observer methods do not do any class checking and so do not enforce any particular coding pattern, ie subclassing versus singleton callbacks on a unique object, etc. All that is required is that any observer have publicly accessible observer callback methods.
This is why I most always use the extension submodule itself as the extension’s
AppObserver since there is only 1 application and therefore I don’t need multiple observer instance objects.
Likewise, I will often use a hybrid
ModelObserver that combines the callbacks for all the model’s collection observers as well. It makes it much easier. Ie, it is cumbersome to share data and state between separate model level observers.
The point I am getting at is that any object can serve as an observer without needing to be any particular subclass of any specific superclass. (This is because API observer superclasses are abstract and have no functionality, ie methods, to pass down to descendants.)
But the new
Overlay class is different because it does have necessary methods and functionality so the subclass paradigm is enforced.
So how to have an overlay and an observer that play well together ?
There is only 1 choice since the overlay pattern must be a subclass of
And that choice is to have your Overlay also be a
ModelObserver that has an
onActivePathChanged callback defined.
Then to honor the overlay toggle, you should attach the overly to the model as an observer in the overlay’s
start callback and detach it from the model in the overlay’s
# Overlay instantiated and added to OverlaysManager by AppObserver.
class ExampleOverlay < Sketchup::Overlay
def initialize(model = Sketchup.active_model)
@model = model
description = "A short sentence describing the overlay."
super('example_inc.my_overlay', 'Example Overlay', description: description)
### other overlay callbacks: draw(), onMouseMove(), etc ...
end # overlay class