Manually specify the number of values to unpack

table.unpack will often stop at the first nil value, meaning some event
arguments may be discarded. By storing the number of arguments through
table.pack, and then using that count when unpacking, we can ensure all
values are returned/resumed with.
This commit is contained in:
SquidDev 2017-05-04 10:49:41 +01:00
parent 58e6e9ea46
commit bd14223ea8
4 changed files with 15 additions and 15 deletions

View File

@ -175,11 +175,11 @@ function os.pullEventRaw( sFilter )
end
function os.pullEvent( sFilter )
local eventData = { os.pullEventRaw( sFilter ) }
local eventData = table.pack( os.pullEventRaw( sFilter ) )
if eventData[1] == "terminate" then
error( "Terminated", 0 )
end
return table.unpack( eventData )
return table.unpack( eventData, 1, eventData.n )
end
-- Install globals
@ -550,13 +550,13 @@ end
-- Install the rest of the OS api
function os.run( _tEnv, _sPath, ... )
local tArgs = { ... }
local tArgs = table.pack( ... )
local tEnv = _tEnv
setmetatable( tEnv, { __index = _G } )
local fnFile, err = loadfile( _sPath, tEnv )
if fnFile then
local ok, err = pcall( function()
fnFile( table.unpack( tArgs ) )
fnFile( table.unpack( tArgs, 1, tArgs.n ) )
end )
if not ok then
if err and err ~= "" then

View File

@ -14,13 +14,13 @@ local function runUntilLimit( _routines, _limit )
local living = count
local tFilters = {}
local eventData = {}
local eventData = { n = 0 }
while true do
for n=1,count do
local r = _routines[n]
if r then
if tFilters[r] == nil or tFilters[r] == eventData[1] or eventData[1] == "terminate" then
local ok, param = coroutine.resume( r, table.unpack(eventData) )
local ok, param = coroutine.resume( r, table.unpack( eventData, 1, eventData.n ) )
if not ok then
error( param, 0 )
else
@ -46,7 +46,7 @@ local function runUntilLimit( _routines, _limit )
end
end
end
eventData = { os.pullEventRaw() }
eventData = table.pack( os.pullEventRaw() )
end
end

View File

@ -47,7 +47,7 @@ local function resumeProcess( nProcess, sEvent, ... )
end
local function launchProcess( tProgramEnv, sProgramPath, ... )
local tProgramArgs = { ... }
local tProgramArgs = table.pack( ... )
local nProcess = #tProcesses + 1
local tProcess = {}
tProcess.sTitle = fs.getName( sProgramPath )
@ -57,7 +57,7 @@ local function launchProcess( tProgramEnv, sProgramPath, ... )
tProcess.window = window.create( parentTerm, 1, 1, w, h, false )
end
tProcess.co = coroutine.create( function()
os.run( tProgramEnv, sProgramPath, table.unpack( tProgramArgs ) )
os.run( tProgramEnv, sProgramPath, table.unpack( tProgramArgs, 1, tProgramArgs.n ) )
if not tProcess.bInteracted then
term.setCursorBlink( false )
print( "Press any key to continue" )
@ -222,7 +222,7 @@ redrawMenu()
-- Run processes
while #tProcesses > 0 do
-- Get the event
local tEventData = { os.pullEventRaw() }
local tEventData = table.pack( os.pullEventRaw() )
local sEvent = tEventData[1]
if sEvent == "term_resize" then
-- Resize event
@ -233,7 +233,7 @@ while #tProcesses > 0 do
elseif sEvent == "char" or sEvent == "key" or sEvent == "key_up" or sEvent == "paste" or sEvent == "terminate" then
-- Keyboard event
-- Passthrough to current process
resumeProcess( nCurrentProcess, table.unpack( tEventData ) )
resumeProcess( nCurrentProcess, table.unpack( tEventData, 1, tEventData.n ) )
if cullProcess( nCurrentProcess ) then
setMenuVisible( #tProcesses >= 2 )
redrawMenu()
@ -280,7 +280,7 @@ while #tProcesses > 0 do
-- Passthrough to all processes
local nLimit = #tProcesses -- Storing this ensures any new things spawned don't get the event
for n=1,nLimit do
resumeProcess( n, table.unpack( tEventData ) )
resumeProcess( n, table.unpack( tEventData, 1, tEventData.n ) )
end
if cullProcesses() then
setMenuVisible( #tProcesses >= 2 )

View File

@ -43,13 +43,13 @@ end
local ok, param = pcall( function()
local sFilter = resume()
while coroutine.status( co ) ~= "dead" do
local tEvent = { os.pullEventRaw() }
local tEvent = table.pack( os.pullEventRaw() )
if sFilter == nil or tEvent[1] == sFilter or tEvent[1] == "terminate" then
sFilter = resume( table.unpack( tEvent ) )
sFilter = resume( table.unpack( tEvent, 1, tEvent.n ) )
end
if coroutine.status( co ) ~= "dead" and (sFilter == nil or sFilter == "mouse_click") then
if tEvent[1] == "monitor_touch" and tEvent[2] == sName then
sFilter = resume( "mouse_click", 1, table.unpack( tEvent, 3 ) )
sFilter = resume( "mouse_click", 1, table.unpack( tEvent, 3, tEvent.n ) )
end
end
if coroutine.status( co ) ~= "dead" and (sFilter == nil or sFilter == "term_resize") then