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

Running a concatenated string?

Started by NovaXeros, 12 January 2016 - 12:17 AM
NovaXeros #1
Posted 12 January 2016 - 01:17 AM
So, bearing in mind that I'm VERY new to Lua, I've managed to make a multi-screen set up across a base in which I have the same controller output on 4 different screens. My old style of code for that required manually setting up pages for each monitor and calling each one into existence individually. In the interests of making the code far more responsive and less maintenance heavy when adding a new monitor I made this:


os.loadAPI("touchpoint")
local reac = peripheral.wrap("BigReactors-Reactor_0")
local names = {
"monitor_5";
"monitor_6";
"monitor_7";
"monitor_9";
}
local conMonsRaw = {}
local conMons = {}
local handleEvents = {}
function primeMons()
for i=1,#names do

conMons[i] = touchpoint.new(names[i])
conMonsRaw[i] = peripheral.wrap(names[i])

conMonsRaw[i].setTextScale(0.5)
conMonsRaw[i].clear()

conMons[i]:add("on", nil, 2, 2, 7, 4, colors.green, colors.lime)
conMons[i]:add("off", nil, 9, 2, 14, 4, colors.red, colors.orange)
conMons[i]:add("100%", nil, 2, 6, 14, 8, colors.red, colors.lightGray)
conMons[i]:add("75%", nil, 2, 9, 14, 11, colors.orange, colors.lightGray)
conMons[i]:add("50%", nil, 2, 12, 14, 14, colors.yellow, colors.lightGray)
conMons[i]:add("25%", nil, 2, 15, 14, 17, colors.lime, colors.lightGray)
conMons[i]:add("Optimal", nil, 2, 18, 14, 20, colors.green, colors.lightGray)
conMons[i]:add("Idle", nil, 2, 21, 14, 23, colors.blue, colors.lightGray)

conMons[i]:draw()
end
end
function primeHandle()
for i=#names,1,-1 do
handleEvents = "conMons["..i.."]:handleEvents("..handleEvents..")"
  end
end

primeMons()
primeHandle()

while true do
  local event, p1 = handleEvents
  if event == "button_click" then

for i=1,#conMons do
  conMons[i]:flash(p1)
end

	if p1 == "on" then
	  reac.setActive(true)
	elseif p1 == "off" then
	  reac.setActive(false)
	elseif p1 == "Optimal" then
	  reac.setAllControlRodLevels(67)
elseif p1 == "Idle" then
   reac.setAllControlRodLevels(95)
	else
	  levInt = 100-(tonumber(string.sub(p1, 1, -2)))
	  reac.setAllControlRodLevels(levInt)
	end
  end
end

The code doesn't work however. Creates a yield issue, and I've narrowed it down to the Events Handler. If the Events handler code reads as follows:


...
while true do
  local event, p1 = conMons[1]:handleEvents(conMons[2]:handleEvents(conMons[3]:handleEvents(conMons[4]:handleEvents(os.pullEvent()))))
  if event == "button_click" then
...

Then all works fine. I've also checked that the output of the primeHandle() function does successfully make handleEvents = conMons[1]:handleEvents(conMons[2]:handleEvents(conMons[3]:handleEvents(conMons[4]:handleEvents(os.pullEvent())))) but this doesn't run.

This is the very last bit of code I need in order to make this script literally only need to add the monitor name into the top table of names and it will auto-populate the rest. Right now though, it requires me to manually also edit the event handler section to also consider the new monitor.

Is there even a solution to this or do I have to accept that this is as close as I get to a responsive monitor script?
Lyqyd #2
Posted 12 January 2016 - 01:40 AM
Why not just:


local function handleEvents()
  local event = {os.pullEvent()}
  for i = 1, #conMons do
    event = {conMons[i]:handleEvents(unpack(event))}
  end
  return unpack(event)
end

And then in your event handling loop:


local event, p1 = handleEvents()
NovaXeros #3
Posted 12 January 2016 - 01:56 AM
That works perfectly. I think I need to go read up on that unpack command. I feel like I'm going to be using that a lot in the future.

Thanks for the help, and the amazing button API.