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

Using function:subfunc()? Self?

Started by DannySMc, 30 March 2015 - 01:12 PM
DannySMc #1
Posted 30 March 2015 - 03:12 PM
Hey there,
I am trying to figure out how this works: self?

I want to make a function called threads with functions inside it. So if I have:

function thread()
    list = function(self, ...)
        return tRunning
    end
end

I want to be able to do:
thread:list()

But this doesn't work? and U wanted to make it so you can give it arguments? But how do I even do this? Add the arguments in the … in the sub function or the main one?:S

Thanks!
KingofGamesYami #2
Posted 30 March 2015 - 03:15 PM
You'd use tables, more specifically metatables, to do this.


local mthread = {
  list = function( self, ... )
    return __
  end,
}
function thread()
  return setmetatable( {}, {__index = mthread}
end

Edit: If you really, really wanted a function you could add __call, like this:

function thread()
  return setmetatable( {}, {__index = mthread, __call = function()
  --#do things
  end } )
end
Edited on 30 March 2015 - 01:21 PM
SquidDev #3
Posted 30 March 2015 - 03:16 PM
Do you mean:

function thread()
  local tRunning = {}
  return {
	list = function(self, arg1, arg2, ...)
	  return tRunning
	end
  }
end

local myThread = thread();
myThread:list()

In this case you are referencing tRunning as an upvalue. This makes access to tRunning private and faster than referencing it like a table like this:


local myThead =  {
	tRunning = {}
	list = function(self, ...)
	  return self.tRunning
	end
  }

Edit: Sorry, Yami beat me.
Edited on 30 March 2015 - 01:17 PM
DannySMc #4
Posted 30 March 2015 - 03:20 PM
Ahh okay yeah I just figured it out that it was tables >.< also I have this, could someone explain why it doesn't work? I want to make it so when I create it, it is not visible, but then be able to make it visible when I go to it?

local thread = {
create = function( self, name )
  table.insert(tRunning[1], name)
  table.insert(tRunning[2], window.create(term.current(), 1, 1, 51, 19, false))
  return true
end,
goto = function( self, name )
  for k, v in ipairs(tRunning[1]) do
   if v == name then
    term.redirect(tRunning[2][k])
    tRunning[2][k].setVisible(val1)
   end
  end
end,
list = function( self )
  return tRunning
end
}


thread:create("desktop")
thread:goto("desktop")
startup()
KingofGamesYami #5
Posted 30 March 2015 - 03:23 PM
1. I don't see the tRunning table
2. What is vall on line 11? Shouldn't this be true?
3. You never turn off visibility when switching
4. I don't know what startup() does.
DannySMc #6
Posted 30 March 2015 - 03:25 PM
1. I don't see the tRunning table
2. What is vall on line 11? Shouldn't this be true?
3. You never turn off visibility when switching
4. I don't know what startup() does.

1. tRunning is defined above the function as:
tRunning = {{},{}}
2. true
3. I am not turning it off, it is set off when created, and when running thread:goto() then it should setVisible(true) on that window,
4. simply prints "hey"

function startup()
	print("hey")
end
Edited on 30 March 2015 - 01:26 PM
DannySMc #7
Posted 30 March 2015 - 03:51 PM
Anyone?
GopherAtl #8
Posted 30 March 2015 - 03:57 PM
there is another syntax for this, which I prefer personally.


--just declare the table
local class_widget = { }
--and metatable
local class_widget_meta = { __index = class_widget }

--now define member functions

function class_widget:introduce()
  print("I'm a widget named "..self.name)
end

function class_widget:rename(name)
  self.name=name
  self:introduce()
end

function newWidget(name)
  local widget={
	 name=name,
  }
  setmetatable(widget,class_widget_meta)
  return widget
end

local w1,w2=newWidget("foo"),newWidget("bar")

w1:introduce()
w2:introduce()
w1:rename("FOO!")


Declaring the functions this way, with "function <table>:<functioname>()", just seems more readable to me, so I always use it in cases where I don't need closures.

:edit: as to your current problem, it's rather hard to diagnose when you keep giving us just the bits of the code you think are relevant instead of the whole program. I'll poke at the code with a stick in a minute and see if I see the problem, but no promises.
Edited on 30 March 2015 - 02:00 PM
GopherAtl #9
Posted 30 March 2015 - 04:10 PM
After poking it with a stick, changing "val1" to "true", and adding the startup() function and tRunning tables as you listed them when asked but inexplicably omitted from your previous post, the code you've given appears to work, though it doesn't actually try to do the things you say are not working, so that's not a terribly meaningful test result.

as yami tried to point out, and you completely missed the point. Yes, you initialize them to false, then goto sets visible to true. But once one is set to true, you never set it back to false again, at least, not in any of this code.

Beyond that, you'll have to give an actual, complete, non-working program if you want people to help you fix said program.
Edited on 30 March 2015 - 02:11 PM
DannySMc #10
Posted 30 March 2015 - 04:28 PM

sCurrent = nil
tRunning = {{},{}}
local thread = {
	create = function( self, name )
		table.insert(tRunning[1], name)
		table.insert(tRunning[2], window.create(term.current(), 1, 1, 51, 19, false))
		return true
	end,
	goto = function( self, name )
		for k, v in ipairs(tRunning[1]) do
			if v == name then
				if sCurrent then
					for k1, v1 in ipairs(tRunning[1]) do
						if v1 == sCurrent then
							tRunning[2][k1].setVisible(false)
						end
					end
				end
				sCurrent = name
				tRunning[2][k].setVisible(true)
				term.redirect(tRunning[2][k])
			end
		end
	end,
	list = function( self )
		return tRunning
	end
}
function main()
if term.isColour() then
  local ok, err = pcall(function()
   thread:create("desktop")
   thread:goto("desktop")
   startup()
  end)
  if not ok then
   omi.crash(err)
  end
else
  omi.crash("Please use an advanced (gold) computer.")
end
end
function startup()
print("hey")
end
main()

That above is the code, that is what I am using, there is more but these aren't a part of what I am using.
I didn't know what you meant on that one.

EDIT: On this I think I have it
Edited on 30 March 2015 - 02:28 PM
KingofGamesYami #11
Posted 30 March 2015 - 04:55 PM
Nothing against you or anything, but you don't seem to be using OOP, just the cool looking syntax (thread:goto). Are you planning to use the self variable at any point, or no?

One thing I'd recommend is actually running something. Currently you have a table of strings that are linked to windows.
DannySMc #12
Posted 30 March 2015 - 05:00 PM
Nothing against you or anything, but you don't seem to be using OOP, just the cool looking syntax (thread:goto). Are you planning to use the self variable at any point, or no?

One thing I'd recommend is actually running something. Currently you have a table of strings that are linked to windows.

Well I am not completely sure, I didn't plan to use OOP, I just wanted that type of syntax as I was slightly confused on how it all works, I am starting to understand more about how it works, but at the moment I do not need it.
The windows currently will be coroutines which will have a window attached, like the script you gave me but when I got more in depth testing it didn't really work, it kept blocking my input to windows, even after I did what you said, so I gave up and started my own and see how well I can do it.
MKlegoman357 #13
Posted 30 March 2015 - 05:26 PM
Before you expand this program more I'd like to make some suggestions/improvements. The current structure of tRunning is not looking good to me. I'd suggest you to make a structure similar to this:

local tRunning = {
  --# this is an example of a single 'thread' object
  {
    name = name_of_thread, --# the name of the thread
    window = the_window_object --# ex.: window.create(...)
  }
}

It will become a lot easier to manage and read through. You can also make a 'find' or 'get' function to find the thread faster.

find = function ( self, name )
  for i, th in ipairs( tRunning ) do --# 'th' stands for 'thread' FYI :P/>
    if th.name == name then
      return th
    end
  end
end

After these few changes, you could rewrite the 'goto' function:

goto = function( self, name )
  local th = thread:find( name )

  if th then
    if sCurrent then
      local prevTh = thread:find( sCurrent )

      prevTh.window.setVisible( false )
    end

    sCurrent = th.name
    th.window.setVisible(true)
    term.redirect(th.window)
  end
end

As you can see, the code becomes a lot more readable and easier to manage. Don't forget that Lua's tables are not just simple arrays, they are whole objects (just like JavaScript's objects)!




The 'self' variable is used with functions inside tables. It is here for OOP purposes in Lua. Imagine we have this code:


local object = {}

object.setName = function (obj, newName)
  obj.name = newName
end

Now if we wanted to change the 'name' property of the 'object' we would do something like this:


object.setName(object, "MyObject")

This was actually done a lot (I believe) in older versions of Lua by people who did OOP. Because of this, the colon ( : ) notation was introduced. So, instead of our previous example, you are able to do this:


object:setName("MyObject")

Which is exactly the same as our previous example, except shorter. The specification of the colon notation could look like this:


<table_name>:<function_name>(...)

Is the same as:


<table_name>.<function_name>(<table_name>, ...)
Edited on 30 March 2015 - 03:30 PM
DannySMc #14
Posted 30 March 2015 - 05:29 PM
I can't figure out how to allow a coroutine to be able to take events? Anyone? I need to be able to use some kind of os.pullEvent() inside a coroutine? Any ideas? All of it is internal though.

Before you expand this program more I'd like to make some suggestions/improvements. The current structure of tRunning is not looking good to me. I'd suggest you to make a structure similar to this:

local tRunning = {
  --# this is an example of a single 'thread' object
  {
	name = name_of_thread, --# the name of the thread
	window = the_window_object --# ex.: window.create(...)
  }
}

It will become a lot easier to manage and read through. You can also make a 'find' or 'get' function to find the thread faster.

find = function ( self, name )
  for i, th in ipairs( tRunning ) do --# 'th' stands for 'thread' FYI :P/>/>
	if th.name == name then
	  return th
	end
  end
end

After these few changes, you could rewrite the 'goto' function:

goto = function( self, name )
  local th = thread:find( name )

  if th then
	if sCurrent then
	  local prevTh = thread:find( sCurrent )

	  prevTh.window.setVisible( false )
	end

	sCurrent = th.name
	th.window.setVisible(true)
	term.redirect(th.window)
  end
end

As you can see, the code becomes a lot more readable and easier to manage. Don't forget that Lua's tables are not just simple arrays, they are whole objects (just like JavaScript's objects)!




The 'self' variable is used with functions inside tables. It is here for OOP purposes in Lua. Imagine we have this code:


local object = {}

object.setName = function (obj, newName)
  obj.name = newName
end

Now if we wanted to change the 'name' property of the 'object' we would do something like this:


object.setName(object, "MyObject")

This was actually done a lot (I believe) in older versions of Lua by people who did OOP. Because of this, the colon ( :)/>/> notation was introduced. So, instead of our previous example, you are able to do this:


object:setName("MyObject")

Which is exactly the same as our previous example, except shorter. The specification of the colon notation could look like this:


<table_name>:<function_name>(...)

Is the same as:


<table_name>.<function_name>(<table_name>, ...)
</table_name></function_name></table_name></function_name></table_name>

Ahh okay, well let me get some basics down as I am so stuck with this coroutine and then yes I shall take your advice and it make it look better, because it is a mess currently, do you know how to be able to use input in a coroutine? So I run a coroutine that's called desktop? I can't use any kind of read or touch screen events? I need it to be all internal though not sending it to another coroutine? I need to be able to run one coroutine when I want and then resume it later I just can't get any input?:s

Thanks again!
KingofGamesYami #15
Posted 30 March 2015 - 06:21 PM
Let's say you have a coroutine "co"


local co = coroutine.create( function()
  while true do
    os.pullEvent()
  end
end )

Next, you start it running


co:resume()

However, this will not suffice if you need to use events in your coroutine. You will have to use a loop


while true do
  coroutine.resume( co )
end

Now, when the coroutine yields at os.pullEvent, we resume it again immediately. This still doesn't give it events though.


while true do
  coroutine.resume( co, os.pullEvent() )
end

Now, when the coroutine yields at os.pullEvent, we pull an event, then resume it with those parameters which are passed "through" os.pullEvent (coroutine.yeild returns the values you pass to coroutine.resume besides the coroutine).

However, this still won't work entirely, because we haven't accounted for os.pullEvent's filter


local sFilter
while true do
  sFilter = coroutine.resume( co, os.pullEvent( sFilter ) )
end

This part does, however, deal with events nicely. When the coroutine yeilds at os.pullEvent, we capture what was given to os.pullEvent (sFilter) and resume the coroutine after pulling an event with the specified filter.

This, however, doesn't allow us to use multiple coroutines. It will only run a single coroutine at a time


local tFilters = {}
local tRunning = { co }
local tEventData = {}
while true do
  for k, v in pairs( tRunning ) do
    if tFilters[ k ] == tEventData[ 1 ] then
      tFilters[ k ] = coroutine.resume( v, unpack( tEventData ) )
    end
  end
  tEventData = { os.pullEvent() }
end

This allows you to use multiple coroutines at a time, as it stores the filter from each, and gives each one the event data requested. However, it does not work correctly if os.pullEvent was called without a parameter, so we need to modify it.


local tFilters = {}
local tRunning = { co }
local tEventData = {}
while true do
  for k, v in pairs( tRunning ) do
    if tFilters[ k ] == tEventData[ 1 ] or tFilters[ k ] == nil then
      tFilters[ k ] = coroutine.resume( v, unpack( tEventData ) )
    end
  end
  tEventData = { os.pullEvent() }
end

Tada, events now work correctly.
DannySMc #16
Posted 31 March 2015 - 10:44 AM
- snip -

I have a problem, this doesn't work?:(/> I did everything you said, but it isn't working, it gives me the option to type, but is still blocking it?:S

Here is my code:

local thread = {
tRunning = {{},{},{}},
create = function( self, name, func )
  table.insert(tRunning[1], name)
  table.insert(tRunning[2], window.create(term.current(), 1, 1, 51, 19, false))
  if func then
   table.insert(tRunning[3], coroutine.create(func))
  else
   table.insert(tRunning[3], false)
  end
  return true
end,
resume = function( self, name )
  for k, v in ipairs(tRunning[1]) do
   if v == name then
    if sCurrent then
	 for k1, v1 in ipairs(tRunning[1]) do
	  if v1 == sCurrent then
	   tRunning[2][k1].setVisible(false)
	  end
	 end
    end
    sCurrent = name
    tRunning[2][k].setVisible(true)
    term.redirect(tRunning[2][k])
    if tRunning[3][k] then
	 coroutine.resume(tRunning[3][k])
    end
   end
  end
end,
list = function( self )
  return tRunning[3]
end,
kill = function( self, name )
  for k,v in ipairs(tRunning[1]) do
   if k == name then
    table.remove(tRunning[1][k])
    table.remove(tRunning[2][k])
    table.remove(tRunning[3][k])
   end
  end
end,
status = function( self, name )
  for k,v in ipairs(tRunning[1]) do
   if k == name then
   
   end
  end
end,
}
function main()
if term.isColour() then
  local ok, err = pcall(function()
   thread:create("test", omi.test)
   local tFilters = {}
   local tRunning = thread:list()
   local tEventData = {}
   while true do
    for k, v in pairs( tRunning ) do
	 if tFilters[ k ] == tEventData[ 1 ] or tFilters[ k ] == nil then
	  tFilters[ k ] = coroutine.resume(v, unpack(tEventData))
	 end
    end
    tEventData = { os.pullEvent() }
   end
  end)
  if not ok then
   crash(err)
  end
else
  crash("Please use an advanced (gold) computer.")
end
end

main()
GopherAtl #17
Posted 31 March 2015 - 01:14 PM
and once again, you give us something that is not your actual, complete code. Even if you add teh things that are missing, this code would crash very early, before the problem you're describing ("it gives me the option to type, but is still blocking it?:S" whatever that means) could possibly have a chance to happen, because tRunning is declared inside the thread table, but referenced as if it were a global. So the first time it hits a tRunning[1] it will crash with an attempt to index nil.

Please, for the love of god, and all that is holy, or unholy, or just theologically neutral, give us real, actual code that you're actually running and actually getting errors from.
Edited on 31 March 2015 - 11:15 AM
DannySMc #18
Posted 31 March 2015 - 01:38 PM
and once again, you give us something that is not your actual, complete code. Even if you add teh things that are missing, this code would crash very early, before the problem you're describing ("it gives me the option to type, but is still blocking it?:S" whatever that means) could possibly have a chance to happen, because tRunning is declared inside the thread table, but referenced as if it were a global. So the first time it hits a tRunning[1] it will crash with an attempt to index nil.

Please, for the love of god, and all that is holy, or unholy, or just theologically neutral, give us real, actual code that you're actually running and actually getting errors from.

For one, the actual code that is executing is the code you see, I am running that code on it's own and when it is fixed putting it back in the main program… The code there is what I am having a problem with.

When I said blocking, I meant, I try to type but it's not letting me, so it starts the read function but doesn't allow me to type characters?

Here is all of the code then:

--[[
Name: Omicron
Creator: DannySMc (dannysmc95)
Platform: Lua Virtual Machine (JVM)
Network: CCSystems
Bugs / Errors:
--------------
https://github.com/dannysmc95/OmicronOS/issues -> Submit an issue, i shall fix it when I get a chance.
License:
--------
This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
]]
-- Vars:
nTries = 0
nLoadAnim = 0
-- Main Functions
omi = {}
omi.__index = omi
-- Draw Functions
omi.draw = {}
omi.draw.__index = omi.draw
-- core Functions
omi.core = {}
omi.core.__index = omi.core
-- Database (CCSystems) Functions
omi.ccsys = {}
omi.ccsys.__index = omi.ccsys
term.clear()
term.setCursorPos(1, 1)
local thread = {
tRunning = {{},{},{}},
sCurrent = nil,
create = function( self, name, func )
  table.insert(self.tRunning[1], name)
  table.insert(self.tRunning[2], window.create(term.current(), 1, 1, 51, 19, false))
  if func then
   table.insert(self.tRunning[3], coroutine.create(func))
  else
   table.insert(self.tRunning[3], false)
  end
  return true
end,
resume = function( self, name )
  for k, v in ipairs(self.tRunning[1]) do
   if v == name then
    if self.sCurrent then
	 for k1, v1 in ipairs(self.tRunning[1]) do
	  if v1 == self.sCurrent then
	   self.tRunning[2][k1].setVisible(false)
	  end
	 end
    end
    self.sCurrent = name
    self.tRunning[2][k].setVisible(true)
    self.tRunning[2][k].redraw()
    term.redirect(self.tRunning[2][k])
    if self.tRunning[3][k] then
	 coroutine.resume(self.tRunning[3][k])
    end
   end
  end
end,
list = function( self )
  return self.tRunning[3]
end,
kill = function( self, name )
  for k,v in ipairs(self.tRunning[1]) do
   if k == name then
    table.remove(self.tRunning[1][k])
    table.remove(self.tRunning[2][k])
    table.remove(self.tRunning[3][k])
   end
  end
end,
status = function( self, name )
  for k,v in ipairs(self.tRunning[1]) do
   if k == name then
   
   end
  end
end,
current = function( self )
  return sCurrent
end,
}
function omi.init()
    local ok, err = pcall( function ()
	 if http then
	  if fs.exists("progutils") then
	  os.loadAPI("progutils")
		  return true
	  end
	  aa = aa or {}
	  local a = http.get("https://vault.dannysmc.com/lua/api/dannysmcapi.lua")
	  a = a.readAll()
	  local env = {}
	  a = loadstring(a)
	  local env = getfenv()
	  setfenv(a,env)
	  local status, err = pcall(a, unpack(aa))
	  if (not status) and err then
		  printError("Error loading api")
		  return false
	  end
	  local returned = err
	  env = env
	  _G["progutils"] = env
	 
	  omi.main()
	 else
	  omi.crash("HTTP needs to be enabled.")
	 end
    end)
    if not ok then
	 if nTries == 3 then
	  print("The program has tried 3 times to get the API, We shall run shell instead.")
		 sleep(5)
		 shell.run("clear")
		 shell.run("shell")
	    else
		 nTries = nTries + 1
		    print("Program, failed to download API, Re-trying...")
		    sleep(1)
		    omi.init()
	    end
    end
end
function omi.crash(errcode)
col.screen("white")
draw.box(1, 51, 1, 1, " ", "grey", "grey")
draw.textc(" Omicron has crashed", 1, false, "cyan", "grey")
local sText = "An error has caused Omicron to crash, the error is below, if this happens again, please report the problem and error code to DannySMc (dannysmc95). Error code is stated below in red."
for k,v in ipairs(data.wordwrap(sText, 51)) do
  draw.texta(v, 1, k+2, false, "lightGrey", "white")
end
for k, v in ipairs(data.wordwrap(errcode, 45)) do
  draw.texta(v, 4, k+8, false, "red", "white")
end
draw.texta("-< Press enter to restart or 's' for shell >-", 4, 19, false, "grey", "white")

while true do
  local args = { os.pullEvent() }
  if args[1] == "key" then
   if args[2] == keys.enter then
    omicron.main()
   elseif args[2] == keys.s then
    shell.run("clear")
    shell.run("shell")
   end
  end
end
end
function omi.draw.loadanimation(intx, inty, txtcol, bkgcol)
if nLoadAnim == 0 then
  draw.texta("|", intx, inty, false, txtcol, bkgcol)
  nLoadAnim = 1
elseif nLoadAnim == 1 then
  draw.texta("/", intx, inty, false, txtcol, bkgcol)
  nLoadAnim = 2
elseif nLoadAnim == 2 then
  draw.texta("-", intx, inty, false, txtcol, bkgcol)
  nLoadAnim = 3
elseif nLoadAnim == 3 then
  draw.texta("\\", intx, inty, false, txtcol, bkgcol)
  nLoadAnim = 0
end
end
function omi.draw.bar(screenname)
draw.box(1, 51, 1, 2, " ", "grey", "grey")
draw.texta("Omicron:", 1, 1, false, "cyan", "grey")
end
function omi.main()
if term.isColour() then
  local ok, err = pcall(function()
   thread:create("test", omi.test)
	  local tFilters = {}
	  local tRunning = thread:list()
	  local tEventData = {}
	  while true do
	   for k, v in pairs( tRunning ) do
		    if tFilters[ k ] == tEventData[ 1 ] or tFilters[ k ] == nil then
			  tFilters[ k ] = coroutine.resume(v, unpack(tEventData))
		    end
	   end
	   tEventData = { os.pullEvent() }
	  end
  end)
  if not ok then
   omi.crash(err)
  end
else
  omi.crash("Please use an advanced (gold) computer.")
end
end
function omi.startup()
col.screen("black")
sleep(0.15)
col.screen("grey")
sleep(0.15)
col.screen("lightGrey")
sleep(0.30)
draw.textc(" Omicron Operating System", 7, false, "white", "lightGrey")
draw.textc(" Created By DannySMc", 19, false, "lightBlue", "lightGrey")
sleep(0.30)
omi.draw.loadanimation(26, 12, "red", "lightGrey")
os.startTimer(0.15)
local count = 0
while true do
  local args = { os.pullEvent() }
  if args[1] == "timer" then
   count = count + 1
   omi.draw.loadanimation(26, 12, "red", "lightGrey")
   os.startTimer(0.15)
   if count == 10 then
    if fs.exists("/core/settings/.install") then
	 omi.login()
	 break
    else
	 omi.core.install()
	 break
    end
   end
  end
end
end
function omi.core.install()
-- Install Omicron OS
local tFolderList = {"/core/","/core/users/","/core/apis/","/core/apps/","/core/addons/","/core/settings/"}
col.screen("lightGrey")
draw.textc(" Omicron: Install", 1, false, "white", "lightGrey")
draw.textc(" ----------------", 2, false, "white", "lightGrey")
draw.texta("We are going to install Omicron, please wait...", 1, 4, false, "lightBlue", "lightGrey")
sleep(1)
draw.texta("Creating folders [0/"..#tFolderList.."]", 1, 6, false, "lightBlue", "lightGrey")
for k, v in ipairs(tFolderList) do
  draw.texta("Creating folders ["..k.."/"..#tFolderList.."]", 1, 6, false, "lightBlue", "lightGrey")
  fs.makeDir(v)
  sleep(0.01)
end
local tSettings = {"https://ccsystems.dannysmc.com/"}
draw.texta("Downloading settings files [0/"..#tFolderList.."]", 1, 7, false, "lightBlue", "lightGrey")
for k, v in ipairs(tFolderList) do
  draw.texta("Creating folders ["..k.."/"..#tFolderList.."]", 1, 7, false, "lightBlue", "lightGrey")
  fs.makeDir(v)
  sleep(0.01)
end
sleep(10)
end
function omi.test()
print("input")
local input = read()
print(input)
print("Done!")
end
function omi.core.uninstall()
-- Uninstall Omicron OS

end
function omi.desktop()
col.screen("white")
while true do
  local args = { os.pullEvent() }
end
end
omi.init()
GopherAtl #19
Posted 31 March 2015 - 02:02 PM
alright, thank you, much better. I was actually able to just run that code and see the problem you described.

After poking it with a stick for a bit, I found the problem, which was originally an issue in yami's code that you just copied over.


tFilters[ k ] = coroutine.resume(v, unpack(tEventData))
This line is wrong. coroutine.resume returns first a true or false, indicating if it successfully resumed the coroutine or not. It is the 2nd arg which will be the filter passed to pullEvent. So you were catching that true as the event filter, and no events of type true are possible, so it never got resumed.

change it to this:

_, tFilters[ k ] = coroutine.resume(v, unpack(tEventData))
and the test function will work.
Edited on 31 March 2015 - 12:03 PM
KingofGamesYami #20
Posted 31 March 2015 - 02:14 PM

tFilters[ k ] = coroutine.resume(v, unpack(tEventData))
This line is wrong. coroutine.resume returns first a true or false, indicating if it successfully resumed the coroutine or not. It is the 2nd arg which will be the filter passed to pullEvent. So you were catching that true as the event filter, and no events of type true are possible, so it never got resumed.

*facepalm*
DannySMc #21
Posted 31 March 2015 - 02:15 PM
You are the new God (I am not religious) ;)/>

Okay so on that, So is that multitasking? Run all them scripts? and then use the thread:resume() function to switch between routines?:s or is that way off?:S

Thanks by the way!
DannySMc #22
Posted 31 March 2015 - 02:36 PM
alright, thank you, much better. I was actually able to just run that code and see the problem you described.

After poking it with a stick for a bit, I found the problem, which was originally an issue in yami's code that you just copied over.


tFilters[ k ] = coroutine.resume(v, unpack(tEventData))
This line is wrong. coroutine.resume returns first a true or false, indicating if it successfully resumed the coroutine or not. It is the 2nd arg which will be the filter passed to pullEvent. So you were catching that true as the event filter, and no events of type true are possible, so it never got resumed.

change it to this:

_, tFilters[ k ] = coroutine.resume(v, unpack(tEventData))
and the test function will work.

On this how would I get it so I can use os.pullEvent()?
How do I get the arguments back?
like I use:

while true do
    local args = { os.pullEvent() }
    --do stuff here
end

So how would I get the arguments back instead?:S
KingofGamesYami #23
Posted 31 March 2015 - 03:16 PM
What exactly do you mean? With the modification Gopher suggested, os.pullEvent *should* work normally within each coroutine.
DannySMc #24
Posted 31 March 2015 - 03:27 PM
Ahh see I did try this but it didn't work, here is the code I have:

It doesn't do anything?:S I am not sure how to get the arguments back?:S

--[[
Name: Omicron
Creator: DannySMc (dannysmc95)
Platform: Lua Virtual Machine (JVM)
Network: CCSystems
Bugs / Errors:
--------------
https://github.com/dannysmc95/OmicronOS/issues -> Submit an issue, i shall fix it when I get a chance.
License:
--------
This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
]]
-- Vars:
nTries = 0
nLoadAnim = 0
-- Main Functions
omi = {}
omi.__index = omi
-- Draw Functions
omi.draw = {}
omi.draw.__index = omi.draw
-- core Functions
omi.core = {}
omi.core.__index = omi.core
-- Database (CCSystems) Functions
omi.ccsys = {}
omi.ccsys.__index = omi.ccsys
term.clear()
term.setCursorPos(1, 1)
local thread = {
tRunning = {{},{},{}},
sCurrent = nil,
create = function( self, name, func )
  table.insert(self.tRunning[1], name)
  table.insert(self.tRunning[2], window.create(term.current(), 1, 1, 51, 19, false))
  if func then
   table.insert(self.tRunning[3], coroutine.create(func))
  else
   table.insert(self.tRunning[3], false)
  end
  return true
end,
resume = function( self, name )
  for k, v in ipairs(self.tRunning[1]) do
   if v == name then
	if self.sCurrent then
	 for k1, v1 in ipairs(self.tRunning[1]) do
	  if v1 == self.sCurrent then
	   self.tRunning[2][k1].setVisible(false)
	  end
	 end
	end
	self.sCurrent = name
	self.tRunning[2][k].setVisible(true)
	self.tRunning[2][k].redraw()
	term.redirect(self.tRunning[2][k])
	if self.tRunning[3][k] then
	 coroutine.resume(self.tRunning[3][k])
	end
   end
  end
end,
list = function( self )
  return self.tRunning[3]
end,
kill = function( self, name )
  for k,v in ipairs(self.tRunning[1]) do
   if k == name then
	table.remove(self.tRunning[1][k])
	table.remove(self.tRunning[2][k])
	table.remove(self.tRunning[3][k])
   end
  end
end,
status = function( self, name )
  for k,v in ipairs(self.tRunning[1]) do
   if k == name then
  
   end
  end
end,
current = function( self )
  return sCurrent
end,
}
function omi.init()
	local ok, err = pcall( function ()
	 if http then
	  if fs.exists("progutils") then
	  os.loadAPI("progutils")
		  return true
	  end
	  aa = aa or {}
	  local a = http.get("https://vault.dannysmc.com/lua/api/dannysmcapi.lua")
	  a = a.readAll()
	  local env = {}
	  a = loadstring(a)
	  local env = getfenv()
	  setfenv(a,env)
	  local status, err = pcall(a, unpack(aa))
	  if (not status) and err then
		  printError("Error loading api")
		  return false
	  end
	  local returned = err
	  env = env
	  _G["progutils"] = env
	
	  omi.main()
	 else
	  omi.crash("HTTP needs to be enabled.")
	 end
	end)
	if not ok then
	 if nTries == 3 then
	  print("The program has tried 3 times to get the API, We shall run shell instead.")
		 sleep(5)
		 shell.run("clear")
		 shell.run("shell")
		else
		 nTries = nTries + 1
			print("Program, failed to download API, Re-trying...")
			sleep(1)
			omi.init()
		end
	end
end
function omi.crash(errcode)
col.screen("white")
draw.box(1, 51, 1, 1, " ", "grey", "grey")
draw.textc(" Omicron has crashed", 1, false, "cyan", "grey")
local sText = "An error has caused Omicron to crash, the error is below, if this happens again, please report the problem and error code to DannySMc (dannysmc95). Error code is stated below in red."
for k,v in ipairs(data.wordwrap(sText, 51)) do
  draw.texta(v, 1, k+2, false, "lightGrey", "white")
end
for k, v in ipairs(data.wordwrap(errcode, 45)) do
  draw.texta(v, 4, k+8, false, "red", "white")
end
draw.texta("-< Press enter to restart or 's' for shell >-", 4, 19, false, "grey", "white")

while true do
  local args = { os.pullEvent() }
  if args[1] == "key" then
   if args[2] == keys.enter then
	omicron.main()
   elseif args[2] == keys.s then
	shell.run("clear")
	shell.run("shell")
   end
  end
end
end
function omi.draw.loadanimation(intx, inty, txtcol, bkgcol)
if nLoadAnim == 0 then
  draw.texta("|", intx, inty, false, txtcol, bkgcol)
  nLoadAnim = 1
elseif nLoadAnim == 1 then
  draw.texta("/", intx, inty, false, txtcol, bkgcol)
  nLoadAnim = 2
elseif nLoadAnim == 2 then
  draw.texta("-", intx, inty, false, txtcol, bkgcol)
  nLoadAnim = 3
elseif nLoadAnim == 3 then
  draw.texta("\\", intx, inty, false, txtcol, bkgcol)
  nLoadAnim = 0
end
end
function omi.draw.bar(screenname)
draw.box(1, 51, 1, 2, " ", "grey", "grey")
draw.texta("Omicron:", 1, 1, false, "cyan", "grey")
end
function omi.main()
if term.isColour() then
  local ok, err = pcall(function()
   thread:create("desktop", omi.desktop)
	  local tFilters = {}
	  local tRunning = thread:list()
	  local tEventData = {}
	  while true do
	   for k, v in pairs( tRunning ) do
			if tFilters[ k ] == tEventData[ 1 ] or tFilters[ k ] == nil then
			  _, tFilters[ k ] = coroutine.resume(v, unpack(tEventData))
			end
	   end
	   tEventData = { os.pullEvent() }
	  end
  end)
  if not ok then
   omi.crash(err)
  end
else
  omi.crash("Please use an advanced (gold) computer.")
end
end
function omi.startup()
col.screen("black")
sleep(0.15)
col.screen("grey")
sleep(0.15)
col.screen("lightGrey")
sleep(0.30)
draw.textc(" Omicron Operating System", 7, false, "white", "lightGrey")
draw.textc(" Created By DannySMc", 19, false, "lightBlue", "lightGrey")
sleep(0.30)
omi.draw.loadanimation(26, 12, "red", "lightGrey")
os.startTimer(0.15)
local count = 0
while true do
  local args = { os.pullEvent() }
  if args[1] == "timer" then
   count = count + 1
   omi.draw.loadanimation(26, 12, "red", "lightGrey")
   os.startTimer(0.15)
   if count == 10 then
	if fs.exists("/core/settings/.install") then
	 omi.login()
	 break
	else
	 omi.core.install()
	 break
	end
   end
  end
end
end
function omi.core.install()
-- Install Omicron OS
local tFolderList = {"/core/","/core/users/","/core/apis/","/core/apps/","/core/addons/","/core/settings/"}
col.screen("lightGrey")
draw.textc(" Omicron: Install", 1, false, "white", "lightGrey")
draw.textc(" ----------------", 2, false, "white", "lightGrey")
draw.texta("We are going to install Omicron, please wait...", 1, 4, false, "lightBlue", "lightGrey")
sleep(1)
draw.texta("Creating folders [0/"..#tFolderList.."]", 1, 6, false, "lightBlue", "lightGrey")
for k, v in ipairs(tFolderList) do
  draw.texta("Creating folders ["..k.."/"..#tFolderList.."]", 1, 6, false, "lightBlue", "lightGrey")
  fs.makeDir(v)
  sleep(0.01)
end
local tSettings = {"https://ccsystems.dannysmc.com/"}
draw.texta("Downloading settings files [0/"..#tFolderList.."]", 1, 7, false, "lightBlue", "lightGrey")
for k, v in ipairs(tFolderList) do
  draw.texta("Creating folders ["..k.."/"..#tFolderList.."]", 1, 7, false, "lightBlue", "lightGrey")
  fs.makeDir(v)
  sleep(0.01)
end
sleep(10)
end
function omi.core.uninstall()
-- Uninstall Omicron OS

end
function omi.desktop()
col.screen("white")
while true do
  local args = { os.pullEvent() }
  print(args[1])
end
end
omi.init()
Edited on 31 March 2015 - 01:28 PM
GopherAtl #25
Posted 31 March 2015 - 03:51 PM
it does work, your desktop function is just printing white text on a white background.
DannySMc #26
Posted 31 March 2015 - 03:53 PM
it does work, your desktop function is just printing white text on a white background.

*facepalm*
DannySMc #27
Posted 01 April 2015 - 09:41 AM
-snip-

I have a question, I am trying to make an installer for but for some reason when it gets to the download part, it seems to just stop? Any ideas? Here is the code:
Spoiler

--[[
	Name: Omicron
	Creator: DannySMc (dannysmc95)
	Platform: Lua Virtual Machine (JVM)
	Network: CCSystems

	Bugs / Errors:
	--------------
	https://github.com/dannysmc95/OmicronOS/issues -> Submit an issue, i shall fix it when I get a chance.

	License:
	--------
	This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
]]

-- Vars:
nTries = 0
nLoadAnim = 0

-- Main Functions
omi = {}
omi.__index = omi

-- Draw Functions
omi.draw = {}
omi.draw.__index = omi.draw

-- core Functions
omi.core = {}
omi.core.__index = omi.core

-- Database (CCSystems) Functions
omi.ccsys = {}
omi.ccsys.__index = omi.ccsys

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

local thread = {
	tRunning = {{},{},{}},
	sCurrent = nil,
	create = function( self, name, func )
		table.insert(self.tRunning[1], name)
		table.insert(self.tRunning[2], window.create(term.current(), 1, 1, 51, 19, false))
		if func then
			table.insert(self.tRunning[3], coroutine.create(func))
		else
			table.insert(self.tRunning[3], false)
		end
		return true
	end,
	resume = function( self, name )
		for k, v in ipairs(self.tRunning[1]) do
			if v == name then
				if self.sCurrent then
					for k1, v1 in ipairs(self.tRunning[1]) do
						if v1 == self.sCurrent then
							self.tRunning[2][k1].setVisible(false)
						end
					end
				end
				self.sCurrent = name
				self.tRunning[2][k].setVisible(true)
				self.tRunning[2][k].redraw()
				term.redirect(self.tRunning[2][k])
				if self.tRunning[3][k] then
					coroutine.resume(self.tRunning[3][k])
				end
			end
		end
	end,
	list = function( self )
		return self.tRunning[3]
	end,
	kill = function( self, name )
		for k,v in ipairs(self.tRunning[1]) do
			if k == name then
				table.remove(self.tRunning[1][k])
				table.remove(self.tRunning[2][k])
				table.remove(self.tRunning[3][k])
			end
		end
	end,
	status = function( self, name )
		for k,v in ipairs(self.tRunning[1]) do
			if k == name then
				
			end
		end
	end,
	current = function( self )
		return sCurrent
	end,
}

function omi.init()
	local ok, err = pcall( function ()
		if http then
			if fs.exists("progutils") then
			os.loadAPI("progutils")
				return true
			end
			aa = aa or {}
			local a = http.get("https://vault.dannysmc.com/lua/api/dannysmcapi.lua")
			a = a.readAll()
			local env = {}
			a = loadstring(a)
			local env = getfenv()
			setfenv(a,env)
			local status, err = pcall(a, unpack(aa))
			if (not status) and err then
				printError("Error loading api")
				return false
			end
			local returned = err
			env = env
			_G["progutils"] = env
			
			omi.main()
		else
			omi.crash("HTTP needs to be enabled.")
		end
	end)
	if not ok then
		if nTries == 3 then
			print("The program has tried 3 times to get the API, We shall run shell instead.")
			sleep(5)
			shell.run("clear")
			shell.run("shell")
		else
			nTries = nTries + 1
			print("Program, failed to download API, Re-trying...")
			sleep(1)
			omi.init()
		end
	end
end

function omi.crash(errcode)
	col.screen("white")
	draw.box(1, 51, 1, 1, " ", "grey", "grey")
	draw.textc(" Omicron has crashed", 1, false, "cyan", "grey")
	local sText = "An error has caused Omicron to crash, the error is below, if this happens again, please report the problem and error code to DannySMc (dannysmc95). Error code is stated below in red."
	for k,v in ipairs(data.wordwrap(sText, 51)) do
		draw.texta(v, 1, k+2, false, "lightGrey", "white")
	end

	for k, v in ipairs(data.wordwrap(errcode, 45)) do
		draw.texta(v, 4, k+8, false, "red", "white")
	end

	draw.texta("-< Press enter to restart or 's' for shell >-", 4, 19, false, "grey", "white")


	while true do
		local args = { os.pullEvent() }
		if args[1] == "key" then
			if args[2] == keys.enter then
				omicron.main()
			elseif args[2] == keys.s then
				shell.run("clear")
				shell.run("shell")
			end
		end
	end
end

function omi.draw.loadanimation(intx, inty, txtcol, bkgcol)
	if nLoadAnim == 0 then
		draw.texta("|", intx, inty, false, txtcol, bkgcol)
		nLoadAnim = 1
	elseif nLoadAnim == 1 then
		draw.texta("/", intx, inty, false, txtcol, bkgcol)
		nLoadAnim = 2
	elseif nLoadAnim == 2 then
		draw.texta("-", intx, inty, false, txtcol, bkgcol)
		nLoadAnim = 3
	elseif nLoadAnim == 3 then
		draw.texta("\\", intx, inty, false, txtcol, bkgcol)
		nLoadAnim = 0
	end
end

function omi.draw.bar(screenname)
	draw.box(1, 51, 1, 2, " ", "grey", "grey")
	draw.texta("Omicron:", 1, 1, false, "cyan", "grey")
end

function omi.main()
	if term.isColour() then
		local ok, err = pcall(function()
			thread:create("startup", omi.startup)
   			local tFilters = {}
   			local tRunning = thread:list()
   			local tEventData = {}
   			while true do
				for k, v in pairs( tRunning ) do
		 			if tFilters[ k ] == tEventData[ 1 ] or tFilters[ k ] == nil then
						  _, tFilters[ k ] = coroutine.resume(v, unpack(tEventData))
		 			end
				end
				tEventData = { os.pullEvent() }
   			end
		end)
		if not ok then
			omi.crash(err)
		end
	else
		omi.crash("Please use an advanced (gold) computer.")
	end
end

function omi.startup()
	col.screen("black")
	sleep(0.15)
	col.screen("grey")
	sleep(0.15)
	col.screen("lightGrey")
	sleep(0.30)
	draw.textc(" Omicron Operating System", 7, false, "white", "lightGrey")
	draw.textc(" Created By DannySMc", 19, false, "lightBlue", "lightGrey")
	sleep(0.30)
	omi.draw.loadanimation(26, 12, "red", "lightGrey")
	os.startTimer(0.15)

	local count = 0

	while true do
		local args = { os.pullEvent() }
		if args[1] == "timer" then
			count = count + 1
			omi.draw.loadanimation(26, 12, "red", "lightGrey")
			os.startTimer(0.15)
			if count == 10 then
				if fs.exists("/core/") then
					omi.login()
					break
				else
					omi.core.install()
					break
				end
			end
		end
	end
end

function omi.core.install()
	-- Install Omicron OS
	local tFolderList = {"/core/","/core/users/","/core/apps/","/core/addons/","/core/settings/", "/core/bios/"}
	col.screen("lightGrey")
	draw.textc(" Omicron: Install", 1, false, "white", "lightGrey")
	draw.textc(" ----------------", 2, false, "white", "lightGrey")
	draw.texta("We are going to install Omicron, please wait...", 1, 4, false, "lightBlue", "lightGrey")
	sleep(1)
	draw.texta("Creating folders [0/"..#tFolderList.."]", 1, 6, false, "lightBlue", "lightGrey")
	for k, v in ipairs(tFolderList) do
		draw.texta("Creating folders ["..k.."/"..#tFolderList.."]", 1, 6, false, "lightBlue", "lightGrey")
		fs.makeDir(v)
		sleep(0.01)
	end

	local url = "https://ccsystems.dannysmc.com/programs/omicron/core/"
	local tSettings = {
		"addons/gps.lua",
		"addons/rednet.lua",
		"apps/ink.lua",
		"apps/luaide.lua",
		"apps/sketch.lua",
		"bios/osdata.lua",
		"bios/bios.lua",
		"settings/omidata.lua",
		"settings/userdata.lua",
	}
	draw.texta("Downloading files [0/"..#tFolderList.."]", 1, 7, false, "lightBlue", "lightGrey")
	for k, v in ipairs(tSettings) do
		draw.texta("Downloading files ["..k.."/"..#tFolderList.."]", 1, 7, false, "lightBlue", "lightGrey")
		local req = http.get(url..""..v)
		local temp = fs.open(fs.combine("/core/",v), "w")
		temp.write(temp.readAll())
		temp.close()
	end
end

function omi.core.uninstall()
	-- Uninstall Omicron OS
	
end

function omi.desktop()
	col.screen("white")
	col.set("black", "white")
	while true do
		local args = { os.pullEvent() }
		for k, v in ipairs(args) do
			print(k..": "..v)
		end
	end
end
omi.init()
MKlegoman357 #28
Posted 01 April 2015 - 05:20 PM
Take a good look at line 3 of this:


local req = http.get(url..""..v)
local temp = fs.open(fs.combine("/core/",v), "w")
temp.write(temp.readAll()) <--# right here
temp.close()
DannySMc #29
Posted 01 April 2015 - 05:24 PM
Take a good look at line 3 of this:


local req = http.get(url..""..v)
local temp = fs.open(fs.combine("/core/",v), "w")
temp.write(temp.readAll()) <--# right here
temp.close()

Oh yeah I figured this out like when I posted it :P/> hahaha *facepalm*
DannySMc #30
Posted 02 April 2015 - 11:40 AM
-snip-

Question:
I have this code:
Spoiler

--[[
	Name: Omicron
	Creator: DannySMc (dannysmc95)
	Platform: Lua Virtual Machine (JVM)
	Network: CCSystems

	Bugs / Errors:
	--------------
	https://github.com/dannysmc95/OmicronOS/issues -> Submit an issue, i shall fix it when I get a chance.

	License:
	--------
	This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
]]

-- Vars:
nTries = 0
nLoadAnim = 0
os.pullEvent = os.pullEventRaw
ccsysurl = "https://ccsystems.dannysmc.com/ccsystems.php"

-- Main Functions
omi = {}
omi.__index = omi

-- Draw Functions
omi.draw = {}
omi.draw.__index = omi.draw

-- core Functions
omi.core = {}
omi.core.__index = omi.core

-- Database (CCSystems) Functions
ccsys = {}
ccsys.__index = ccsys
ccsys.user = {}
ccsys.user.__index = ccsys.user


-- Start Controls
term.clear()
term.setCursorPos(1, 1)

function ccsys.user.login(username, password)
	local req = http.post(ccsysurl, "ccsys="..textutils.urlEncode(tostring("user")).."&amp;cccmd="..textutils.urlEncode(tostring("login")).."&amp;username="..textutils.urlEncode(tostring(username)).."&amp;password="..textutils.urlEncode(tostring(password)))
	req = req.readAll()
	if req == "true" then
		return true
	else
		return req:sub(10)
	end
end

function ccsys.user.register(username, password, email)
	local req = http.post(ccsysurl, "ccsys="..textutils.urlEncode(tostring("user")).."&amp;cccmd="..textutils.urlEncode(tostring("register")).."&amp;username="..textutils.urlEncode(tostring(username)).."&amp;password="..textutils.urlEncode(tostring(password)).."&amp;email="..textutils.urlEncode(tostring(email)))
	req = req.readAll()
	if req == "true" then
		return true
	else
		return req:sub(10)
	end
end

local thread = {
	tRunning = {{},{},{}},
	sCurrent = nil,
	create = function( self, name, func )
		table.insert(self.tRunning[1], name)
		table.insert(self.tRunning[2], window.create(term.current(), 1, 1, 51, 19, false))
		if func then
			table.insert(self.tRunning[3], coroutine.create(func))
		else
			table.insert(self.tRunning[3], false)
		end
		return true
	end,
	resume = function( self, name )
		for k, v in ipairs(self.tRunning[1]) do
			if v == name then
				if self.sCurrent then
					for k1, v1 in ipairs(self.tRunning[1]) do
						if v1 == self.sCurrent then
							self.tRunning[2][k1].setVisible(false)
						end
					end
				end
				self.sCurrent = name
				self.tRunning[2][k].setVisible(true)
				self.tRunning[2][k].redraw()
				term.redirect(self.tRunning[2][k])
				if self.tRunning[3][k] then
					coroutine.resume(self.tRunning[3][k])
				end
			end
		end
	end,
	list = function( self )
		return self.tRunning[3]
	end,
	listall = function( self )
		return self.tRunning
	end,
	kill = function( self, name )
		for k,v in ipairs(self.tRunning[1]) do
			if k == name then
				table.remove(self.tRunning[1][k])
				table.remove(self.tRunning[2][k])
				table.remove(self.tRunning[3][k])
			end
		end
	end,
	status = function( self, name )
		for k,v in ipairs(self.tRunning[1]) do
			if k == name then
				
			end
		end
	end,
	current = function( self )
		return sCurrent
	end,
}

function omi.init()
    local ok, err = pcall( function ()
    	if http then
    		if fs.exists("progutils") then
    		os.loadAPI("progutils")
    		    return true
    		end
    		aa = aa or {}
    		local a = http.get("https://vault.dannysmc.com/lua/api/dannysmcapi.lua")
    		a = a.readAll()
    		local env = {}
    		a = loadstring(a)
    		local env = getfenv()
    		setfenv(a,env)
    		local status, err = pcall(a, unpack(aa))
    		if (not status) and err then
    		    printError("Error loading api")
    		    return false
    		end
    		local returned = err
    		env = env
    		_G["progutils"] = env
    		
    		omi.main()
    	else
    		omi.crash("HTTP needs to be enabled.")
    	end
    end)
    if not ok then
    	if nTries == 3 then
    		print("The program has tried 3 times to get the API, We shall run shell instead.")
        	sleep(5)
        	shell.run("clear")
        	shell.run("shell")
        else
        	nTries = nTries + 1
            print("Program, failed to download API, Re-trying...")
            sleep(1)
            omi.init()
        end
    end
end

function omi.crash(errcode)
	col.screen("white")
	draw.box(1, 51, 1, 1, " ", "grey", "grey")
	draw.textc(" Omicron has crashed", 1, false, "cyan", "grey")
	local sText = "An error has caused Omicron to crash, the error is below, if this happens again, please report the problem and error code to DannySMc (dannysmc95). Error code is stated below in red."
	for k,v in ipairs(data.wordwrap(sText, 51)) do
		draw.texta(v, 1, k+2, false, "lightGrey", "white")
	end

	for k, v in ipairs(data.wordwrap(errcode, 45)) do
		draw.texta(v, 4, k+8, false, "red", "white")
	end

	draw.texta("-< Press enter to restart or 's' for shell >-", 4, 19, false, "grey", "white")


	while true do
		local args = { os.pullEvent() }
		if args[1] == "key" then
			if args[2] == keys.enter then
				omicron.main()
			elseif args[2] == keys.s then
				shell.run("clear")
				shell.run("shell")
			end
		end
	end
end

function omi.draw.loadanimation(intx, inty, txtcol, bkgcol)
	if nLoadAnim == 0 then
		draw.texta("|", intx, inty, false, txtcol, bkgcol)
		nLoadAnim = 1
	elseif nLoadAnim == 1 then
		draw.texta("/", intx, inty, false, txtcol, bkgcol)
		nLoadAnim = 2
	elseif nLoadAnim == 2 then
		draw.texta("-", intx, inty, false, txtcol, bkgcol)
		nLoadAnim = 3
	elseif nLoadAnim == 3 then
		draw.texta("\\", intx, inty, false, txtcol, bkgcol)
		nLoadAnim = 0
	end
end

function omi.draw.bar(screenname)
	draw.box(1, 51, 1, 1, " ", "grey", "grey")
	draw.texta("Omicron:", 1, 1, false, "cyan", "grey")
	draw.texta(misc.time(), 47, 1, false, "lime", "grey")
	draw.texta("<", 45, 1, false, "lightBlue", "grey")
	if screenname then
		draw.texta(screenname, 10, 1, false, "white", "grey")
	end
end

function omi.draw.threads()
	draw.box(51, 1, 2, 18, " ", "cyan", "cyan")
	sleep(0.05)
	draw.box(50, 1, 2, 18, " ", "cyan", "cyan")
	sleep(0.05)
	draw.box(49, 1, 2, 18, " ", "cyan", "cyan")
	sleep(0.05)
	draw.box(48, 1, 2, 18, " ", "cyan", "cyan")
	sleep(0.05)
	draw.box(47, 1, 2, 18, " ", "cyan", "cyan")
	sleep(0.05)
	draw.box(46, 1, 2, 18, " ", "cyan", "cyan")
	sleep(0.05)
	draw.box(45, 1, 2, 18, " ", "cyan", "cyan")
	sleep(0.05)
	draw.box(44, 1, 2, 18, " ", "cyan", "cyan")
	sleep(0.05)
	draw.box(43, 1, 2, 18, " ", "cyan", "cyan")
	sleep(0.05)
	draw.box(42, 1, 2, 18, " ", "cyan", "cyan")
	sleep(0.05)
	draw.box(41, 1, 2, 18, " ", "cyan", "cyan")
	sleep(0.05)
	draw.box(40, 1, 2, 18, " ", "cyan", "cyan")
	sleep(0.05)

	local list = thread:listall()

	for k,v in ipairs(list[1]) do
		draw.texta(v, 41, k+2, false, "white", "cyan")
	end

	while true do
		local args = { os.pullEvent("mouse_click") }
		if args[2] == 1 then
			if (args[3] >= 40 and args[3] <= 51) and (args[4] >= 3 and args[4] <= 18) then
				print(list[1][args[4] - 2])
				thread:resume(list[3][args[4] - 2])
				break
			end
		end
	end
end

function omi.main()
	if term.isColour() then
		local ok, err = pcall(function()
			thread:create("kernal", omi.startup)
   			local tFilters = {}
   			local tRunning = thread:list()
   			local tEventData = {}
   			while true do
    			for k, v in pairs( tRunning ) do
         			if tFilters[ k ] == tEventData[ 1 ] or tFilters[ k ] == nil then
          				_, tFilters[ k ] = coroutine.resume(v, unpack(tEventData))
         			end
    			end
    			tEventData = { os.pullEvent() }
   			end
		end)
		if not ok then
			omi.crash(err)
		end
	else
		omi.crash("Please use an advanced (gold) computer.")
	end
end

function omi.startup()
	col.screen("black")
	sleep(0.15)
	col.screen("grey")
	sleep(0.15)
	col.screen("lightGrey")
	sleep(0.30)
	draw.textc(" Omicron Operating System", 7, false, "white", "lightGrey")
	draw.textc(" Created By DannySMc", 19, false, "lightBlue", "lightGrey")
	sleep(0.30)
	omi.draw.loadanimation(26, 12, "red", "lightGrey")
	os.startTimer(0.15)

	local count = 0

	while true do
		local args = { os.pullEvent() }
		if args[1] == "timer" then
			count = count + 1
			omi.draw.loadanimation(26, 12, "red", "lightGrey")
			os.startTimer(0.15)
			if count == 10 then
				if fs.exists("/core/") then
					--thread:create("login", omi.core.login())
					--thread:goto("login")
					thread:create("desktop", omi.core.desktop())
					thread:goto("desktop")
					break
				else
					omi.core.install()
					break
				end
			end
		end
	end
end

function omi.core.install()
	-- Install Omicron OS
	local tFolderList = {"/core/","/core/users/","/core/apps/","/core/addons/","/core/settings/", "/core/bios/"}
	col.screen("lightGrey")
	draw.textc(" Omicron: Install", 1, false, "white", "lightGrey")
	draw.textc(" ----------------", 2, false, "white", "lightGrey")
	draw.texta("We are going to install Omicron, please wait...", 1, 4, false, "lightBlue", "lightGrey")
	sleep(1)
	draw.texta("Creating folders [0/"..#tFolderList.."]", 1, 6, false, "lightBlue", "lightGrey")
	for k, v in ipairs(tFolderList) do
		draw.texta("Creating folders ["..k.."/"..#tFolderList.."]", 1, 6, false, "lightBlue", "lightGrey")
		fs.makeDir(v)
		sleep(0.01)
	end

	local url = "https://ccsystems.dannysmc.com/programs/omicron/core"
	local tSettings = {
		"addons/gps.lua", 
		"addons/rednet.lua", 
		"apps/ink.lua", 
		"apps/luaide.lua", 
		"apps/sketch.lua", 
		"bios/osdata.lua", 
		"bios/bios.lua",
		"settings/omidata.lua",
		"settings/userdata.lua",
	}
	draw.texta("Downloading files [0/"..#tSettings.."]", 1, 7, false, "lightBlue", "lightGrey")
	for k, v in pairs(tSettings) do
		draw.texta("Downloading files ["..k.."/"..#tSettings.."]", 1, 7, false, "lightBlue", "lightGrey")
		local req = http.get(url.."/"..v)
		local temp = fs.open(fs.combine("/core/",v), "w")
		temp.write(req.readAll())
		temp.close()
	end

	local url = "https://ccsystems.dannysmc.com/ccsystems.php"
	draw.texta("Pinging CCSystems Database...", 1, 8, false, "lightBlue", "lightGrey")
	local req = http.post(url, "ccsys="..textutils.urlEncode(tostring("ping")))
	if req.readAll() == "true" then
		draw.texta("Server is online...", 1, 9, false, "lightBlue", "lightGrey")
	else
		draw.texta("Server is offline...", 1, 9, false, "lightBlue", "lightGrey")
	end

	sleep(1.5)

	thread:create("login", omi.core.login())
	thread:goto("login")

end

function omi.core.register()

end

function omi.core.login()
	if fs.exists("/core/settings/.saveuserdata") then
		local config = config.load("/core/settings/userdata.lua")
		username = config.username
		password = config.password
		local stat = ccsys.user.login(username, password)
		if stat then
			thread:create("desktop", omi.core.desktop)
			thread:goto("desktop")
		end
	else
		local savecred = false
		col.screen("white")
		draw.box(1, 51, 1, 1, " ", "grey", "grey")
		draw.texta("Omicron Login", 1, 1, false, "cyan", "grey")
		draw.texta(misc.time(), 47, 1, false, "lime", "grey")
		draw.box(1, 51, 2, 1, " ", "lightGrey", "lightGrey")
		draw.texta("         Register         |          Login          ", 1, 2, false, "white", "lightGrey")
		draw.texta("Login", 38, 2, false, "lime", "lightGrey")
	
		draw.texta("Username", 8, 5, false, "lightGrey", "white")
		draw.texta("Password", 8, 9, false, "lightGrey", "white")
		draw.texta("Login", 38, 2, false, "lime", "lightGrey")
		draw.box(8, 37, 6, 1, false, "cyan", "cyan")
		draw.box(8, 37, 10, 1, false, "cyan", "cyan")
		draw.texta("   Login   ", 8, 16, false, "white", "cyan")
		draw.texta("   Exit   ", 35, 16, false, "white", "cyan")
		draw.texta(" Toggle ", 8, 13, false, "white", "cyan")
		draw.texta("Save Credentials: "..tostring(savecred), 17, 13, false, "lightGrey", "white")
	
		while true do
			local args = { os.pullEvent() }
			if args[1] == "timer" then
				draw.texta(misc.time(), 47, 1, false, "lime", "grey")
			elseif args[1] == "mouse_click" then
				if args[2] == 1 then
					if (args[3] >= 1 and args[3] <= 25) and (args[4] == 2) then
						omi.core.register()
					elseif (args[3] >= 8 and args[3] <= 45) and (args[4] == 6) then
						col.set("white", "cyan")
						term.setCursorPos(8, 6)
						write("                                     ")
						term.setCursorPos(8, 6)
						write(": ")
						username = tostring(read())
					elseif (args[3] >= 8 and args[3] <= 45) and (args[4] == 10) then
						col.set("white", "cyan")
						term.setCursorPos(8, 10)
						write("                                     ")
						term.setCursorPos(8, 10)
						write(": ")
						password = crypt.sha256(tostring(read("*")))
					elseif (args[3] >= 8 and args[3] <= 18) and (args[4] == 16) then
						local stat = ccsys.user.login(username, password)
						if stat then
							draw.popup("Logged In!")
							sleep(1)
							thread:create("desktop", omi.core.desktop)
							thread:create("test", omi.test)
							thread:resume("desktop")
						else
							omi.core.login()
						end
					elseif (args[3] >= 35 and args[3] <= 44) and (args[4] == 16) then						
						shell.run("shell")
					end
				end
			end
		end
	end
end

function omi.core.uninstall()
	-- Uninstall Omicron OS
	
end

function omi.core.desktop()
	col.screen("white")
	omi.draw.bar("Desktop")
	col.set("black", "white")
	term.setCursorPos(1,3)
	local list = thread:listall()
	for k,v in pairs(list[1]) do
		print(v)
	end
	while true do
		local args = { os.pullEvent() }
		if args[1] == "timer" then
			omi.draw.bar("Desktop")
		elseif args[1] == "char" then
			if args[2] == "1" then
				thread:create("switcher", omi.draw.threads)
			end
		end
	end
end

function omi.test()
	col.screen("black")
	print("> Running coroutine")
	for i = 1, 10 do
		print(i)
	end

	print("Killing...")
	thread:resume("desktop")
end
omi.init()

but for some reason it is adding tasks? and when I try to create the test one at the bottom it runs it, then it dies, and I didn't use thread:resume()?:s
Please help! Thanks!