From 2b1b04d76459458458e6172091e6a3d93226fc04 Mon Sep 17 00:00:00 2001 From: kepler155c Date: Sat, 23 Sep 2017 21:46:46 -0400 Subject: [PATCH] monitor manager --- apps/Turtles.lua | 2 - apps/mirrorHost.lua | 7 +- apps/monitorManager.lua | 261 +++++++++++++++++++++++++++++----------- etc/recipes.db | 7 ++ 4 files changed, 201 insertions(+), 76 deletions(-) diff --git a/apps/Turtles.lua b/apps/Turtles.lua index 3ed9717..1b0eb02 100644 --- a/apps/Turtles.lua +++ b/apps/Turtles.lua @@ -348,9 +348,7 @@ Event.onInterval(1, function() local t = _G.network[page.turtle.id] page.turtle = t page:draw() -debug('sync') page:sync() -debug('sync done') end end) diff --git a/apps/mirrorHost.lua b/apps/mirrorHost.lua index 4ece283..8ddefee 100644 --- a/apps/mirrorHost.lua +++ b/apps/mirrorHost.lua @@ -6,11 +6,14 @@ local Socket = require('socket') Logger.setScreenLogging() +local mon = term.current() local args = { ... } -local mon = device[args[1] or 'monitor'] +if args[1] then + mon = device[args[1]] +end if not mon then - error('Monitor not attached') + error('Invalid monitor') end mon.setBackgroundColor(colors.black) diff --git a/apps/monitorManager.lua b/apps/monitorManager.lua index ffcef2f..3a604f8 100644 --- a/apps/monitorManager.lua +++ b/apps/monitorManager.lua @@ -1,11 +1,8 @@ +requireInjector = requireInjector or load(http.get('https://raw.githubusercontent.com/kepler155c/opus/develop/sys/apis/injector.lua').readAll())() requireInjector(getfenv(1)) local Util = require('util') -local args = { ... } -local processes = { } -local parentTerm = term.current() - local function syntax() printError('Syntax:') printError('Start a new session') @@ -17,46 +14,34 @@ local function syntax() error() end -local option = table.remove(args, 1) - -if option == 'run' then - local run = table.remove(args, 1) - if not run then - syntax() - end - os.queueEvent('monitor_client', { run = run, args = args }) - return -end - -if option ~= 'start' then - syntax() -end - +local args = { ... } +local UID = 0 +local processes = { } +local parentTerm = term.current() local configFile = args[1] or syntax() local monitor = peripheral.find(args[2] or 'monitor') or syntax() +local defaultEnv = Util.shallowCopy(getfenv(1)) + monitor.setTextScale(.5) monitor.clear() -local monDim = { } +local monDim, termDim = { }, { } monDim.width, monDim.height = monitor.getSize() - -if fs.exists(configFile) then - local config = Util.readTable(configFile) - if config then - for _,v in pairs(config) do - os.queueEvent('monitor_client', v) - end - end -end +termDim.width, termDim.height = parentTerm.getSize() local function saveConfig() local t = { } for _,process in pairs(processes) do - process.args.x = process.x - process.args.y = process.y - process.args.width = process.width - 2 - process.args.height = process.height - 3 - table.insert(t, process.args) + if process.path and not process.isShell then + table.insert(t, { + x = process.x, + y = process.y, + width = process.width - 2, + height = process.height - 3, + path = process.path, + args = process.args, + }) + end end Util.writeTable(configFile, t) end @@ -68,12 +53,28 @@ end local function redraw() monitor.clear() - for k,process in pairs(processes) do + for k,process in ipairs(processes) do process.container.redraw() process:focus(k == #processes) end end +local function focusProcess(process) + if #processes > 0 then + processes[#processes]:focus(false) + end + + for k,v in pairs(processes) do + if v == self then + table.remove(processes, k) + break + end + end + + table.insert(processes, process) + process:focus(true) +end + local Process = { } function Process:focus(focused) @@ -84,11 +85,8 @@ function Process:focus(focused) end self.titleBar.clear() self.titleBar.setTextColor(colors.black) - self.titleBar.setCursorPos(2, 1) - self.titleBar.write(self.title or 'Terminal') - - self.titleBar.setCursorPos(self.width - 3, 1) - self.titleBar.write('*') + write(self.titleBar, 2, 1, self.title) + write(self.titleBar, self.width - 3, 1, '*') if focused then self.window.restoreCursor() @@ -125,15 +123,20 @@ function Process:drawSizers() end function Process:new(args) - self.args = args + args.env = args.env or Util.shallowCopy(defaultEnv) + args.width = args.width or termDim.width + args.height = args.height or termDim.height - args.width = args.width or 42 - args.height = args.height or 18 + UID = UID + 1 + self.uid = UID self.x = args.x or 1 self.y = args.y or 1 self.width = args.width + 2 self.height = args.height + 3 + self.path = args.path + self.args = args.args or { } + self.title = args.title or 'shell' self:adjustDimensions() @@ -145,12 +148,16 @@ function Process:new(args) self.co = coroutine.create(function() - local result, err = shell.run('shell', args.run) + local result, err + + if args.fn then + result, err = Util.runFunction(args.env, args.fn, table.unpack(self.args)) + elseif args.path then + result, err = os.run(args.env, args.path, table.unpack(self.args)) + end -Util.print({ result, err }) if not result and err ~= 'Terminated' then if err then -Util.print(tostring(err)) printError(tostring(err)) os.sleep(3) end @@ -161,15 +168,13 @@ Util.print(tostring(err)) break end end -Util.print('dead') - read() --saveConfig() redraw() end) - self:focus(true) + local previousTerm = term.current() self:resume() - self.title = multishell.getTab(multishell.getCurrent()).title + term.redirect(previousTerm) return tab end @@ -247,6 +252,135 @@ function getProcessAt(x, y) end end +defaultEnv.multishell = { } + +function defaultEnv.multishell.getFocus() + return processes[#processes].uid +end + +function defaultEnv.multishell.setFocus(uid) + local process, key = Util.find(processes, 'uid', uid) + + if process then + if processes[#processes] ~= process then + focusProcess(process) + end + return true + end + return false +end + +function defaultEnv.multishell.getTitle(uid) + local process = Util.find(processes, 'uid', uid) + if process then + return process.title + end +end + +function defaultEnv.multishell.setTitle(uid, title) + local process = Util.find(processes, 'uid', uid) + if process then + process.title = title or '' + process:focus(processs == processes[#processes]) + end +end + +function defaultEnv.multishell.getCurrent() + return processes[#processes].uid +end + +function defaultEnv.multishell.getCount() + return Util.size(processes) +end + +function defaultEnv.multishell.launch(env, file, ...) + return defaultEnv.multishell.openTab({ + path = file, + env = env, + title = 'shell', + args = { ... }, + }) +end + +function defaultEnv.multishell.openTab(tabInfo) + local process = setmetatable({ }, { __index = Process }) + + table.insert(processes, process) + process:new(tabInfo) + focusProcess(process) + saveConfig() + + return process.uid +end + +if fs.exists(configFile) then + local config = Util.readTable(configFile) + if config then + for _,v in pairs(config) do + local process = setmetatable({ }, { __index = Process }) + table.insert(processes, process) + process:new(v) + process:focus(false) + end + end +end + +local function addShell() + + UID = UID + 1 + + local process = setmetatable({ + x = monDim.width - 8, + y = monDim.height, + width = 9, + height = 1, + isShell = true, + uid = UID, + }, { __index = Process }) + + table.insert(processes, 1, process) + + function process:focus(focused) + self.window.setVisible(focused) + if focused then + self.window.restoreCursor() + self.container.setTextColor(colors.green) + self.container.setBackgroundColor(colors.black) + else + parentTerm.clear() + parentTerm.setCursorBlink(false) + self.container.setTextColor(colors.lightGray) + self.container.setBackgroundColor(colors.black) + end + write(self.container, 1, 1, '[ shell ]') + end + + function process:resizeClick() + end + + function process:drawSizers() + end + + process.container = window.create(monitor, process.x, process.y, process.width, process.height, true) + process.window = window.create(parentTerm, 1, 1, termDim.width, termDim.height, true) + process.terminal = process.window + + process.co = coroutine.create(function() + while true do + os.run(defaultEnv, shell.resolveProgram('shell')) + end + end) + + process:focus(false) + local previousTerm = term.current() + process:resume() + term.redirect(previousTerm) +end + +addShell() + +processes[#processes]:focus(true) + while true do local event = { os.pullEventRaw() } @@ -255,30 +389,13 @@ while true do term.redirect(parentTerm) break - elseif event[1] == 'monitor_client' then - local process = { } - setmetatable(process, { __index = Process }) - - local focused = processes[#processes] - if focused then - focused:focus(false) - end - - table.insert(processes, process) - process:new(event[2]) - saveConfig() - elseif event[1] == "monitor_touch" then local x, y = event[3], event[4] local key, process = getProcessAt(x, y) if process then if key ~= #processes then - local focused = processes[#processes] - focused:focus(false) - process:focus(true) - table.remove(processes, key) - table.insert(processes, process) + focusProcess(process) end x = x - process.x + 1 @@ -314,10 +431,10 @@ while true do end end - elseif event == "char" or - event == "key" or - event == "key_up" or - event == "paste" then + elseif event[1] == "char" or + event[1] == "key" or + event[1] == "key_up" or + event[1] == "paste" then local focused = processes[#processes] if focused then diff --git a/etc/recipes.db b/etc/recipes.db index f69c131..8c61497 100644 --- a/etc/recipes.db +++ b/etc/recipes.db @@ -1036,6 +1036,13 @@ [ 7 ] = "minecraft:redstone:0", }, }, + [ "minecraft:sticky_piston:0" ] = { + count = 1, + ingredients = { + "minecraft:slime_ball:0", + [ 5 ] = "minecraft:piston:0", + }, + }, [ "minecraft:wool:5" ] = { count = 1, ingredients = {