1

Тема: AHK: Как ускорить вычисление цвета

Существует сайт на проверку реакции. https://www.humanbenchmark.com/tests/reactiontime
Я написал скрипт для данного сайта, в среднем выходит 70-110мс, но я хотел бы ускорить скорость реакции.

Есть идеи?


#SingleInstance, Force
SetKeyDelay, -1, -1
SetMouseDelay, -1
SetBatchLines, -1
SendMode, Input

*$XButton2::
BlockInput, MouseMove
MouseGetPos, xpos, ypos
PixelGetColor, color1, xpos, ypos, RGB
BlockInput, MouseMoveOff
While GetKeyState("XButton2", "P")
{
	MouseGetPos, xpos1, ypos1
	PixelGetColor, color2, xpos1, ypos1, RGB
	if (color1 <> color2) {
		SendInput,{LButton}
		break
	}
	;sleep,1
}
return

2

Re: AHK: Как ускорить вычисление цвета

А какой браузер у вас?

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

3

Re: AHK: Как ускорить вычисление цвета

PixelGetColor - 98 ms, альтернативная функция (GetDCEx, GetPixel, ReleaseDC) - 38 мс.

4

Re: AHK: Как ускорить вычисление цвета

teadrinker

Google Chrome.

5

Re: AHK: Как ускорить вычисление цвета

Возможно, скорость реакции зависит от герцовки монитора.

6

Re: AHK: Как ускорить вычисление цвета

Уверен, скрипт о мониторе ничего не знает.

7

Re: AHK: Как ускорить вычисление цвета

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

8 (изменено: teadrinker, 2020-03-30 16:23:38)

Re: AHK: Как ускорить вычисление цвета

Если задача автоматизировать клик, когда меняется цвет, можно так:

/*
для сайта
https://www.humanbenchmark.com/tests/reactiontime
*/
SetBatchLines, -1
js =
(
   if (!window._ahk_mobs_) {
      window._ahk_mobs_ = true;
      new MutationObserver(mutArr => {
         if (mutArr[0].target.classList[2] === 'view-go') {
            const event = new MouseEvent('mousedown', { bubbles: true });
            mutArr[0].target.dispatchEvent(event);
         }
      }).observe(document.querySelector('.reaction-time-test'), {
         attributes: true, 
         attributeFilter: ['class']
      });
   };
)
RunJsFromChromeAddressBar(js)

RunJsFromChromeAddressBar(js, exe := "chrome.exe") {
   static WM_GETOBJECT := 0x3D
        , ROLE_SYSTEM_TEXT := 0x2A
        , STATE_SYSTEM_FOCUSABLE := 0x100000
        , SELFLAG_TAKEFOCUS := 0x1
        , AccAddrBar, window
   if !AccAddrBar {
      window := "ahk_class Chrome_WidgetWin_1 ahk_exe " . exe
      SendMessage, WM_GETOBJECT, 0, 1, Chrome_RenderWidgetHostHWND1, % window
      AccChrome := AccObjectFromWindow( WinExist(window) )
      AccAddrBar := SearchElement(AccChrome, {Role: ROLE_SYSTEM_TEXT, State: STATE_SYSTEM_FOCUSABLE})
   }
   AccAddrBar.accValue(0) := "javascript:" . js
   AccAddrBar.accSelect(SELFLAG_TAKEFOCUS, 0)
   ControlSend,, {Enter}, % window, Chrome Legacy Window
}

SearchElement(parentElement, params)
{
   found := true
   for k, v in params {
      try {
         if (k = "ChildCount")
            (parentElement.accChildCount != v && found := false)
         else if (k = "State")
            (!(parentElement.accState(0) & v) && found := false)
         else
            (parentElement["acc" . k](0) != v && found := false)
      }
      catch 
         found := false
   } until !found
   if found
      Return parentElement
   
   for k, v in AccChildren(parentElement)
      if obj := SearchElement(v, params)
         Return obj
}

AccObjectFromWindow(hWnd, idObject = 0) {
   static IID_IDispatch   := "{00020400-0000-0000-C000-000000000046}"
        , IID_IAccessible := "{618736E0-3C3D-11CF-810C-00AA00389B71}"
        , OBJID_NATIVEOM  := 0xFFFFFFF0, VT_DISPATCH := 9, F_OWNVALUE := 1
        , h := DllCall("LoadLibrary", "Str", "oleacc", "Ptr")
        
   VarSetCapacity(IID, 16), idObject &= 0xFFFFFFFF
   DllCall("ole32\CLSIDFromString", "Str", idObject = OBJID_NATIVEOM ? IID_IDispatch : IID_IAccessible, "Ptr", &IID)
   if DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject, "Ptr", &IID, "PtrP", pAcc) = 0
      Return ComObject(VT_DISPATCH, pAcc, F_OWNVALUE)
}

AccChildren(Acc) {
   static VT_DISPATCH := 9
   Loop 1  {
      if ComObjType(Acc, "Name") != "IAccessible"  {
         error := "Invalid IAccessible Object"
         break
      }
      try cChildren := Acc.accChildCount
      catch
         Return ""
      Children := []
      VarSetCapacity(varChildren, cChildren*(8 + A_PtrSize*2), 0)
      res := DllCall("oleacc\AccessibleChildren", "Ptr", ComObjValue(Acc), "Int", 0
                                                , "Int", cChildren, "Ptr", &varChildren, "IntP", cChildren)
      if (res != 0) {
         error := "AccessibleChildren DllCall Failed"
         break
      }
      Loop % cChildren  {
         i := (A_Index - 1)*(A_PtrSize*2 + 8)
         child := NumGet(varChildren, i + 8)
         Children.Push( (b := NumGet(varChildren, i) = VT_DISPATCH) ? AccQuery(child) : child )
         ( b && ObjRelease(child) )
      }
   }
   if error
      ErrorLevel := error
   else
      Return Children.MaxIndex() ? Children : ""
}

AccQuery(Acc) {
   static IAccessible := "{618736e0-3c3d-11cf-810c-00aa00389b71}", VT_DISPATCH := 9, F_OWNVALUE := 1
   try Return ComObject(VT_DISPATCH, ComObjQuery(Acc, IAccessible), F_OWNVALUE)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9

Re: AHK: Как ускорить вычисление цвета

Кстати, броузер в принципе не важен.
Можно и в фаерфоксе через адресную строку js инжектить.

Set up a Bookmark with the location: javascript:%s and set the keyword for that bookmark as: javascript
Now you can run Javascript from the address bar in the format: javascript alert('Hello World') which is very similar to the old javascript:alert('Hello World') method - it's just that the colon needs to be replaced by a space

10

Re: AHK: Как ускорить вычисление цвета

Инжектить можно, но реализации JS могут отличаться немного, надо проверять, все ли объекты будут работать.

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

11

Re: AHK: Как ускорить вычисление цвета

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

12

Re: AHK: Как ускорить вычисление цвета

teadrinker

Всё отлично работает, только я не понимаю почему значка ahk нет.

13

Re: AHK: Как ускорить вычисление цвета

AHK только загружает javascript на страницу. Немного подправил.

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

14

Re: AHK: Как ускорить вычисление цвета

teadrinker

Не знаю почему, но код перестал работать.

15

Re: AHK: Как ускорить вычисление цвета

Значит код страницы изменился. Смотрите, соответствуют ли названия классов элементов указанным в скрипте.

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

16

Re: AHK: Как ускорить вычисление цвета

js =
(
   if (!window._ahk_mobs_) {
      window._ahk_mobs_ = true;
      const event = new MouseEvent('mousedown', { bubbles: true });
      new MutationObserver(mutArr => {
         if (mutArr[0].target.classList.contains('view-go'))
            mutArr[0].target.dispatchEvent(event);
      }).observe(document.querySelector('.view-splash'), {
         attributes: true, 
         attributeFilter: ['class']
      });
   };
)
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

17 (изменено: romzes96, 2020-05-22 17:50:26)

Re: AHK: Как ускорить вычисление цвета

https://prnt.sc/slrunf - это скрин результата за 20 замеров код под спойлером.
Первый клик 48ms.

+ открыть спойлер
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
;SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance, Force
SetKeyDelay, -1, -1
SetMouseDelay, -1
SetBatchLines, -1
SendMode, Input

F1::

Loop,
{
	color := "0xCE2636"
	while(color == "0xCE2636")
	{
		MouseGetPos, xm, ym
		PixelGetColor, color, xm, ym, Fast RGB
	}
	Send, {LButton}
}
return

F2::
ExitApp

https://prnt.sc/sls08i - это скрин результата за 20 замеров код под спойлером.
Первый клик 16ms.

+ открыть спойлер
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
;SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance, Force
SetKeyDelay, -1, -1
SetMouseDelay, -1
SetBatchLines, -1
SendMode, Input

F1::
MouseGetPos, xm, ym
Loop,
{
	color := "0xCE2636"
	while(color == "0xCE2636")
	{
		PixelGetColor, color, xm, ym, Fast RGB
	}
	Send, {LButton}
}
return

F2::
ExitApp

Разница в том что из цикла достал MouseGetPos.
Оба раза запускал после перезагрузки пк, в автозапуске пусто. Все закрыто, только 1 вкладка в хроме.

UPD:
https://prnt.sc/sls9s8 - это скрин результата за 20 замеров но уже с настройкой монитора в 25 Гц, используя 2-ой вариант.
Первый клик 90ms.
Предыдущие разы монитор был в 59 Гц.

18

Re: AHK: Как ускорить вычисление цвета

А в чём вопрос?

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