Using deactivate

I have created a tool that places components. Upon deactivation I call a method outside my tool that starts the process over(it opens a dialog to select a component to place).However on the second time around it skips over all my methods and jumps to starting the process all over again.

def initialize(component, rotateComponent, isSelect)
	@ip = Sketchup::InputPoint.new	
	@componentDefinition = component					
	@comp = nil	
	@isRotate = rotateComponent
	@rotation = 0			
	@rotateTransformation = nil	
	@openSelect = isSelect
end#def initialize


    def deactivate(view)
	view.invalidate
	self.clearComponent view
end#def deactivate

def clearComponent(view)
	model = view.model
	entities = model.active_entities
	
	if(@comp != nil)
		entities.erase_entities @comp
	end#if

	if(@openSelect == 1)
		@openSelect = nil
		MyModule::reopenSelection(1)
	else
		@openSelect = nil
		MyModule::reopenSelection(0)
	end#if

	model.abort_operation	
end#def clearComponent

To be more specific. The user opens a dialog window and selects which component they want to place in the scene. Once they select one, I create a tool to place:

 myTool = MyModule::PlaceTool.new(newComponent, rotateComponent, isSelect)

 Sketchup.active_model.select_tool(myTool)

Inside that tool upon deactivate I call clearComponent to stop the placing and then call to open the dialog window again. reopenSelection checks which dialog to open(1 or 0), then calls the initial method that started the entire process.

It is not clear why you re-select your tool in deactivate (which happens when the user wants to use another tool). This is not what the user expects how the application behaves and makes not necesssarily users happy.

By “all my methods” and “starting the process again” what do you mean, don’t you reselect your tool to start again? What is the exact procedure (what API methods do you use), and to what step does it jump?

When using object oriented programming and variables, you are dealing with application states. The more variables you have that can be accessed/changed at many places in your whole code base (and maybe even switch types), the more likely is it that your application can get into an inconsistent state (variables have values that should not occur in combination).

  • You switch the type of @openSelect between integer and nil. Although dynamic languages allow that, it is a design that leads to errors. Semantically you seem to want a Boolean flag (true/false) or an enumeration for a state machine.

  • You use control coupling in MyModule::reopenSelection(1). Better use two separate methods, one for each behavior.

FYI: Ruby should use 2 space indents, not 8 space tabs. (It looks ugly when posted in the forums and may cause unnecessary horizontal scrolling.).


BTW, Model#place_component can likely do all that you’re attempting to do. If the second “repeat” argument is false, the built-in rotation points can be used during the tool.