Cocoa-AppleScript idle handler

Hi,

Is there an equivalent to an AppleScript idle handler in a Cocoa-AppleScript application?

Thanks,
kel

You can use a timer, or performSelector_withObject_afterDelay_. There’s an example in my book:

Hi Shane,

I didn’t want to use a repeat loop, so I’ll look up the performSelector. I searched for nsselector, but it’s not in the developer site… Lately, I’ve seen a lot of selector stuff. Maybe I’m reaching the second level! :expressionless: Nah.

Thanks,
kel

A selector is more-or-less the name of a method, using colons rather than underscores. So in this case using “fauxIdle:” means call a handler “on fauxIdle_(someArgument)”.

I hope I don’t obfuscate. :slight_smile:

The name selector comes from Smalltalk, and is short for message selector. It pretty much means the datatype, or entity message. But it isn’t any concrete message, it is any message, free for you to specify, but it is your responsibility, to assure that it is convenient to use in the context you are using it.

A protocol consists of 1 or more selectors. A class definition contains methods, that are later used as messages and selectors upon the class object, or the instantaniated object.

Hi,

Got it working and the application uses 0% cpu from the idle and no repeat loop like you need with timers.

Edited: found the performSelector method under NSObject class reference (for any other beginners).

Thanks a lot,
kel

FYI, timers don’t need a repeat loop either. In fact, performSelector_withObject_afterDelay_ uses a timer to do its stuff.

Hi Shane,

I see now. I thought the run loop was a repeat loop.

Thanks,
kel

Hi Shane,

Thanks for the info on the timers. I found the repeating one and somehow got it to work. :slight_smile: Now I have two idle handlers in one run loop.

script AppDelegate
	property parent : class "NSObject"
    property myTimer1: missing value
    property myTimer2: missing value
    property theIncrement: 0
	
	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened
	end applicationWillFinishLaunching_
    
    on applicationDidFinishLaunching_(aNotification)
        -- main code
        set myTimer1 to current application's NSTimer's scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(5,me,"doSomething1:",missing value,true)
        set myTimer2 to current application's NSTimer's scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(15,me,"doSomething2:",missing value,true)
        say "The timers are starting."
        return
    end applicationDidFinishLaunching_
	
    on doSomething1_(aArgument)
        beep 1
        return
    end doSomething1_
    
    on doSomething2_(aArgument)
        set theIncrement to theIncrement + 1
        display dialog theIncrement
        if theIncrement is 3 then
            quit
        end if
        return
    end doSomething2_
    
	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits
        myTimer1's invalidate()
        myTimer2's invalidate()
		return current application's NSTerminateNow
	end applicationShouldTerminate_
	
end script

Hope there isn’t anything wrong with doing this.

Edited: although it has just a little more cpu usage.

Thanks a lot,
kel

Added try block to the example, so the user can quit:

script AppDelegate
	property parent : class "NSObject"
    property myTimer1: missing value
    property myTimer2: missing value
    property theIncrement: 0
	
	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened
	end applicationWillFinishLaunching_
    
    on applicationDidFinishLaunching_(aNotification)
        -- main code
        set myTimer1 to current application's NSTimer's scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(5,me,"doSomething1:",missing value,true)
        set myTimer2 to current application's NSTimer's scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(15,me,"doSomething2:",missing value,true)
        say "The timers are starting."
        return
    end applicationDidFinishLaunching_
	
    on doSomething1_(aTimer)
        beep 1
        return
    end doSomething1_
    
    on doSomething2_(aTimer)
        set theIncrement to theIncrement + 1
        try
            display dialog theIncrement
            if theIncrement = 3 then
                quit
            end if
        on error -- user canceled
            quit
        end try
        return
    end doSomething2_
    
	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits
        myTimer1's invalidate()
        myTimer2's invalidate()
		return current application's NSTerminateNow
	end applicationShouldTerminate_
	
end script

Edited: had to change the names of the argument to timer.