1 (изменено: Malcev, 2012-04-03 17:48:32)

Тема: AHK: При повторном нажатии кнопки прервать задержку

Имеется следующий код


#MaxThreadsPerHotkey 5
PgDn::
ErrorLevel := 0
n := 1
k := 1
t := 590
while((!ErrorLevel)&&(n<=10)&&(k=1))
{
   ImageSearch, x%n%, y%n%, 410, t, 600, 1050, D:\Abola\video1.png
   t := y%n% + 10
   n++
}
k++
Send, ^!1^!2{PgDn}!0!9   ;     Toggle video all on Toggle audio all on PgDn Toggle video all off Toggle audio all off
sleep, 100
while(a_index<n)
{
   ControlClick, % "x" x%a_index% " y" y%a_index%, ahk_class Premiere Pro
}
sleep, 100
return

Задача состоит чтобы при нажати PgDn более чем один раз, скрипт останавливался в тот момент когда нажат PgDn и начинался с

Send, ^!1^!2{PgDn}!0!9   ;     Toggle video all on Toggle audio all on PgDn Toggle video all off Toggle audio all off

Но до выполнения

Send, ^!1^!2{PgDn}!0!9   ;     Toggle video all on Toggle audio all on PgDn Toggle video all off Toggle audio all off

скрипт завершить свою работу не мог
И главное, повторное нажатие должно останавливать скрипт даже во время текущей задержке (sleeps)
Возможно ли такое?
Набрёл на это
http://www.autohotkey.com/forum/viewtopic.php?t=70892
Но не знаю как применить.

2 (изменено: creature.ws, 2012-04-03 17:50:18)

Re: AHK: При повторном нажатии кнопки прервать задержку

По ссылке предлагается «спать урывками, поглядывая с определённой периодичностью на часы».
Применить — использовать упомянутую функцию вместо стандартного Sleep.
Если без излишеств — разбить некий Sleep 1000 на While (условие) Sleep 10.

Если требуются подобные ухищрения —подход наверняка можно изменить.
Задачу я понять не осилил

3

Re: AHK: При повторном нажатии кнопки прервать задержку

Немного подправил.
Нужно чтобы при нажатии PgDn делался скрипт.
А при повторном нажатии скрипт прекращал свою работу и начинал с определённого места.
При следующем нажатии опять прекращал свою работу и начинал с определённого места.
Притом метка прекращения работы тоже есть (то есть скрипт заканчивает свою работу не раньше такой-то строки.)

4

Re: AHK: При повторном нажатии кнопки прервать задержку

«Определённое место» при повторных нажатиях — тоже что и при втором нажатии pgdn?

5

Re: AHK: При повторном нажатии кнопки прервать задержку

Да.

6 (изменено: Irbis, 2012-04-03 18:43:06)

Re: AHK: При повторном нажатии кнопки прервать задержку

Не совсем понял, что требуется, посмотри такой вариант:

#MaxThreadsPerHotkey 5
Broken := 0
Enable_interrupt := 1
Return
PgDn_1st:
; MsgBox 1ый
; return
ErrorLevel := 0
n := 1
k := 1
t := 590
NumPressed := 0
while((!ErrorLevel)&&(n<=10)&&(k=1))
{
      IfEqual, Broken, True
         Break
   ImageSearch, x%n%, y%n%, 410, t, 600, 1050, D:\Abola\video1.png
   t := y%n% + 10
   n++
}
if !Broken
   k++

PgDn_2nd:
; MsgBox 2 и более
; return
Send, ^!1^!2{PgDn}!0!9   ;     Toggle video all on Toggle audio all on PgDn Toggle video all off Toggle audio all off
Sleepit(100,10)
while(a_index<n)
{
   ControlClick, % "x" x%a_index% " y" y%a_index%, ahk_class Premiere Pro
}
Sleepit(100,10)
return

Sleepit(TotalSleepLen,ChunkSize) {
   Global Broken
   nowBroken := Broken
   NumLoops := Round(TotalSleeplen // ChunkSize)
   Loop, %Numloops%
   {  
      sleep, %ChunkSize%
      If (Broken > NowBroken)
         Break
   }
}

PgDn::
   if !Enable_interrupt
      return
   if Broken
      Goto PgDn_2nd
   else 
      Broken += 1
   Goto PgDn_1st
Return

При первом нажатии Page Down скрипт запускается с метки PgDn_1st, при 2ом и следующих нажатиях - переход на PgDn_2nd

Если нужно, чтоб какой-то участок кода не прерывался нажатием PgDn, ставь перед ним Enable_interrupt := 0

7 (изменено: Malcev, 2012-04-03 21:30:47)

Re: AHK: При повторном нажатии кнопки прервать задержку

Сотрите пожалуйста это сообщение.

8 (изменено: Malcev, 2012-04-04 06:22:51)

Re: AHK: При повторном нажатии кнопки прервать задержку

Спасибо!
Это то, что нужно.
2 проблемы.
1) Мне надо, чтобы когда скрипт доходит до конца (т.е. когда последний нажатый PgDn завершит скрипт не прерываясь новым нажатием PgDn), то при следующем нажатии PgDn заново происходил поиск картинки.

while((!ErrorLevel)&&(n<=10)&&(k=1))
{
      IfEqual, Broken, True
         Break
   ImageSearch, x%n%, y%n%, 410, t, 600, 1050, D:\Abola\video1.png
   t := y%n% + 10
   n++
}

Проверку переменной к:=1 я для этого и ввел, но что-то тут не складывается.
Видимо из-за переменной

IfEqual, Broken, True
         Break

2) После повторного нажатия на PgDn не выполняется условие

Send, ^!1^!2{PgDn}!0!9   ;     Toggle video all on Toggle audio all on PgDn Toggle video all off Toggle audio all off

Если один раз PgDn нажмешь, то выполняется, а если несколько, то нет.
Чувствую, что из-за неправильно расставленных Enable_interrupt.
Я их расставил так, чтобы эту часть скрипта нельзя было прервать

PgDn_1st:
; MsgBox 1ый
; return
ErrorLevel := 0
n := 1
k := 1
t := 590
NumPressed := 0
while((!ErrorLevel)&&(n<=10)&&(k=1))
{
      IfEqual, Broken, True
         Break
   ImageSearch, x%n%, y%n%, 410, t, 600, 1050, D:\Abola\video1.png
   t := y%n% + 10
   n++
}
if !Broken
   k++
 
PgDn_2nd:
; MsgBox 2 и более
; return
Send, ^!1^!2{PgDn}!0!9   ;     Toggle video all on Toggle audio all on PgDn Toggle video all off Toggle audio all off

Вот скрипт целиком.

#MaxThreadsPerHotkey 5
Broken := 0
Enable_interrupt := 1
Return
PgDn_1st:
Enable_interrupt := 0
; MsgBox 1ый
; return
ErrorLevel := 0
n := 1
k := 1
t := 590
NumPressed := 0
while((!ErrorLevel)&&(n<=10)&&(k=1))
{
      IfEqual, Broken, True
         Break
   ImageSearch, x%n%, y%n%, 410, t, 600, 1050, D:\Abola\video1.png
   t := y%n% + 10
   n++
}
if !Broken
   k++
 
PgDn_2nd:
; MsgBox 2 и более
; return
Send, ^!1^!2{PgDn}!0!9   ;     Toggle video all on Toggle audio all on PgDn Toggle video all off Toggle audio all off
Enable_interrupt := 1
Sleepit(100,10)
while(a_index<n)
{
   ControlClick, % "x" x%a_index% " y" y%a_index%, ahk_class Premiere Pro
}
Sleepit(100,10)
msgbox %x1% %y1%
return
 
Sleepit(TotalSleepLen,ChunkSize) {
   Global Broken
   nowBroken := Broken
   NumLoops := Round(TotalSleeplen // ChunkSize)
   Loop, %Numloops%
   {  
      sleep, %ChunkSize%
      If (Broken > NowBroken)
         Break
   }
}
 
PgDn::
   if !Enable_interrupt
      return
   if Broken
      Goto PgDn_2nd
   else 
      Broken += 1
   Goto PgDn_1st
Return

9 (изменено: Malcev, 2012-04-05 15:57:20)

Re: AHK: При повторном нажатии кнопки прервать задержку

Раз никто не отвечает, попробую обрисовать задачу иначе.
Допустим имеется скрипт, который по нажатию F11 производит последовательно 10 действий - с первого по десятое.
Мне надо чтобы при нажатии F11 проверялось условие происходит сейчас Current Thread или нет.
Если не происходит, то запускается New Thread с 1 действия по 10ое.
Если Current Thread происходит, то Current Thread мгновенно останавливается и начинается New Thread, но не с первого по десятое действие, а с 5 по 10 действие.
И так по кругу.
Возможно ли такое?
Или надо копать (надеюсь, что нет) http://www.autohotkey.net/~HotKeyIt/AutoHotkey

10 (изменено: creature.ws, 2012-04-05 19:36:18)

Re: AHK: При повторном нажатии кнопки прервать задержку

Согласен, был бы уместен этакий «гипервизор псевдопотоков»
— захотел - прервал подпрограмму в текущей точке выполнения, захотел - приостановил

По поводу «возможно ли» — возможно, но, как обычно, с определёнными оговорками.
Вышеупомянутого «гипервизора» что-то не особо наблюдается, а значит прервать выполнение «потока»
возможно лишь из его тела (вариант с выгрузкой программы не рассматриваем).
А значит в «ключевых точках» подпрограммы должны присутствовать проверки некого,
доступного к изменению извне, признака.

#MaxThreadsPerHotkey 2
F1::
    If (thisSubExec = 1) {
        breakThread := 1
        Sleep 500 ; задержка должна соответствовать наибольшей паузе между проверками breakThread  в выполняющемся потоке
        GoSub Action5
    }
    Else {
        thisSubExec := 1
        GoSub Action1
    }
    return

Action1:
    ; действие 1
    ; проверка значения переменной breakThread и если 1 — breakThread := 0 и Exit
    ; действие 2
    ; проверка значения переменной breakThread и если 1 — breakThread := 0 и Exit
    ; и так далее
    ; return не нужен
Action5:
    ; и так далее
    ; return не нужен
Action10: ; метка к которой нет необходимости обращаться — символизирует «конец подпрограммы»
    thisSubExec := 0
    return

Адаптируйте

11 (изменено: Malcev, 2012-04-06 03:33:46)

Re: AHK: При повторном нажатии кнопки прервать задержку

Интересное решение.
Сколько думал, а в голову не пришло.
Спасибо!
Завтра адаптирую и протестирую.
Может стоит его как-то обобщить и добавить в коллекцию с темой "проверка завершения выполнения потока"?
Потому что ответ на данный вопрос имхо не очевиден.
И с ходу вопрос

; действие 1
    ; проверка значения переменной breakThread и если 1 — breakThread := 0 и Exit
    ; действие 2
    ; проверка значения переменной breakThread и если 1 — breakThread := 0 и Exit
    ; и так далее
    ; return не нужен

Реально ли написать функцию для проверки

; проверка значения переменной breakThread и если 1 — breakThread := 0 и Exit

Или делать это с помощью таймера?
Так как для 5 строк это хорошо, а для ста, не очень - код вырастает в несколько раз.

12 (изменено: creature.ws, 2012-04-06 06:04:04)

Re: AHK: При повторном нажатии кнопки прервать задержку

Это не решение, а «костыль» который в любом виде не только для коллекции не применим, но и предлагаться как «вариант» не должен.

Функцию написать реально, при помощи таймера «это» делать не нужно, от вставки в «ключевых точках» вызова функции не уйти, «ключевые точки» подразумеваются не «через каждую строку», а из расчёта скорости выполнения отдельных участков кода.

Правильным было бы пересмотреть требуемое поведение скрипта — неужто на привязке к одной клавише сошелся клином свет, неужто подпрограмму нельзя представить совокупностью простых повторяющихся фрагментов, и т.д.

13 (изменено: Malcev, 2012-04-07 21:45:23)

Re: AHK: При повторном нажатии кнопки прервать задержку

По-другому никак не могу придумать.
Смотрите.
http://www.efxi.ru/file/premiere_cs55_timeline.files/image005.gif
Скрипт рассчитан для того, чтобы запомнить текущее выделение треков - на данной картинке - Video1
У меня ищется картинка выделенной буквы d и те координаты, где находит, сохраняются в переменные.

ErrorLevel := 0
n := 1
t := 590
while((!ErrorLevel)&&(n<=10))
{
   ImageSearch, x%n%, y%n%, 410, t, 600, 1050, D:\Abola\video1.png
   t := y%n% + 10
   n++
}

Потом выделить все треки, послать Pgdn, снять выделение со всех треков.

Send, ^!1^!2{PgDn}!0!9   ;     Toggle video all on Toggle audio all on PgDn Toggle video all off Toggle audio all off
sleep, 100

И выделить треки которые были выделенными изначально.
Посылается клик на запомненные переменные

while(a_index<n)
{
   ControlClick, % "x" x%a_index% " y" y%a_index%, ahk_class Premiere Pro
}
sleep, 100
return

Ваше решение я адаптировал так.
Так-как запомнить текущее выделение треков нужно только при первом нажатии PgDn и прерывать этот процесс ненужно, то

#MaxThreadsPerHotkey 2
PgDn::
    If (thisSubExec = 1) {
        breakThread := 1
        Sleep 100 ; задержка должна соответствовать наибольшей паузе между проверками breakThread  в выполняющемся потоке
        GoSub Action2
    }
    Else {
        thisSubExec := 1
        GoSub Action1
    }
    return

Action1:
   ErrorLevel := 0
   n := 1
   t := 590
   while((!ErrorLevel)&&(n<=10))
   {
      ImageSearch, x%n%, y%n%, 410, t, 600, 1050, D:\Abola\video1.png
      t := y%n% + 10
      n++
   }

Action2:
   Send, ^!1^!2{PgDn}!0!9   ;     Toggle video all on Toggle audio all on PgDn Toggle video all off Toggle audio all off
   If (breakThread = 1)
   {
       breakThread := 0
       Exit
   }
   sleep, 100
   while(a_index<n)
   {
      ControlClick, % "x" x%a_index% " y" y%a_index%, ahk_class Premiere Pro
      If (breakThread = 1)
      {
         breakThread := 0
         Exit
      }

   }
Konec: ; метка к которой нет необходимости обращаться — символизирует «конец подпрограммы»
   thisSubExec := 0
   sleep, 100
   return

Но появилась проблема.
Оказывается, если закончить Thread, то сохранённые и задействованные в нём переменные тоже пропадают.
Как это-то побороть?
Может создать 3ий Thread который будет запускаться, только при первом нажатии PgDn и будет только сохранять переменные?
Или с первого Thread копировать переменные в 3-ий Thread а потом уже оттуда их доставать?
Можно, конечно, INIWrite
А есть ли варианты без создания доплнительных файлов?

14

Re: AHK: При повторном нажатии кнопки прервать задержку

Оказывается, если закончить Thread, то сохранённые и задействованные в нём переменные тоже пропадают.

Не пропадают. Единственный момент —

Each thread retains its own value of ErrorLevel, meaning that if the current thread is interrupted by another, when the original thread is resumed it will still have its original value of ErrorLevel, not the ErrorLevel that may have been set by the interrupting thread.

15 (изменено: Malcev, 2012-04-08 04:15:35)

Re: AHK: При повторном нажатии кнопки прервать задержку

Ну ErrorLevel не при чём.
Так как он фигурирует только вначале скрипта.
Проблема где-то здесь.

while(a_index<n)
   {
      ControlClick, % "x" x%a_index% " y" y%a_index%, ahk_class Premiere Pro
      If (breakThread = 1)
      {
         breakThread := 0
         Exit
      }
 
   }

Потому как, когда он посылает 10 кликов и я его прерываю на 6-ом, то в следующий раз он посылает только оставшиеся 4.

16

Re: AHK: При повторном нажатии кнопки прервать задержку

Поставьте перед|после каждого действия (клика, нажатия, поиска) вызов listvars — возможно поможет понять какой поток что отправляет и в какой момент.

«Оставшихся 4-х кликов» ведь не существует, n заполняется в action1 и более не изменяется до следующего вызова action1.

17 (изменено: Malcev, 2012-04-08 05:01:40)

Re: AHK: При повторном нажатии кнопки прервать задержку

creature.ws, Вы не поверите.
Исправило проблему вот эта строчка.
SetControlDelay -1
Не понимаю только почему?
Чем же этот Delay мешал и что во время него происходило?

Апдейт, не спасло, просто когда я прерываю поток в момент control click происходит это недоразумение.

18

Re: AHK: При повторном нажатии кнопки прервать задержку

Вероятно, потому, что  n*delay > (100 мс установленных как время ожидания завершения потока при повторных вызовах)

19

Re: AHK: При повторном нажатии кнопки прервать задержку

Апдейт, не спасло, просто когда я прерываю поток в момент control click происходит это недоразумение.

20 (изменено: creature.ws, 2012-04-08 05:16:03)

Re: AHK: При повторном нажатии кнопки прервать задержку

Попробуйте изменить:

PgDn::
    If (thisSubExec = 1) {
        breakThread := 1
        Sleep 300 ; задержка должна соответствовать наибольшей паузе между проверками breakThread  в выполняющемся потоке
        GoSub Action2
    }

и

while(!breakThread && a_index<n)
    ControlClick, % "x" x%a_index% " y" y%a_index%, ahk_class Premiere Pro

If (breakThread = 1)
{
    breakThread := 0
    Exit
}

21

Re: AHK: При повторном нажатии кнопки прервать задержку

А нету какого-нибудь другого костыля?
А то я заблокировал повторное нажатие PgDn аж до последнего слипа.
А он всё-равно, если зажать  PgDn глючит.

22

Re: AHK: При повторном нажатии кнопки прервать задержку

Попробуйте изменить:

#MaxThreadsPerHotkey 2
PgDn::
    KeyWait pgdn
    ; …

23

Re: AHK: При повторном нажатии кнопки прервать задержку

Не помогает.
Как только выставляешь максимальное количество потоков = 1, то всё нормализовывается.
Получается, что всё-таки псевдо-мультипоточность не победить?

24

Re: AHK: При повторном нажатии кнопки прервать задержку

Вероятно имеется в виду не «потоков», а «потоков на хоткей».

Получается, что всё-таки псевдо-мультипоточность не победить?

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

А нету какого-нибудь другого костыля?

Позвольте еще раз вам посоветовать не костыль искать, а алгоритм пересмотреть.
Делать всё одним нажатием конечно же «очень дружелюбно к пользователю», но даже на компьютерной мыше более одной кнопки.

25

Re: AHK: При повторном нажатии кнопки прервать задержку

Спасибо!
Буду пересматривать алгоритм, либо вообще плюну на это.
Лучшее - враг хорошего.
Но для очистки совести задам подобный вопрос на офф.форуме.
Если что предложат интересного, то тут отпишусь.