Object destruction?

In C++, an object is destroyed when it exits scope. If I create an object within a handler, and that the scope for that handler exits, is the object destroyed? Is there a secret “destructor” handler that I could implement on object destruction?

Specifically, I want to create an object that I can create within a handler, which will set my search rectangle, and when the handler exits (for whatever reason) the search rectangle is restored to its previous state. Can this be done?

Objects created in a handler will be destroyed when you exit the handler unless you specifically set them to have a global or universal scope (or you pass them back to the calling handler via a return statement.) However, the Search Rectangle is not an object property; it’s a global property (think of it more like an environment variable.) You’ll need to either reset the search rectangle before exiting the handler (just set it to empty) or set it on a command-by-command basis using the searchRectangle property:

Click (imageName:"myImage", searchRectangle:(200,200,350,524))

Thanks. Is there a handle that would be called on the object destruction (i.e. finalize, destroy, et cetera?)

I was thinking of writing a SRHelper script:

properties
	new_sr:fullscreen
	old_sr:fullscreen
end properties

to initialize
	if my new_sr is not fullscreen
		set my old_sr to GetOption(SearchRectangle)
		set the SearchRectangle to new_sr
	end if
end initialize

to finalize
	if my new_sr is not fullscreen
		set the SearchRectangle to old_sr
	end if
end finalize

I could declare at the beginning of my handler:

 put a new SRHelper with (new_sr:(0,0,100,100) ) into srh 

which would set the SearchRectangle when declared, and put it back when we’re done.

There is no finalize mechanism for SenseTalk objects, but I can see how it would be useful for a case like you’ve presented. We will consider adding a finalize call in the future, but it may not provide as clean a solution as you would like. The likely problem with such a mechanism would be that you would have no control over when it would be called. It might happen immediately upon exit from the handler (the most likely case in a simple scenario like yours) but there are a number of possible complications that might change the situation and lead to it being called later, or never, or more than once.

For now, you’ll need to reset the searchRectangle another way, although to be completely safe that may mean wrapping your code in a big try/catch block so you can reset it if an exception is thrown, etc. Your proposal is more elegant, but for now I’m afraid you’ll have to do it the hard way.

In lieu of using my destructor idea, I came up with an alternative solution, using a list as a stack of rectangles. I thought I’d share with the rest of the community:


(* SearchRect
 *
 * This Script will provide a push/pop interface for setting the SearchRectangle
 *
 *  usage:
 * 		SearchRect.push (x1,y1, x2,y2)
 *		... search for your image ...
 *		SearchRect.pop
 *
 *)

to SearchRect rect
	push rect
end SearchRect

to push rect
	global search_rect_stack

	if search_rect_stack is empty then set search_rect_stack to an empty list
	
	insert the SearchRectangle nested after search_rect_stack
	
	set the SearchRectangle to rect
end push

to pop
	global search_rect_stack
	
	if search_rect_stack is empty then
		set the SearchRectangle to fullscreen
	else
		set rect to the last item of search_rect_stack
		set the SearchRectangle to rect
		delete the last item of search_rect_stack
	end if

end pop

to reset
	global search_rect_stack

	set the SearchRectangle to fullscreen

	set search_rect_stack to an empty list
end reset

Thanks for sharing this.