From bd14223ea86e607bfe5e3cbeb02d33542c0c2ec9 Mon Sep 17 00:00:00 2001 From: SquidDev Date: Thu, 4 May 2017 10:49:41 +0100 Subject: [PATCH] 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. --- src/main/resources/assets/computercraft/lua/bios.lua | 8 ++++---- .../assets/computercraft/lua/rom/apis/parallel | 6 +++--- .../computercraft/lua/rom/programs/advanced/multishell | 10 +++++----- .../assets/computercraft/lua/rom/programs/monitor | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/resources/assets/computercraft/lua/bios.lua b/src/main/resources/assets/computercraft/lua/bios.lua index 5b4a10f52..3218f6d64 100644 --- a/src/main/resources/assets/computercraft/lua/bios.lua +++ b/src/main/resources/assets/computercraft/lua/bios.lua @@ -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 diff --git a/src/main/resources/assets/computercraft/lua/rom/apis/parallel b/src/main/resources/assets/computercraft/lua/rom/apis/parallel index db63a3ec5..5c2d06faf 100644 --- a/src/main/resources/assets/computercraft/lua/rom/apis/parallel +++ b/src/main/resources/assets/computercraft/lua/rom/apis/parallel @@ -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 diff --git a/src/main/resources/assets/computercraft/lua/rom/programs/advanced/multishell b/src/main/resources/assets/computercraft/lua/rom/programs/advanced/multishell index cf73b35bd..15c58cb4f 100644 --- a/src/main/resources/assets/computercraft/lua/rom/programs/advanced/multishell +++ b/src/main/resources/assets/computercraft/lua/rom/programs/advanced/multishell @@ -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 ) diff --git a/src/main/resources/assets/computercraft/lua/rom/programs/monitor b/src/main/resources/assets/computercraft/lua/rom/programs/monitor index bf123516d..2cb47ada4 100644 --- a/src/main/resources/assets/computercraft/lua/rom/programs/monitor +++ b/src/main/resources/assets/computercraft/lua/rom/programs/monitor @@ -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