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

[Lua][Question] m.write() shell.run()

Started by MegaMech, 17 May 2013 - 09:06 PM
MegaMech #1
Posted 17 May 2013 - 11:06 PM
hello, i'm making a railcraft track control program. I'm calling it RailCraft OS (it probably shouldn't/wouldn't be called an OS, but that's what i'm gonna call it)


I've made a little boot up logo the computer write's to the monitor "rcOS"
then the program loads some tables (coords of signal controller boxes)
then it checks to see how long the table is ex. [1] to [7]
then writes 7 'O' onto the screen

the problem is that the write() is conflicting with the other write()

ex. write("rcOS")
later on we have a for loop that writes depending on what a table variable is.
ex.

--Set variables: --these variables tell the program to write the 'O''s to the next line before we reach the end of the monitor
X =2
Y = 2
inc = 1 --inc stands for increment

for i = 1, table.getn(tableY()) do  --calls the function tableY, it returns the length of the table ex.[7]
   m.setCursorPos(X,Y)
   m.write("O")
   X = X+2
   inc = inc+1
   if inc == 5 then Y=Y+2 inc = 1 X=2 end
end


So what's happening is the write("rcOS") isn't appearing on the screen, just the write("O") which is way later on in the code.

So I decided to put the boot logo in a separate file and then have that file run the main program

startup file shows boot logo then runs main program: http://pastebin.com/MGmm1BdG





  m = peripheral.wrap("top")
  if m == nil then error("Error: Monitor not found") end --if no monitor then error()

  m.clear() --clear monitor incase there is previous data on it
  sleep(1.5)
  local maxw,maxh = m.getSize()  --get monitor size
  local Calc = 1
  if maxh <= 4 then Calc = 0 end  --calculate if the monitor is small, and if so use 0 so that the text centers to the screen better (aesthetic purposes only)
  print(Calc)
  local mx = math.floor(maxw/2-1)
  local mh = math.floor(maxh/2+Calc)  --Takes screen size ex. 30 and /2 to find center of screen(15)
  print("w", maxw)
  print("h", maxh)

  m.setCursorPos(mx,mh) -- sets cursor to the above
  --m.setCursorPos(math.floor(maxw/2-1),math.floor(maxh/2)) --Change +1 to +0 if you have a small monitor   --This one didn't seem to be working, so I was testing the above code, using variables. (didn't work)

  print(mx)
  print(mh)
  m.setTextScale(5)
  m.setTextColor(16384)
  m.write("rcOS")  --should display to screen, but it doesn't

  sleep(2) 

function runNextFile()

  shell.run("rcOS") --Runs the main program

end
  runNextFile()

note that *–* is meaning that I put '–' so that the code ignores shell.run()

The same thing is happening but some even weirder trickery is going on.
if I put *–*shell.run("rcOS") then the logo "randomly" appears ex. the first time I run this program after I change the above it won't write, but the second time and onwards it will write. As soon as I put shell.run("rcOS") then the logo stops displaying.

So here's the weird part. I didn't have function runNextFile() I just had shell.run("rcOS") at the end of the code thinking it would be ran last. NOPE! this program ran ("rcOS") as soon as it started running. BUT, this main code had print() and other commands, none of those displayed or showed up. I noticed it was writing to the screen code from this file. ex. write("O")
I think it even ran the code multiple times, or was changing the textScale.
I put shell.run() into a function hoping this would force it to be ran last. (I think it kind of worked but could be still running in the background)

So incase that wasn't clear:
I run "startup" which SHOULD show "rcOS" on the monitor (it doesn't) but during this time is writing the following to the monitor:
"O O O O O O
O O O O O O" (these O's are from the main program, which should NOT be running yet)
BUT none of the print(variable) is running, (I have sleep() throughout the file) nothing else is running from the main program I think.

Then after the main sleep time is over the print() and all the other data start showing up.


I'm a bit frustrated at this point, if you need any more info ask, and i'll give.


Question #2 (it's shorter) (also the main reason why I split the program into two different programs)

You can't have "m.setTextScale() twice in a program. I can't display "rcOS" at scale 5 and then near the bottom of the script have "O" displayed at scale 2. (I think "rcOS" isn't displayed)

So I thought, if I can only have m.setTextScale() written ONCE in a file then how about we write it to a variable?

textScale = 5 – Not local, it needs to be accessed throughout the code
function scale()
m.setTextScale(textScale) –now wrapped to a variable :D/>
end

so now when I want to change the text size I do this

textScale = 2
scale()

So now maybe it will work?? Nope, it just ignores the upper most part and displays the bottom part

the uppermost part:
textScale = 5 –I don't need to put 5 and scale() because it's like that at default, but why not? what if I want to call the boot logo to run again. I might want to call it on PC shutdown, which means I would have to change it back to 5
scale()
m.write("rcOS")

I'm thankful for any help :D/>
LordIkol #2
Posted 18 May 2013 - 12:51 AM
Thats a detailed Description of you Problem :)/>

I would like to help you on your problem. Would you mind to Show The Code for the Main Part? That would Be helpful.

For The textscale Problem.
Textscale always changes The scale of the whole screen. So its Not possible to have 2 different textsizes on One screen.

I don't think 2 Programms are needed. Will have a Look at it when im at work :)/>
MegaMech #3
Posted 18 May 2013 - 02:08 AM
First off I forgot to say i'm playing Feed the Beast should be latest MindCrack version. Which has misc peripherals. I have not implemented this part of the code yet, the code is still WIP. It doesn't really do anything yet.

for textscale:I'm not having 2 different sizes of text _At the same time_ I'm having two different sizes of text _At different times_
ex. Writes to screen, Sleeps, Clears the screen, Does some stuff, Writes to screen with different size than before.

So http://pastebin.com/MGmm1BdG this file shows the boot logo, and then runs shell.run("rcOS") which is the file below


http://pastebin.com/UtUcVviH

Please don't abuse my code, meaning copying chunks of it and publishing it publicly

I've added commenting to the following: But not detailed comments on the pastebin link



print("running RCOS") --Was using this to tell me if this file was being ran, this print did not show up in console and yet the m.write("O") command below was showing up on the AdvMonitor. (then it would show up after sleeps have finished running)
    m = peripheral.wrap("top")
  if m == nil then error("Error: Monitor not found") end  --if Monitor is missing throw an error and end

  esc = peripheral.wrap("right")   --this is a block added by misc peripherals
  if esc == nil then error("Please put an Electronic Signal Controller to the right of the Computer") end

function startup() --The boot logo code was in this function before.

  local maxw,maxh = m.getSize()
  print("rcOS has detected your monitor size: ", maxw)

end

function tableX(X)    --The following functions TableX through TableZ loads a table holding X Y and Z coords

  local dataX = fs.open("boxData/dataX","r")   --Opens file for reading
  local data = dataX.readAll()     --reads ALL zeh awesome data
  dataX.close()            --Closes the file, very important
  return textutils.unserialize(data)       --unserializes the table so that we may read it. This way I can call tableX()[3] and get a value

end 

function tableY(Y) --see tableX Same thing repeated here

  local dataY = fs.open("boxData/dataY","r")
  local data = dataY.readAll()
  dataY.close()
  return textutils.unserialize(data)

end

function tableZ(Z)   --Same thing as tableX
  local dataZ = fs.open("boxData/dataZ","r")
  local data = dataZ.readAll()
  dataZ.close()
  return textutils.unserialize(data)

end

function load()        -- The above functions tableX-Z aren't actually ran yet. This function runs and checks to see if files are setup correctly. If not, it throws an error. This would be the operators fault, not having entered the coordinate data correctly
  --term.redirect(peripheral.wrap("top"))
  print("Loading Tables")
  sleep(0.2)
  print(tableX())   --this prints the tables. It returns a table code. ex. Table: 61558631
  print(tableY())
  print(tableZ())
  print("tableX=", table.getn(tableX()))   --This tells us how long the table is. ex. [1]-[7] This value at the moment will return 7
  print("tableY=", table.getn(tableY()))   -- The operator may add or remove as many coordinate data as he likes.
  print("tableZ=", table.getn(tableZ()))  

-- I can't put XYZ all into one file, things will get confused, which numbers are for X? and which ones for Y?? or Z?
-- So I put XYZ into their respective files, DataX, DataY, and DataZ BUT, if DataX has 5 coords and Data Y has 8 Coords when the program tries to get the coords for block 7 it will be missing data and will throw an error, OR will have the wrong coords.
-- tableX()[7] == nil, you can't have a table with nil

  if table.getn(tableX()) ~= table.getn(tableY()) then error("Tables entered incorrectly")   --Checks all files to make sure they are the same length
  elseif table.getn(tableZ()) ~= table.getn(tableY()) then error("Tables entered incorrectly")  --X and Z are compared against Y

  else print("Tables entered correctly")  --If all Data files have the same length then continue execution
  end

end

function Draw()   --HERE'S THE STUFF YOU NEED TO KNOW (caps to make it easier for you to jump to this, it stands out)
  m.clear()    --Clears incase any remaining text is on the screen, we want a different scale so we can't have any other text on it.
  sleep(0.5)
  m.setTextScale(2)    --sets the scale to 2
  m.setTextColor(colors.red)

-- the following writes the same amount of O's as there is data Length if data length == 5 then O's == 5
-- the following increments to space the O's correctly on the screen will be using the following code once everything else is working properly
--w, h = m.getSize()   we need to know when to switch to the next line   math.floor(w-variable number)

  X = 2
  Y = 2
  inc = 1

  for i = 1,table.getn(tableY()) do     --This for, will loop the same amount of times as there is table length (i'm using Y to be checked against, to be consistent we may continue using Y)
  m.setCursorPos(X,Y)
  m.write("O")
  X = X+2   -- Increments to space the O two "pixels" apart
  inc = inc+1   --self explanatory
  if inc == 5 then Y=Y+2 inc = 1 X=2 end  --if inc == 5 then switch to a new line, reset X, 5 will be a variable, length of monitor
  end

end

startup()  -- function startup is ran and then load() and then Draw()
load()
Draw()

-- and that's it!

LordIkol #4
Posted 18 May 2013 - 03:24 AM
Hi Buddy,

I will have a look into your Code to see what i can do.
The Logo Stuff i can not check for now cause at work i just have CCEmu which has no support for Monitors.

Do you mind if i change your code here and there to make it a little bit shorter or do you want to have it unaltered as long as your version is working?
from first look on it i would change the following for example:


function tableX(X)	--The following functions TableX through TableZ loads a table holding X Y and Z coords
  local dataX = fs.open("boxData/dataX","r")   --Opens file for reading
  local data = dataX.readAll()	 --reads ALL zeh awesome data
  dataX.close()			--Closes the file, very important
  return textutils.unserialize(data)	   --unserializes the table so that we may read it. This way I can call tableX()[3] and get a value
end
function tableY(Y) --see tableX Same thing repeated here
  local dataY = fs.open("boxData/dataY","r")
  local data = dataY.readAll()
  dataY.close()
  return textutils.unserialize(data)
end
function tableZ(Z)   --Same thing as tableX
  local dataZ = fs.open("boxData/dataZ","r")
  local data = dataZ.readAll()
  dataZ.close()
  return textutils.unserialize(data)
end

i would remove them and replace with this


function loadtable(coord)	--The following functions TableX through TableZ loads a table holding X Y and Z coords
  local mytable = "boxData/data"..coord
  local dataX = fs.open(mytable,"r")   --Opens file for reading
  local data = dataX.readAll()	 --reads ALL zeh awesome data
  dataX.close()			--Closes the file, very important
  return textutils.unserialize(data)	   --unserializes the table so that we may read it. This way I can call tableX()[3] and get a value
end

so you have only 1 function that can call all coords like loadtable("X"),loadtable("Y"),loadtable("Z")
even better would be to creare just one table with all coords like this.


mycoords = {}
mycoords[1] = {}
mycoords[1].x = 12
mycoords[1].y = 21
mycoords[1].z = 64

then you could serialize it and store it in a file
and later you just load the complete table from the file and can access your data with
mycoords.x etc
MegaMech #5
Posted 18 May 2013 - 03:22 PM
You can change the code as much as you want, I might not implement it though. I don't think I quite understand how the part you edited works so I'll fool around with it a bit.

I typed what you put above exactly and I got this error:

testing:3: attempt to concatenate string and nil
if I remove ..coord the program runs. Maybe you meant to put ,coord? ',' instead of '.'

when I print (loadtable()) or print(loadtable("X") or print(loadtable(x)) or print(loadtable(X)) it just prints the entire file instead of a piece of it. It throws an error if I put print(loadtable(x[1])
MegaMech #6
Posted 29 May 2013 - 07:42 PM
bump?
Bomb Bloke #7
Posted 29 May 2013 - 11:14 PM
That segment looks ok to me, so long as you always call "loadtable" with a string or other relevant value.