MyEntitiesObserver crashes SketchUp on mac!


#1

As the title says, I have the bad surprise to discover that MyEntitiesObserver crashes on mac while it works very well on pc.

Here is a simple example:

class MyEntitiesObserver < Sketchup::EntitiesObserver
  def onElementAdded(entities, entity)
    return unless entity.is_a?(Sketchup::ComponentInstance)
    entity.model.start_operation('add texture', true, false, true)
    $dc_observers.get_latest_class.redraw_with_undo(entity)
    entity.model.commit_operation
    entities.remove_observer(self)
  end
end
Sketchup.active_model.entities.add_observer(MyEntitiesObserver.new)

Just import a component with multiple nested entities to crash SketchUp on mac.

The bute is to redraw the next dynamic components inserted in SketchUp.

Is there another solution that MyEntitiesObserver that works on mac?

Thank you in advance for your help.

David


#2

The crashing is not specified in the API, so there is no “correct way” that it does not crash. The crash is likely an instability or bug in the macOS version of SketchUp.

In order to analyse what causes it (and what you can do to circumvent it), you need to decompose your code snippet into smaller steps (and comment/uncomment line by line) and retry.
I suspect that:

  • doing an operation within an observer callback (that could be triggered from within another operation) is highly risky. If this is the cause of the crash, you could “defer” it with a UI.start_timer(0, false).
  • undo within an operation (within an observer callback), like redraw_with_undo

Does it crash with anythin imported (simple, not nested component) or only nested ones?


#3

Two problems here.

  1. This is explicitly starting another undo operation inside yours. Operations cannot be nested.
    So you’d need to move this after your commit call.

  2. As the name of the receiver implies, the object is an observer that specifically watches dynamic components, has a set of observers which call that method to redraw instances when needed. That method creates a undo operation which might not play nice with other operations.
    So, you could try calling .redraw(entity) instead of .redraw_with_undo(entity),
    (as the latter just calls the former anyway.)


#4

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.