This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
cyanisaac's profile picture

{SOLVED} Looking for a workaround to a potential bug with CC.

Started by cyanisaac, 27 June 2015 - 12:49 AM
cyanisaac #1
Posted 27 June 2015 - 02:49 AM
I have created a superterminate button in my OS. It works by having a parallel.waitForAny, and it ends any program once the function designed to end when it is triggered is triggered.

The issue is that when the textutils API is called with a paged whatever function (pagedTabulate for instance). It will make all of the output on the screen pause and wait for a keypress (with "press any key to continue") shown. This is because, I think, textutils is overriding stuff.

Can anyone give me a workaround to this? I need to backup and restore any values the textutils API overrides when doing anything with paged scrolling.

EDIT: Here are the OSes affected, in case you are wondering:
  • O[OS] by ProjectB, and any modifications and redistributions of it.
  • OpenTerminalOS by cyanisaac, and any modifications and redistributions of it.
EDIT 2: THE BUG HAS BEEN FIXED. SEE THE FIX BELOW:

local currentTerm = term.current()
--# run your parallel code
term.redirect(currentTerm)

Credit to MKLegoman357 for this fix.
Edited on 27 June 2015 - 04:36 PM
KingofGamesYami #2
Posted 27 June 2015 - 03:04 AM
relevant source code

local function makePagedScroll( _term, _nFreeLines )
    local nativeScroll = _term.scroll
    local nFreeLines = _nFreeLines or 0
    return function( _n )
        for n=1,_n do
            nativeScroll( 1 )

            if nFreeLines <= 0 then
                local w,h = _term.getSize()
                _term.setCursorPos( 1, h )
                _term.write( "Press any key to continue" )
                os.pullEvent( "key" )
                _term.clearLine()
                _term.setCursorPos( 1, h )
            else
                nFreeLines = nFreeLines - 1
            end
        end
    end
end

function pagedPrint( _sText, _nFreeLines )
    -- Setup a redirector
    local oldTerm = term.current()
    local newTerm = {}
    for k,v in pairs( oldTerm ) do
        newTerm[k] = v
    end
    newTerm.scroll = makePagedScroll( oldTerm, _nFreeLines )
    term.redirect( newTerm )

    -- Print the text
    local result
    local ok, err = pcall( function()
        result = print( _sText )
    end )

    -- Removed the redirector
    term.redirect( oldTerm )

    -- Propogate errors
    if not ok then
        error( err, 0 )
    end
    return result
end

As you can see, it "overrides" term.scroll. Hopefully, this helps.
cyanisaac #3
Posted 27 June 2015 - 03:25 AM
relevant source code

local function makePagedScroll( _term, _nFreeLines )
	local nativeScroll = _term.scroll
	local nFreeLines = _nFreeLines or 0
	return function( _n )
		for n=1,_n do
			nativeScroll( 1 )

			if nFreeLines <= 0 then
				local w,h = _term.getSize()
				_term.setCursorPos( 1, h )
				_term.write( "Press any key to continue" )
				os.pullEvent( "key" )
				_term.clearLine()
				_term.setCursorPos( 1, h )
			else
				nFreeLines = nFreeLines - 1
			end
		end
	end
end

function pagedPrint( _sText, _nFreeLines )
	-- Setup a redirector
	local oldTerm = term.current()
	local newTerm = {}
	for k,v in pairs( oldTerm ) do
		newTerm[k] = v
	end
	newTerm.scroll = makePagedScroll( oldTerm, _nFreeLines )
	term.redirect( newTerm )

	-- Print the text
	local result
	local ok, err = pcall( function()
		result = print( _sText )
	end )

	-- Removed the redirector
	term.redirect( oldTerm )

	-- Propogate errors
	if not ok then
		error( err, 0 )
	end
	return result
end

As you can see, it "overrides" term.scroll. Hopefully, this helps.

Hmm. This does seem like the right solution, however despite backing it up and then restoring it my OS continues to have the scrolling pause for a key.
Are you sure there's not something else being overriden as well?

Here's the code that should fix it but doesn't:

  local oldTermScroll = term.scroll
  parallel.waitForAny(forceQuit, runTheProgram)
  sleep(0)
  postInfoBar() -- Ignore this line, it is unimportant
  term.scroll = oldTermScroll
Edited on 27 June 2015 - 01:26 AM
Bomb Bloke #4
Posted 27 June 2015 - 03:28 AM
Where's the bit where you actually use your backed up "term.scroll()"…?
cyanisaac #5
Posted 27 June 2015 - 03:34 AM
Where's the bit where you actually use your backed up "term.scroll()"…?


term.scroll = oldTermScroll

It takes the backed up term.scroll (oldTermScroll = term.scroll) and has the overwritten term.scroll set back to its original.
Bomb Bloke #6
Posted 27 June 2015 - 03:52 AM
That's great and all, but doing it after the processes you passed to parallel.waitForAny have finished isn't going to help much.

No, the answer here is to override the relevant functions in the textutils API, so that they never attempt to mess with term. The reason they currently do it is so that Dan didn't have to re-write the functionality of the print() function into his "paged" functions - altering term so that all scroll attempts wait on user-input was a shortcut.
cyanisaac #7
Posted 27 June 2015 - 05:11 AM
That's great and all, but doing it after the processes you passed to parallel.waitForAny have finished isn't going to help much.

No, the answer here is to override the relevant functions in the textutils API, so that they never attempt to mess with term. The reason they currently do it is so that Dan didn't have to re-write the functionality of the print() function into his "paged" functions - altering term so that all scroll attempts wait on user-input was a shortcut.

Could someone do this for me? I find Dan200's code unreadable personally. Thanks :D/>
MKlegoman357 #8
Posted 27 June 2015 - 10:18 AM
Instead of backing up term.scroll, which is pointless anyway because it does't change, you should be getting the current term object, running your functions and then restoring the term object:


local currentTerm = term.current()

--# run your parallel code

term.redirect(currentTerm)
ProjectB #9
Posted 27 June 2015 - 04:58 PM
Instead of backing up term.scroll, which is pointless anyway because it does't change, you should be getting the current term object, running your functions and then restoring the term object:
 local currentTerm = term.current() --# run your parallel code term.redirect(currentTerm) 

Thanks a bunch, the current development O has the fix implemented and it works great. It will be out sometime today to all people on the dev stream.
Edited on 27 June 2015 - 02:58 PM
cyanisaac #10
Posted 27 June 2015 - 06:28 PM
Instead of backing up term.scroll, which is pointless anyway because it does't change, you should be getting the current term object, running your functions and then restoring the term object:
 local currentTerm = term.current() --# run your parallel code term.redirect(currentTerm) 

Thanks a BUNCH, the current development O2.1V3 has the fix implemented and it works pretty decent. It will be out this millennium to some people on the pork bacon chops

OpenTerminalOS has this fix ready to go for it's S4 release. Thank you very much good sir. This is super helpful.
Edited on 27 June 2015 - 04:30 PM