Posted 20 June 2013 - 02:01 PM
I am writing a custom Program to control my entire Base via rednet. To do this, I want to have the main program running useing coroutines to pause and resume different functions while the computer is also waiting for an event to happen. If an evvent occurs, the currently running coroutine is supposed to run until it hits coroutine.yield() before the program reacts to the occured event. I first looked into the parallel API and used that in my Code, but after reading a bit more in the wiki and this Forum, I found out, that the parallel API itsself is useing Coroutines which means, that it would probably mess up with the rest of my program. Now I am looking for a way to work around this. Most important is, not to loose an occuring Event. I have all coroutines, that are not dead in an array co={}.
The loop function is not yet finished, but it will handle my coroutines. I am looking for a way to work around the parallel API so I don't loose either the state of my coroutines nor an event, Please, help me…
Complete Code:
The loop function is not yet finished, but it will handle my coroutines. I am looking for a way to work around the parallel API so I don't loose either the state of my coroutines nor an event, Please, help me…
--[Main Program]--
local function event()
e,p1,p2,p3,p4,p5=os.pullEvent()
occ=="event"
return e
end
--this function is part of the main program
--it gives the Main loop to control everything
function loop()
while true do
if co[1]==0 then
co[2]=coroutine.create(home())
co[1]=1
end
for local coi=1,co[1] do
coroutine.resume(co[coi+1])
end
end
occ="loop"
end
while true do
--checking for any occurance (event or feedback from the loop)
parallel.waitForAny(event(),loop())
--the next part of code decides how to handle the occurance
--not yet implemented
end
Complete Code:
Spoiler
--[Milch Operating System Version 0.2]--
--[by Milchschokolade]--
--[Instructions:]--
--[Put 5x4 Advanced Monitors on the Ground, than the Advanced Computer]--
--[with this Program on it 1 block above the Ground and 5x4 advanced Monitors]--
--[on the other side of the Computer: (X is an Advanced Monitor, C the Computer]--
--[X.X.X.X.X. .X.X.X.X.X]--
--[X.X.X.X.X. .X.X.X.X.X]--
--[X.X.X.X.X.C.X.X.X.X.X]--
--[X.X.X.X.X. .X.X.X.X.X]--
--[Make sure, this program is saved as 'startup'. Label the Computer!]--
--[Run the 'id' program on the Computer and put the resulting ID]--
--[(the number only, without '#') as Value behind the 'id=']--
id=
--[reboot the computer]--
--[To add a new Program, make sure to change the Global Variable]--
--['prognumb' to the correct number of programs.]--
--[Color Settings:]--
mtc=265 --Main Text Color
utc=1 --Secondary Text Color
stc=32 --Text Colour to show Sucess
ftc=16384 --Text Color to show faliure
mbc=32768 --Main Background Color
mc=256 --Menu Color
mct=1 --Menu Text Color
bc1=18 --Main Button Color
bc2=32768 --Secondary Button Color
--[Global Variables]--
prog={} --List of all programs.
co={0} --List of currently running/unfinished coroutines, co[1] is the number of coroutines
selecP=(home)
prognumb=0
version=0.2
lma={}
loGlength=0
loG={}
e,p1,p2,p3,p4,p5=nil --global event variables (see function event)
occ==" " --this variable is used to tell the main program, if an event has happened or
--if something else happened
button=" " --gives the pressed Button
--[Global Functions]--
--lmonctrl()
--this function updates the left Monitor and handles its graphical interface
local function lmonctrl()
lmon.clear()
for local lmonctrli=1,5 do
lmon.setCursorPos(1,lmonctrli)
lmon.setBackgroundColor(mc)
lmon.write(" ")
end
lmon.setCursorPos(1,1)
lmon.setTextColor(mct)
lmon.write("Milch OS Version "..tostring(version))
--reboot button
lmon.setCursorPos(44,4)
lmon.setBackgroundColor(bc1)
lmon.write(" ")
lmon.setCursorPos(44,5)
lmon.setTextColor(bc2)
lmon.write("Reboot")
--settings button
lmon.setCursorPos(35,4)
lmon.write(" ")
lmon.setCursorPos(35,5)
lmon.write("Settings")
--console handling:
for local lmonctrlk=6,27 do
lmon.setCurorPos(1,lmonctrlk)
for local lmonctrlm=1,lma[lmonctrlk-5][1] do
lmon.setBackgroundColor(lma[lmonctrlk-5][(lmonctrlm*2)+(lmonctrlm-1)])
lmon.setTextColor(lma[lmonctrlk-5][lmonctrlm*2)+(lmonctrlm-1)+1])
lmon.write(lma[lmonctrlk-5][lmonctrlm*2)+(lmonctrlm-1)+2])
end
end
end
--rmonctrl()
--this function updates the right Monitor and handles its graphical interface
local function rmonctrl()
rmon.clear()
for local rmonctrli=1,5 do
lmon.setCursorPos(1,rmonctrli)
lmon.setBackgroundColor(mc)
lmon.write(" ")
end
rmon.setCursorPos(1,1)
rmon.setTextColor(mct)
rmon.write(tostring(SelecP))
--home button
rmon.setCursorPos(46,4)
rmon.setBackgroundColor(bc1)
rmon.seTextColor(bc2)
rmon.write(" ")
rmon.setCursorPos(46,5)
rmon.write("Home")
end
--event()
--this function constantly checks if an event is occuring
local function event()
e,p1,p2,p3,p4,p5=os.pullEvent()
occ=="event"
return e
end
local function buttontest(a,b,c)
button==" "
if a=="left" then
--Button on the left Monitor (Control Buttons)
--'settings' Button
if b<43 then
if b>34 then
if c<6 then
if c>3 then
button=="settings"
end
end
end
end
--'reboot' Button
if b<51 then
if b>43 then
if c<6 then
if c>3 then
button=="reboot"
end
end
end
end
elseif a=="right" then
--Button on the right Monitor (functions)
else
loGadd(loG,"Error: Wrong Parameter in function buttontest()")
end
end
local function loGadd(a,B)/>/>/>
table.insert(a,B)/>/>/>
loGlength=loGlength+1
end
--[Available Programs]--
--Programs are Managed in an array
--home
--this function is used if no other Program is selected
--It acts like a desktop
--Important: all this Program MUST be the first to get added to the 'prog' array
local function home()
rmon.setTextColor(bc2)
rmon.setBackgroundColor(bc1)
prognumb=(table.maxn(prog))/2
if prognumb<11 then
for local homei=2,prognumb do
rmon.setCursorPos(1,(homei*2)+3)
rmon.write(prog[homei*2])
end
else
local f=math.floor(prognumb/10)
for d=1,f do
for local homei=((d-1)*10)+2,((d-1)*10)+11 do
rmon.setCursorPos(1,(homei*2)+3)
rmon.write(prog[homei*2])
end
if d==1 then
rmon.setCursorPos(1,26)
rmon.write("Next Page")
elseif d==f then
rmon.setCursorPos(1,27)
rmon.write("Previous Page")
else
rmon.setCursorPos(1,26)
rmon.write("Next Page")
rmon.setCursorPos(1,27)
rmon.write("Previous Page")
end
rmon.setCursorPos(1,25)
rmon.setTextColor(utc)
rmon.setBackgroundColor(mbc)
rmon.write("Page "..tostring(d).."/"..tostring(f))
rmon.setTextColor(bc2)
rmon.setBackgroundColor(bc1)
coroutine.yield()
rmonctrl()
end
end
end
table.insert(prog,home())
table.insert(prog,"Home")
--[Main Program]--
--this function is part of the main program
--it gives the Main loop to control everything
function loop()
while true do
if co[1]==0 then
co[2]=coroutine.create(home())
co[1]=1
end
for local coi=1,co[1] do
coroutine.resume(co[coi+1])
end
end
occ="loop"
end
loGadd(loG,"MilchOS "..tostring(version).."started")
rednet.open("back")
term.clear()
term.setCursorPos(1,1)
term.setTextColor(256)
term.setBackgroundColor(32768)
lmon=peripheral.wrap("left")
rmon=peripheral.wrap("right")
term.write("Welcome to MilchOS Version "..tostring(version))
lmonctrl()
rmonctrl()
while true do
--checking for any occurance (event or feedback from the loop)
parallel.waitForAny(event(),loop())
--the next part of code decides how to handle the occurance
if occ=="event" then
if e=="monitor_touch" then
buttontest(p1,p2,p3)
elseif e=="rednet_message" then
else
end
end
--updating both monitors
lmonctrl()
rmonctrl()
end