Logitech Lua script for high precision sleep - lua

This is my attempt to make a Logitech high-precision delay, accurate to 1ms.
Why do you need high precision delay? Because starting with Win10 release 2004, Logitech Sleep(1) is actually sleeps for 15.6ms, so you might need a more precise Sleep() to preserve the original (Win10 1909) behavior of your old scripts.
function Sleep3(time)
local a = GetRunningTime()
while GetRunningTime()-a < time do
end
end
Is Sleep3() accuracy really equals to 1ms?

Logitech GetRunningTime() just invokes WinAPI function GetTickCount
As you can see from the doc,
The resolution of the GetTickCount function is limited to the resolution of the system timer, which is typically in the range of 10 milliseconds to 16 milliseconds
In other words, the values returned by GetRunningTime() are not sequential integers.
When you call GetRunningTime() in a loop, you will receive something like the following:
0,0,0,...,0,15,15,15,...,15,31,31,..,31,46,46,...
This means it is unable to make 1ms-precision delay by using GetRunningTime().
The actual precision of Sleep3() is 15ms, as usual Sleep() has.

function OnEvent(event,arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 4 then
a = GetRunningTime()
for i = 1,1000,1 do
Sleep(1)
end
OutputLogMessage((GetRunningTime() - a) / 1000)
end
end

Related

How to turn off a function after a desired amount of time?

I know my question would sound silly but I'm new to Lua so I'm trying to make the best practice as I can.
function wait(n)
local start = os.time()
repeat until os.time() > start + n
end
function hi(x)
while x do
print("Hi")
wait(.5)
end
end
hi(true)
For example, I want to turn off the function "hi" after running for 6 seconds and re-enable it after stopping for 2 seconds, how can I do it? Thank you so much!
Try this changes...
function wait(n)
local start = os.clock()
repeat until os.clock() > start + n
end
function hi(x)
for i = 1, x do
print("Hi")
wait(.5)
end
end
hi(4) -- With the hardcoded wait(.5) this will end after 2s
One warning.
Lua is fast so wait() will run in high performance mode.
Let it run by hi(120) for a minute will also run your fans in high cooling mode.
...it is better to have a more CPU friendly wait/sleep.
Easy Peasy with LuaJIT: https://luajit.org/ext_ffi_tutorial.html

Can I make my Lua program to sleep for AROUND a day?

I want to make my mydicebot (by seuntje) Lua program sleep AROUND A DAY, after betting for a day... like
function sleep(n)
t = os.clock()
while os.clock() - t <= n do
-- nothing
end
end
function playsleep()
sec = math.random(80000,90000)
sleep(sec) -- around 86400 seconds
end
timestart = os.time()
dur = math.random(70000,80000)
function dobet()
if os.time() - timestart < math.random then
playsleep()
end
timestart = os.time() -- reset the time counter
end
but when I call the playsleep function in the dobet function
it ends up I cannot click anything in my program, cannot move another tab also
and the CPU is not sleeping either, even get busy
and sometimes it stucks even after 90000 seconds
-- THE QUESTIONS --
A. so can I make a function where the sleep is a real sleep?
B. can it sleep until 90000 seconds?
C. or what is the max number of sleep in seconds for the variable "sec" above?
Use the posix module to sleep:
posix = require("posix")
posix.sleep(86400)
But this will still block your program and you won't be able to click anything. You will need to provide more detail about your program in order to receive better advice.
Also os is there.
Why not...
do os.execute('$(type -path sleep) '..(3600*24)) end
...?

Confused over precision of lua's os.clock

I thought Lua os.clock() returns times in second. But from the documentation here https://www.lua.org/pil/22.1.html, the example they have
local x = os.clock()
local s = 0
for i=1,100000 do s = s + i end
print(string.format("elapsed time: %.2f\n", os.clock() - x))
Is rounding the result to 2 decimal places. Is os.clock() returns second.ms?
Also running this in Lua gives
> print(os.clock())
0.024615
What are these decimal places?
os.clock and os.time are not the same sort of time.
os.time is dealing with "wall-clock time, the sort of time humans use.
os.clock is a counter reporting CPU time. The decimal number you get from os.clock is the number of seconds the CPU spent running the current task. The CPU time has no correlation to wall-clock time other than using the same base time units (seconds).

I want lua function to run once

I'm quite new to lua scripting.. now i'm trying to code in game boss
local function SlitherEvents(event, creature, attacker, damage)
if(creature:GetHealthPct() <= 60) then
creature:SendUnitYell("Will punish you all",0)
creature:RegisterEvent(AirBurst, 1000, 0) -- 1 seconds
return
end
end
this should make the boss talk when his health = 60% or less but it should run one time, when I run the code the boss keep saying and attacking all the time. How can I make it run once?
Use a boolean created outside the scope of the function callback:
local has_talked = false
local function SlitherEvents(event, creature, attacker, damage)
if creature:GetHealthPct() <= 60 and not has_talked then
has_talked = true
creature:SendUnitYell("Will punish you all",0)
creature:RegisterEvent(AirBurst, 1000, 1) -- 1 seconds
return
end
end
EDIT
If you are actually using the Eluna Engine's RegisterEvent call, then set the number of repeats to 1 and not 0. This will resolve the issue you had.

Lua Coroutine Error

I'm currently working on a simple 'guess the number' game using Lua. I'm programming through an app on my iPad called TouchLua+. One of the game modes is you have a certain amount of time to guess the number. I thought that to do this, I would create a coroutine that counts down from the given time. For some reason, I can't input a number while the coroutine is running. Can anyone help? Here is what I have so far.
target = math.random(1, 100)
coroutine.resume(coroutine.create(function()
for i = 1, roundTime do
sleep(1000)
sys.alert("tock")
end
lose = true
coroutine.yield()
end))
repeat
local n = tonumber(io.read())
if (n > target) then
print("Try a lower number.\n")
elseif (n < target) then
print("Try a higher number.\n")
else
win = true
end
until (lose or win)
return true
Coroutines are not a form of multiprocessing, they are a form of cooperative multithreading. As such, while the coroutine is running, nothing else is running. A coroutine is meant to yield control back to the caller often, and the caller is meant to resume the coroutine so the coroutine can continue where it yielded. You can see how this will appear to be parallel processing.
So in your case you would want to yield from inside the loop, after a small sleep time:
co = coroutine.create(function()
for i = 1, roundTime do
sleep(1)
sys.alert("tock")
coroutine.yield()
end
lose = true
end)
Unfortunately, you can't interrupt io.read(), which means the above is of no use. Ideally you would want a "io.peek" function so you could do the following:
while coroutine.status(co) ~= "dead" do
coroutine.resume(co)
if io.peek() then -- non-blocking, just checks if a key has been pressed
... get the answer and process ...
end
end
I am not aware of a non-blocking keyboard IO in Lua. You could create a C extension that exposes some of C non-blocking keyboard input to Lua, assuming that TouchLua+ supports C extensions. I doubt it, given that it is an iOS app.
It doesn't appear that there is a time loop or callbacks or such, and couldn't find docs. If you have option of creating a text box where user can enter answer and they have to click accept then you can measure how long it took. If there is a time loop you could check time there and show message if run out of time. All this is very easy to do in Corona, maybe not possible in TouchLua+.

Resources