unstable idle handler - how to fix

I’ve created a basic panel of buttons with AppleScript studio (xcode using 10.3.9)
and I have also invoked the commands:

on idle theObject
– keep updating certain things
end idle

each button has a "on clicked theObject… if name of the object is “button 1” then… (etc)

all the buttons work fine whatever happens but the idle process will stop running if there is an error or
a process is invoked with one of the buttons that involves bringing up a “choose from list” or “display dialog” or “choose file”
(something that brings up another external window) Then I need to quit the program and run it again.

How can I keep the idle process chugging along in the event of errors and other things?

I know the answer may be quite complex and I’m happy to work with any small clues anyone might have,
or links to topics of this nature.

Thanks very much
Mark

You might try wrapping any code that could cause an error in a try statement, Mark. For further details, check out:

Appart from that, seems that the idle handler will work fine if you use the “attached to window blah” parameter. And also, you may look into substituting “choose from list” with a table view in a different IB-made window, and “choose file” with the studio-controls for save-panel and open-panel…

Thanks for suggestions, still no luck… I tried the open panel either attached to window or not. The open panel works but still gets an error and stops the idle process. Is it the idle handler that gets attached to the window? Not sure how to do that…

I can avoid seeing any errors by using try around the idle process, but the process still quits at open panel.

This is a simple script based on what I need to do - the window in IB obviously has on button called “choose” and a window called “display” - Note that the idle works initially, I have it hooked to File’s Owner and everything, it’s just that the idle process quits when the open panel command is hit - and I get a “NSReceiverEvaluationScriptError: 4 (1)” BTW - I seem to need the “on action” bit at the end, it does nothing but if I delete it from the script there’s an error. (?)

Thanks for any suggestions…
Mark


property curTime : 1
on idle theObject
	try
		tell window of theObject to set contents of text field "display" to curTime
		set curTime to curTime + 1
	end try
	return 1
end idle
on clicked theObject
	if name of theObject is "choose" then
		set var to display open panel
	end if
end clicked
on action theObject
	(*Add your script here.*)
end action

OK, I got it to work with “choose file” by setting a true/false variable inside the idle commands, that suspends idle activities while invoking choose file. Does not work with lists, but I can do that within the program.

Thanks for the help!
Mark

I also am having problems with an “on idle” handler.
I have a lengthy applescript (3700+ lines) within XCode 2.2, which - amongst other things - controls several Quicktime windows and the DVD player. I would like it to display in a separate window the video timecode, which a separate subroutine reads from either one of the QT windows, or from the DVD player.
To cut a long story short, it seemed to me that the best way to do this would be something like:

on idle theObject
global s_PlayPoint
GetMovieStats()
set contents of text field "PlayClock" of window "Timer" to s_PlayPoint
--Since I need the clock updated every second, I have a return value of '1'
return 1
end idle

However, this constantly - after a variable period of playback - results in the Applescript Error -1726, after which the Idle handler stops functioning. Even an empty handler:

on idle theObject
	(*Add your script here.*)
end idle

results in the -1726 error.

Has anyone experienced similar problems?
What am I doing wrong? Any suggested fix would be appreciated.

Many thanks,

PJWilson

Model: Intel iMac 20"
AppleScript: XCode 2.2
Browser: Safari 417.8
Operating System: Mac OS X (10.4)

I’m back again, with a partial reply to my own question!
It eventually occurred to me that the script would only report the Applescript Error -1726 if another part of the script was executing a ‘delay’ statement. These delays are necessary, for example between displaying a graphic, then hiding it.

I have since substituted the ‘delay’ commands for either:

do shell script "sleep " & (MySeconds) as string

or (and this is much more messy):

		set Time1 to current date
		repeat
			if (current date) is greater than (Time1 + MySeconds) then exit repeat
		end repeat

However, the ‘sleep’ command freezes all interaction with the application, and none of the buttons work.
Therefore, I need an alternative command to ‘delay’ which still allows interaction (hence the messy 2nd option).
I know there has to be a better way, but at the moment this is the best I know how.
Any improvements welcome.

What if you create a separate app (a simple applet) to execute the idle stuff? (and update the timer of the main app)

jj,
Thanks for the suggestion: it certainly seems like the way forward.
However, I am afraid my background is medical rather than programming, so would you be so kind as to explain in words of 1 syllable how I create a separate Applet that communicates with my XCode app?
I have managed to use an external Applet to ‘set contents of text field “PlayClock” of window “Timer” to NewString’

But how do I get the Applet to execute the ‘GetMovieStats’ XCode routine, and pass the variable s_PlayPoint back to the Applet?

Many thanks in advance for your wisdom.

If the “GetMovieStats” routine is used only in the “idle” routine, just move it within the “separate applet”. If “s_PlayPoint” is defined at some point of the “GetMovieStats” execution, just don’t declare it as a global property (if it isn’t used in the rest of the Xcode project). Just return it. Ie (pseudo-code):

on idle
	tell app "foo" to set contents of x to my GetMovieStats()
	return 1
end

to GetMovieStats()
	tell app "blah" to set s_PlayPoint to xxx
	return s_PlayPoint
end GetMovieStats

But I don’t know how you constructed your code, so I don’t know if you need “s_PlayPoint” to be shared accross the Xcode project or if it’s only needed to update the timer, etc. If you need it somewhere else, you could write it to an external file and read-write to it when needed. But it’s just a guess without knowing the code…