Browse Source

initial commit

master
mort 7 years ago
commit
b9cca6e47c
19 changed files with 1374 additions and 0 deletions
  1. 10
    0
      bin/craft.lua
  2. 34
    0
      bin/floor.lua
  3. 54
    0
      bin/guitest.lua
  4. 6
    0
      bin/help.lua
  5. 3
    0
      bin/ls.lua
  6. 6
    0
      bin/man.lua
  7. 68
    0
      install.lua
  8. 839
    0
      lib/graphics.lua
  9. 143
    0
      lib/mturtle.lua
  10. 42
    0
      lib/program.lua
  11. 141
    0
      lib/util.lua
  12. 3
    0
      manpages/craft
  13. 3
    0
      manpages/floor
  14. 3
    0
      manpages/help
  15. 3
    0
      manpages/ls
  16. 3
    0
      manpages/man
  17. 2
    0
      pastebin.lua
  18. 4
    0
      run.lua
  19. 7
    0
      update.lua

+ 10
- 0
bin/craft.lua View File

@@ -0,0 +1,10 @@
local args = {...}

local count
if args[1] == nil then
count = 1
else
count = tonumber(args[1])
end

turtle.craft(count)

+ 34
- 0
bin/floor.lua View File

@@ -0,0 +1,34 @@
local args = {...}

os.loadAPI("/lib/mturtle")

local mx = tonumber(args[1])
local mz = tonumber(args[2])

local origin = mturtle.getPos()

local placeFunc
if args[3] == nil then
placeFunc = function()
mturtle.selectItem()
turmle.placeDown()
end
else
placeFunc = loadstring(args[3])
end

for x = 1, mx do
for z = 1, mz - 1 do
placeFunc()
mturtle.forward()
end
if x < mx then
placeFunc()
mturtle.alterturn(x)
mturtle.forward()
mturtle.alterturn(x)
end
end
placeFunc()

mturtle.goTo(origin)

+ 54
- 0
bin/guitest.lua View File

@@ -0,0 +1,54 @@
os.loadAPI("/lib/program")
os.loadAPI("/lib/graphics")

local prog = program.Prog()
local gui = graphics.Gui(prog)

local root = graphics.FloatingLayout()
gui.setRoot(root)

local txtHelloWorld = graphics.TextView()
.text("hello world")
.left("center")
.top("center")

local txtCounter = graphics.TextView()
.text("0")
.right("center")
.top("center + 1")

local btn1 = graphics.Button()
.text("Button!")
.top(2)
.left(2)
.on("click", function()
txtCounter.text(tonumber(txtCounter.text()) + 1)
end)

local btn2 = graphics.Button()
.text("Button Two")
.top(3)
.left(2)
.on("click", function()
txtCounter.text(tonumber(txtCounter.text()) - 1)
end)

local input = graphics.TextInput()
.bottom(1)
.left("40% - 40$ + 1")
.width("80% + 1")
.text("Hey")

local btnExit = graphics.Button()
.text("X")
.right(1)
.on("click", function() gui.exit() end)

root.addChild(txtHelloWorld)
root.addChild(btn1)
root.addChild(btn2)
root.addChild(txtCounter)
root.addChild(input)
root.addChild(btnExit)

prog.init()

+ 6
- 0
bin/help.lua View File

@@ -0,0 +1,6 @@
local args = {...}

local file = "/manpages/" .. args[1]
local f = fs.open(file, "r")
print(f.readLine())
f.close()

+ 3
- 0
bin/ls.lua View File

@@ -0,0 +1,3 @@
for key, val in pairs(fs.list("/bin")) do
print(string.sub(val, 0, -5))
end

+ 6
- 0
bin/man.lua View File

@@ -0,0 +1,6 @@
local args = {...}

local file = "/manpages/" .. args[1]
local f = fs.open(file, "r")
print(f.readAll())
f.close()

+ 68
- 0
install.lua View File

@@ -0,0 +1,68 @@
local base = "http://s.mort.coffee/mortcc"

local files = {
bin = {
"floor.lua";
"ls.lua";
"help.lua";
"man.lua";
"craft.lua";
"guitest.lua";
},
manpages = {
"floor";
"ls";
"help";
"man";
"craft";
},
lib = {
mturtle = "mturtle.lua";
util = "util.lua";
program = "program.lua";
graphics = "graphics.lua";
},

run = "run.lua";
update = "update.lua";
}

function download(src, dst)
local url = base .. src
print("Downloading")
print(url)
local ok, err = http.checkURL(url)
if not ok then
print(err)
return
end

local h = http.get(url)
if h == nil then
print("Invalid URL.")
return
end
local f = fs.open(dst, "w")

f.write(h.readAll())
f.close()
end

function mkfiles(dir, path)
for key, val in pairs(dir) do
if type(key) == "number" then
local p = path .. "/" .. val
download(p, p)
elseif type(val) == "string" then
local src = path .. "/" .. val
local dst = path .. "/" .. key
download(src, dst)
else
local p = path .. "/" .. key
fs.makeDir(p)
mkfiles(dir[key], p)
end
end
end

mkfiles(files, "")

+ 839
- 0
lib/graphics.lua View File

@@ -0,0 +1,839 @@
os.loadAPI("/lib/util")

function prettyPrintSize(tokens)
if type(tokens) == "number" then
return tostring(tokens)
end

local str = "( "
for key, token in pairs(tokens) do
if token.tokentype == "list" then
str = str .. prettyPrintSize(token)
elseif token.tokentype == "num" then
str = str .. token.val .. " "
elseif token.tokentype == "percent" then
str = str .. token.val .. "% "
elseif token.tokentype == "selfpercent" then
str = str .. token.val .. "$ "
elseif token.tokentype == "auto" then
str = str .. "& "
elseif token.tokentype == "add" then
str = str .. "+ "
elseif token.tokentype == "sub" then
str = str .. "- "
elseif token.tokentype == "multiply" then
str = str .. "* "
elseif token.tokentype == "divide" then
str = str .. "/ "
end
end
return str .. ")"
end

function parseSize(size)
if type(size) == "number" then
return size
end

size = size .. " "
size = string.gsub(size, "center", "50%% - 50$")
print(size)

local res = {
tokentype = "list"
}
local current = ""
local parsing = true
local i = 1
while i <= #size do
local c = string.sub(size, i, i)

if tonumber(c) ~= nil then
current = current .. c
elseif current ~= "" then
local cur = tonumber(current)
if cur == nil or current == "+" or current == "-" then
-- Don't do anything because there's no number
elseif c == "%" then
table.insert(res, {
tokentype = "percent";
val = cur;
})
elseif c == "$" then
table.insert(res, {
tokentype = "selfpercent";
val = cur;
})
else
table.insert(res, {
tokentype = "num";
val = cur;
})
end
current = ""
end

if c == "(" then
local substr = ""
local depth = 1

while depth > 0 do
i = i + 1
local cc = string.sub(size, i, i)
if cc == "(" then
depth = depth + 1
elseif cc == ")" then
depth = depth - 1
end

if depth > 0 then
substr = substr .. cc
end
end
table.insert(res, parseSize(substr))
elseif c == "&" then
table.insert(res, {
tokentype = "auto"
})
elseif c == "+" then
table.insert(res, {
tokentype = "add"
})
elseif c == "-" then
table.insert(res, {
tokentype = "sub"
})
elseif c == "*" then
table.insert(res, {
tokentype = "multiply"
})
elseif c == "/" then
table.insert(res, {
tokentype = "divide"
})
end

i = i + 1
end

return res
end

function calcSize(tokens, parentSizeArg, selfSizeArg, autoSizeArg)
if type(tokens) == "number" then
return tokens
elseif tokens == nil then
return nil
end

local parentSize = 0
if type(parentSizeArg) == "function" then
parentSize = parentSizeArg()
elseif type(parentSizeArg) == "number" then
parentSize = parentSizeArg
end
local selfSize = 0
if type(selfSizeArg) == "function" then
selfSize = selfSizeArg()
elseif type(selfSizeArg) == "number" then
selfSize = selfSizeArg
end
local autoSize = 0
if type(autoSizeArg) == "function" then
autoSize = autoSizeArg()
elseif type(autoSizeArg) == "number" then
autoSize = autoSizeArg
end

function getVal(token)
if token.tokentype == "num" then
return token.val
elseif token.tokentype == "percent" then
return util.percentOf(token.val, parentSize)
elseif token.tokentype == "selfpercent" then
return util.percentOf(token.val, selfSize) - 1
elseif token.tokentype == "auto" then
return autoSize
elseif token.tokentype == "list" then
return calcSize(token, parentSize, selfSize)
else
return 0
end
end

local sum = 0
local opr = "add"

local i = 1
while i <= #tokens do
local num = getVal(tokens[i])
if opr == "add" then
sum = sum + num
elseif opr == "sub" then
sum = sum - num
elseif opr == "multiply" then
sum = sum * num
elseif opr == "divide" then
sum = sum / num
else
error("Unexpected operator: "..opr)
return 0
end

local oprToken = tokens[i + 1]
if oprToken ~= nil then
opr = oprToken.tokentype
else
opr = ""
end

i = i + 2
end

return math.floor(sum)
end

function Widget()
local self = util.newObject()
util.makeEventListener(self)

local prog = nil
local focused = false
local children = {}
local parent = nil
local top = 1
local bottom = nil
local left = 1
local right = nil
local width = parseSize("&")
local height = parseSize("&")
local background = "black"
local foreground = "white"

local x = 1
local y = 1

self.getset("prog",
function() return prog end,
function(val) prog = val end)

self.getset("focused",
function() return focused end)
self.getset("children",
function() return children end)

self.getset("parent",
function() return parent end)
self.getset("_parent",
function() return parent end,
function(val) parent = val end)

self.getset("width",
function() return calcSize(width, parent.width, 0, self.autoWidth) end,
function(val) width = parseSize(val) end)
self.getset("height",
function() return calcSize(height, parent.height, 0, self.autoHeight) end,
function(val) height = parseSize(val) end)

self.getset("background",
function() return background end,
function(val) background = val end)
self.getset("foreground",
function() return foreground end,
function(val) foreground = val end)

self.getset("top",
function() return calcSize(top, parent.height, self.height, 0) end,
function(val) top = parseSize(val) end)
self.getset("bottom",
function() return calcSize(bottom, parent.height, self.height, 0) end,
function(val) bottom = parseSize(val) end)
self.getset("left",
function() return calcSize(left, parent.width, self.width, 0) end,
function(val) left = parseSize(val) end)
self.getset("right",
function() return calcSize(right, parent.width, self.width, 0) end,
function(val) right = parseSize(val) end)

self.getset("x",
function() return x end,
function(val) x = val end)
self.getset("y",
function() return y end,
function(val) y = val end)

self.focus = function()
focused = true
self.emit("focus", self)
end
self.unfocus = function()
focused = false
self.emit("unfocus", self)
end

self.onclick = function(x, y)
for key, child in pairs(self.children()) do
local cx = child.x()
local cy = child.y()
local cw = child.width()
local ch = child.height()

if x >= cx and x < cx + cw
and y >= cy and y < cy + ch then
child.onclick(x, y)
end
end
end

self.onchar = function(char) end
self.onkey = function(key) end

self.setColors = function(screen)
screen.setTextColor(colors[foreground])
screen.setBackgroundColor(colors[background])

local w = self.width()
local h = self.height()

local str = ""
for i = 1, w do
str = str .. " "
end

local x = self.x()
local y = self.y()
for i = 1, h do
screen.setCursorPos(x, y + i - 1)
screen.write(str)
end
screen.setCursorPos(x, y)
end

self.addChild = function(widget)
if widget.parent() ~= nil then
error("Widget already has a parent")
return
end
table.insert(children, widget)
widget._parent(self)
widget.prog(prog)

widget.on("mustreflow", function()
self.emit("mustreflow")
end)

widget.on("mustredraw", function(elem)
self.emit("mustredraw", elem)
end)

widget.on("focus", function(elem)
self.emit("focus", elem)
end)

widget.on("unfocus", function(elem)
self.emit("unfocus", elem)
end)

self.emit("mustreflow")
end

self.removeChild = function(child)
local removed = false
for key, val in pairs(children) do
if val == child then
removed = true
child.unfocus()
table.remove(children, key)
end
end
if removed then
self.emit("mustreflow")
end
end

self.reflow = util.abstract

self.draw = util.abstract

return self
end

function LinearLayout()
local self = Widget()

local orientation = "vertical"
local reversed = false

self.getset("orientation",
function() return orientation end,
function(val) orientation = val end)
self.getset("reversed",
function() return reversed end,
function(val) reversed = val end)

self.draw = function(screen)
self.setColors(screen)
for key, child in pairs(self.children()) do
child.draw(screen)
end
end

self.reflow = function(screen, x, y)
self.x(x)
self.y(y)

local selfw = self.width()
local selfh = self.height()
local offset = 0
for key, child in pairs(self.children()) do
local cx = x
local cy = y
local height = child.height()
local width = child.width()
local top = child.top()
local bottom = child.bottom()
local left = child.left()
local right = child.right()

if right ~= nil then
cx = cx +
selfw -
width -
right + 1
else
cx = cx + top - 1
end
if bottom ~= nil then
cy = cy +
selfh -
height -
bottom + 1
else
cy = cy + top - 1
end

if orientation == "vertical" then
cy = y + offset + top - 1
offset = offset +
top - 1 +
height +
(bottom or 1) - 1

if reversed then
cy = selfh - cy - height + 2
end
elseif orientation == "horizontal" then
cx = x + offset + left - 1
offset = offset +
left - 1 +
width +
(right or 1) - 1

if reversed then
cx = selfw - cx - width + 2
end
end

child.reflow(screen, cx, cy)
end
end

return self
end

function FloatingLayout()
local self = Widget()

self.draw = function(screen)
self.setColors(screen)
for key, child in pairs(self.children()) do
child.draw(screen)
end
end

self.reflow = function(screen, x, y)
self.x(x)
self.y(y)

for key, child in pairs(self.children()) do
local cx = x
local cy = y
if child.right() ~= nil then
cx = cx +
self.width() -
child.width() -
child.right() + 1
else
cx = cx + child.left() - 1
end
if child.bottom() ~= nil then
cy = cy +
self.height() -
child.height() -
child.bottom() + 1
else
cy = cy + child.top() - 1
end

child.reflow(screen, cx, cy)
end
end

self.autoWidth = function()
return self.parent().width()
end
self.autoHeight = function()
return self.parent().height()
end

return self
end

function TextView()
local self = Widget()

local text = ""

self.getset("text",
function() return text end,
function(val)
local pre = text
text = tostring(val)
if #pre == #text then
self.emit("mustredraw", self)
else
self.emit("mustreflow")
end
end)

self.reflow = function(screen, x, y)
self.x(x)
self.y(y)
end

self.draw = function(screen)
self.setColors(screen)

screen.setCursorPos(self.x(), self.y())
local w = self.width()
local h = self.height()

local offy = math.floor(h / 2)
local offx = math.floor(w - #text - ((w - #text) / 2))
screen.setCursorPos(self.x() + offx, self.y() + offy)
screen.write(text)
end

self.autoWidth = function()
return #text
end
self.autoHeight = function()
return 1
end

self.onclick = function(x, y)
-- TextViews don't have any interesting onclick actions
end

return self
end

function TextInput()
local self = Widget()

local backgroundInactive = "blue"
local backgroundActive = "red"
local foregroundInactive = "white"
local foregroundActive = "white"

local key_backspace = 14
local key_left = 203
local key_right = 205
local key_delete = 211

local text = ""
local cursor = 0

self.getset("text",
function() return text end,
function(val)
local pre = text
text = tostring(val)
if #pre == #text then
self.emit("mustredraw", self)
else
self.emit("mustreflow")
end
end)

self.getset("backgroundInactive",
function() return backgroundInactive end,
function(val) backgroundInactive = val end)
self.getset("backgroundActive",
function() return backgroundActive end,
function(val) backgroundActive = val end)
self.getset("foregroundInactive",
function() return foregroundInactive end,
function(val) foregroundInactive = val end)
self.getset("foregroundActive",
function() return foregroundActive end,
function(val) foregroundActive = val end)

self.reflow = function(screen, x, y)
self.x(x)
self.y(y)
end

self.draw = function(screen)
if self.focused() then
self.background(backgroundActive)
self.foreground(foregroundActive)
else
self.background(backgroundInactive)
self.foreground(foregroundInactive)
end

self.setColors(screen)

screen.setCursorPos(self.x(), self.y())
screen.write("|")
screen.setCursorPos(self.x() + self.width() - 1, self.y())
screen.write("|")

local len = self.width() - 2
screen.setCursorPos(self.x() + 1, self.y())
screen.write(string.sub(text, 1, len))

if self.focused() then
screen.setCursorPos(self.x() + 1 + cursor, self.y())
screen.setBackgroundColor(colors.white)
screen.write(" ")
end
end

self.autoWidth = function()
return #text + 2
end
self.autoHeight = function()
return 1
end

self.onclick = function(x, y)
local w = self.width()
if x == self.x() or x == w then
cursor = #text
else
cursor = math.min(x - self.x() - 1, #text)
end
self.focus()
end

self.onchar = function(char)
local pre = string.sub(text, 1, cursor)
local post = string.sub(text, cursor + 1, #text)
text = pre .. char .. post
cursor = cursor + 1
self.emit("mustreflow")
end

self.onkey = function(key)
if key == key_backspace then
local pre = string.sub(text, 1, cursor - 1)
local post = string.sub(text, cursor + 1, #text)
text = pre .. post
if cursor > 0 then
cursor = cursor - 1
end
self.emit("mustreflow")
elseif key == key_delete then
local pre = string.sub(text, 1, cursor)
local post = string.sub(text, cursor + 2, #text)
text = pre .. post
self.emit("mustreflow")
elseif key == key_left then
if cursor > 0 then
cursor = cursor - 1
end
self.emit("mustredraw", self)
elseif key == key_right then
if cursor < #text then
cursor = cursor + 1
end
self.emit("mustredraw", self)
end
end

self.on("focus", function() self.emit("mustredraw", self) end)
self.on("unfocus", function() self.emit("mustredraw", self) end)

return self
end

function Button()
local self = TextView()

local backgroundInactive = "blue"
local backgroundActive = "red"
local foregroundInactive = "white"
local foregroundActive = "white"

self.getset("backgroundInactive",
function() return backgroundInactive end,
function(val) backgroundInactive = val end)
self.getset("backgroundActive",
function() return backgroundActive end,
function(val) backgroundActive = val end)
self.getset("foregroundInactive",
function() return foregroundInactive end,
function(val) foregroundInactive = val end)
self.getset("foregroundActive",
function() return foregroundActive end,
function(val) foregroundActive = val end)

self.background(backgroundInactive)
self.foreground(foregroundInactive)

local resetTimeout

self.onclick = function(x, y)
if resetTimeout ~= nil then
self.prog().cancelTimeout(resetTimeout)
end
self.background(backgroundActive)
self.foreground(foregroundActive)
self.emit("mustredraw", self)

self.emit("focus", self)
self.emit("click")

resetTimeout = self.prog().setTimeout(0.3, function()
self.background(backgroundInactive)
self.foreground(foregroundInactive)
self.emit("mustredraw", self)
end)
end

return self
end

function DummyScreen()
local self = {}

self.getSize = function()
return term.getSize()
end
self.clear = function() end
self.write = function() end
self.setCursorPos = function() end
self.setTextColor = function() end
self.setBackgroundColor = function() end

return self
end

function Gui(prog, screen)
local self = util.newObject()

if screen == nil then
screen = term
end

local focusedWidget = nil
local rootWidget = nil

self.getset("width",
function()
local x, y = screen.getSize()
return x
end)
self.getset("height",
function()
local x, y = screen.getSize();
return y
end)

self.getset("screen",
function() return screen end,
function(val) screen = val end)

self.getset("focused",
function() return focusedWidget end)

-- Handle focusing and unfocusing of widgets
local function onRootChildFocus(widget)
if focusedWidget ~= nil then
focusedWidget.unfocus()
end
focusedWidget = widget
end

local function onRootChildUnfocus(widget)
if widget == focusedWidget then
focusedWidget = nil
end
end

local function onRootChildRedraw(widget)
widget.draw(screen)
end

self.setRoot = function(root)
if rootWidget ~= nil then
rootWidget.removeListener("focus", onRootChildFocus)
rootWidget.removeListener("unfocus", onRootChildUnfocus)
rootWidget.removeListener("mustreflow", self.reflow)
rootWidget.removeListener("mustredraw", onRootChildRedraw)
end
rootWidget = root
root._parent(self)
root.on("focus", onRootChildFocus)
root.on("unfocus", onRootChildUnfocus)
root.on("mustreflow", self.reflow)
root.on("mustredraw", onRootChildRedraw)
root.prog(prog)
end

self.reflow = function()
if rootWidget == nil then
return
end
screen.clear()
screen.setCursorPos(1, 1)
rootWidget.reflow(screen, 1, 1)
rootWidget.draw(screen)
end

self.exit = function()
prog.exit()
end

prog.on("init", self.draw)

prog.on("exit", function()
screen.setTextColor(colors.white)
screen.setBackgroundColor(colors.black)
screen.clear()
screen.setCursorPos(1, 1)
end)

prog.on("mouse_click", function(button, x, y)
if focusedWidget ~= nil then
focusedWidget.unfocus()
end
if rootWidget ~= nil then
rootWidget.onclick(x, y)
end
end)
prog.on("char", function(char)
if focusedWidget ~= nil then
focusedWidget.onchar(char)
end
end)
prog.on("key", function(key)
if focusedWidget ~= nil then
focusedWidget.onkey(key)
end
end)

return self
end

+ 143
- 0
lib/mturtle.lua View File

@@ -0,0 +1,143 @@
local pos = {x = 0, y = 0, z = 0, face = 0}

local function addToPos(n)
if pos.face == Faces.FORWARD then
pos.z = pos.z + n
elseif pos.face == Faces.BACK then
pos.z = pos.z - n
elseif pos.face == Faces.RIGHT then
pos.x = pos.x + n
elseif pos.face == Faces.LEFT then
pos.x = pos.x - n
end
end

local function addToFace(n)
pos.face = (pos.face + n) % 4
if pos.face < 0 then
pos.face = 4 + pos.face
end
end

Faces = {
FORWARD = 0;
RIGHT = 1;
BACK = 2;
LEFT = 3;
};

function getPos()
return {
x = pos.x;
y = pos.y;
z = pos.z;
face = pos.face;
}
end

function dig()
while turtle.detect() do turtle.dig() end
end
function digUp()
while turtle.detectUp() do turtle.digUp() end
end
function digDown()
while turtle.detectDown() do turtle.digDown() end
end

function right()
turtle.turnRight()
addToFace(1)
end
function left()
turtle.turnLeft()
addToFace(-1)
end

function forward()
while not turtle.forward() do end
addToPos(1)
end
function back()
while not turtle.back() do end
addToPos(-1)
end
function up()
while not turtle.up() do end
pos.y = pos.y + 1
end
function down()
while not turtle.down() do end
pos.y = pos.y - 1
end

function digForwards()
dig()
forward()
digUp()
digDown()
end

function alterturn(i)
if i % 2 == 1 then
right()
else
left()
end
end

function selectItem()
if turtle.getItemCount(turtle.getSelectedSlot()) > 0 then
return
end
for i = 1, 16 do
if turtle.getItemCount(i) > 0 then
turtle.select(i)
return true
end
end
turtle.select(1)
return false
end

function turnTo(face)
if pos.face == 0 and face == 3 or
pos.face == 1 and face == 0 or
pos.face == 2 and face == 1 or
pos.face == 3 and face == 2 then
left()
else
while pos.face ~= face do
right()
end
end
end

function goTo(dest)
-- Correct X value
if dest.x > pos.x then
turnTo(Faces.RIGHT)
elseif dest.x < pos.x then
turnTo(Faces.LEFT)
end
for i = 1, math.abs(dest.x - pos.x) do
forward()
end

-- Correct Z value
if dest.z > pos.z then
turnTo(Faces.FORWARD)
elseif dest.z < pos.z then
turnTo(Faces.BACK)
end
for i = 1, math.abs(dest.z - pos.z) do
forward()
end

-- Correct Y value
while dest.y > pos.y do up() end
while dest.y < pos.y do down() end

-- Correct facing
turnTo(dest.face)
end

+ 42
- 0
lib/program.lua View File

@@ -0,0 +1,42 @@
os.loadAPI("/lib/util")

function Prog()
local self = {}
util.makeEventListener(self)

local running = true

local timeouts = {}

self.init = function()
self.emit("init")
while running do
evt, a, b, c, d, e = os.pullEvent()

if evt == "timer" and timeouts[a] then
timeouts[a]()
else
self.emit(evt, a, b, c, d, e)
end
end
end

self.exit = function()
self.emit("exit")
running = false
os.startTimer(0)
end

self.setTimeout = function(time, cb)
local id = os.startTimer(time)
timeouts[id] = cb
return id
end

self.cancelTimeout = function(id)
os.cancelTimer(id)
timeouts[id] = nil
end

return self
end

+ 141
- 0
lib/util.lua View File

@@ -0,0 +1,141 @@
function percentOf(val1, val2)
return math.ceil(val2 * (val1 / 100))
end

function expect(var1, var2)
if var1 ~= var2 then
error("Expected "..tostring(var2)..", got "..tostring(var1))
end
end

function printTable(tbl, depth)
if depth == nil then
depth = 0
end

local pre = ""
for i = 1, depth do
pre = pre .. " "
end

local str = ""
for key, val in pairs(tbl) do
if type(val) == "table" then
str = str .. pre .. key .. ": {\n"
.. printTable(val, depth + 1)
.. pre .. "}\n"
else
str = str .. pre .. key .. ": " .. tostring(val) .. "\n"
end
end

return str
end

function writeFile(path, str)
local h = fs.open(path, "w")
h.write(str)
h.close()
end
function appendFile(path, str)
local h = fs.open(path, "a")
h.write(str)
h.close()
end

function newObject()
local self = {}

self.getset = function(name, getter, setter)
self[name] = function(val)
if val == nil then
if getter == nil then
error("No getter.")
end
return getter()
else
if setter == nil then
error("No setter.")
end
setter(val)
return self
end
end
end

return self
end

function makeEventListener(self)
util.expect(type(self), "table")

local callbacks = {}
local anyListeners = {}

self.emit = function(name, ...)
local funcs = callbacks[name]
if funcs == nil then
return
end

for key, func in pairs(funcs) do
func(...)
end

for key, func in pairs(anyListeners) do
func(name, ...)
end

return self
end

self.on = function(name, func)
if callbacks[name] == nil then
callbacks[name] = {}
end
table.insert(callbacks[name], func)

return self
end

self.onany = function(func)
table.insert(anyListeners, func)

return self
end

self.removeListener = function(name, listener)
local funcs = callbacks[name]
if funcs == nil then
return
end

for key, func in pairs(funcs) do
if func == listener then
table.remove(funcs, key)
end
end

return self
end

self.once = function(name, func)
self.on(name, function(...)
func(...)
self.removeListener(name, func)
end)

return self
end

self.removeAllListeners = function()
callbacks = {}
anyListeners = {}

return self
end
end

function abstract()
error("This method is abstract and must be overridden.")
end

+ 3
- 0
manpages/craft View File

@@ -0,0 +1,3 @@
craft [count]

Crafts [count] or 1 of the item in the inventory.

+ 3
- 0
manpages/floor View File

@@ -0,0 +1,3 @@
floor <width> <height>

Creates a floor.

+ 3
- 0
manpages/help View File

@@ -0,0 +1,3 @@
help <program name>

Shows a tl;dr version of the man page.

+ 3
- 0
manpages/ls View File

@@ -0,0 +1,3 @@
ls

Lists the executables programs.

+ 3
- 0
manpages/man View File

@@ -0,0 +1,3 @@
man <program name>

Reads the man page of a program.

+ 2
- 0
pastebin.lua View File

@@ -0,0 +1,2 @@
local h = http.get("http://s.mort.coffee/mortcc/init.lua")
loadstring(h.readAll())()

+ 4
- 0
run.lua View File

@@ -0,0 +1,4 @@
local args = {...}

args[1] = "/bin/" .. args[1] .. ".lua"
shell.run(unpack(args))

+ 7
- 0
update.lua View File

@@ -0,0 +1,7 @@
local h = http.get("http://s.mort.coffee/mortcc/install.lua")
local f = fs.open("tmp", "w")
f.write(h.readAll())
f.close()

shell.run("tmp")
fs.delete("tmp")

Loading…
Cancel
Save