Search code examples
lualogitechlogitech-gaming-software

Logitech/LGHUB Lua - Loop with break


i recently picked up Lua while making a macro script for my LG mouse. Unfortunately the Lua-API is really restricted with debug, io and file not working (source: http://www.softpanorama.org/Hardware/Peripherals/Keyboards/Logitech_G_keyboard_macros/lua_scripting.shtml#Limitations) Here is also the official reference: https://douile.github.io/logitech-toggle-keys/APIDocs.pdf

The script is running a LGHUB macro while i want to attach mouse movement to that macro while it is running. There is no function for checking if a macro is currently running to just loop and stop the lua-side. So I'm looking for a possibility in Lua to 'run a loop independent' which does not stop the execution of the rest of my script (to check if a status variable [isMacroRunning] has changed). I also want to break that macro if i hit another button while the macro is running. BUT if i loop the mouse-movement, i cannot trigger another onEvent-function because the script-pointer(?) is still stuck in my loop. My current idea is to break that with a coroutine but iam not sure how to continue while no key-input is happening.

The script doesnt stop and wait if it encounters 'PlayMacro()', also this API-Function has no return value to just attach lua actions to the PlayMacro-function.

There would be also the possibility to transfer the LGHUB-macro (essentially its just pressButton A and leftclick for 40s then release the buttons) but that doesnt solve the problem (at least i cant find a solution within this) with the function being stuck in the loop and no way to break it. For example, if MouseButton11 triggers a loop and i press MouseButton10, the $arg variable does not change to 10 but stays at 11 because the script-pointer(?) is still in the loop instead of triggering the onEvent function.

The script seems to get executed once at load (example on switching mouse-profiles) and then the onEvent-function listens. If i could somehow run a looping check on [isMacroRunning] while still be able to trigger the onEvent-function, i can make this work. But otherwise i know to little about Lua and its behavior.

Edit1: Added "essential script" which only describes the needed core-functions. This is not working due to a 2nd onEvent cannot be triggered until the 1st onEvent has finished. But the 1st onEvent is designed to break on a variable change. The variable change is triggered in the 2nd onEvent. Needed solution: some kind of workaround or use of other Lua functions to seperate the 1st onEvent execution from the 2nd onEvent.

Essential Script:

```
isMacroRunning = false

function wiggle()
    PressKey("a")
    while true do
        if not isMacroRunning then break end

        OutputLogMessage("wiggle\n")
        MoveMouseRelative (5, 0)
        Sleep(150)
        MoveMouseRelative (-5, 0)
        Sleep(150)
    end
end

function OnEvent(event, arg)
    if (event == "MOUSE_BUTTON_PRESSED" and arg == 11) then
        isMacroRunning = true
        wiggle()
    end
    if(event == "MOUSE_BUTTON_PRESSED" and arg == 10 and isMacroRunning) then
        isMacroRunning = false
        ReleaseKey("a")
    end
end
´´´

Full Script:

    local isMacroRunning = false
    
    coco = coroutine.create(function()
        while true do
            if not isMacroRunning then break end
            MoveMouseRelative (5, 0)
            Sleep(150)
            MoveMouseRelative (-5, 0)
            Sleep(150)
            coroutine.yield()
        end
    end)
    
    function OnEvent(event, arg)
        if (event == "MOUSE_BUTTON_PRESSED" and arg == 11) then
            isMacroRunning = true
            runMacro()
        elseif(event == "MOUSE_BUTTON_PRESSED" and arg == 10 and isMacroRunning) then
            isMacroRunning = false
            runMacro()
        end
    end
    
    function runMacro()
        if isMacroRunning then
            PlayMacro('farm')
            coroutine.resume(coco)
            OutputLogMessage("Start Macro\n")
        else
            AbortMacro()
            OutputLogMessage("Aborted\n")
        end
    end
    
    
    coroutine.resume(coco)
´´´

Solution

  • Step 1.
    Make sure you're not using MB#4 ("backward") in the game.
    If some action is assigned to MB#4 in the game, do the following:

    • choose keyboard button you don't currently use in the game (for example, F12)
    • goto GHUB(KEYS tab); bind F12 to your physical MB#4
    • goto game options; bind the action to F12 instead of MB#4

    Now when you press physical MB#4, the game sees F12 and executes your old action.


    Step 2.
    Goto GHUB(SYSTEM tab); bind "Back" to MB#10


    Step 3.
    The script.

    function OnEvent(event, arg)
       if event == "MOUSE_BUTTON_PRESSED" and arg == 11 then
          PressMouseButton(1)      -- down LMB
          PressKey("A")            -- down "A"
          repeat
             MoveMouseRelative(5,0)
             Sleep(150)
             MoveMouseRelative(-5,0)
             Sleep(150)
          until IsMouseButtonPressed(4)  -- btn#4 is bound to btn#10
          ReleaseKey("A")          -- up "A"
          ReleaseMouseButton(1)    -- up LMB
       end
    end
    

    How does it work:
    When you press MB#11, the loop starts.
    When you later press MB#10, IsMouseButtonPressed() sees that button#4 is pressed, and the loop exits.