Der einfachste Weg, um Lua Script Warte / Pause / Schlaf / Block für ein paar Sekunden zu machen?
-
06-07-2019 - |
Frage
Ich kann nicht herausfinden, wie lua bekommen alle gängigen Timing Tricks, wie
-
Schlaf - alle Maßnahmen auf Thread stoppen
-
Pause / wait - nicht zum nächsten weitergehen Befehl, aber zulassen, dass andere Code in der Anwendung fortsetzen
-
Block - nicht zum nächsten Befehl weitergehen, bis die aktuelle Rendite
Und ich habe gelesen, dass ein
while os.clock()<time_point do
--nothing
end
frisst CPU-Zeit.
Irgendwelche Vorschläge? Gibt es einen API-Aufruf fehle ich?
UPDATE :. Ich diese Frage schrieb vor langer Zeit WOW Lua replay Aktionen auf einem Zeitplan zu bekommen versuchen (dh steht, wartet 1 Sekunde, Tanz, wartet 2 Sekunden, sitzen, ohne Pausen, diese passieren fast alle im gleichen Quartal Sekunde.) Wie sich herausstellte WOW war absichtlich so ziemlich alles deaktiviert, die Aktion auf einer Uhr zu tun erlaubt, weil es das Spiel oder ermöglichen Bots brechen könnte. ich dachte an neu erstellen, sobald eine Uhr es weggenommen worden war, muß ich wie verrückt etwas tun würde, eine Arbeit Array erstellen (mit einer Aktion und die Ausführungszeit) und dann einen Event-Handler auf einer Reihe von gemeinsamen Veranstaltungen registrieren, wie Maus bewegen, dann in dem auch Handler Prozess hatte eine Aktion, deren Zeit gekommen. Der Event-Handler nicht tatsächlich alle X Millisekunden passieren, aber wenn es alle 2-100 ms vorging, wäre es nahe genug sein. Leider habe ich nie versucht.
Lösung
Es wird nicht einfacher als diese. Schlaf könnte in Ihrem FLTK oder was auch immer umgesetzt werden, aber dies deckt alle die besten Möglichkeiten, Standard Art von System zu tun, schläft ohne besonderes Ereignis Interrupts. Siehe da:
-- we "pcall" (try/catch) the "ex", which had better include os.sleep
-- it may be a part of the standard library in future Lua versions (past 5.2)
local ok,ex = pcall(require,"ex")
if ok then
-- print("Ex")
-- we need a hack now too? ex.install(), you say? okay
pcall(ex.install)
-- let's try something else. why not?
if ex.sleep and not os.sleep then os.sleep = ex.sleep end
end
if not os.sleep then
-- we make os.sleep
-- first by trying ffi, which is part of LuaJIT, which lets us write C code
local ok,ffi = pcall(require,"ffi")
if ok then
-- print("FFI")
-- we can use FFI
-- let's just check one more time to make sure we still don't have os.sleep
if not os.sleep then
-- okay, here is our custom C sleep code:
ffi.cdef[[
void Sleep(int ms);
int poll(struct pollfd *fds,unsigned long nfds,int timeout);
]]
if ffi.os == "Windows" then
os.sleep = function(sec)
ffi.C.Sleep(sec*1000)
end
else
os.sleep = function(sec)
ffi.C.poll(nil,0,sec*1000)
end
end
end
else
-- if we can't use FFI, we try LuaSocket, which is just called "socket"
-- I'm 99.99999999% sure of that
local ok,socket = pcall(require,"socket")
-- ...but I'm not 100% sure of that
if not ok then local ok,socket = pcall(require,"luasocket") end
-- so if we're really using socket...
if ok then
-- print("Socket")
-- we might as well confirm there still is no os.sleep
if not os.sleep then
-- our custom socket.select to os.sleep code:
os.sleep = function(sec)
socket.select(nil,nil,sec)
end
end
else
-- now we're going to test "alien"
local ok,alien = pcall(require,"alien")
if ok then
-- print("Alien")
-- beam me up...
if not os.sleep then
-- if we still don't have os.sleep, that is
-- now, I don't know what the hell the following code does
if alien.platform == "windows" then
kernel32 = alien.load("kernel32.dll")
local slep = kernel32.Sleep
slep:types{ret="void",abi="stdcall","uint"}
os.sleep = function(sec)
slep(sec*1000)
end
else
local pol = alien.default.poll
pol:types('struct', 'unsigned long', 'int')
os.sleep = function(sec)
pol(nil,0,sec*1000)
end
end
end
elseif package.config:match("^\\") then
-- print("busywait")
-- if the computer is politically opposed to NIXon, we do the busywait
-- and shake it all about
os.sleep = function(sec)
local timr = os.time()
repeat until os.time() > timr + sec
end
else
-- print("NIX")
-- or we get NIXed
os.sleep = function(sec)
os.execute("sleep " .. sec)
end
end
end
end
end
Andere Tipps
[Ich wollte dies als Kommentar hinterlassen auf John Cromartie des Post, aber wusste nicht, dass Sie nicht in einem Kommentar Formatierung nutzen könnten.]
Ich bin damit einverstanden. Dropping es zu einer Schale mit os.execute () wird auf jeden Fall arbeiten, aber im Allgemeinen macht Shell Anrufe ist teuer. einig C-Code Wrapping wird viel schneller zur Laufzeit sein. In C / C ++ auf einem Linux-System, können Sie verwenden:
static int lua_sleep(lua_State *L)
{
int m = static_cast<int> (luaL_checknumber(L,1));
usleep(m * 1000);
// usleep takes microseconds. This converts the parameter to milliseconds.
// Change this as necessary.
// Alternatively, use 'sleep()' to treat the parameter as whole seconds.
return 0;
}
Dann, in dem Haupt tun:
lua_pushcfunction(L, lua_sleep);
lua_setglobal(L, "sleep");
, wobei "L" ist Ihr lua_State. Dann Skript in Ihrem Lua von C / C ++ genannt, können Sie Ihre Funktion durch den Aufruf verwenden:
sleep(1000) -- Sleeps for one second
Wenn Sie LuaSocket in Ihrem Projekt passieren verwenden, oder muß es nur installiert und haben nichts dagegen, es zu benutzen, können Sie die socket.sleep(time)
Dies funktioniert sowohl unter Windows und Unix, und Sie müssen keine zusätzlichen Module kompiliert werden.
Ich sollte hinzufügen, dass die Funktion für Sekundenbruchteile als Parameter unterstützt, das heißt socket.sleep(0.5)
wird eine halbe Sekunde schlafen. Es verwendet Sleep()
auf Fenster und nanosleep()
an anderer Stelle, so dass Sie Probleme mit Windows Genauigkeit haben können, wenn time
zu niedrig werden.
Sie können es in reiner Lua nicht ohne CPU essen, aber es gibt eine einfache, nicht tragbare Weise:
os.execute ( "sleep 1")
(es wird Block)
Natürlich funktioniert dies nur auf Betriebssysteme, für die „sleep 1“ ist ein gültiger Befehl, zum Beispiel Unix, aber nicht unter Windows.
für Fenster können Sie dies tun:
os.execute("CHOICE /n /d:y /c:yn /t:5")
Sleep-Funktion - Verbrauch: sleep(1) -- sleeps for 1 second
local clock = os.clock
function sleep(n) -- seconds
local t0 = clock()
while clock() - t0 <= n do
end
end
Pause-Funktion - Verbrauch: pause() -- pause and waits for the Return key
function pause()
io.stdin:read'*l'
end
Hoffnung, das ist, was Sie brauchen! : D - Joe DF
Ich würde eine einfache Funktion implementieren, um das Host-System Sleep-Funktion in C zu wickeln.
Reine Lua verwendet nur, was ist in ANSI-Standard C Luiz Figuereido der
Für die zweite Anforderung, Pause / warten, wo Sie die Verarbeitung in Lua stoppen und weiterhin Ihre Anwendung auszuführen, müssen Sie Koroutinen. Sie enden wie diese folgenden mit C-Code auf: und in Lua, haben Sie die folgenden Schritte aus: Lthread=lua_newthread(L);
luaL_loadfile(Lthread, file);
while ((status=lua_resume(Lthread, 0) == LUA_YIELD) {
/* do some C code here */
}
function try_pause (func, param)
local rc=func(param)
while rc == false do
coroutine.yield()
rc=func(param)
end
end
function is_data_ready (data)
local rc=true
-- check if data is ready, update rc to false if not ready
return rc
end
try_pause(is_data_ready, data)
require 'alien'
if alien.platform == "windows" then
kernel32 = alien.load("kernel32.dll")
sleep = kernel32.Sleep
sleep:types{ret="void",abi="stdcall","uint"}
else
-- untested !!!
libc = alien.default
local usleep = libc.usleep
usleep:types('int', 'uint')
sleep = function(ms)
while ms > 1000 do
usleep(1000)
ms = ms - 1000
end
usleep(1000 * ms)
end
end
print('hello')
sleep(500) -- sleep 500 ms
print('world')
ich mit John überein, die Schlaf-Funktion auf Einwickeln. Sie könnten auch diese gewickelte Sleep-Funktion verwenden, um eine Pause-Funktion in Lua zu implementieren (die dann einfach schlafen würden überprüfen, um zu sehen, ob eine bestimmte Bedingung jeden so oft geändert hat). Eine Alternative ist der Haken zu verwenden.
Ich bin mir nicht ganz sicher, was Sie mit Ihrem dritten Listenpunkt bedeuten (keine Befehle in der Regel abgeschlossen, bevor die nächsten ausgeführt wird?), Aber Haken kann möglicherweise auch mit diesen helfen.
Siehe auch: Frage: Wie kann ich sauber ein Lua Fadenende Ein Beispiel für Haken.
Sie können mit:
os.execute("sleep 1") -- I think you can do every command of CMD using os.execute("command")
oder Sie verwenden können:
function wait(waitTime)
timer = os.time()
repeat until os.time() > timer + waitTime
end
wait(YourNumberHere)
Sie wollen win.Sleep(milliseconds)
, dünkt mich.
Ja, Sie definitiv nicht wollen, eine tun Belegt warten wie Sie beschreiben.
Es ist auch einfach Alien als libc / msvcrt Wrapper zu verwenden:
> luarocks install alien
Dann von lua:
require 'alien'
if alien.platform == "windows" then
-- untested!!
libc = alien.load("msvcrt.dll")
else
libc = alien.default
end
usleep = libc.usleep
usleep:types('int', 'uint')
function sleep(ms)
while ms > 1000 do
usleep(1000)
ms = ms - 1000
end
usleep(1000 * ms)
end
print('hello')
sleep(500) -- sleep 500 ms
print('world')
Caveat lector: Ich habe nicht versucht, diese auf MSWindows; Ich weiß nicht einmal, ob msvcrt eine usleep hat ()
Ich begann mit Lua, aber dann fand ich, dass ich die Ergebnisse und nicht nur die guten alten Kommandozeile blinken sehen wollte. Also habe ich nur die folgende Zeile in meiner Datei und schwupps, die Standard:
please press any key to continue...
os.execute("PAUSE")
Meine Beispieldatei ist nur ein Druck und dann so eine Pause statment Ich bin sicher, dass Sie nicht, dass hier gepostet müssen.
Ich bin nicht die CPU Auswirkungen eines sicher ein Verfahren für eine vollständige Skript ausgeführt wird. Jedoch stoppen könnte den Code Mitte fließt in dem Debuggen nützlich sein.
Ich glaube, für Fenster, die Sie verwenden können: os.execute("ping 1.1.1.1 /n 1 /w <time in milliseconds> >nul
als einfacher Timer.
(Entfernen des „<>“, wenn die Zeit in Millisekunden Einfügen) (es gibt einen Raum zwischen dem Rest des Codes und >nul
)
Dies sollte funktionieren:
os.execute("PAUSE")
cy = function()
local T = os.time()
coroutine.yield(coroutine.resume(coroutine.create(function()
end)))
return os.time()-T
end
sleep = function(time)
if not time or time == 0 then
time = cy()
end
local t = 0
repeat
local T = os.time()
coroutine.yield(coroutine.resume(coroutine.create(function() end)))
t = t + (os.time()-T)
until t >= time
end