Poll

Вы хотели бы добавить себе в скрипт(ы) хоткеи для вызова нужных функций по желанию?

Нет, мне это не нужно. Либо я не знаю, как это сделать!
0 (0%)
Мне это нужно, но не часто. Было б хорошо добавлять хоткеи с лёгкостью.
3 (37.5%)
Я использую комбинации клавиш/хоткеи в некоторых скриптах, можно б и чаще.
0 (0%)
Я король автоматизации. Все мои скрипты с хоткеями!
2 (25%)
Свой вариант, который я напишу в комментариях ниже.
3 (37.5%)

Total Members Voted: 8

Author Topic: [РЕШЕНО] Проверка условия повторного нажатия вместе с хоткеем iskeydown + ОПРОС  (Read 8303 times)

0 Members and 1 Guest are viewing this topic.

Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
Решил организовать в своём скрипте вызов функции по хоткею. Для этого полез в руководство и стырил пару строк оттуда:
[spoiler=Проверка нажатия клавиши/комбинации]
Code: (clickermann) [Select]
// проверка нажатия пробела
if ( iskeydown(#space)=1 )
 logwrite("space!")
END_IF

// проверка нажатия пробела и клавиши A
if ( (iskeydown(#space)=1) & (iskeydown(#a)=1) )
 logwrite("space and a!")
END_IF
[/spoiler]
Решил проверить на практике, работает ли функция так, как ожидается. А вышло, как всегда -- "тут помню, а тут не помню"  :D
Добавил ожидание в 10 мс в конце. Вышло, что лограйт срабатывает несколько раз за нажатие.
Чтоб исключить такое поведение (многократное срабатывание), дописал переменную с инкрементацией и проверкой:
Code: (clickermann) [Select]
$a=0
if ( ( $a < 1 ) & ( iskeydown(#a) = 1 ) )
 logwrite("a!")
 inc($a)
END_IF
waitms(10)
Перепробовал несколько вариантов написания синтаксиса строки проверки: 
Code: (clickermann) [Select]
if (($a<1)&(iskeydown(#a)=1))
if ( ($a<1) & (iskeydown(#a)=1) )
if ( ( $a < 1 ) & ( iskeydown(#a) = 1 ) )
и прочие с пробелами/скобками/без оных

Но увы, при каждом из вариантов скрипт каждый раз выдавал ошибку и предлагал сделать аборт:
[spoiler=Ошибка при интерпретации строки Кликерманн][/spoiler]

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

Попробовал также запасной вариант с подусловием, результат тот же (но здесь ожидаемо, ведь с каждым запуском переменная нулится):
[spoiler]
Code: (clickermann) [Select]
$a=0
if (  ( iskeydown(#a) = 1 ) )
   if ( $a < 1 )
      logwrite("a!")
      inc($a)
   END_IF
END_IF
Неожиданно:

[/spoiler]

Теперь даже не знаю, какие варианты рассматривать. Может, заморочиться с потоками и переменными проверки/состояния в них? И что-то задний моск мне подсказывает, что без потоков туточки не обойтись.
« Last Edit: November 22, 2016, 09:41:59 PM by Cleoss »

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Конечно, здесь очень нужны потоки. Просто необходимы.

Раз
Code: (clickermann) [Select]
IF(($a < 1) & (iskeydown(#a) = 1))
    logwrite("a!")
    inc($a)
END_IF
waitms(20)

Два
Code: (clickermann) [Select]
DEFINE($a, 0)
IF(($a < 1) & (iskeydown(#a) = 1))
    logwrite("a!")
    inc($a)
END_IF
waitms(20)

Самый нормальный, три
Code: (clickermann) [Select]
IF(iskeydown(#a) = 1)
    logwrite("a!")
   
    WHILE(iskeydown(#a) = 1)
        waitms(20)
    END_CYC
END_IF
waitms(20)

P.S. Пробелы здесь не критичны, они при парсинге игнорируются от слова "совсем".
« Last Edit: November 22, 2016, 03:49:52 PM by Vint »


Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
Первый вариант печатает лограйтом один раз и больше уже не печатает, сколько ни жми клавишу, вместо того, чтоб печатать один раз за нажатие.

Второй как ни странно делает то же самое, хотя казалось, что DEFINE($a, 0) и $a=0 эквивалентны и должны действовать одинаково, но мой вариант с $a=0 печатает много раз за нажатие, как уже писалось выше.

А вот в третьем разе как раз вроде и делается всё, как полагается, даже несмотря на такое казалось бы нетривиальное решение:
Code: (clickermann) [Select]
    WHILE(iskeydown(#a) = 1)
        waitms(20)
    END_CYC
то есть внутри цикла нет ничего.. кроме паузы и ожидания. Я б до такого не додумался Х(
Спасибо, Винтец! Щёлкаешь всё с закрытыми глазами))

Терь попробую добавлю сразу несколько хоткеев и потестирую, как будет загружаться проц вместе с проверкой всех нажатий с короткими паузами 10-20 мс (у меня delay_between_lines = 0 в конфиге).  Поищу компромисс между загруженностью, быстродействием и правильным функционированием нажатий.
« Last Edit: November 22, 2016, 09:08:03 PM by Cleoss »

Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
А, вот! Дошло, почему здесь нужны треды: цикл вайл выполняется до тех пор, пока не будет отжата клавиша, то есть значит тем временем нажатие других клавиш не проверяется, а проверяется в текущем цикле только одна клавиша/комбинация. То есть чтоб проверять сразу несколько нажатий, нужно сделать это всё во множестве отдельных потоков, чтоб мочь обработать все возможные нажатия. Ну не знаю, может, как-то там можно и через GETKEYSDOWN. Щас бум пробовать.

Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
Ппц, вот такой код: [spoiler=Пара тредов с двумя паузами по 5 мс]
Code: (clickermann) [Select]
thread(a)
  IF(iskeydown(#a) = 1)
    logwrite("a!")
    WHILE(iskeydown(#a) = 1)
        waitms(5)
    END_CYC
  END_IF
  waitms(5)
end_thread

thread(b)
  IF(iskeydown(#b) = 1)
    logwrite("b!")
    WHILE(iskeydown(#b) = 1)
        waitms(5)
    END_CYC
  END_IF
  waitms(5)
end_thread
[/spoiler]
загружает двухъядерный проц почти на 100 %, а временами и вешает комп, не давая мыши ни на что нажимать.
И этого проверка только двух клавиш.. А как же организовать тогда сотни комбинаций?!

ПС. Скрипт загружает проц даже без нажатий, зависания происходят на несколько секунд примерно раз в минуту.
Без работы скрипта проц загружен на 15-20%. Хотя может загрузка будет меньше, если вместо лограйта юзать кейпресс?
« Last Edit: November 22, 2016, 09:33:45 PM by Cleoss »

Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Выстави в конфиге "delay_between_lines = 1"
Значение 0 приводит к чрезмерной нагрузке. Вернее сказать при значении 0 кликер постоянно грузит проц на 50% даже в задержке (по крайней мере у меня так).
Рекомендую ставить задержку в скрипте 20 мс и выше.

Вот вариант с GETKEYSDOWN
Code: (clickermann) [Select]
GETKEYSDOWN ($arr_key)
IF(ARRSIZE($arr_key) > 0)
   WHILE(ISKEYDOWN($arr_key[0])=1)
      WAITMS(20)
   END_CYC
   
   SWITCH($arr_key[0])
   CASE(#A)
      LOGWRITE ("A")
   CASE(#B)
      LOGWRITE ("B")
   END_SWITCH
   
ELSE
   WAITMS(20)
END_IF
« Last Edit: November 22, 2016, 09:51:33 PM by Oraven »

Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
Если сделать вот таким макаром (по примеру из доки):
[spoiler]
Code: (clickermann) [Select]
// пример 2, анализ нажатых клавиш через switch
// данный пример использует тот факт что $kvar тоже самое что и $kvar[0]
getkeysdown($kvar)
SWITCH($kvar)
CASE(#q)
   print("Q")
CASE(#w)
   print("W")
CASE(#e)
   print("E")
CASE(#R)
   print("R")
CASE(#T)
   print("T")
CASE(#Y)
   print("Y")
CASE(#U)
   print("U")
CASE(#I)
   print("I")
CASE(#O)
   print("O")
CASE(#P)
   print("P")
CASE(#A)
   print("A")
CASE(#S)
   print("S")
CASE(#D)
   print("D")
CASE(#F)
   print("F")
CASE(#G)
   print("G")
CASE(#H)
   print("H")
CASE(#J)
   print("J")
CASE(#K)
   print("K")
CASE(#L)
   print("L")
CASE(#Z)
   print("Z")
CASE(#X)
   print("X")
CASE(#C)
   print("C")
CASE(#V)
   print("V")
CASE(#B)
   print("B")
CASE(#N)
   print("N")
CASE(#M)
   print("M")
END_SWITCH
waitms(10)
[/spoiler]
то скрипт грузит проц уже на 50 про, слава б-гу хоть не на сто)) Это уже терпимо.

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

Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
Выстави в конфиге "delay_between_lines = 1"
Значение 0 приводит к чрезмерной нагрузке. Вернее сказать при значении 0 кликер постоянно грузит проц на 50% даже в задержке (по крайней мере у меня так).
Рекомендую ставить задержку в скрипте 20 мс и выше.

Вот вариант с GETKEYSDOWN

Спасиб за готовое решение, Андрей! Вот вроде Винт уже использовал похожий код:
[spoiler=Цикл вайловый с массивом набранных клавиш]
Code: (clickermann) [Select]
   WHILE(ISKEYDOWN($arr_key[0])=1)
      WAITMS(20)
   END_CYC
[/spoiler]
а вот чёт я б и не смог допетрить, как запихнуть массив в в цикл. Мне б такое и в голову не пришло, спасибо ещё раз.

Ну а по поводу задержки я эти моменты понимаю и сам уже не раз тестировал разные варианты загруженности с разными задержками, а также меру задержек для адекватного поведения приложений. Для меня эти тесты актуальны, поскольку машина не фонтан, а.. редиска у меня. Но я бы согласился на загрузку кликера 20-60 процентов в случае успешной обработки всех нужных/возможных комбинаций (ориентировочно около 1000 вариантов хоткеев), но чую над этим решениям ещё надо буит малость попотеть. Не исключаю и вариант, что не получится обрабатывать всю эту 1к вариантов нажатий с адекватным поведением системы. А относительно "Рекомендую ставить задержку в скрипте 20 мс и выше" -- дилемма в том, что длительность самых коротких нажатий составляет как раз 20-30 мс, и если сделать задержку чаще/дольше, то будут часто пропускаться эти сами "короткие нажатия" ввиду редкости проверок нажатия (та же проблема и с вайлом).

Но delay_between_lines = 1 я конечно же приму к сведению (1 мс не б-г весть какая долгая длительность и для нажатия погоды не сыграет, а вот проц наверняка подразгрузит). Главное, опять же в тестах определить баланс адекватности и отсутствия пропусков нажатий. Но я при тестах пару недель назад понял, что надеяться на загрузку моего не ахти-какого процессора кликером меньше, чем на 10-20 процентов слишком глупо (либо работаем/обрабатываем нажатия и грузим проц, либо отдыхаем/остываем и ничего не обрабатываем). Но по началу я надеялся на загрузку в пределах 2-10 про (кстати, такой загруженности можно добиться при работе скрипта в фоне, без нажатий, но с величиной задержки проверок 50-150 мс и больше). Но чем дольше задержек, тем опять же больше пропусков нажатий, и к сожалению даже при задержке 50 мс пропуски достаточно часто случаются, хотя казалось бы интервал достаточно не большой.

Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
Отсюда, из последнего абзаца, можно сделать вывод (как вариант, может кому и подойдёт такое), что если вам нужно сделать систему, которая обрабатывает 1000-2000 хоткеев, то можно просто спроектировать скрипт таким образом, что задержки будут достаточно большими (от 100-200 мс и выше с шагом в 100 мс) и при этом вам придётся достаточно долго (соответственно 0,2+ сек, хотя не так уж это и много, можно и полсекунды подержать) нажимать на каждую клавишу, причём делать это сознательно и каждый раз, но думаю, через полчаса-час таких "осознанных" долгих нажатий рука с мозгом сами привыкнут и выработают моторику, благодаря которой вы станете автоматически каждую клавишу нажимать (относительно) "долго" (то есть столько, сколько нужно для успевания обработки и срабатывания нужной вам функции). Кстати, в некоторых программах-хоткеизаторах есть отдельные обработчики для коротких/длинных нажатий, то есть при коротком нажатии срабатывает вызов обычной для клавиши функции, а при длительном нажатии запускается особая, отдельно запрограммированная/заданная функция, примерно такую же реализацию охота и мне заиметь в своём обработчике))

Также нужно отметить, что при моих экспериментах с прошлым кликером тоже проводил эксперименты по ускорению скриптов и при этом более-менее вменяемому поведению окон определилось (у меня, для моего компа), что при клике на заголовках окон для переключения фокуса на него нужно для адекватного поведения окошка делать задержку между кейдавном и кейапом в пределах 300-350 мс (не меньше) и примерно аналогичную задержку после кейапа по заголовку, иначе время от времени скрипт может глюкануть (чем меньше задержка, тем более вероятность этого) и перетащить окно вместо клика по нему или переставить фокус на другой элемент, на который скрипт жмёт следующим. Даже больше, если все задержки будут очень короткими либо отсутствовать, многие действия в скрипте не смогут быть выполнены либо же будут выполнены неверно и исполнение скрипта пойдёт совсем не по нужной колее, может даже испортить чтот в системе или перенастроить. В остальных же местах можно ставит достаточно короткие задержки (имхо 100-200 не такие уж и долгие задержки, как возможно здесь принято считать, но местами могут позволить вашим приложениям работать более стабильно) по своему усмотрению и в зависимости от величины быстродействия вашего компа. То бишь клик по окну часто является слабым звеном при работе со многими окнами и при переключении между ними всеми в том смысле, что он требует отдельную, бОльшую задержку. Мени прыкро, что такую важную инфу я пишу где-то в глубине какой-то своей узкоспециальной темы, тем более что пользователи кликера часто неграмотно работают с задержками (точнее, убирают их под ноль) да и в мануале нету толковой наводки на эту тему. Единственное место, где нужны особо большие задержки это пинги (ожидание загрузки/дозагрузки веб-страницы и отдельных/всех её элементов), но благо для обхода этого в Клмн есть циклы и ифпикин.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
то скрипт грузит проц уже на 50 про, слава б-гу хоть не на сто)) Это уже терпимо.
Ремонтируй свою систему. У меня на очень не новом компе 3-7%, в среднем 5%.

хотя казалось, что DEFINE($a, 0) и $a=0 эквивалентны и должны действовать одинаково
Они НЕ одинаковы.

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

А, вот! Дошло, почему здесь нужны треды: цикл вайл выполняется до тех пор, пока не будет отжата клавиша, то есть значит тем временем нажатие других клавиш не проверяется, а проверяется в текущем цикле только одна клавиша/комбинация. То есть чтоб проверять сразу несколько нажатий, нужно сделать это всё во множестве отдельных потоков, чтоб мочь обработать все возможные нажатия.
Обычно хоткеи не используются как управление и им не нужна одновременная реакция на разные. Но соглашусь, если юзание активное, то ожидать отпускание только при делении по потокам.

Ппц, вот такой код: [spoiler=Пара тредов с двумя паузами по 5 мс]
загружает двухъядерный проц почти на 100 %, а временами и вешает комп, не давая мыши ни на что нажимать.
Потому что погрешность waitms как раз 5 мс. И на некоторых компах и в некоторых случаях, это всё равно что задержки нет совсем.
У меня на преведущем рабочем компе всё меньше 5 было равно 0.
Сейчас конечно и 2 мс рабочие.

имхо 100-200 не такие уж и долгие задержки, как возможно здесь принято считать
никто так не считает. Это у тебя в скриптах то 5, то 10.
Я только в самых нужных, нагруженных местах ставлю 5-20. При обработках массивов данных, например в файле.

То бишь клик по окну часто является слабым звеном при работе со многими окнами и при переключении между ними всеми в том смысле, что он требует отдельную, бОльшую задержку. Мени прыкро, что такую важную инфу я пишу где-то в глубине какой-то своей узкоспециальной темы, тем более что пользователи кликера часто неграмотно работают с задержками (точнее, убирают их под ноль) да и в мануале нету толковой наводки на эту тему.
менi прикро - тебя не все поймут  :)
Клик по окну = сделать активным окно и перевести на него фокус - время реакции это не проблема кликера, а проблема реакции системы, которая зависит от железа, загруженности компа и загаженности системы. У меня эта реакция на глаз совсем не отличается от многих других. Но я и не ставлю 5-10 мс.
По задержкам много индивидуальностей и много зависит от приложений и задач. Что там в мануале писать? Солить по вкусу? Или расписывать все возможные варианты?...
Ну, трудные места не мешало бы упомянуть. Всех проблем всех пользователей это не решит пока они не будут писать и писать. Потом придёт просветление и в голове у каждого будет "свой" мануал, не совпадающий с другими.
« Last Edit: November 23, 2016, 01:05:34 PM by Vint »


Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
А кто это тут "король автоматизации" судя по опросу? А ну отзовись!))

Золотой

  • Оплот сообщества
  • ****
  • Posts: 312
    • View Profile
А кто это тут "король автоматизации" судя по опросу? А ну отзовись!))
Королей не знаю и знать не хочу, но судя по опросу, Я БОГ АВТОМАТИЗАЦИИ!     :P

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Голосование подтасовано  ;D
Мой любимый 2 пункт
Quote
"Мне это нужно, но не часто. Было б хорошо добавлять хоткеи с лёгкостью."
испорчен. Мне подходит "Мне это нужно, но не часто". Но зачем здесь сопутствующий товар в виде
"Было б хорошо добавлять..." ?

Что это за тяга к "чехол не нужен?"  :D
Выходит от моего имени там чего то просят.


i0

  • Оплот сообщества
  • ****
  • Posts: 353
  • CMann 4.13.014 final, ie, presto, win7 x86, x64
    • View Profile
Мне подходит "Мне это нужно, но не часто". Но зачем здесь сопутствующий товар в виде
"Было б хорошо добавлять..." ?
поэтому 5+

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Опрос с нарушением правил составления.

10 правил составления опросов

Вот прям пункт 1 нарушается.