Der einfachste Weg, um Lua Script Warte / Pause / Schlaf / Block für ein paar Sekunden zu machen?

StackOverflow https://stackoverflow.com/questions/1034334

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

War es hilfreich?

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

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.

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

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top