Stop timer in class

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
tic
Posts: 92
Joined: 03 Nov 2014, 03:10

Stop timer in class

23 Feb 2016, 23:03

Hi all

How can you access the same instance of a timer in a class, in order to stop and delete it?
The following will start the timer, but can't stop it. I have tried all variations I can think of, including attempting to make the function object a class variable.

Code: Select all

#SingleInstance Force
#Persistent

myTimer1 := new MyTimer()
myTimer1.Play()
Sleep, 2000
myTimer.Stop()
return

class MyTimer
{
	count := 0
	
	Play()
	{
		fn := this._Play.Bind(this)
		SetTimer, % fn, 500
	}
	
	Stop()
	{
		fn := this._Play.Bind(this)
		SetTimer, % fn, Delete
	}
	
	_Play()
	{
		this.count++
		Tooltip % this.count
	}
}
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: Stop timer in class

24 Feb 2016, 00:28

The BoundFunc object you are creating within the Stop() method is a different object reference. To Update/Delete/Off/On/ an existing timer with a callable object as its routine, you must specify the same object reference. You should store it in a variable so that you can use it again when calling SetTimer.
Example:

Code: Select all

class Timer
{
	IsRunning := 0
	
	__New(target) ; target must be a callable object
	{
		this.Target := target
	}

	Start(period:="")
	{
		this.IsRunning := true
		this.Period := period
		SetTimer %this%, %period%
	}

	Stop(del:=false)
	{
		if (this.IsRunning) {
			SetTimer %this%, % del ? "Delete" : "Off"
			this.IsRunning := false
		}
	}

	Call()
	{
		if (this.Period < 0) ; Delete one-time timers
			this.Stop(true)
		this.Target.Call()
	}
}
Last edited by Coco on 24 Feb 2016, 00:47, edited 1 time in total.
tic
Posts: 92
Joined: 03 Nov 2014, 03:10

Re: Stop timer in class

24 Feb 2016, 00:47

This is still the same problem though. I don't want to provide the bound function to the class instantiation, and don't want to call _Call. I would like for the timer to call a method and stop that method that it decides upon. So this will work:

Code: Select all

#SingleInstance Force
#Persistent

t1 := new Timer()
t1.Start()
Sleep, 2000
t1.Stop()
return

class Timer
{
	Count := 0
	
	Start(period:=500)
	{
		this.Target := this._Start.Bind(this)
		SetTimer % this, % period
	}
	
	_Start()
	{
		this.Count++
		Tooltip, % this.Count
	}
 
	Stop()
	{
		SetTimer % this, Delete
	}
 
	Call()
	{
		this.Target.Call()
	}
}
but if I try to do

Code: Select all

		this.Target := this._Start.Bind(this)
		SetTimer % this.Target, % period
then it will tell me that the function doesn't exist, but if I do:

Code: Select all

		target := this._Start.Bind(this)
		SetTimer % target, % period
then it's fine with it.
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: Stop timer in class

24 Feb 2016, 00:49

Yeah, unfortunately to pass an object, the parameter must be either %object% or % object. Other expressions are not supported
tic
Posts: 92
Joined: 03 Nov 2014, 03:10

Re: Stop timer in class

24 Feb 2016, 00:53

Oof....Seems like a pretty bad "bug" (Kind of) if a class can't create a timer, and dispose of it, unless the class' only purpose is to be a timer
tic
Posts: 92
Joined: 03 Nov 2014, 03:10

Re: Stop timer in class

24 Feb 2016, 01:02

Ugly as hell, but you can get round the problem with ahk not liking the dot with:

Code: Select all

#SingleInstance Force
#Persistent

t1 := new MyTimer()
t1.Start()
Sleep, 3000
t1.Stop()
return

class MyTimer
{
	Count := 0
	
	Start(period:=500)
	{
		fn := this._Start.Bind(this)
		this.Timer := new MyTimer.Timer(fn, period)
		this.Timer.Start()
	}
	
	_Start()
	{
		this.Count++
		Tooltip, % this.Count
	}
 
	Stop()
	{
		this.Timer.Stop()
	}
 
	class Timer
	{
		__New(target, period)
		{
			this.Target := target
			this.Period := period
		}
		
		Start()
		{
			SetTimer, % this, % this.Period 
		}
		
		Stop()
		{
			SetTimer, % this, Delete
		}
		
		Call()
		{
			this.Target.Call()
		}
	}
}
lexikos
Posts: 9635
Joined: 30 Sep 2013, 04:07
Contact:

Re: Stop timer in class

24 Feb 2016, 02:56

tic wrote:Oof....Seems like a pretty bad "bug" (Kind of) if a class can't create a timer, and dispose of it, unless the class' only purpose is to be a timer
Huh? Any class or other code can create a timer and dispose of it. You only need to pass the same value to SetTimer both times. How else could it be done?
Ugly as hell, but you can get round the problem with ahk not liking the dot
Huh? Which part of that verbose script is the workaround? There's only a minor syntactic limitation, that SetTimer requires a variable (SetTimer % target, % period), not an expression (SetTimer % this.Target, % period). So just give it a variable. target := this.Target is a pretty simple workaround...

To be clear, the limitation is with the interpreter, not the SetTimer command.
tic
Posts: 92
Joined: 03 Nov 2014, 03:10

Re: Stop timer in class

24 Feb 2016, 03:04

Ah, I hadn't realized that

Code: Select all

target := this.Target
SetTimer, % target, % period
Would work. Thanks

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: arrondark, CoffeeChaton, ntepa and 92 guests