Il modo più semplice per fare in modo che lo script lua attenda / pausa / sospensione / blocco per qualche secondo?

Non riesco a capire come ottenere lua per fare trucchi temporali comuni, come ad esempio

E ho letto che a

while os.clock()<time_point do --nothing end 

mangia il tempo della CPU.

Eventuali suggerimenti? C’è una chiamata API che mi manca?

AGGIORNAMENTO : Ho scritto questa domanda molto tempo fa cercando di convincere Wow Lua a ripetere le azioni su un programma (es. Stand, attendere 1 secondo, ballare, aspettare 2 secondi, sedersi. Senza pause, accadono quasi tutte nello stesso quarto di secondo. ) Come si è scoperto, WOW aveva intenzionalmente distriggersto praticamente tutto ciò che consente di agire su un orologio perché potrebbe interrompere il gioco o abilitare i bot. Ho pensato di ricreare un orologio una volta che era stato portato via, avrei dovuto fare qualcosa di pazzo come creare un array di lavoro (con un’azione e tempo di esecuzione) e quindi registrare un gestore di eventi su una serie di eventi comuni, come mossa del mouse, quindi nel gestore pari, elaborare qualsiasi azione il cui tempo era arrivato. Il gestore di eventi in realtà non accadrebbe ogni X millisecondi, ma se accadesse ogni 2-100 ms, sarebbe abbastanza vicino. Purtroppo non l’ho mai provato.

Non è più facile di così. Il sonno potrebbe essere implementato nel FLTK o in qualsiasi altro modo, ma questo copre tutti i modi migliori per eseguire un sistema standard di sospensione del sistema senza interruzioni di eventi speciali. ecco:

 -- 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 

[Stavo per postare questo come commento sul post di John Cromartie , ma non mi ero reso conto che non si poteva usare la formattazione in un commento.]

Sono d’accordo. Lasciarlo in una shell con os.execute () funzionerà sicuramente, ma in generale fare le chiamate di shell è costoso. Il wrapping del codice C sarà molto più rapido in fase di esecuzione. In C / C ++ su un sistema Linux, è ansible utilizzare:

 static int lua_sleep(lua_State *L) { int m = static_cast (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; } 

Quindi, in main, fai:

 lua_pushcfunction(L, lua_sleep); lua_setglobal(L, "sleep"); 

dove “L” è il tuo lua_State. Quindi, nel tuo script Lua chiamato da C / C ++, puoi usare la tua funzione chiamando:

 sleep(1000) -- Sleeps for one second 

Se ti capita di usare LuaSocket nel tuo progetto, o semplicemente di averlo installato e non ti dispiace usarlo, puoi usare la funzione socket.sleep(time) che dorme per un dato periodo di tempo (in secondi).

Funziona sia su Windows che su Unix e non è necessario compilare moduli aggiuntivi.

Dovrei aggiungere che la funzione supporta i secondi frazionari come parametro, ad esempio socket.sleep(0.5) dormirà per mezzo secondo. Usa Sleep() su Windows e nanosleep() altrove, quindi potresti avere problemi con la precisione di Windows quando il time diventa troppo basso.

Non puoi farlo in puro Lua senza mangiare CPU, ma c’è un modo semplice e non portabile:

os.execute (“sleep 1”)

(bloccherà)

Ovviamente, questo funziona solo su sistemi operativi per i quali “sleep 1” è un comando valido, ad esempio Unix, ma non Windows.

per Windows puoi fare questo:

 os.execute("CHOICE /n /d:y /c:yn /t:5") 

Funzione Sleep – Uso: sleep(1) -- sleeps for 1 second

 local clock = os.clock function sleep(n) -- seconds local t0 = clock() while clock() - t0 <= n do end end 

Funzione di pausa - Uso: pause() -- pause and waits for the Return key

 function pause() io.stdin:read'*l' end 

spero, questo è quello che ti serviva! : D - Joe DF

Implementerei una semplice funzione per avvolgere la funzione sleep del sistema host in C.

Pure Lua usa solo ciò che è nello standard ANSI C. Il modulo lposix di Luiz Figuereido contiene molte cose di cui hai bisogno per fare cose più sistemiche.

Per la seconda richiesta, sospendi / attendi, dove interrompi l’elaborazione in Lua e continui a eseguire l’applicazione, hai bisogno di coroutine. Si finisce con un codice C simile a questo:

 Lthread=lua_newthread(L); luaL_loadfile(Lthread, file); while ((status=lua_resume(Lthread, 0) == LUA_YIELD) { /* do some C code here */ } 

e in Lua, hai il seguente:

 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') 

Sono d’accordo con John su come avvolgere la funzione sleep. Si potrebbe anche usare questa funzione di sonno avvolto per implementare una funzione di pausa in lua (che sarebbe semplicemente dormire, quindi controllare per vedere se una certa condizione è cambiata ogni tanto). Un’alternativa è usare ganci.

Non sono esattamente sicuro di cosa intendi con il tuo terzo punto (i comandi di solito non vengono completati prima dell’esecuzione del prossimo?) Ma anche i ganci potrebbero essere d’aiuto.

Vedi: Domanda: Come posso terminare un thread Lua in modo pulito? per un esempio di utilizzo di ganci.

Puoi usare:

 os.execute("sleep 1") -- I think you can do every command of CMD using os.execute("command") 

oppure puoi usare:

 function wait(waitTime) timer = os.time() repeat until os.time() > timer + waitTime end wait(YourNumberHere) 

Vuoi win.Sleep(milliseconds) , mi pare.

Sì, sicuramente non vuoi fare un indaffarato-aspetta come descrivi.

È anche facile usare Alien come wrapper libc / msvcrt:

 > luarocks install alien 

Quindi da 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') 

Avvertenza: non l’ho provato su MSWindows; Non so nemmeno se msvcrt ha un usleep ()

Ho iniziato con Lua ma, poi ho scoperto che volevo vedere i risultati invece del buon vecchio flash da linea di comando. Quindi ho appena aggiunto la seguente riga al mio file e hey presto, lo standard:

 please press any key to continue... os.execute("PAUSE") 

Il mio file di esempio è solo una stampa e quindi una pausa, quindi sono sicuro che non ti serva quella postata qui.

Non sono sicuro delle implicazioni della CPU di eseguire un processo per uno script completo. Tuttavia, potrebbe essere utile interrompere il stream medio del codice nel debug.

Credo che per windows tu possa usare: os.execute("ping 1.1.1.1 /n 1 /w come un semplice timer. (Rimuovi il” <> “quando inserisci il tempo in millisecondi) (lì è uno spazio tra il resto del codice e >nul )

Questo dovrebbe funzionare:

  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