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

Menu Issues

Started by OS_MAN_10!, 11 November 2015 - 03:36 AM
OS_MAN_10! #1
Posted 11 November 2015 - 04:36 AM
Hello i am making a new feature for my os and i'm stuck on it. HELP PLS.

Here's the part i'm stuck on

local function fscontrol()
print("--------------------------------------------------")
print("|[1]Previous Menu								|")
print("|[2]Make Folder								  |")
print("|[3]Delete Folder(NYI)						   |")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("--------------------------------------------------")
fsinput = io.read()
if fsinput == "1" then
drawMainMenu()

end
local function drawMainMenu()
term.clear()
term.setCursorPos(1,1)
print("--------------------------------------------------")
print("|[1]Shutdown									 |")
print("|[2]Reboot									   |")
print("|[3]N Paint Pro (by: nitrogenfingers)			|")
print("|[4]Lua Ide (by: GravityScore)				   |")
print("|[5]FS Control								   |")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("--------------------------------------------------")
inputread = io.read()
if inputread == "1" then
os.shutdown()
elseif inputread == "2" then
os.reboot()
elseif inputread == "3" then
shell.run("progs/npaint")
elseif inputread == "4" then
shell.run("progs/luaide")
elseif inputread == "5" then
fscontrol()
end
end
So i'm trying to have it where you can go back to the main menu and also go to the other menu but that is not possible since for it to work they have to be already created functions which cannot be done because they would have to be behind each other and ERRORS galore.(i know the code is messy but just ignore that.)
valithor #2
Posted 11 November 2015 - 04:55 AM
It would actually be better to fix this error by simply restructuring your code. Although it is unlikely someone would ever experience this problem it is possible that with this setup you could reach the 255 recursive function call limit in CC. I am not going to explain that as it is not completely relevant.

So let's simplify your problem to a something like:
Spoiler

local function printMenu1()
  print("this is a menu type hi to return")
  local input = read()
  if input == "hi" then
	mainMenu()
  end
end

local function printMenu2()
  print("this is a menu type hi to return")
  local input = read()
  if input == "hi" then
	mainMenu()
  end
end

local function mainMenu()
  term.clear()
  term.setCursorPos(1,1)
  print("Press 1 for menu 1")
  print("Press 2 for menu 2")
  local input = tonumber(read())
  if input == 1 then
	printMenu1()
  elseif input == 2 then
	printMenu2()
  end
end
That code is just basically what yours is right now. It will have the same problem you have, but there are a few changes we can make.

So there is a few assumptions you can use to your advantage. The first is you will always go back to the main menu at some point. Even if it isn't going directly back to it, it will happen at some point (is the case for most programs). The second important piece is you do not need to actually call the main menu function to get back to it.

Spoiler

local function printMenu1()
  print("this is a menu type hi to return")
  local input = read()
  if input == "hi" then
	--#mainMenu()  -- Leaving this here just so you can see what I replace it with
	return --# this will cause the function to exit, and the program will go back and continue running code from where this function was called
  end
end

local function printMenu2()
  print("this is a menu type hi to return")
  local input = read()
  if input == "hi" then
	--#mainMenu() -- same thing as above
	return --# same thing as above
  end
end

local function mainMenu()
  while true do  --# since we always will return to the main menu, might as well always having it run in the background
	print("Press 1 for menu 1")
	print("Press 2 for menu 2")
	local input = tonumber(read())
	if input == 1 then
	  printMenu1()
	elseif input == 2 then
	  printMenu2()
	end
  end
end
Hope this helps. :P/>

edit:

This could actually be applied to as many nested menus as you want.

Example:

Spoiler

local function printMenu2()
  while true do
	print("This is menu 2 type 1 to get back to menu 1, or home to get back to the main menu")
	local input = read()
	if input == "home" then
	  return "home" --# returning the string "home", printMenu1 will receive this from where it called it.
	elseif input == "1" then
	  return --# just returning back to where it was called in printMenu1
	end
  end
end

local function printMenu1()
  while true do
	print("This is menu 1, type home to get to the main menu, or 2 to get to menu 2")
	local input = read()
	if input == "home" then
	  return --# returning to the main menu where it was called
	elseif input == "1" then
	  result = printMenu2() --# getting the return value from printMenu2
	  if result = "home" then --# checking to see what the function returned
		return --# returning to the main menu because that is what the return value from printMenu2 said to do
	  end
	end
  end
end

local function mainMenu()
  while true do  --# since we always will return to the main menu, might as well always having it run in the background
	print("Press 1 for menu 1")
	print("Press 2 for menu 2")
	local input = tonumber(read())
	if input == 1 then
	  printMenu1()
	elseif input == 2 then
	  printMenu2()
	end
  end
end
Edited on 11 November 2015 - 04:15 AM
OS_MAN_10! #3
Posted 11 November 2015 - 05:25 AM
It would actually be better to fix this error by simply restructuring your code. Although it is unlikely someone would ever experience this problem it is possible that with this setup you could reach the 255 recursive function call limit in CC. I am not going to explain that as it is not completely relevant.

So let's simplify your problem to a something like:
Spoiler

local function printMenu1()
  print("this is a menu type hi to return")
  local input = read()
  if input == "hi" then
	mainMenu()
  end
end

local function printMenu2()
  print("this is a menu type hi to return")
  local input = read()
  if input == "hi" then
	mainMenu()
  end
end

local function mainMenu()
  term.clear()
  term.setCursorPos(1,1)
  print("Press 1 for menu 1")
  print("Press 2 for menu 2")
  local input = tonumber(read())
  if input == 1 then
	printMenu1()
  elseif input == 2 then
	printMenu2()
  end
end
That code is just basically what yours is right now. It will have the same problem you have, but there are a few changes we can make.

So there is a few assumptions you can use to your advantage. The first is you will always go back to the main menu at some point. Even if it isn't going directly back to it, it will happen at some point (is the case for most programs). The second important piece is you do not need to actually call the main menu function to get back to it.

Spoiler

local function printMenu1()
  print("this is a menu type hi to return")
  local input = read()
  if input == "hi" then
	--#mainMenu()  -- Leaving this here just so you can see what I replace it with
	return --# this will cause the function to exit, and the program will go back and continue running code from where this function was called
  end
end

local function printMenu2()
  print("this is a menu type hi to return")
  local input = read()
  if input == "hi" then
	--#mainMenu() -- same thing as above
	return --# same thing as above
  end
end

local function mainMenu()
  while true do  --# since we always will return to the main menu, might as well always having it run in the background
	print("Press 1 for menu 1")
	print("Press 2 for menu 2")
	local input = tonumber(read())
	if input == 1 then
	  printMenu1()
	elseif input == 2 then
	  printMenu2()
	end
  end
end
Hope this helps. :P/>

edit:

This could actually be applied to as many nested menus as you want.

Example:

Spoiler

local function printMenu2()
  while true do
	print("This is menu 2 type 1 to get back to menu 1, or home to get back to the main menu")
	local input = read()
	if input == "home" then
	  return "home" --# returning the string "home", printMenu1 will receive this from where it called it.
	elseif input == "1" then
	  return --# just returning back to where it was called in printMenu1
	end
  end
end

local function printMenu1()
  while true do
	print("This is menu 1, type home to get to the main menu, or 2 to get to menu 2")
	local input = read()
	if input == "home" then
	  return --# returning to the main menu where it was called
	elseif input == "1" then
	  result = printMenu2() --# getting the return value from printMenu2
	  if result = "home" then --# checking to see what the function returned
		return --# returning to the main menu because that is what the return value from printMenu2 said to do
	  end
	end
  end
end

local function mainMenu()
  while true do  --# since we always will return to the main menu, might as well always having it run in the background
	print("Press 1 for menu 1")
	print("Press 2 for menu 2")
	local input = tonumber(read())
	if input == 1 then
	  printMenu1()
	elseif input == 2 then
	  printMenu2()
	end
  end
end
But the thing is i have a conflict in my code, i have a loading screen that has to call the drawmenu function which will just create more errors?! I somewhat tried to put in what you suggested it didn't work.
Full Code:

term.clear()
term.setCursorPos(1,1)
--functions
local function drawLoadMenu()
term.clear()
term.setCursorPos(1,1)
print("--------------------------------------------------")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|AndOS Is Loading!							   |")
print("--------------------------------------------------")
sleep(2)
drawMainMenu()
end
local function drawLogonMenu()
term.clear()
term.setCursorPos(1,1)
print("--------------------------------------------------")
print("|[1]Logon										|")
print("|[2]Shutdown									 |")
print("|[3]Reboot									   |")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("--------------------------------------------------")
inputread2 = io.read()
if inputread2 == "1" then
drawLoadMenu()
elseif inputread2 == "2" then
os.shutdown()
elseif inputread2 == "3" then
os.reboot()
end
end
local function fscontrol()
term.clear()
term.setCursorPos(1,1)
print("--------------------------------------------------")
print("|[1]Previous Menu								|")
print("|[2]Make Folder								  |")
print("|[3]Delete Folder (NYI)						  |")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("--------------------------------------------------")
fsinput = io.read()
if fsinput == "1" then
return
elseif fsinput == "2" then
customMakeDir()
end
end
local function customMakeDir
term.clear()
term.setCursorPos(1,1)
print("--------------------------------------------------")
print("|Enter Folder Name							   |")
print("|[1]Goto Previous Menu						 |")
print("|															  |")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("----------------------------------------")
customdirinput = io.read()
if customdirinput == "1" then
fscontrol()
else
fs.makeDir(customdirinput)
end
end
local function drawMainMenu()
while true do
term.clear()
term.setCursorPos(1,1)
print("--------------------------------------------------")
print("|[1]Shutdown									 |")
print("|[2]Reboot									   |")
print("|[3]N Paint Pro (by: nitrogenfingers)			|")
print("|[4]Lua Ide (by: GravityScore)				   |")
print("|[5]Fs Control								   |")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("--------------------------------------------------")
inputread = io.read()
if inputread == "1" then
os.shutdown()
elseif inputread == "2" then
os.reboot()
elseif inputread == "3" then
shell.run("progs/npaint")
elseif inputread == "4" then
elseif inputread == "4" then
fscontrol()
end
end
end
--main code
drawLogonMenu()
I bet i won't be able to implement this feature.
Edited on 11 November 2015 - 04:27 AM
Creator #4
Posted 11 November 2015 - 05:36 AM
I had this same issue a long time ago. Sadly, I have no time for a detailed response, but you might want to take a look at this thread.
OS_MAN_10! #5
Posted 11 November 2015 - 05:42 AM
nevermind i just won't make this feature, i've benn trying for 3 hours and have been getting nowhere. Thanks for the help anyways. :)/>
valithor #6
Posted 11 November 2015 - 05:43 AM
-snip

It is all about restructuring, and thinking ahead. There is actually a much easier way to fix this (just remove the locals), but I decided to try and show you a way to do it, which will help you in the long run. If you want to see your code fixed:
Spoiler

term.clear()
term.setCursorPos(1,1)
--functions

local function customMakeDir() -- # this function is only called by fscontrol, so it must go above it somewhere
  term.clear()
  term.setCursorPos(1,1)
  print("--------------------------------------------------")
  print("|Enter Folder Name							   |")
  print("|[1]Goto Previous Menu						 |")
  print("|															  |")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("----------------------------------------")
  customdirinput = io.read()
  if customdirinput == "1" then
	--#fscontrol()
	return--# needed to be changed to return
  else
	fs.makeDir(customdirinput)
  end
end

local function fscontrol() --# function is only called by drawMainMenu, so it must go above it somewhere
  while true do
term.clear()
term.setCursorPos(1,1)
print("--------------------------------------------------")
print("|[1]Previous Menu								|")
print("|[2]Make Folder								  |")
print("|[3]Delete Folder (NYI)						  |")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("|												|")
print("--------------------------------------------------")
   fsinput = io.read()
if fsinput == "1" then
return
	elseif fsinput == "2" then
	 customMakeDir()
	end
  end
end

local function drawMainMenu() --# this is only called by drawLoadMenu, so it must go above it somewhere
  while true do
	term.clear()
	term.setCursorPos(1,1)
	print("--------------------------------------------------")
	print("|[1]Shutdown									 |")
	print("|[2]Reboot									   |")
	print("|[3]N Paint Pro (by: nitrogenfingers)			|")
	print("|[4]Lua Ide (by: GravityScore)				   |")
	print("|[5]Fs Control								   |")
	print("|												|")
	print("|												|")
	print("|												|")
	print("|												|")
	print("|												|")
	print("|												|")
	print("|												|")
	print("|												|")
	print("|												|")
	print("|												|")
	print("|												|")
	print("--------------------------------------------------")
	inputread = io.read()
	if inputread == "1" then
	  os.shutdown()
	elseif inputread == "2" then
	  os.reboot()
	elseif inputread == "3" then
	  shell.run("progs/npaint")
	elseif inputread == "4" then
	elseif inputread == "5" then
	  fscontrol()
	end
  end
end

local function drawLoadMenu()  --# This function is only called by drawLogonMenu, so it only needs to be before it
  term.clear()
  term.setCursorPos(1,1)
  print("--------------------------------------------------")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|AndOS Is Loading!							   |")
  print("--------------------------------------------------")
  sleep(2)
  drawMainMenu()
end

local function drawLogonMenu()  --# this function is not called by any other function, so I moved it to the bottom
  term.clear()
  term.setCursorPos(1,1)
  print("--------------------------------------------------")
  print("|[1]Logon										|")
  print("|[2]Shutdown									 |")
  print("|[3]Reboot									   |")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("|												|")
  print("--------------------------------------------------")
  inputread2 = io.read()
  if inputread2 == "1" then
	drawLoadMenu()
  elseif inputread2 == "2" then
	os.shutdown()
  elseif inputread2 == "3" then
	os.reboot()
  end
end

--main code
drawLogonMenu()

Just know anywhere in the code above that I talk about me moving the code somewhere to make it work, just keep in mind that the position only maters in this case due to the fact you defined the variables functions as local. Also know I fixed a number of simple errors, such as you defined a function without (), the option for fscontrol was 4 instead of 5, etc…

edit:

The only thing I did here was apply what I talked about in my post. For the most part you can do just about anything you want with code if you plan ahead.
Edited on 11 November 2015 - 04:54 AM
valithor #7
Posted 11 November 2015 - 06:37 AM
As I was going to sleep I realized I was a idiot and showed you the hard way to fix this problem… You actually do not need to restructure your code at all, instead you just need to "initialize" your local functions at the top of your code. Essentially what this means is you make local variables with the same names as your functions at the top of your code, and then just define your functions how you would define them globally.

So sorry I did not think of just doing that the first time… But, this is the easy way to do it.

Since I am tired only going to show it on the original code you posted.
Spoiler

local fscontrol
local drawMainMenu

function fscontrol()
print("--------------------------------------------------")
print("|[1]Previous Menu                                                                |")
print("|[2]Make Folder                                                            |")
print("|[3]Delete Folder(NYI)                                              |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("--------------------------------------------------")
fsinput = io.read()
if fsinput == "1" then
drawMainMenu()
end

end
function drawMainMenu()
term.clear()
term.setCursorPos(1,1)
print("--------------------------------------------------")
print("|[1]Shutdown                                                                      |")
print("|[2]Reboot                                                                          |")
print("|[3]N Paint Pro (by: nitrogenfingers)                    |")
print("|[4]Lua Ide (by: GravityScore)                              |")
print("|[5]FS Control                                                              |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("|                                                                                                |")
print("--------------------------------------------------")
inputread = io.read()
if inputread == "1" then
os.shutdown()
elseif inputread == "2" then
os.reboot()
elseif inputread == "3" then
shell.run("progs/npaint")
elseif inputread == "4" then
shell.run("progs/luaide")
elseif inputread == "5" then
fscontrol()
end
end
Edited on 11 November 2015 - 05:40 AM