I must be doing something really dumb. I’m setting a timer and I want to use an expression. If I use:
set theTimer to current application's NSTimer's scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(60, me, "timerExpired:", "Closing time", false)
all is well. However if I use and expression to convert a variable delay in minutes I get an error:
set theTimer to current application's NSTimer's scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_((minutes * 60), me, "timerExpired:", "Closing time", false)
I’ve tried to coerce it to number, or integer to get the data passed. I’m just learning this stuff, so I’m probably missing something really basic.
TIA
That error message is telling you the problem is in the method sound:didFinishPlaying:. Is your timer being set up in that method?
There’s no reason I can see that you can’t use (minutes * 60) as you have there…
Yes, sound_didFinishPlaying_ is my main state change handler. I play a sound in a handler in response to a start button. As each of several sounds completes from NSSound, sound_didFinishPlaying_ is called. Here is the full Applescript below. When I put a constant seconds timer in the NSTimer method, everything works fine. It is only when I try to calculate the seconds wait time that I get the error, thanks:
script rs_MedTAppDelegate
property parent : class "NSObject"
property meditationTime : 20
property callSound : "TibetanSakyaBell"
property timerSound : "SoftStruckTibetanSingingBowl"
property programState : 0
property idleState : 0
property callingState : 1
property startingState : 2
property timingState : 3
property ending1State : 4
property ending2State : 5
property ending3State : 6
property isIdle : true
property theTimer : missing value
property theSound : missing value
on applicationWillFinishLaunching_(aNotification)
-- Insert code here to initialize your application before any files are opened
end applicationWillFinishLaunching_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return current application's NSTerminateNow
end applicationShouldTerminate_
on startMeditation_(sender)
set my isIdle to false
set programState to callingState
tell current application's NSSound to set theSound to soundNamed_(callSound)
tell theSound
setDelegate_(me)
play()
end tell
end startMeditation_
on sound_didFinishPlaying_(someSound, theResult)
if theResult as boolean = true then
if programState = callingState then
set programState to startingState
log "Playing start sound: " & programState
tell current application's NSSound to set theSound to soundNamed_(timerSound)
tell theSound
setDelegate_(me)
play()
end tell
else if programState = startingState then
set programState to timingState
log "starting timer: " & programState
set secondsTimer to (meditationTime * 60)
set theTimer to current application's NSTimer's scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(secondsTimer, me, "timerExpired:", "Closing time", false)
else if programState = ending1State then
set programState to ending2State
log "Playing second end sound: " & programState
tell theSound
setDelegate_(me)
play()
end tell
else if programState = ending2State then
set programState to ending3State
log "Playing third end sound: " & programState
tell theSound
setDelegate_(me)
play()
end tell
else if programState = ending3State then
set programState to idleState
log "Finishing." & programState
set my isIdle to true
else
log "sound_didFinishPlaying_: Invalid state" & programState
set programState to idleState
set my isIdle to true
end if
else
display dialog "The sound was not played."
end if
end sound_didFinishPlaying_
on timerExpired_(someTimer)
if programState = timingState then
-- theSound should already be set from startingState
set programState to ending1State
tell theSound
setDelegate_(me)
play()
end tell
else
log "TimerExpired_: Invalid state " & programState
set programState to idleState
set my isIdle to true
end if
end timerExpired_
on resetTimer_(sender)
set programState to idleState
set my isIdle to true
try
tell theTimer to invalidate()
on error
-- just to catch bad timer?
end try
end resetTimer_
end script
And the |play| went away when I cut and pasted.
Is meditationTime involved in some binding? If so, my guess is that it’s becoming an NSNumber, and the error is in fact happening when you try to use it in an AS multiplication. Have you tried:
set secondsTimer to ((meditationTime as integer) * 60)
or:
set secondsTimer to ((meditationTime as real) * 60)
Yes meditationTime is bound to a text box in the main window. I had originally used the expression:
(meditationTime * 60) as integer
for the elapsed seconds argument and that didn’t work. But I tried your suggestion and that works! Wonderful!
I am very grateful for your help!
Model: MacBook Pro
Browser: Safari 537.31
Operating System: Mac OS X (10.8)