mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-15 18:30:27 -04:00
timer implementation on the lua side (driven via event.fire)
This commit is contained in:
parent
12da32bc6c
commit
d7905fe737
@ -19,6 +19,8 @@
|
||||
command that will be executed when pressing enter.
|
||||
]]
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
--[[ Distribute signals as events. ]]
|
||||
local listeners = {}
|
||||
local weakListeners = {}
|
||||
@ -36,6 +38,7 @@ end
|
||||
|
||||
--[[ Event API table. ]]
|
||||
event = {}
|
||||
local timers = {}
|
||||
|
||||
--[[ Register a new event listener for the specified event. ]]
|
||||
function event.listen(name, callback, weak)
|
||||
@ -53,23 +56,69 @@ end
|
||||
function event.fire(name, ...)
|
||||
if name then
|
||||
for callback, _ in pairs(listenersFor(name, false)) do
|
||||
callback(name, ...)
|
||||
local result, message = xpcall(callback, event.error, name, ...)
|
||||
if not result and message then
|
||||
error(message, 0)
|
||||
end
|
||||
end
|
||||
for callback, _ in pairs(listenersFor(name, true)) do
|
||||
callback(name, ...)
|
||||
local result, message = xpcall(callback, event.error, name, ...)
|
||||
if not result and message then
|
||||
error(message, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
local elapsed = {}
|
||||
for id, info in pairs(timers) do
|
||||
if info.after < os.clock() then
|
||||
elapsed[id] = info
|
||||
end
|
||||
end
|
||||
for id, _ in pairs(elapsed) do
|
||||
timers[id] = nil
|
||||
end
|
||||
for _, info in pairs(elapsed) do
|
||||
local result, message = xpcall(info.callback, event.error)
|
||||
if not result and message then
|
||||
error(message, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[ Calls the specified function after the specified time. ]]
|
||||
function event.after(timeout, callback)
|
||||
local id = #timers
|
||||
timers[id] = {after = os.clock() + timeout, callback = callback}
|
||||
return id
|
||||
end
|
||||
|
||||
function event.cancel(timerId)
|
||||
checkArg(1, timerId, "number")
|
||||
timers[timerId] = nil
|
||||
end
|
||||
|
||||
--[[ Error handler for ALL event callbacks. If this returns a value,
|
||||
the computer will crash. Otherwise it'll keep going. ]]
|
||||
function event.error(message)
|
||||
return message
|
||||
end
|
||||
|
||||
--[[ Suspends a thread for the specified amount of time. ]]
|
||||
function coroutine.sleep(seconds)
|
||||
checkArg(1, seconds, "number")
|
||||
local target = os.clock() + seconds
|
||||
repeat
|
||||
event.fire(os.signal(nil, target - os.clock()))
|
||||
local closest = target
|
||||
for _, info in pairs(timers) do
|
||||
if info.after < closest then
|
||||
closest = info.after
|
||||
end
|
||||
end
|
||||
event.fire(os.signal(nil, closest - os.clock()))
|
||||
until os.clock() >= target
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
--[[ Keep track of connected components across address changes. ]]
|
||||
local components = {}
|
||||
@ -122,6 +171,7 @@ event.listen("component_changed", function(_, newAddress, oldAddress)
|
||||
components[id].address = newAddress
|
||||
end)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
--[[ Setup terminal API. ]]
|
||||
local idGpu, idScreen = 0, 0
|
||||
@ -166,16 +216,6 @@ event.listen("screen_resized", function(_, address, w, h)
|
||||
end
|
||||
end)
|
||||
|
||||
term = {}
|
||||
|
||||
function term.gpu()
|
||||
return boundGpu
|
||||
end
|
||||
|
||||
function term.screenSize()
|
||||
return screenWidth, screenHeight
|
||||
end
|
||||
|
||||
local function bindIfPossible()
|
||||
if idGpu > 0 and idScreen > 0 then
|
||||
if not boundGpu then
|
||||
@ -192,6 +232,16 @@ local function bindIfPossible()
|
||||
end
|
||||
end
|
||||
|
||||
term = {}
|
||||
|
||||
function term.gpu()
|
||||
return boundGpu
|
||||
end
|
||||
|
||||
function term.screenSize()
|
||||
return screenWidth, screenHeight
|
||||
end
|
||||
|
||||
function term.gpuId(id)
|
||||
if id then
|
||||
checkArg(1, id, "number")
|
||||
@ -272,6 +322,7 @@ write = function(...)
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
--[[ Primitive command line. ]]
|
||||
local command = ""
|
||||
|
@ -232,7 +232,8 @@ return pcall(function()
|
||||
deadline = os.realTime() + 3
|
||||
local result = {coroutine.resume(init, table.unpack(data))}
|
||||
if result[1] then
|
||||
-- Init should never return, so we have a system yield.
|
||||
-- Init should never return, so we have a yield. The first yielded
|
||||
-- value can only be set by system yields.
|
||||
result = result[2]
|
||||
else
|
||||
-- Some other error, go kill ourselves.
|
||||
|
@ -44,7 +44,10 @@ class TileEntityComputer(isClient: Boolean) extends TileEntityRotatable with ICo
|
||||
}
|
||||
}
|
||||
|
||||
override protected def onReconnect() = computer.signal("address_change", address)
|
||||
override protected def onReconnect() = {
|
||||
super.onReconnect()
|
||||
computer.signal("address_change", address)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// General
|
||||
|
Loading…
x
Reference in New Issue
Block a user