1

Тема: AHK: Функция "Пауза" (замена команды sleep)

1::
s1 := A_TickCount
Pause(2000)
ToolTip, % A_TickCount - s1
Return

2::
s2 := A_TickCount
Pause(3000)
ToolTip, % A_TickCount - s2
Return

Pause(wait) {
	CurrentTimePC := A_TickCount
	While ((A_TickCount - CurrentTimePC) < wait)
		Continue
}

Для одного потока работает хорошо, например, в конструкции:

Loop
{
Pause(5000)
MsgBox, Я появился после паузы!
}
Return

При этом работают команды SetTimer, которые не засыпают как в случае с командой sleep. Даже если почему-то вызывать функцию сначала с большим значением в ее параметре, а следом поменьше, то тоже работает, но если наоборот - уже нет.

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

Попробовал через массивы, но как-то разбить не получается. А у вас какие идеи?

2

Re: AHK: Функция "Пауза" (замена команды sleep)

AutoHotKey - язык, который не поддерживает многопоточность. Сожалею

3 (изменено: stealzy, 2017-10-02 02:06:32)

Re: AHK: Функция "Пауза" (замена команды sleep)

Странникх пишет:

При этом работают команды SetTimer, которые не засыпают как в случае с командой sleep

#Persistent
SetTimer Test, -2000
Sleep 5000
ToolTip Sleep, 100, 200, 1
Return

Test() {
	ToolTip Timer, 200, 200, 2
}

Все ровно наоборот — таймеры работают во время Sleep, в отличии от циклов (не пытайтесь тестировать это с помощью MsgBox ввиду ограничений самого MsgBox).
Ваша ф-ия паузы использует цикл, а рабочий цикл в ahk возможен только один, предыдущий цикл останавливается на время работы последнего.

y:=0, x:=0

1::
	Loop {
		ToolTip % ++y, 200, 200, 1
		Sleep 500
	}

2::
	Loop {
		ToolTip % ++x, 100, 100, 2
		Sleep 500
	}
global x:=0, y:=0, i:=false, j:=false

1::
	i := !i
	SetTimer Loop_1, -1
	Return
2::
	j := !j
	SetTimer Loop_2, -1
	Return

Loop_1() {
	While i {
		ToolTip % ++x, 300, 200, 1
		Sleep 500
	}
}
Loop_2() {
	While j {
		ToolTip % ++y, 400, 200, 2
		Sleep 500
	}
}

Вопрос - зачем вам нужна эта странная функция Pause?

4 (изменено: Странникх, 2017-10-02 02:52:40)

Re: AHK: Функция "Пауза" (замена команды sleep)

stealzy, а если у нас конструкция бесконечного цикла и горячей клавиши.

Loop
{
ToolTip, Loop
sleep, 2000
}
Return

1::
ToolTip, 1
sleep, 1000
Return

Разве, указав и запустив оба sleep, они не влияют на друг друга - то есть не прибавляют задержки, не важно в каких частях кода они вставлены? Если влияют, тогда функция паузы разделяет и не суммирует их задержки и пригодится хотя бы в циклах.

Вот пример, они суммируются

SetTimer, Label, On
Loop
{
	s1 := A_TickCount
	sleep, 1000
	ToolTip, % A_TickCount - s1 " `n `n " A_TickCount - s2
}
Return

Label:
	s2 := A_TickCount
	sleep, 2000
	ToolTip, % A_TickCount - s1 " `n `n " A_TickCount - s2
Return

Хотя мой код с паузой я посмотрел тоже не помогает. Sleep и туда вползает, и в итоге увеличивает время в цикле Loop все равно. Видимо разбить на разные независимые задержки нельзя.

5 (изменено: teadrinker, 2017-10-02 19:42:21)

Re: AHK: Функция "Пауза" (замена команды sleep)

MyPause(delay)  {
   Thread, NoTimers
   Sleep, delay
   Thread, NoTimers, false
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

6 (изменено: stealzy, 2017-10-02 21:15:31)

Re: AHK: Функция "Пауза" (замена команды sleep)

Странникх, если вы еще не поняли код ahk исполняется не параллельно, поэтому Sleep будет суммироваться.
Вот я и предлагаю вам заменить цикл со Sleep на SetTimer, МеткаИлиФункцияПослеЗадержки, % "-" задержка_мс.

Странникх пишет:

а если у нас конструкция бесконечного цикла и горячей клавиши.

В вашем примере задержка по ГК бессмысленна, поскольку после нее сразу происходит возврат. Если же там предполагаются действия, то вы можете использовать SetTimer.
Если у вас только один поток крутит цикл и использует Sleep - проблем не будет, хотя и тут можно обойтись без.

teadrinker, если это был не сарказм, то ТС нужно ровно наоборот — пауза, во время которой исполняется код других "потоков" .
Вот только переписать SetTimer в виде ф-ии Pause() не получится, поскольку SetTimer должен явно указывать на лейбл или ф-ию, с которой начнется выполнение кода после задержки.

7

Re: AHK: Функция "Пауза" (замена команды sleep)

А, я не понял, значит.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

8 (изменено: Alectric, 2017-10-02 21:49:19)

Re: AHK: Функция "Пауза" (замена команды sleep)

start:=a_tickcount

Loop
{
  tooltip,% a_tickcount-start
  if Pause(10000)
    continue
  MsgBox, Я появился после паузы!
}
Return



Pause(t)
{
  static timer,oCT
  CycleTime:=a_tickcount-oCT
  oCT:=a_tickcount
  timer+=CycleTime
  if (timer<t)
    return 1
  else
    timer=0
  return 0
}
start:=a_tickcount

Loop
{
  CycleTime:=oldCycleTime!="" ? a_tickcount-oldCycleTime : 0
  oldCycleTime:=a_tickcount

  tooltip,% a_tickcount-start



  if (!PeriodicTimer:=PeriodicTimer>5000 ? 0 : PeriodicTimer="" ? 1 : PeriodicTimer+CycleTime)
  {
    MsgBox, Я появился после паузы!
  }



  if (!AnotherPeriodicTimer:=AnotherPeriodicTimer>17000 ? 0 : AnotherPeriodicTimer="" ? 1 : AnotherPeriodicTimer+CycleTime)
  {
    MsgBox, Я появился после другой паузы!
  }
}
Return
start:=a_tickcount

Loop
{
  CycleTime:=oldCycleTime!="" ? a_tickcount-oldCycleTime : 0
  oldCycleTime:=a_tickcount

  tooltip,% a_tickcount-start "`n" PeriodicTimer "`n" AnotherPeriodicTimer


  if dofirst
  if (!PeriodicTimer:=PeriodicTimer>5000 ? 0 : PeriodicTimer="" ? 1 : PeriodicTimer+CycleTime)
  {
    PeriodicTimer=
    dofirst=
    MsgBox, Я появился после паузы!
  }


  if dosecond
  if (!AnotherPeriodicTimer:=AnotherPeriodicTimer>17000 ? 0 : AnotherPeriodicTimer="" ? 1 : AnotherPeriodicTimer+CycleTime)
  {
    AnotherPeriodicTimer=
    dosecond=
    MsgBox, Я появился после другой паузы!
  }
}
Return


1::dofirst=1

2::dosecond=1

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

9

Re: AHK: Функция "Пауза" (замена команды sleep)

Nice try, but no. Замеры времени в вашей ф-ии в первом наброске производятся в цикле, а значит приходим опять же к ограничению на один действующий цикл.
Следующие два примера демонстрируют убегание от проблемы путем запихивания всего в один цикл.

10

Re: AHK: Функция "Пауза" (замена команды sleep)

stealzy пишет:

Странникх, если вы еще не поняли код ahk исполняется не параллельно, поэтому Sleep будет суммироваться.

Не параллельно, но действия из цикла Loop и SetTimer, например на кликер мышки, могут наложиться на друг друга.

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

Нужна пауза на строчку в блоке или в какой-либо части кода, подобно команде sleep, но не влиять глобально задержкой на скрипт.
Имеется в виду:


SetTimer, Timer, On
Loop
{
MouseMove, 10, 20
Pause(5000)
MouseMove, 10, 120
Pause(5000)
MouseMove, 10, 240
}
Return

Timer:
MouseMove, 10, 10
Pause(1000)
MouseMove, 20, 10
Pause(1000)
MouseMove, 30, 10
Return

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


o_Clicker := [ {key:L, x:10, y:10, count:1, speed:2}
			 , {key:L, x:20, y:10, count:1, speed:2}
			 , {key:L, x:30, y:10, count:1, speed:2}
			 , {key:L, x:40, y:10, count:1, speed:2}
			 , {key:L, x:50, y:10, count:1, speed:2}
			 , {key:L, x:60, y:10, count:1, speed:2}
			 , {key:L, x:70, y:10, count:1, speed:2}
			 , {key:L, x:80, y:10, count:1, speed:2}
			 , {key:L, x:90, y:10, count:1, speed:2}
			 , {key:L, x:100, y:10, count:1, speed:2}
			 , {key:L, x:110, y:10, count:1, speed:2}
			 , {key:L, x:120, y:10, count:1, speed:2}
			 , {key:L, x:130, y:10, count:1, speed:2} ]
Loop
{
MouseMove, 10, 20
sleep, 5000
MouseMove, 10, 120
sleep, 5000
MouseMove, 10, 240
sleep, 5000
}
Return
Clicker:
i_Clicker++
If (i_Clicker > o_Clicker.MaxIndex())
	i_Clicker = 1
MouseClick, % o_Clicker[i_Clicker].key, % o_Clicker[i_Clicker].x, % o_Clicker[i_Clicker].y, % o_Clicker[i_Clicker].count
Return

11 (изменено: stealzy, 2017-10-02 23:17:20)

Re: AHK: Функция "Пауза" (замена команды sleep)

Странникх, последняя попытка достучаться:

#Persistent
1Move:
MouseMove, 10, 20
SetTimer 2Move, -5000
Return

2Move:
MouseMove, 10, 120
SetTimer 3Move, -5000
Return

3Move:
MouseMove, 10, 240
SetTimer 1Move, -1
Return

12

Re: AHK: Функция "Пауза" (замена команды sleep)

stealzy, не понял, а что это иллюстрирует?

13

Re: AHK: Функция "Пауза" (замена команды sleep)

Это ваш цикл из предыдущего сообщения, переписанный так, что:

Странникх пишет:

подобно команде sleep, не влиять глобально задержкой на скрипт

14 (изменено: Ядрён, 2017-10-03 01:54:41)

Re: AHK: Функция "Пауза" (замена команды sleep)

Доброго времени суток . Подскажите пожалуйста как можно переделать этот скрипт со "sleep" на "Pause". А то получается скорость движения мыши теряется (в файле *.amc порядка 1750 строк ) после 15 секунды выполнения макроса. Файл *.amc это макрос от мышки X7. Подробное описание тут .

Arr := []


#SingleInstance force
#Persistent
#NoEnv
SendMode Input
SetBatchLines, -1
CoordMode,Mouse
#MaxHotkeysPerInterval
#HotkeyInterval, -1


*~vk5B::


FileSelectFile, SelectedFile, 24, , Загрузить макрос, *.amc
text := FileOpen(SelectedFile,"r").Read()


 While pEx := RegExMatch(text , "O)MoveR (?<x>-?\d+) (?<y>-?\d+)(?:`r`n)?Delay (?<Delay>-?\d+) ms", match, pEx ? pEx : 1) + StrLen(match.0)
 
	 Arr.Insert(match)


return




~vk79::  ; выход
Suspend, Off
ExitApp
return



~vk78::
Suspend, toggle
return



*~vk47:: ; G - 
 KeyWait, LButton
Suspend, On
KeyWait, LButton, D
 Suspend, Off
return

*~WheelDown::
on := 0
 return

*~vk51::  ; Q 
on := 0
return

*~WheelUp:: 
on := 1

Suspend, Off

	
#if on
	
*~LButton::
for i,k in Arr

	{



if !GetKeyState("LButton","p")

			Return

DllCall("mouse_event", Uint, 1, int, k.x, int, k.y)
Sleep, % k.Delay

}
Return
#if
OS: Win11x64, AutoHotkey v1.1.25.01 (Unicode 64-bit).