mirror of
https://github.com/IgorTimofeev/MineOS.git
synced 2025-12-20 02:59:20 +01:00
Create Event.lua
This commit is contained in:
parent
2b68b4b4f9
commit
8f5e89a645
@ -1,134 +1,138 @@
|
||||
|
||||
local event, handlers, interruptingKeysDown, lastInterrupt = {
|
||||
interruptingEnabled = true,
|
||||
interruptingDelay = 1,
|
||||
interruptingFunction = error,
|
||||
defaultInterruptingFunction = error,
|
||||
interruptingKeyCodes = {
|
||||
[29] = true,
|
||||
[46] = true,
|
||||
[56] = true
|
||||
},
|
||||
push = computer.pushSignal
|
||||
interruptingEnabled = true,
|
||||
interruptingDelay = 1,
|
||||
defaultInterruptingFunction = function()
|
||||
error("interrupted", 0)
|
||||
end,
|
||||
interruptingKeyCodes = {
|
||||
[29] = true,
|
||||
[46] = true,
|
||||
[56] = true
|
||||
},
|
||||
push = computer.pushSignal
|
||||
}, {}, {}, 0
|
||||
|
||||
event.interruptingFunction = event.defaultInterruptingDFunction
|
||||
|
||||
local computerPullSignal, computerUptime, mathHuge, mathMin, skipSignalType = computer.pullSignal, computer.uptime, math.huge, math.min
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
function event.addHandler(callback, interval, times)
|
||||
checkArg(1, callback, "function")
|
||||
checkArg(2, interval, "number", "nil")
|
||||
checkArg(3, times, "number", "nil")
|
||||
checkArg(1, callback, "function")
|
||||
checkArg(2, interval, "number", "nil")
|
||||
checkArg(3, times, "number", "nil")
|
||||
|
||||
local handler = {
|
||||
callback = callback,
|
||||
times = times or mathHuge,
|
||||
interval = interval,
|
||||
nextTriggerTime = interval and computerUptime() + interval or 0
|
||||
}
|
||||
local handler = {
|
||||
callback = callback,
|
||||
times = times or mathHuge,
|
||||
interval = interval,
|
||||
nextTriggerTime = interval and computerUptime() + interval or 0
|
||||
}
|
||||
|
||||
handlers[handler] = true
|
||||
handlers[handler] = true
|
||||
|
||||
return handler
|
||||
return handler
|
||||
end
|
||||
|
||||
function event.removeHandler(handler)
|
||||
checkArg(1, handler, "table")
|
||||
checkArg(1, handler, "table")
|
||||
|
||||
if handlers[handler] then
|
||||
handlers[handler] = nil
|
||||
if handlers[handler] then
|
||||
handlers[handler] = nil
|
||||
|
||||
return true
|
||||
else
|
||||
return false, "Handler with given table is not registered"
|
||||
end
|
||||
return true
|
||||
else
|
||||
return false, "Handler with given table is not registered"
|
||||
end
|
||||
end
|
||||
|
||||
function event.getHandlers()
|
||||
return handlers
|
||||
return handlers
|
||||
end
|
||||
|
||||
function event.skip(signalType)
|
||||
skipSignalType = signalType
|
||||
skipSignalType = signalType
|
||||
end
|
||||
|
||||
function event.pull(preferredTimeout)
|
||||
local uptime, signalData = computerUptime()
|
||||
local deadline = uptime + (preferredTimeout or mathHuge)
|
||||
|
||||
repeat
|
||||
-- Determining pullSignal timeout
|
||||
timeout = deadline
|
||||
for handler in pairs(handlers) do
|
||||
if handler.nextTriggerTime > 0 then
|
||||
timeout = mathMin(timeout, handler.nextTriggerTime)
|
||||
end
|
||||
end
|
||||
local uptime, signalData = computerUptime()
|
||||
local deadline = uptime + (preferredTimeout or mathHuge)
|
||||
|
||||
repeat
|
||||
-- Determining pullSignal timeout
|
||||
timeout = deadline
|
||||
for handler in pairs(handlers) do
|
||||
if handler.nextTriggerTime > 0 then
|
||||
timeout = mathMin(timeout, handler.nextTriggerTime)
|
||||
end
|
||||
end
|
||||
|
||||
-- Pulling signal data
|
||||
signalData = { computerPullSignal(timeout - computerUptime()) }
|
||||
|
||||
-- Handlers processing
|
||||
for handler in pairs(handlers) do
|
||||
if handler.times > 0 then
|
||||
uptime = computerUptime()
|
||||
-- Pulling signal data
|
||||
signalData = { computerPullSignal(timeout - computerUptime()) }
|
||||
|
||||
-- Handlers processing
|
||||
for handler in pairs(handlers) do
|
||||
if handler.times > 0 then
|
||||
uptime = computerUptime()
|
||||
|
||||
if
|
||||
handler.nextTriggerTime <= uptime
|
||||
then
|
||||
handler.times = handler.times - 1
|
||||
if handler.nextTriggerTime > 0 then
|
||||
handler.nextTriggerTime = uptime + handler.interval
|
||||
end
|
||||
if
|
||||
handler.nextTriggerTime <= uptime
|
||||
then
|
||||
handler.times = handler.times - 1
|
||||
if handler.nextTriggerTime > 0 then
|
||||
handler.nextTriggerTime = uptime + handler.interval
|
||||
end
|
||||
|
||||
-- Callback running
|
||||
handler.callback(table.unpack(signalData))
|
||||
end
|
||||
else
|
||||
handlers[handler] = nil
|
||||
end
|
||||
end
|
||||
-- Callback running
|
||||
handler.callback(table.unpack(signalData))
|
||||
end
|
||||
else
|
||||
handlers[handler] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Program interruption support. It's faster to do it here instead of registering handlers
|
||||
if (signalData[1] == "key_down" or signalData[1] == "key_up") and event.interruptingEnabled then
|
||||
-- Analysing for which interrupting key is pressed - we don't need keyboard API for this
|
||||
if event.interruptingKeyCodes[signalData[4]] then
|
||||
interruptingKeysDown[signalData[4]] = signalData[1] == "key_down" and true or nil
|
||||
end
|
||||
-- Program interruption support. It's faster to do it here instead of registering handlers
|
||||
if (signalData[1] == "key_down" or signalData[1] == "key_up") and event.interruptingEnabled then
|
||||
-- Analysing for which interrupting key is pressed - we don't need keyboard API for this
|
||||
if event.interruptingKeyCodes[signalData[4]] then
|
||||
interruptingKeysDown[signalData[4]] = signalData[1] == "key_down" and true or nil
|
||||
end
|
||||
|
||||
local shouldInterrupt = true
|
||||
for keyCode in pairs(event.interruptingKeyCodes) do
|
||||
if not interruptingKeysDown[keyCode] then
|
||||
shouldInterrupt = false
|
||||
end
|
||||
end
|
||||
|
||||
if shouldInterrupt and uptime - lastInterrupt > event.interruptingDelay then
|
||||
lastInterrupt = uptime
|
||||
event.interruptingFunction("interrupted", 0)
|
||||
end
|
||||
end
|
||||
|
||||
-- Loop-breaking condition
|
||||
if signalData[1] then
|
||||
if signalData[1] == skipSignalType then
|
||||
skipSignalType = nil
|
||||
else
|
||||
return table.unpack(signalData)
|
||||
end
|
||||
end
|
||||
until uptime >= deadline
|
||||
local shouldInterrupt = true
|
||||
for keyCode in pairs(event.interruptingKeyCodes) do
|
||||
if not interruptingKeysDown[keyCode] then
|
||||
shouldInterrupt = false
|
||||
end
|
||||
end
|
||||
|
||||
if shouldInterrupt and uptime - lastInterrupt > event.interruptingDelay then
|
||||
lastInterrupt = uptime
|
||||
|
||||
event.interruptingFunction()
|
||||
end
|
||||
end
|
||||
|
||||
-- Loop-breaking condition
|
||||
if signalData[1] then
|
||||
if signalData[1] == skipSignalType then
|
||||
skipSignalType = nil
|
||||
else
|
||||
return table.unpack(signalData)
|
||||
end
|
||||
end
|
||||
until uptime >= deadline
|
||||
end
|
||||
|
||||
-- Sleeps "time" of seconds via "busy-wait" concept
|
||||
function event.sleep(time)
|
||||
checkArg(1, time, "number", "nil")
|
||||
checkArg(1, time, "number", "nil")
|
||||
|
||||
local deadline = computerUptime() + (time or 0)
|
||||
repeat
|
||||
event.pull(deadline - computerUptime())
|
||||
until computerUptime() >= deadline
|
||||
local deadline = computerUptime() + (time or 0)
|
||||
repeat
|
||||
event.pull(deadline - computerUptime())
|
||||
until computerUptime() >= deadline
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user