Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2Keys AHK helper libraries feature tracker #2

Open
Gum-Joe opened this issue Oct 31, 2018 · 1 comment
Open

2Keys AHK helper libraries feature tracker #2

Gum-Joe opened this issue Oct 31, 2018 · 1 comment
Labels
good first issue Good for newcomers help wanted Extra attention is needed v1 Features and issues for v1

Comments

@Gum-Joe
Copy link
Owner

Gum-Joe commented Oct 31, 2018

This is the feature tracker/list of features for the 2Keys helper libraries for AHK to replace functions that don't work with 2Keys (i.e. GetKeyState) and add helpers for i.e. cross script variables

What are the 2Keys helper libraries?

Some AHK functions, such as GetKeyState obviously won't work with 2Keys as the keyboards are physically plugged into a separte device. The aim of the 2Keys helper libraries is to add support for these functions, whether that be through the use of:

  • A sockets server (for communcation between server and detector)
  • Local sockets (i.e. Unix sockets to communicate with the detector so we don't have to mess with async in python
  • IPC (inter-process communcation), see above

In addition, the helper library would also provide some function to help with execution of scripts, script communcation and the development of scripts.

Ideally, it would also be possible to extend the helpers with your own scripts, alllowing for custom code to be used between detector and scripts.

Submitting a proposal

Include:

  • A description of the library and where in the core library it would go
  • Sample syntax (start from root import, see below)
  • Explanation of how it works

The root import is #Include <2Keys>, which is the dir which contains all the helpers in their categories

Categories

  • Core/common helpers: #Include <2Keys/core>
  • Variables: #Include <2Keys/vars>
    • Create variables namespace (a storage of variables for a certain script)
    • Add, remove and modify variables in it
    • Will only support basic types (string, numbers, boolean), no object or functions
  • Keyboards: #Include <2Keys/keyboards>

Helpers

Prelude

The prelude is the section of AHK code executed before the user's specified function is executed.

Global variables

These are variables, defined in the prelude, that are accessible by all scripts (including ones imported with #Include) being executed.

  • TWOKEYS_CWD: Defines the current working directory of the 2Keys process. ✅ Added by 2f1e45b

Core helpers

2Keys.core.callbacks

Designed for use by runner to make calback functions so 2Keys native addons stops execution once the script is done.
Ideally, a callback generator would be used, but AHK doesn't appear to support returning of functions from functions. As such, methods are used for now to use an INI file with statuses pending, resolved (script done) or rejected (script errored).

Needed due to #3.

2Keys.core.callbacks.reserveCallbackID(id)

Where id is a unique 64 bit ID used to identify the execution (so that the correct callback stops execution of the correct program).

How it works

NOTE: Ideally sockets or IPC would be used, but this solution is simpler; a 'bodge' is ok here.

On execution of this function, an entry is added to a callback.ini file in ~/.2Keys/ini/callback.ini:

[f062de12] # Would be the 64-bit id in hexadecimal being used, provided as id, this is an example
enabled=true # This id is now in use
status=pending # Use promise language, so pending, resolved or rejected
err=null # Only checked if status === rejected

2Keys.core.callbacks.defaultCallback(id, err)

Where id is a unique 64 bit ID used to identify the execution (so that the correct callback stops execution of the correct program).

Where err is an error string or a 2Keys AHK error object.

How it works

On execution of this function, the callback.ini file is edited:

[f062de12] 
enabled=true
status=resolved
err=null 

If there is an error in the script, provided as err:

[f062de12] 
enabled=true
status=resolved
err=Error message

The executor then sees this and invokes a nodejs callback function, supplying the error if necessary. enabled is also set to false.

Note: how function would be executed using callbacks:
// JS CODE
ahk_exec(`
#Include <2Keys/core/callbacks>
callbacks.reserveCallback(0xf062de12) ; Reserve this id
callback(err) {
   callbacks.defaultCallback(0xf062de12, err)
}
FunctionToExec(callback) ; So function will be required to accept a callback
`, err => {
   if (err) logger.throw(err);
   logger.debug("Exec sucess")
};

If the user wanted to pass the callback to another function for use, such as a callback for a GUI, the AutoHotkey code would be as follows:

#Include <2Keys/core/callbacks>
callbacks.reserveCallback(0xf062de12) ; Reserve this id

; This section is user code
; The below line would be read by 2Keys and tell it to use 
#2KEYS_USE_GLOBAL_CALLBACK
FunctionToExec() { ; Callback arg not needed now as callback is global
   ; ...do stuf...
}

; Here we define the global callback
Global callback(err) {
   callbacks.defaultCallback(0xf062de12, err)
}

; Call func
FunctionToExec()

NB: Since the addon may be blocking, Nodejs thread/workers may be needed.

Keyboard helpers

2Keys.keyboards.getKeyState(keyboard, key, callback)

Where key is the name of the key to lookup (see detector/util/keyboard_map.py)
Where keyboard is the keyboard to lookup key in
Where callback is a function to run when the state is received.

Returns either up or down, or true (toggled on)/false (toggles off) for keys such as Numpad and Caps Lock.

How it works

This function allows a user to fetch the state of a key from any keyboard attached to the detector
It works like so:

  1. User invokes helper
  2. Either by DLL call or a 3rd party AHK library, IPC or sockets is used to make a request to the server for the key state
  3. The server, either by native add-ons, a 3rd party lib from npm or via socket.io receives the request and forwards it via socket.io to the detector
  4. The detector reads the key state, preferably from memory but more likely from a file, and send it back via socket.io to the server
  5. The server receives this and sends by IPC or sockets to the original place where the request was sent from (step 2.)
  6. The sender used in step. 2 invokes a callback with the result, or return the value when done.
Sample syntax
#Include <2Keys/keyboards>
HowIsNumPad() {
   if (keyboards.getKeyState("keyboard_2", "CAPS_LOCK")) {
      MsgBox "Caps Lock is on"
      ; More likely we'll do something different if Caps Lock is on
   } else {
      state := keyboard.getKeyState("keyboard_3", "<^")
      if (state) {
         MsgBox "A action like this is useless"
      }
   }
}
@Gum-Joe Gum-Joe added help wanted Extra attention is needed good first issue Good for newcomers labels Oct 31, 2018
@Gum-Joe
Copy link
Owner Author

Gum-Joe commented Nov 12, 2018

AHK doesn't appear to support returning functions. As such, separte methods must be used:

reserveCallback(id)

callback(err) {
   resolveCallback()
}

Function(callback) {
   callback(null)
}

Function(callback)

Edit: Added this to issues

@Gum-Joe Gum-Joe pinned this issue Dec 17, 2018
Gum-Joe added a commit that referenced this issue Aug 16, 2019
Added ahk.ts tests
Added mock configs.

Add prelude varibale TWOKEYS_CWD for current working dir, accesible by all authotkey executing code. (see #2)
@Gum-Joe Gum-Joe added the v1 Features and issues for v1 label Jun 9, 2020
@Gum-Joe Gum-Joe unpinned this issue Sep 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers help wanted Extra attention is needed v1 Features and issues for v1
Projects
None yet
Development

No branches or pull requests

1 participant