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

Monitor Display Confusion

Started by Jaronel, 07 June 2013 - 08:41 PM
Jaronel #1
Posted 07 June 2013 - 10:41 PM
Greetings! I've been delving into the realm of Lua recently while playing a modpack that includes both ComputerCraft and OpenCCSensors. I am asking this question here because I feel that the OpenCCSensors part of this is not creating this issue.

And so, the issue! I have two similar lua programs, that both project onto their respective monitors (3x3 regular monitor, if it matters). The first program emits names as it should onto the monitor, starting from the top the names quickly move to the bottom of the monitor, and then remain there. There is no flickering. The second program should* do the exact same thing, but the names flicker constantly. I don't know if this is because I did something funky I do not know about, or if it is because I am calling for more information (perhaps a small lag spike not seen in first program for access time?). So here I am, asking for help from you fine folk.

First Program
Spoiler
os.loadAPI("ocs/apis/sensor")
local prox = sensor.wrap("top")
repeat
  local targets = prox.getTargets()
  term.clear()
  for name, basicDetails in pairs(targets) do
	term.redirect(peripheral.wrap("left"))
	print("--> "..name.." <--")
  end
until false

Second Program
Spoiler
os.loadAPI("ocs/apis/sensor")

local proxSense = sensor.wrap("top")
term.redirect(peripheral.wrap("right"))

repeat
  term.clear()

  for target in pairs(proxSense.getTargets()) do

	local detailedInfo = proxSense.getTargetDetails(target)
	if detailedInfo.Name == "Player" then
	print("--> "..target.." <--")
	end
  end
until false

The programs in question are on pastebin as well. First Program: http://pastebin.com/Ntn706mi and Second Program (Troublemaker):http://pastebin.com/Ut7YXSjK

Thank you for any light you can shine on this :)/>/>
Lyqyd #2
Posted 08 June 2013 - 02:01 AM
Split into new topic.
Bomb Bloke #3
Posted 08 June 2013 - 05:48 AM
In your first program, you gather all the data from the sensor into the table, clear the screen, then spam that information onto the display. Rinse and repeat.

In your second program, you clear the screen, then one at a time, you gather the detailed information sets for each target and put them on the display. Rinse and repeat.

Spamming the content of a table onto your screen is indeed faster then calling "proxSense.getTargetDetails(target)" for every entry in the table. My bet is that slight delay is what's causing your flicker.

Assuming that's the case, you can probably make it update without flickering using something like this:

os.loadAPI("ocs/apis/sensor")

local proxSense = sensor.wrap("top")
term.redirect(peripheral.wrap("right"))

local targets,detailedInfo = {},{}

repeat
  targets = {}
  for target in pairs(proxSense.getTargets()) do
        detailedInfo = proxSense.getTargetDetails(target)
        if detailedInfo.Name == "Player" then table.insert(targets,target) end
  end

  term.clear()
  for i=1,table.getn(targets) do print("--> "..targets[i].." <--") end

  sleep(1)  -- Optional, but does your display *really* need to update full speed?
until false
Jaronel #4
Posted 08 June 2013 - 06:11 AM
Thank you kindly Bomb Bloke! That worked perfectly. I don't know exactly why, but I'm still learning so I'll get there :)/>

I was planning to eventually add additional parameters to the display, like calling for IsSneaking(boolean) and PotionEffects(table, i think?).

So now I've got to try to wrap my head around where those would go in here hehe.
Bomb Bloke #5
Posted 08 June 2013 - 10:16 AM
The basic idea is to spend as little time as possible getting from the point where you clear the screen, to finishing your display update. If you spend too long, then the user gets enough time to see the "halfway" points - where only part of the display has had time to be drawn. Turn a slow redraw process into a loop, and the result is a flicker.

Usually you'd use a buffering system where you could draw/write everything you wanted to an internal RAM buffer somewhere, then when it's all drawn up, slap the whole page directly onto the screen. This allows you to take your sweet time filling out your display because the user only ever sees the finished product, and never gets to see it while it's in the process of being drawn.

I'm not sure there's any system in Lua intended for this purpose, though it's probably possible to rig one up. The simple solution is to minimise the time you spend redrawing the screen. Another option is to only clear each line on the display as you re-write to it, instead of clearing the whole display at once.