class RuboCop::Cop::SketchupRequirements::ObserversStartOperation

Observers that perform model changes must create transparent operations to ensure the user can easily undo.

An important part of SketchUp's user experience is to be able to easily undo any modification to the model. This is important to prevent accidental loss of work.

If you for example have an observer that assigns a material to new faces then the user would still expect to undo this in a single operation.

To achieve this, set the fourth argument in `model.start_operation` to `true` in order to chain your observer operation to the previous operation.

@example

class ExampleObserver < Sketchup::EntitiesObserver
  def onElementAdded(entities, entity)
    return unless entity.valid?
    return unless entity.is_a?(Sketchup::Face)
    entity.model.start_operation('Paint Face', true, false, true)
    entity.material = 'red'
    entity.model.commit_operation
  end
end

Constants

MSG
OBSERVER_METHODS

Public Instance Methods

on_def(node) click to toggle source
# File lib/rubocop/sketchup/cop/requirements/observers_start_operation.rb, line 124
def on_def(node)
  return unless observer_event?(node)

  operations = start_operation(node)
  operations.each { |operation|
    _name, _disable_ui, _next_tr, transparent = operation.arguments
    next unless transparent.nil? || transparent.falsey_literal?

    location = operation_location(operation)
    add_offense(operation, location: location)
  }
end

Private Instance Methods

observer_event?(node) click to toggle source
# File lib/rubocop/sketchup/cop/requirements/observers_start_operation.rb, line 154
def observer_event?(node)
  OBSERVER_METHODS.include?(node.method_name)
end
operation_location(node) click to toggle source
# File lib/rubocop/sketchup/cop/requirements/observers_start_operation.rb, line 143
def operation_location(node)
  # Highlight the fourth argument if it's used. Fall back to the method
  # name.
  transparent_argument = node.arguments[3]
  if transparent_argument
    range(transparent_argument.loc.expression)
  else
    :selector
  end
end
range(node) click to toggle source
# File lib/rubocop/sketchup/cop/requirements/observers_start_operation.rb, line 139
def range(node)
  range_between(node.begin_pos, node.end_pos)
end