1 (изменено: Botsy, 2020-09-30 17:05:03)

Тема: AHK: несколько SetTimer

Есть скрипт с несколькими таймерами:


F10::

SetTimer, Rabbit, 120000
SetTimer, Lion, 60000
SetTimer, Bear, 30000

Rabbit:
console.log("Кроль")

Lion:
console.log("Лев")

Bear:
console.log("Мишка")

Loop
{
.....
}
return

Сейчас работает ровно так, как написано:
- При выполнении Rabbit, выполняются он, два других таймера и потом Loop.
- При выполнении Lion, выполняется он, Bear и потом Loop.
- При выполнении Bear, выполняется он и потом Loop.

А можно ли сделать так, чтобы при выполнении таймера Rabbit, остальные таймеры не выполнялись, если не пришло их время ?
То есть:
- При выполнении Rabbit, выполняются он, и потом Loop. (если не пришло время других таймеров)
- При выполнении Lion, выполняется он, и потом Loop. (если не пришло время других таймеров)
- При выполнении Bear, выполняется он и потом Loop.

2 (изменено: qqlexa, 2020-09-30 17:23:56)

Re: AHK: несколько SetTimer

Думаю могут пригодится знания в следующих операторах:
https://www.autohotkey.com/docs/commands/Gosub.htm?
https://www.autohotkey.com/docs/commands/Goto.htm
https://www.autohotkey.com/docs/commands/Return.htm


F10::

SetTimer, Rabbit, 120000
SetTimer, Lion, 60000
SetTimer, Bear, 30000
return

Rabbit:
console.log("Кроль")
goto, Bat                   ; переход на метку Bat

Lion:
console.log("Лев")
goto, Bat                     ; переход на метку Bat


Bear:
console.log("Мишка")
                              ; переход на метку Bat, без оператора goto
Bat:
Loop
{
.....
}
return

3

Re: AHK: несколько SetTimer

qqlexa я пробовал через эти команды, но у меня тогда не получилось. А почему вы команду return подняли вверх к таймерам ?

4

Re: AHK: несколько SetTimer

Botsy, нам нужно остановить поток же, верно? Если не остановить, после нажатия на F10 мы пройдем все метки.

5

Re: AHK: несколько SetTimer

Botsy, лучшей практикой будет использование функции, ведь у вас меняются только аргументы "Кроль", "Лев" и "Мишка".

6

Re: AHK: несколько SetTimer

Сейчас попробую с return после таймеров.

лучшей практикой будет использование функции, ведь у вас меняются только аргументы "Кроль", "Лев" и "Мишка".

не совсем понял о чем речь

7

Re: AHK: несколько SetTimer


F1::
print("Bat")
print("Lion")
print("Bear")
return

print(message){
	msgbox, % message
}

8

Re: AHK: несколько SetTimer

qqlexa аа, это я для удобства чтения убрал в скрипте все лишнее, оставив только текст для наглядности. Возможно и можно использовать ф-цию в моем случаем, но не думаю что у меня получится ее реализовать.

qqlexa пишет:

Botsy, нам нужно остановить поток же, верно? Если не остановить, после нажатия на F10 мы пройдем все метки.

Если добавить return после таймеров, скрипт работать не будет. Поток останавливается и на этом выполнение скрипта тоже.
Без return, таймер действительно пропускает не нужные метки и переходит к циклу, но есть одно "но":
- скрипт так же пропускает срабатывание таймеров, в нужные сроки. Каждые два "льва", должен срабатывать один "кроль". Так как там по времени 1 минута и 2 минуты. Но когда срабатывает "кроль", он просто пропускает "льва" и идет к циклу, хотя время же пришло и для "льва".
- при запуске, должны же сработать все таймеры и пойти отсчет. А сейчас срабатывает только первый, в принципе это аналогично первому пункту.

9 (изменено: stealzy, 2020-10-01 02:09:34)

Re: AHK: несколько SetTimer

Botsy, в конкретный момент времени исполняется один конкретный цикл.
А у вас что? После первого же таймера запустился бесконечный (Или нет? Где код самого цикла?) цикл, и каждый следующий таймер открывает новый. А прежний цикл кто будет завершать? Ведь программа таймера не может завершиться после входа в цикл, а значит следующее выполнение откладывается.

Можно лишь вам указать на логические ошибки — попытки повторно войти в исполняющийся цикл и подпрограмма таймера, исполняющаяся дольше периода таймера.
А помочь, не зная логики кода в цикле (который вы не привели) — нельзя.

0xFFFFFF
0xFF0000
0xFFFFFF

10

Re: AHK: несколько SetTimer


SetTimer, Rabbit, 120000
SetTimer, Lion, 60000
SetTimer, Bear, 30000

Rabbit:
	console.log("Кроль")
	SetTimer, Loop, -1
	return
	
Lion:
	console.log("Лев")
	SetTimer, Loop, -1
	return

Bear:
	console.log("Мишка")
	SetTimer, Loop, -1
	return

Loop:
	Loop
	{
	.....
	}
	return
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v2004, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

11 (изменено: Botsy, 2020-10-26 20:23:17)

Re: AHK: несколько SetTimer

stealzy Выкладывать цикл на 2000+ строк - не думаю что кто-то вообще будет разбираться в тех дебрях, что там написаны. Важно что цикл бесконечный, не так ли ? Я выкинул все лишнее на мой взгляд, и оставил скелет в приведенном выше примере.

А прежний цикл кто будет завершать? Ведь программа таймера не может завершиться после входа в цикл, а значит следующее выполнение откладывается.

Вроде таймер и завершает цикл по его истечению ? Ведь когда выполняется цикл и истекает время, запускается таймер и начинается цикл по новой, а не продолжается в том же месте, на котором он прервался.

serzh82saratov у вас получается:
- таймер Rabbit, запускается каждые 120000мс. Он запускает таймер Loop, один раз, мгновенно.
- аналогично для таймеров Lion и Bear, 60000 и 30000 соответственно.
- т.к. цикл бесконечный, то команды "return" в таймерах Rabbit, Lion, Bear никогда не наступят.
- цикл будет выполняться до ближайшего таймера.

Правильно понял написанное ?

12

Re: AHK: несколько SetTimer

Botsy пишет:

Он запускает таймер Loop, один раз, мгновенно.

Не один раз, а каждые 120000мс.

Botsy пишет:

- т.к. цикл бесконечный, то команды "return" в таймерах Rabbit, Lion, Bear никогда не наступят.

Нет, наступают сразу.
Если цикл бесконечный, зачем вы его несколько раз запускаете.
Каждый таймер, будет прерывать выполняемый цикл, и запускать его в новом потоке, это будет есть память.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v2004, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

13 (изменено: Botsy, 2020-10-26 20:22:54)

Re: AHK: несколько SetTimer

serzh82saratov пишет:

Не один раз, а каждые 120000мс.

Разве эта строчка "SetTimer, Loop, -1" не означает перейти к метке Loop, один раз, мгновенно ?

14

Re: AHK: несколько SetTimer

Означает, но я говорил про логику всего сценария.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v2004, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

15 (изменено: Botsy, 2020-10-26 19:14:10)

Re: AHK: несколько SetTimer

serzh82saratov пишет:

Означает, но я говорил про логику всего сценария.

Так и понял, прост уточнил. Проверил предложенный вами способ, остались те же проблемы, как и при помощи 2-ого поста в этой теме от "qqlexa".
"- скрипт так же пропускает срабатывание таймеров, в нужные сроки. Каждые два "льва", должен срабатывать один "кроль". Так как там по времени 1 минута и 2 минуты. Но когда срабатывает "кроль", он просто пропускает "льва" и идет к циклу, хотя время же пришло и для "льва".
- при запуске, должны же сработать все таймеры и пойти отсчет. А сейчас срабатывает только первый, в принципе это аналогично первому пункту."

Возможно это из-за отсутствия мультипоточности в AHK.

16

Re: AHK: несколько SetTimer

Да, я ошибся в теории, даже так происходит не более 10 прерываний цикла.
Значит перед запуском того же цикла, надо его предварительно завершать.


SetTimer, Rabbit, 1000
SetTimer, Lion, 2000
SetTimer, Bear, 4000
return

Rabbit:
	log("Кроль")
	f := Func("Loop").Bind(A_TickCount)
	SetTimer, % f, -10 
	return
	
Lion:
	log("Лев")
	f := Func("Loop").Bind(A_TickCount)
	SetTimer, % f, -10 
	return

Bear:
	log("Мишка")
	f := Func("Loop").Bind(A_TickCount)
	SetTimer, % f, -10 
	return

Loop() {
	Loop
	{
		ToolTip % A_Index
		Sleep 10
	}
	return
}

log(txt) {
	Static list 
	list .= txt "`n" 
	ToolTip % list, 2, 2, 2
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v2004, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

17 (изменено: Botsy, 2020-10-01 18:20:30)

Re: AHK: несколько SetTimer

serzh82saratov

f := Func("Loop").Bind(A_TickCount)

а зачем передавать в функцию цикла, переменную A_TickCount ?
сейчас выдает такой результат : https://i.ibb.co/4FMST0c/Timer.jpg

Мишка просто зацикливается и больше другие таймеры не работают. Меняя Sleep в цикле, меняется и зависающий log(txt)

18

Re: AHK: несколько SetTimer

Замените на это, зависать не будет.
Видимо ограничение на кол-во прерванных потоков одной процедуры, знающие скажут точнее.
Циклы надо завершать до их повторного вызова.


Loop() {
	Loop 1
	{
		ToolTip % A_Index
		Sleep 10
	}
	return
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v2004, AutoHotkey_L v1.1.33.02 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

19

Re: AHK: несколько SetTimer

Ситуация проясняется, после срабатывания таймера выполнение цикла должно прерваться и перейти в начало цикла.

Botsy пишет:

Вроде таймер и завершает цикл по его истечению ? Ведь когда выполняется цикл и истекает время, запускается таймер и начинается цикл по новой, а не продолжается в том же месте, на котором он прервался.

Нет, таймер после завершения своей подпрограммы передает исполнение назад в место, где он прервал поток выполнения.

А цикл нужно прерывать. Это можно сделать либо изнутри цикла, проверяя в нем условие выхода, либо снаружи, прерывая сам процесс AutoHotkey.exe.
Поскольку нужно сохранять состояния таймеров, в вашем случае сподручнее будет изнутри:

i := 0
F10::
	SetTimer Кроль, 12000
	SetTimer Лев, 6000
	SetTimer Мишка, 3000

	Loop {
		Sleep 1000
		If timer {
			timer := ""
			Continue
		}
		++i
		Tooltip % log "`n" i
	}
Return

Кроль:
Лев:
Мишка:
	timer := A_ThisLabel
	log .= timer " " ; console.log(timer)
Return
0xFFFFFF
0xFF0000
0xFFFFFF

20 (изменено: Botsy, 2020-10-26 19:15:22)

Re: AHK: несколько SetTimer

stealzy Реально работает, еще не понимаю почему, но работает .

21

Re: AHK: несколько SetTimer

stealzy а если у каждого таймера есть свои действия в подпрограмме ? Например не только вывести лог, но и что-то еще, пусть будет Send.

Типо у "Кроль" будет Send 1, у "Лев" Send 2, и т.д.


Кроль:
send 1
sleep, 1000

Лев:
send 2
sleep, 1000

Мишка:
send 3
sleep, 1000

	timer := A_ThisLabel
	log .= timer " " ; console.log(timer)
Return

В таком случае, мы вернемся к тому, с чего начинали:
- При выполнении Rabbit, выполняются он, два других таймера и потом Loop.
- При выполнении Lion, выполняется он, Bear и потом Loop.
- При выполнении Bear, выполняется он и потом Loop.

22

Re: AHK: несколько SetTimer


F10::
SetTimer, Rabbit, 12000
SetTimer, Lion, 6000
SetTimer, Bear, 3000

Loop
{
  tooltip,% a_index "`n" text,,0
  sleep,1000
}

Rabbit:
  text.="Кроль`n"
return

Lion:
  text.="Лев`n"
return

Bear:
  text.="Мишка`n"
return


esc::exitapp
Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

23

Re: AHK: несколько SetTimer

Alectric супер.

Спасибо всем за помощь.

24

Re: AHK: несколько SetTimer

А подскажите, как использовать команду Thread, NoTimers ? Задача выполнять одну функцию, что бы таймеры ее не прерывали. Или они на паузу становились во время выполнения этой функции или как-то еще, главное не прерывать выполнение функции.
В данном примере, добавил эту команду перед функцией и эту же команду после функции с параметром "false". Это правильно?


F10::
SetTimer, Rabbit, 12000
SetTimer, Lion, 6000
SetTimer, Bear, 3000

Loop
{
...
}

Rabbit:
  Send 1
return

Lion:
  Send 2
return

Bear:
Thread, NoTimers
func()
Thread, NoTimers, False
return

25

Re: AHK: несколько SetTimer

А зачем вы спрашиваете, если можете это проверить, запустив код?

0xFFFFFF
0xFF0000
0xFFFFFF

26 (изменено: Botsy, 2020-10-26 19:17:03)

Re: AHK: несколько SetTimer

stealzy пишет:

А зачем вы спрашиваете, если можете это проверить, запустив код?

Как и в начале этой темы, код у меня работал, но не факт что правильно. Так, например с таймерами, мне изменили структуру на более "правильную".