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

[lua][question] parallel - closing one and executing another

Started by Ghozer, 07 July 2012 - 08:24 PM
Ghozer #1
Posted 07 July 2012 - 10:24 PM
I have a menu navigation script that uses 6 buttons to navigate through a menu on a large monitor…

the menu navigation is all working, the pages are all working, however when I terminate, it spams the console with "Terminated"

i'm assuming this is because I am calling a parallel.waitForAny(x, y), then later on i'm calling parallel.waitForAny(x, y) again


I did try to eliminate this problem by making it use os.run({}, "menu") instead of re-loading the main menu function in parallel when I navigate back to main menu, but it's still giving "Terminated" like 10 (some times more) times..

so, can I 'clean up' all parallel sessions before starting a new one? or do I have to quit the script to clean it up?
MysticT #2
Posted 07 July 2012 - 10:28 PM
You shouldn't call the functions over and over, use a loop instead.
Ghozer #3
Posted 07 July 2012 - 10:30 PM
I can't use a loop, as I have each "page" in a function… lemme show you my code, feel free to change it or show me how you would accomplish it in a better way (still learning here)
tried to limit it by using os.run({}, "menu") each time the "back" or "main menu" button is pressed, but it didn't help


-- ------------ PAGES
function membersPage()
m.clear("back")
m.writePos("back", "Members Page", 1, 1)
bR("[Back] -", 16)
-- ----
bRead = true
while(bRead) do
  local sEvent, param = os.pullEvent("key")
  if(sEvent == "key") then
   bMenu(param, "members")
  end
end
-- ----
end
function rulesPage()
m.clear("back")
m.writePos("back", "Rules Page", 1, 1)
bR("[Back] -", 16)
-- ----
bRead = true
while(bRead) do
  local sEvent, param = os.pullEvent("key")
  if(sEvent == "key") then
   bMenu(param, "rules")
  end
end
-- ----
end
function joiningPage()
m.clear("back")
m.writePos("back", "Joining Page", 1, 1)
bR("[Back] -", 16)
-- ----
bRead = true
while(bRead) do
  local sEvent, param = os.pullEvent("key")
  if(sEvent == "key") then
   bMenu(param, "joining")
  end
end
-- ----
end
-- ------------ MAIN MENU
function mMenu()
m.clear("back")
m.writePos("back", "---- Welcome to SCF! ----", 16, 1)
m.writePos("back", "|	   Main Menu	   |", 16, 2)
bL("- [Members]", 3)
bL("- [Rules]", 10)
bL("- [Joining]", 16)
bR("[EMPTY] -", 3)
bR("[EMPTY] -", 10)
bR("[EMPTY] -", 16)
-- ----
bRead = true
while(bRead) do
  local sEvent, param = os.pullEvent("key")
  if(sEvent == "key") then
   bMenu(param, "main")
  end
end
-- ----
end
-- ------------ BUTTON ACTIONS
function bMenu(x, y)
if(y == "main") then
  if(x == 2) then
   parallel.waitForAny(membersPage, buttons)
  elseif(x == 3) then
   parallel.waitForAny(rulesPage, buttons)
  elseif(x == 4) then
   parallel.waitForAny(joiningPage, buttons)  
  end
elseif(y == "members") then
  if(x == 7) then
   os.run({}, "menu")
  end

elseif(y == "rules") then
  if(x == 7) then
   os.run({}, "menu")
  end

elseif(y == "joining") then
  if(x == 7) then
   os.run({}, "menu")
  end
end
end
-- ------------ BUTTON DETECT
function buttons()
while true do
  os.pullEvent("redstone")
  if rs.testBundledInput("front", 2) then
	os.queueEvent("key", 2)
  elseif rs.testBundledInput("front", 16) then
	os.queueEvent("key", 3)
  elseif rs.testBundledInput("front", 1) then
	os.queueEvent("key", 4)
  elseif rs.testBundledInput("front", 16384) then
	os.queueEvent("key", 5)
  elseif rs.testBundledInput("front", 8192) then
	os.queueEvent("key", 6)
  elseif rs.testBundledInput("front", 2048) then
	os.queueEvent("key", 7)
  end
end
end
-- ------------ PRINT FUNCTIONS
function bL(text, y)
m.writePos("back", text, 2, y)
end
function bR(text, y)
m.writePos("back", text, 47, y)
end
-- ------------ INITIALIZATION
parallel.waitForAny(mMenu, buttons)
MysticT #4
Posted 07 July 2012 - 10:44 PM
You can do it like:

local function menu1()
  while true do
    -- draw menu, get input, etc.
    if option == 1 then
	  doSomethingCool()
    else
	  -- to return to the main menu
	  break
    end
  end
end

local function menu2()
  -- same as menu1
end

local function mainMenu()
  while true do
    -- draw menu, get input, etc.
    -- open sub menu:
    if sub_menu == 1 then
      menu1()
    elseif sub_menu == 2 then
      menu2()
    -- etc.
    end
    -- when you want to exit
    if exit then
	  break -- break the loop, so the function returns
    end
  end
end
So, you call the main menu, when you want to open a sub menu it calls the function, to go back to the main menu you end return from function, the main menu is in a loop so it starts again. To exit the main menu, do the same, returrn from the function and it will exit.
Ghozer #5
Posted 07 July 2012 - 10:55 PM
Hmm,

I wanted to try and collect things in individual functions, so I didn't have to have a copy of the buttons under every single page's function, hence having the button 'actions' in thier own function
Luanub #6
Posted 07 July 2012 - 11:44 PM
I would really consider doing it the way MysticT listed. With using os.run()/shell.run() you are nesting the program inside of itself. This is causing the "Termininated" spam as it is terminating each entity that has been started in the memory stack. This is just a symptom of what can turn into a much larger issue.. If you get to much in the memory stack things get ugly… You should avoid it at all cost..
Ghozer #7
Posted 07 July 2012 - 11:49 PM
Yeah I know…

is there any way of doing it how he suggested, but only having the inputs/checks once, instead of per function?

that's kinda what I wanted to accomplish…
Ghozer #8
Posted 08 July 2012 - 12:27 AM
ok, I did this, but it doesn't return to main menu when pressing button 6 (param 7)


function mainMenu()
while true do
  -- ---- DRAW MENU
  m.clear("back")
  m.writePos("back", "---- Welcome to SCF! ----", 16, 1)
  m.writePos("back", "|	   Main Menu	   |", 16, 2)
  bL("- [Members]", 3)
  bL("- [Rules]", 10)
  bL("- [Joining]", 16)
  bR("[EMPTY] -", 3)
  bR("[EMPTY] -", 10)
  bR("[EMPTY] -", 16)
  -- ---- PULL INPUT
  os.pullEvent("redstone")
  if rs.testBundledInput("front", 2) then
    os.queueEvent("key", 2)
  elseif rs.testBundledInput("front", 16) then
    os.queueEvent("key", 3)
  elseif rs.testBundledInput("front", 1) then
    os.queueEvent("key", 4)
  elseif rs.testBundledInput("front", 16384) then
    os.queueEvent("key", 5)
  elseif rs.testBundledInput("front", 8192) then
    os.queueEvent("key", 6)
  elseif rs.testBundledInput("front", 2048) then
    os.queueEvent("key", 7)
  end
  local sEvent, param = os.pullEvent("key")
  if(sEvent == "key") then
 
  -- ---- DO SOMETHING WITH INPUT 
   if(param == 2) then
    membersMenu()
   elseif(param == 3) then
    rulesMenu()
   elseif(param == 4) then
    joinMenu()
   else
    break
   end
  -- ---- END
  end
  if exit then
   break
  end 
end
end
function membersMenu()
while true do
  -- ---- DRAW MENU
  m.clear("back")
  m.writePos("back", "---- Welcome to SCF! ----", 16, 1)
  m.writePos("back", "|	 Members Menu	  |", 16, 2)
  bL("- [EMPTY]", 3)
  bL("- [EMPTY]", 10)
  bL("- [EMPTY]", 16)
  bR("[EMPTY] -", 3)
  bR("[EMPTY] -", 10)
  bR("[Back] -", 16)
  -- ---- PULL INPUT
  os.pullEvent("redstone")
  if rs.testBundledInput("front", 2) then
    os.queueEvent("key", 2)
  elseif rs.testBundledInput("front", 16) then
    os.queueEvent("key", 3)
  elseif rs.testBundledInput("front", 1) then
    os.queueEvent("key", 4)
  elseif rs.testBundledInput("front", 16384) then
    os.queueEvent("key", 5)
  elseif rs.testBundledInput("front", 8192) then
    os.queueEvent("key", 6)
  elseif rs.testBundledInput("front", 2048) then
    os.queueEvent("key", 7)
  end
  local sEvent, param = os.pullEvent("key")
  if(sEvent == "key") then
  -- ---- DO SOMETHING WITH INPUT 
   if(param == 7) then
    mainMenu()
   else
    break
   end
  -- ---- END  
  end
end
end
-- ------------ PRINT FUNCTIONS
function bL(text, y)
m.writePos("back", text, 2, y)
end
function bR(text, y)
m.writePos("back", text, 47, y)
end
-- ----
mainMenu()
Ghozer #9
Posted 08 July 2012 - 04:35 PM
It's ok, i got it sorted the way I wanted to do it originally any ways, without executing multiple functions etc!! :)/>/>