@Chuck
It's a small wrapper/library and assumes you know some OO-type AHK. Put it into your Lib directory. Usage example is below.
The $log, $dump, etc. are for my logger, you can safely delete them.
#Warn All
#Warn UseUnsetLocal, Off
#Warn LocalSameAsGlobal, Off
; #Include <cCuLogger>
class cScheduler {
/*
Helper class which automatically
- starts a timer at given frequency
- calls given callback functions for the time points 'Start', 'Update', 'Stop'
- calls 'ValidCondition' callback to determine whether the timer should continue or not
- IMPORTANT: if an exit_after (max runtime) is specified, the caller script's 'fn_stop()' will be called and script will exit via ExitApp!
It also has an ExitHandler() method which can be bound at the top of any script as
OnExit(ObjBindMethod(cScheduler, "ExitHandler"))
Sample call:
this.server_scheduler := new cScheduler({ check_freq : 1000
, exit_after : 5000
, fn_start : false
, fn_update : false
, fn_is_valid : ObjBindMethod(cMovieManager.oServer, "IsIdleTooLong")
, fn_stop : ObjBindMethod(cMovieManager.oServer, "Cleanup")
, fn_exit : ObjBindMethod(cMovieManager.oServer, "ExitHandler")
, auto_start : true })
OnExit(ObjBindMethod(this.server_scheduler, "ExitHandler"))
This class relies on the fact that it will be included by other classes,
thus A_ScriptHwnd will be set to the caller's handle.
*/
; __New(pInterval := 15000, pFNStart := false, pFNUpdate := false, pFNValidCondition := false, pFNStop := false, pAutoStart := true) {
__New(pParamsObj) {
; $dbg(A_ThisFunc, "Starting Scheduler", "handle: " A_ScriptHwnd ", pid: " (this._GetPID()))
this.timer := ObjBindMethod(this, "Tick")
this.interval := pParamsObj.check_freq > 0 ? pParamsObj.check_freq : 15000
this.exit_after := pParamsObj.exit_after > 0 ? pParamsObj.exit_after : 0
this.fn_start := IsObject(pParamsObj.fn_start) ? pParamsObj.fn_start : false
this.fn_update := IsObject(pParamsObj.fn_update) ? pParamsObj.fn_update : false
this.fn_is_valid := IsObject(pParamsObj.fn_is_valid) ? pParamsObj.fn_is_valid : false
this.fn_stop := IsObject(pParamsObj.fn_stop) ? pParamsObj.fn_stop : false
this.fn_exit := IsObject(pParamsObj.fn_exit) ? pParamsObj.fn_exit : false
this.auto_start := pParamsObj.auto_start ? true : false
if (this.auto_start) {
this.Start()
}
}
_GetPID() {
_prevDetectHiddenWindows := A_DetectHiddenWindows
_prevTitleMatchMode := A_TitleMatchMode
DetectHiddenWindows On
SetTitleMatchMode 2
WinGet, _pid, PID, ahk_id %A_ScriptHwnd%
DetectHiddenWindows %_prevDetectHiddenWindows%
SetTitleMatchMode %_prevTitleMatchMode%
return _pid
}
Start() {
; $verbose(A_ThisFunc)
this.cancelled := false
this.time_exceeded := false
this.start_ts := A_TickCount
timer := this.timer
if (IsObject(this.fn_start)) {
this.fn_start.call()
}
SetTimer % timer, % this.interval
}
IsTimerValid() {
; $verbose(A_ThisFunc)
if (IsObject(this.fn_is_valid) && !this.fn_is_valid.call()) {
; check for special key combos to abort the action, etc.
; $dbg(A_ThisFunc, "timer invalidated")
this.cancelled := true
return false
}
if (this.exit_after && (A_TickCount - this.start_ts) > this.exit_after) {
; check if max running time has been exceeded
; $dbg(A_ThisFunc, "timer exceeded max runtime: " this.exit_after)
this.time_exceeded := true
return false
}
return true
}
Update() {
; $verbose(A_ThisFunc)
if (IsObject(this.fn_update)) {
this.fn_update.call()
}
}
Stop() {
; $verbose(A_ThisFunc)
if (IsObject(this.fn_stop)) {
this.fn_stop.call()
}
}
Tick() {
; $verbose(A_ThisFunc)
if(!this.IsTimerValid()) {
this.Stop()
timer := this.timer
SetTimer % timer, Off
; note: unlike all other methods in this class, here we trigger ExitHandler() on behalf of the client
if (this.time_exceeded) {
this.ExitHandler()
}
} else {
this.Update()
}
}
SuspendHandler(pParams := false) {
; $verbose(A_ThisFunc)
Suspend
}
ReloadHandler(pParams := false) {
; $verbose(A_ThisFunc)
Reload
}
PauseHandler(pParams := false) {
; $verbose(A_ThisFunc)
Pause
}
ExitHandler(pParams := false) {
DetectHiddenWindows On
SetTitleMatchMode 2
WinGet, _pid, PID, ahk_id %A_ScriptHwnd%
; $dbg(A_ThisFunc, "Exiting Scheduler", "handle: " A_ScriptHwnd ", pid: " (this._GetPID()))
if (pParams.Length()) {
; $dump(pParams)
}
if (IsObject(this.fn_exit)) {
this.fn_exit.call()
}
ExitApp
}
}