Loop through all instances of a class Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
lp230889
Posts: 16
Joined: 06 May 2016, 05:49

Loop through all instances of a class

25 May 2018, 19:10

Hi,

I tried using a class variable to set true via a button(Alarm.ResetAll := true), but i can only change it once then it remains false.
Is it possible to do something like this instead?

Thanks.

Code: Select all

;Example
Foreach instance in Alarm
{
   instance.ResetAll()
}

class Alarm
{
	ResetAll()
	{
		;Disable All Alarms
	}
}

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Loop through all instances of a class

25 May 2018, 19:35

not unless youre saving them in a collection upon instantiation, i dont think so

Code: Select all

Alarms := []
Alarms.Push(new Alarm())
Alarms.Push(new Alarm())
Alarms.Push(new Alarm())

for each, Alarm in Alarms
{
	Alarm.Reset()
}
gregster
Posts: 9000
Joined: 30 Sep 2013, 06:48

Re: Loop through all instances of a class  Topic is solved

25 May 2018, 21:30

I guess you could store the instances in a static variable and something like this (if I am understanding your question correctly):

Code: Select all

A1 := new Alarm(1, "active")
A2 := new Alarm(2, "active")
A3 := new Alarm(3, "active" )

A2.Reset()
for each, instance in Alarm.Alarmlist
	msgbox % instance.number " " instance.status		; check the statuses
Alarm.ResetAll()								; make all alarms inactive

for each, instance in Alarm.Alarmlist
	msgbox % instance.number " " instance.status		; check the statuses again
ExitApp
;------------------------------------------------
class Alarm
{
	Static Alarmlist := []

	__New(index, status){ 
		Alarm.Alarmlist.Push(this)
		this.number := index
		this.status := status
	}
	
	ResetAll(){
		;Disable All Alarms
		for each, instance in Alarm.Alarmlist
			instance.status := "inactive"
	}
	Reset(){
		this.status := "inactive"
	}

}
Edit: Of course, you could also have a Reset() method to reset specific (single) alarms... use this then (now included)
Last edited by gregster on 25 May 2018, 21:39, edited 3 times in total.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Loop through all instances of a class

25 May 2018, 21:35

- Just thought I'd mention that some of this information is visible when you do ListVars.
- So for a quick-and-dirty script you could grab the ListVars text and parse it, and put each pointer into the Object function, to then operate on the instance.
- To grab that information without displaying the window:
ScriptInfo(): Get ListLines/ListVars/ListHotkeys/KeyHistory text - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=9656

Code: Select all

;show object information in ListVars
oArray1 := ["a", "b", "c"]
oArray2 := new MyEmptyClass
ListVars
MsgBox
return

class MyEmptyClass
{
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
gregster
Posts: 9000
Joined: 30 Sep 2013, 06:48

Re: Loop through all instances of a class

25 May 2018, 21:50

I think, I prefer quick-and-clean in this case.

Of course, you could instead use a static associative array for more sophisticated alarm management (deletion etc.), if needed
lp230889
Posts: 16
Joined: 06 May 2016, 05:49

Re: Loop through all instances of a class

26 May 2018, 04:23

Thanks all ^
I'm calling aAlarm.Reset() bAlarm.Reset() etc atm.

I'll try another solution when i get round to it later.
Putting them in an array looks like the best solution for me.
I can just add them to the array while creating the alarms, then just do what a need with the array (If it works :D)
Thanks again.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Loop through all instances of a class

26 May 2018, 06:52

I agree with gregster's suggestion, but be aware that this creates circular references which might present problems when freeing objects.

You can add a method such as,

Code: Select all

clear(){
	Alarm.Alarmlist.delete(this)
}
; example
myAlarmInstance.clear()
In the example, this is not needed, consider this a note for future reference.

Cheers.

Edit:
gregster wrote:but I was lazy
:thumbup: cheers.
Last edited by Helgef on 26 May 2018, 07:07, edited 1 time in total.
gregster
Posts: 9000
Joined: 30 Sep 2013, 06:48

Re: Loop through all instances of a class

26 May 2018, 07:01

Helgef wrote:I agree with gregster's suggestion, but be aware that this creates circular references which might present problems when freeing objects.

You can add a method such as,

Code: Select all

clear(){
	Alarm.Alarmlist.delete(this)
}
; example
myAlarmInstance.clear()
In the example, this is not needed, consider this a note for future reference.

Cheers.
Thanks for pointing out. In the class I am working on at the moment, I actually solved it a bit differently than I suggested here, to prevent this :shh: Well, that's what happens when I post this early in the morning :yawn: I already thought if I should mention it... but I was lazy ;) .
lp230889
Posts: 16
Joined: 06 May 2016, 05:49

Re: Loop through all instances of a class

26 May 2018, 19:21

Thanks for the help! i got it working now.

Code: Select all


CreateAlarms()
{
	static aAlarm
	if (!IsObject(aAlarm))
	{
		aAlarm := new Alarm(a_sfx, 5)
	}

	static bAlarm
	if (!IsObject(bAlarm))
	{
		bAlarm := new Alarm(b_sfx, 10)
	}
}

ResetAlarms()
{
	;Works!!
	Alarm.ResetAll()
}

Class Alarm
{
	Static Alarmlist := []
	
	alarmSoundClip := ""
	alarmTriggerCount := 0
	alarmCounter := 0
	alarmTimer := 0
	alarmEndTime := 0
	
	__New(soundClip, triggerCount)
	{
		this.alarmSoundClip := soundClip
		this.alarmTriggerCount := triggerCount
		
		Alarm.Alarmlist.Push(this)
	}
	
	TripResetTimer(endTime)
	{
			this.alarmTimer := A_TickCount
			this.alarmEndTime := endTime
	}
	
	IncrimentCounter()
	{
		this.alarmCounter++
						
		;TripResetTimer has been activated
		if (this.alarmEndTime > 0)
			&& (A_TickCount - this.alarmTimer > this.alarmEndTime)
				&& (!this.Tripped())
		{
			this.Reset()
		}
	}
	
	Tripped()
	{
		if (this.alarmCounter >= this.alarmTriggerCount)
		{
			return true
		}
		else
		{
			return false
		}
	} 
	
	Reset()
	{
		this.alarmCounter := 0
		this.alarmTimer := A_TickCount
	}
	
	ResetAll()
	{
		for each, instance in Alarm.Alarmlist
		{
			instance.Reset()
		}
	}
	
	SoundAlarm()
	{
		if (CheckedBox("checkAlerts"))
		{ 
			;Fix Play Interval
			;static playIntStartTime := A_TickCount
			;static playIntEndTime := 500  ; < Only play every (ms)
			
			;if (A_TickCount - playIntStartTime > playIntEndTime ) 
			;{		
				SoundPlay, % this.alarmSoundClip
			;	playIntStartTime := A_TickCount
			;}
		}
	}
}



Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Joey5, mikeyww, RussF and 370 guests