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

Help

Started by Buski, 24 August 2014 - 05:32 PM
Buski #1
Posted 24 August 2014 - 07:32 PM
I got a little problem with my program.

The program should display the actual data about a reactor connected to it, here is a picture how it looks at this moment:

Spoiler

My problem is that i want to update the data displayed BUT be able to click on the monitor to activate or deactivate the reactor.
I already tried to use parallel but then i couldnt click on anything, it just updated the data.

Here's the code without the parallel stuff:
Spoiler

slc = 0
reactor = peripheral.wrap("BigReactors-Reactor_0")
function drawBackground()
background = paintutils.loadImage("bg_cut")
paintutils.drawImage(background,1,1)
end
function drawTitleBar()
term.setCursorPos(1,1)
term.setBackgroundColor(256)
term.setTextColor(1)
term.setCursorPos(35,1)
term.write(" Menu ")
term.setCursorPos(2,1)
term.write("Update")
term.setBackgroundColor(8)
end
function drawReactorStats()
term.setCursorPos(2,3)
term.setTextColor(colors.black)
term.write("Reaktor:")
if reactor.getActive() == true then
  term.setCursorPos(11,3)
  term.setTextColor(colors.green)
  term.write("Aktiv")
elseif reactor.getActive() == false then
  term.setCursorPos(11,3)
  term.setTextColor(colors.red)
  term.write("Inaktiv")
end
term.setCursorPos(2,4)
term.setTextColor(colors.black)
local r_storedenergy = reactor.getEnergyStored()
term.write("Energie: ")
if r_storedenergy >= 7500000 then
  term.setCursorPos(11,4)
  term.setTextColor(colors.green)
  term.write(r_storedenergy.."RF")
elseif r_storedenergy < 2000000 then
  term.setCursorPos(11,4)
  term.setTextColor(colors.red)
  term.write(r_storedenergy.."RF")
elseif r_storedenergy >= 2000000 and r_storedenergy < 7500000 then
  term.setCursorPos(11,4)
  term.setTextColor(colors.black)
  term.write(r_storedenergy.."RF")
end
term.setCursorPos(2,5)
term.setTextColor(colors.black)
local r_fueltemp = reactor.getFuelTemperature()
term.write("Kern-Temperatur: ")
if r_fueltemp < 500 then
  term.setCursorPos(19,5)
  term.setTextColor(colors.blue)
  term.write(r_fueltemp.."C")
elseif r_fueltemp >= 500 and r_fueltemp < 1000 then
  term.setCursorPos(19,5)
  term.setTextColor(colors.orange)
  term.write(r_fueltemp.."C")
elseif r_fueltemp >= 1000 then
  term.setCursorPos(19,5)
  term.setTextColor(colors.red)
  term.write(r_fueltemp.."C")
end
end
function drawDesktop()
term.setBackgroundColor(1)
term.clear()
drawBackground()
drawTitleBar()
drawReactorStats()
end
function drawDropDownMenu1()
term.setTextColor(1)
term.setBackgroundColor(256)
term.setCursorPos(35,2)
term.write(" Beenden	")
term.setCursorPos(35,3)
term.write(" Neustarten ")
term.setCursorPos(35,4)
term.write(" Update	 ")
end
drawDesktop()
while true do
local event, button, X, Y = os.pullEventRaw()
if slc == 0 then
  if event == "mouse_click" then
   if X >= 35 and X <= 41 and Y == 1 and button==1 then --open menu
	drawDropDownMenu1()
	slc = 1
   elseif X >= 2  and X <= 8  and Y == 1 and button==1 then
	drawDesktop()
   elseif X >= 11 and X <= 18 and Y == 3 and button==1 then
	if reactor.getActive() == false then
	 reactor.setActive(true)
	 drawDesktop()
	elseif reactor.getActive() == true then
	 reactor.setActive(false)
	 drawDesktop()
	end
	drawDesktop()
   else
	drawDesktop()
   end
  end
elseif slc == 1 then
  if event == "mouse_click" then
   if X >= 35 and X <= 48 and Y == 2 and button==1 then slc=0 --beenden
	error("Programm wurde beendet")
   elseif X >= 35 and X <= 46 and Y == 3 and button==1 then slc=0 --pc neustart
	os.reboot()
   elseif X >= 35 and X <= 44 and Y == 4 and button==1 then slc=0 --update values
	drawDesktop()
   else
	slc = 0
	drawDesktop()
   end
  end
end
end

And here the code with the parallel thing i tried:
Spoiler

slc = 0
reactor = peripheral.wrap("BigReactors-Reactor_0")
function drawBackground()
background = paintutils.loadImage("bg_cut")
paintutils.drawImage(background,1,1)
end
function drawTitleBar()
term.setCursorPos(1,1)
term.setBackgroundColor(256)
term.setTextColor(1)
term.setCursorPos(35,1)
term.write(" Menu ")
term.setCursorPos(2,1)
term.write("Update")
term.setBackgroundColor(8)
end
function drawReactorStats()
while true do
  term.setCursorPos(2,3)
  term.setTextColor(colors.black)
  term.write("Reaktor:")
  if reactor.getActive() == true then
   term.setCursorPos(11,3)
   term.setTextColor(colors.green)
   term.write("Aktiv")
  elseif reactor.getActive() == false then
   term.setCursorPos(11,3)
   term.setTextColor(colors.red)
   term.write("Inaktiv")
  end
  term.setCursorPos(2,4)
  term.setTextColor(colors.black)
  local r_storedenergy = reactor.getEnergyStored()
  term.write("Energie: ")
  if r_storedenergy >= 7500000 then
   term.setCursorPos(11,4)
   term.setTextColor(colors.green)
   term.write(r_storedenergy.."RF")
  elseif r_storedenergy < 2000000 then
   term.setCursorPos(11,4)
   term.setTextColor(colors.red)
   term.write(r_storedenergy.."RF")
  elseif r_storedenergy >= 2000000 and r_storedenergy < 7500000 then
   term.setCursorPos(11,4)
   term.setTextColor(colors.black)
   term.write(r_storedenergy.."RF")
  end
  term.setCursorPos(2,5)
  term.setTextColor(colors.black)
  local r_fueltemp = reactor.getFuelTemperature()
  term.write("Kern-Temperatur: ")
  if r_fueltemp < 500 then
   term.setCursorPos(19,5)
   term.setTextColor(colors.blue)
   term.write(r_fueltemp.."C")
  elseif r_fueltemp >= 500 and r_fueltemp < 1000 then
   term.setCursorPos(19,5)
   term.setTextColor(colors.orange)
   term.write(r_fueltemp.."C")
  elseif r_fueltemp >= 1000 then
   term.setCursorPos(19,5)
   term.setTextColor(colors.red)
   term.write(r_fueltemp.."C")
  end
  sleep(3)
end
end
function drawDesktop()
term.setBackgroundColor(1)
term.clear()
drawBackground()
drawTitleBar()
drawReactorStats()
end
function drawDropDownMenu1()
term.setTextColor(1)
term.setBackgroundColor(256)
term.setCursorPos(35,2)
term.write(" Beenden	")
term.setCursorPos(35,3)
term.write(" Neustarten ")
term.setCursorPos(35,4)
term.write(" Update	 ")
end
drawDesktop()
function actualProgram()
while true do
  local event, button, X, Y = os.pullEventRaw()
  if slc == 0 then
   if event == "mouse_click" then
	if X >= 35 and X <= 41 and Y == 1 and button==1 then --open menu
	 drawDropDownMenu1()
	 slc = 1
	elseif X >= 2  and X <= 8  and Y == 1 and button==1 then
	 drawDesktop()
	elseif X >= 11 and X <= 18 and Y == 3 and button==1 then
	 if reactor.getActive() == false then
	  reactor.setActive(true)
	  drawDesktop()
	 elseif reactor.getActive() == true then
	  reactor.setActive(false)
	  drawDesktop()
	 end
	 drawDesktop()
	else
	 drawDesktop()
	end
   end
  elseif slc == 1 then
   if event == "mouse_click" then
	if X >= 35 and X <= 48 and Y == 2 and button==1 then slc=0 --beenden
	 error("Programm wurde beendet")
	elseif X >= 35 and X <= 46 and Y == 3 and button==1 then slc=0 --pc neustart
	 os.reboot()
	elseif X >= 35 and X <= 44 and Y == 4 and button==1 then slc=0 --update values
	 drawDesktop()
	else
	 slc = 0
	 drawDesktop()
	end
   end
  end
end
end
while true do
parallel.waitForAll(actualProgram(),drawReactorStats())
end

There was no different between waitForAll or waitForAny.
flaghacker #2
Posted 24 August 2014 - 09:00 PM
When using the parallel API, you have to pass function pointers, not their returns.


parallel.waitForAll(a(), b())
Here you call function a, wait until it ends, then you call function b, wait until that one ends and then you pass the returns to the parallel API. Because your first function never ends, the second one never runs.

parallel.waitForAll(a, b )
Here you pass the functions themselves to the parallel API.

In short, remove the parentheses of the 2 main functions at the bottom line.
Edited on 24 August 2014 - 07:01 PM
Buski #3
Posted 25 August 2014 - 09:18 AM
Still the same problem, i cant click on things.
Dragon53535 #4
Posted 25 August 2014 - 10:46 PM
In your first function there is nothing that calls os.pullEvent or os.pullEventRaw. The parallel API works in a way that whenever it hits one of those it swaps to the other, alternating until one returns a value. The problem with your code is that you just keep running through the first function without anything that would os.pullEvent and so the parallel API can't stop it and go to the other program. Now if i'm not mistaken, sleep() uses os.pullEvent and adding one in there, even for 0.05 should allow it to swap to the other function for a split second.

Edited for readability

ps. technically the parallel API actually works by finding coroutines, but the thing is that os.pullEvent and os.pullEventRaw use the coroutine API as well so in actuality os.pullEvent and os.pullEventRaw are just coroutine filters, that work in a special way.
Edited on 25 August 2014 - 08:57 PM
Bomb Bloke #5
Posted 26 August 2014 - 03:39 AM
In your first function there is nothing that calls os.pullEvent or os.pullEventRaw.

If that were the case, the script would bomb out due to failure to yield. actualProgam() calls os.pullEventRaw() and drawReactorStats() calls sleep().

I'd hook up a monitor, and print stuff to that about whatever events are detected in the actualProgram loop, along with a report on the state of slc and any other variables you think should be affected. Make sure your clicks are actually registering then work from there.

I find it a bit odd that the drawDesktop() function calls drawReactorStats() (the latter of which should be constantly called anyway due to your use of the parallel API). I suspect you're drawing over your drop down menu at some point in the code.
Buski #6
Posted 26 August 2014 - 12:53 PM
Well you were quite right, the problem seems to be that it redrawed the desktop all the time.

I edited the code a bit, now it just redraws the values of the reactor data like the temperature and so on.
And this time i deleted the part with the dropdown menu, it's just not necessary. Instead i just put the options of the dropdown menu into the title bar.
Thanks for the help so far :3
Well. then my next question, can i manipulate the string so, that it only prints the first 5 chars for example?
Actually i am using string.sub and string.reverse for it, is there an easier way?

Code (Reactor)
Spoiler

--slc = 0 --deprecated
reactor = peripheral.wrap("BigReactors-Reactor_0")
function drawBasicGUI()
term.clear()
term.setCursorPos(1,1)
background = paintutils.loadImage("bg_cut")
paintutils.drawImage(background,1,1)
term.setBackgroundColor(colors.lightGray)
term.setTextColor(colors.white)
term.setCursorPos(2,1)
term.write("Update")
term.setCursorPos(50,1)
term.setTextColor(colors.red)
term.write("X")
--writing Labels for Reactor Stats
term.setBackgroundColor(colors.lightBlue)
term.setCursorPos(2,3)
term.setTextColor(colors.black)
term.write("Reaktor: ")
term.setCursorPos(2,4)
term.setTextColor(colors.black)
term.write("Energie: ")
term.setCursorPos(2,5)
term.setTextColor(colors.black)
term.write("Kern-Temperatur: ")
end
function getReactorData()
r_State = tostring(reactor.getActive())
r_EnergyStored = tostring(reactor.getEnergyStored())
r_CoreTemp = tostring(reactor.getFuelTemperature())
end
function drawReactorData()
term.setCursorPos(11,3)
term.write(r_State)
term.setCursorPos(11,4)
term.write(r_EnergyStored)
term.setCursorPos(19,5)
term.write(r_CoreTemp)
end
function updateReactorData()
while true do
  getReactorData()
  drawReactorData()
  sleep(5)
end
end
drawBasicGUI()
function reactorProgram()
while true do
  local event, button, X, Y = os.pullEventRaw()
  if event == "mouse_click" then
   if X >= 2 and X <= 7 and Y==1 and button==1 then
	getReactorData()
	drawReactorData()
   elseif X == 50 and Y==1 and button==1 then
	error("exit")
   end
  end
end
end
while true do
parallel.waitForAll(reactorProgram,updateReactorData)
end
Edited on 26 August 2014 - 11:21 AM
Bomb Bloke #7
Posted 26 August 2014 - 01:30 PM
string.sub sounds perfect to me. I'm not sure why you'd use string.reverse.

print(myString:sub(1,5))
Buski #8
Posted 26 August 2014 - 01:41 PM
Yeah nevermind i didnt realize it has a third parameter