Posted 17 March 2015 - 01:25 PM
Hi guys,
I have been writing an OS for some time (2 weeks), and now I am struggling with the multitasking. Here is the code I have hacked together: ( this is some new code now)
It kind of works, but it is not perfect. The gap on the right side ( window width is w-1 ) is for switching between processes. I would love it if helped me make this system better. To submit improvements, do it on the formus or on the github.
Edit: Sometimes it manages to launch processes, but throws an error when I click on the process I want to launch only once. It does not show the correct process too. When I click on desktop ( in the right gap) it show FileX, but reacts to desktop layout.
Why is #routines always = 0 ?
Some pictures:
Thanks in advance
and have a great day.
~Creator
PS: If you want to learn more about the project, visit this page.
I have been writing an OS for some time (2 weeks), and now I am struggling with the multitasking. Here is the code I have hacked together: ( this is some new code now)
Spoiler
--[[
TheOS Kernel
by Creator
for TheOS &
you to learn
from it
]]--
local args = {...}
local w,h = term.getSize()
local currTerm = term.current()
local routines = {}
local routinesToKill = {}
local activeRoutine = ""
local eventGlobal = true
local halfH = math.floor(h/2 +2)
local first = true
local function drawClosed()
paintutils.drawLine(w,1,w,h,colors.black)
term.setTextColor(colors.white)
term.setBackgroundColor(colors.black)
term.setCursorPos(w,halfH)
term.write("<")
end
local function drawOpen()
paintutils.drawFilledBox(w-15,1,w,h,colors.black)
local xVsProcess = {}
local curr = 1
term.setTextColor(colors.white)
for i,v in pairs(routines) do
term.setCursorPos(w-14,(curr*2))
term.write("x "..v.title)
term.setCursorPos(w-12,(curr*2)+1)
term.write(coroutine.status(v.routine))
xVsProcess[curr*2] = v.ID
curr = curr + 1
end
local notH = true
local switchRoutine = false
while notH do
evnt = {os.pullEventRaw("mouse_click")}
if w-12 <= evnt[3] and evnt[3] <= w then
if xVsProcess[evnt[4]] ~= nil then
notH = false
switchRoutine = true
end
else
notH = false
end
end
if switchRoutine then
term.clear()
print(textutils.serialize(xVsProcess))
for i,v in pairs(routines) do
term.write(i.." ") print(v)
end
print(evnt[4])
routines[activeRoutine].window.setVisible( false )
print(activeRoutine)
activeRoutine = xVsProcess[evnt[4]]
print(activeRoutine)
routines[activeRoutine].window.setVisible(true)
--os.pullEventRaw()
end
routines[activeRoutine].window.redraw()
end
function newRoutine(name,func,...)
local sName = name
name = name.."1"
local notUnique = true
local tries = 1
while notUnique do
tries = tries + 1
if routines[name] ~= nil then
name = name:sub(1,-2)..tostring(tries)
else
notUnique = false
end
end
local arguments = {...}
routines[name] = {}
routines[name].routine = coroutine.create(func)
if first then
routines[name].window = window.create(term.current(),1,1,w-1,h,true)
activeRoutine = name
first = false
else
routines[name].window = window.create(term.current(),1,1,w-1,h,false)
end
os.pullEventRaw()
routines[name].title = sName
routines[name].ID = name
routines[name].arguments = arguments
routines[name].hasRun = false
end
local function main()
os.queueEvent("slagadalahssj")
while true do
routinesToKill = {}
event = {os.pullEventRaw()}
if event[1] == "key" or event[1] == "mouse_click" or event[1] == "monitor_touch" then
eventGlobal = false
else
eventGlobal = true
end
if (event[1] == "mouse_click" or event[1] == "monitor_touch") and event[3] == w then
drawOpen()
drawClosed()
routines[activeRoutine].window.redraw()
else
for i,v in pairs(routines) do
local status = coroutine.status(routines[i].routine)
if status == "dead" then
routinesToKill[#routinesToKill+1] = i
if activeRoutine == i then activeRoutine = "Desktop1" end
else
if routines[i].hasRun == false then
routines[i].hasRun = true
term.redirect(routines[i].window)
coroutine.resume(routines[i].routine,unpack(routines[i].arguments))
term.redirect(currTerm)
else
if i == activeRoutine then
term.redirect(routines[i].window)
coroutine.resume(routines[i].routine,unpack(event))
term.redirect(currTerm)
else
if eventGlobal then
term.redirect(routines[i].window)
coroutine.resume(routines[i].routine,unpack(event))
term.redirect(currTerm)
end
end
end
end
end
for i,v in pairs(routinesToKill) do
routines[v] = nil
end
end
end
end
drawClosed()
newRoutine(unpack(args))
main()
It kind of works, but it is not perfect. The gap on the right side ( window width is w-1 ) is for switching between processes. I would love it if helped me make this system better. To submit improvements, do it on the formus or on the github.
Edit: Sometimes it manages to launch processes, but throws an error when I click on the process I want to launch only once. It does not show the correct process too. When I click on desktop ( in the right gap) it show FileX, but reacts to desktop layout.
Why is #routines always = 0 ?
Some pictures:
Thanks in advance
and have a great day.
~Creator
PS: If you want to learn more about the project, visit this page.
Edited on 18 March 2015 - 01:29 PM