mirror of
https://github.com/kepler155c/opus
synced 2025-01-23 13:46:53 +00:00
transition tot kernel
This commit is contained in:
parent
d224f5df25
commit
fc8d44b60d
2
startup
2
startup
@ -1,6 +1,6 @@
|
|||||||
local bootOptions = {
|
local bootOptions = {
|
||||||
{ prompt = 'Default Shell', file = '/sys/boot/default.boot' },
|
{ prompt = 'Default Shell', file = '/sys/boot/default.boot' },
|
||||||
{ prompt = 'Opus' , file = '/sys/boot/multishell.boot' },
|
{ prompt = 'Opus' , file = '/sys/boot/opus.boot' },
|
||||||
-- { prompt = 'TLCO' , file = '/sys/boot/tlco.boot' },
|
-- { prompt = 'TLCO' , file = '/sys/boot/tlco.boot' },
|
||||||
}
|
}
|
||||||
local bootOption = 2
|
local bootOption = 2
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
local DEFAULT_UPATH = 'https://raw.githubusercontent.com/kepler155c/opus/develop/sys/apis'
|
local DEFAULT_UPATH = 'https://raw.githubusercontent.com/kepler155c/opus/develop-1.8/sys/apis'
|
||||||
local PASTEBIN_URL = 'http://pastebin.com/raw'
|
local PASTEBIN_URL = 'http://pastebin.com/raw'
|
||||||
local GIT_URL = 'https://raw.githubusercontent.com'
|
local GIT_URL = 'https://raw.githubusercontent.com'
|
||||||
|
|
||||||
|
@ -125,9 +125,9 @@ function Manager:init()
|
|||||||
focused = true })
|
focused = true })
|
||||||
|
|
||||||
elseif ch and self.currentPage then
|
elseif ch and self.currentPage then
|
||||||
if not self.currentPage.parent.device.side then
|
--if not self.currentPage.parent.device.side then
|
||||||
self:click(ch, button, x, y)
|
self:click(ch, button, x, y)
|
||||||
end
|
--end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
@ -412,9 +412,9 @@ function Util.httpGet(url, headers)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Util.download(url, filename)
|
function Util.download(url, filename)
|
||||||
local contents = Util.httpGet(url)
|
local contents, msg = Util.httpGet(url)
|
||||||
if not contents then
|
if not contents then
|
||||||
error('Failed to download ' .. url)
|
error(string.format('Failed to download %s\n%s', url, msg))
|
||||||
end
|
end
|
||||||
|
|
||||||
if filename then
|
if filename then
|
||||||
@ -441,6 +441,7 @@ function Util.runUrl(env, url, ...) -- os.run equivalent
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Util.run(env, path, ...)
|
function Util.run(env, path, ...)
|
||||||
|
if type(env) ~= 'table' then error('Util.run: env must be a table', 2) end
|
||||||
setmetatable(env, { __index = _G })
|
setmetatable(env, { __index = _G })
|
||||||
local fn, m = loadfile(path, env)
|
local fn, m = loadfile(path, env)
|
||||||
if fn then
|
if fn then
|
||||||
|
@ -17,7 +17,9 @@ sandboxEnv.exit = function() Event.exitPullEvents() end
|
|||||||
sandboxEnv._echo = function( ... ) return { ... } end
|
sandboxEnv._echo = function( ... ) return { ... } end
|
||||||
injector(sandboxEnv)
|
injector(sandboxEnv)
|
||||||
|
|
||||||
|
if multishell and multishell.setTitle then
|
||||||
multishell.setTitle(multishell.getCurrent(), 'Lua')
|
multishell.setTitle(multishell.getCurrent(), 'Lua')
|
||||||
|
end
|
||||||
UI:configure('Lua', ...)
|
UI:configure('Lua', ...)
|
||||||
|
|
||||||
local command = ''
|
local command = ''
|
||||||
@ -143,9 +145,6 @@ function page:eventHandler(event)
|
|||||||
self.prompt:updateCursor()
|
self.prompt:updateCursor()
|
||||||
|
|
||||||
elseif event.type == 'device' then
|
elseif event.type == 'device' then
|
||||||
if not _G.device then
|
|
||||||
sandboxEnv.device = Peripheral.getList()
|
|
||||||
end
|
|
||||||
self:setPrompt('device', true)
|
self:setPrompt('device', true)
|
||||||
self:executeStatement('device')
|
self:executeStatement('device')
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ local Util = require('util')
|
|||||||
|
|
||||||
local multishell = _ENV.multishell
|
local multishell = _ENV.multishell
|
||||||
|
|
||||||
multishell.setTitle(multishell.getCurrent(), 'Tabs')
|
multishell.setTitle(multishell.getCurrent(), 'Tasks')
|
||||||
UI:configure('Tabs', ...)
|
UI:configure('Tasks', ...)
|
||||||
|
|
||||||
local page = UI.Page {
|
local page = UI.Page {
|
||||||
menuBar = UI.MenuBar {
|
menuBar = UI.MenuBar {
|
||||||
@ -19,7 +19,7 @@ local page = UI.Page {
|
|||||||
grid = UI.ScrollingGrid {
|
grid = UI.ScrollingGrid {
|
||||||
y = 2,
|
y = 2,
|
||||||
columns = {
|
columns = {
|
||||||
{ heading = 'ID', key = 'tabId', width = 4 },
|
{ heading = 'ID', key = 'uid', width = 4 },
|
||||||
{ heading = 'Title', key = 'title' },
|
{ heading = 'Title', key = 'title' },
|
||||||
{ heading = 'Status', key = 'status' },
|
{ heading = 'Status', key = 'status' },
|
||||||
{ heading = 'Time', key = 'timestamp' },
|
{ heading = 'Time', key = 'timestamp' },
|
||||||
@ -39,9 +39,9 @@ function page:eventHandler(event)
|
|||||||
local t = self.grid:getSelected()
|
local t = self.grid:getSelected()
|
||||||
if t then
|
if t then
|
||||||
if event.type == 'activate' or event.type == 'grid_select' then
|
if event.type == 'activate' or event.type == 'grid_select' then
|
||||||
multishell.setFocus(t.tabId)
|
multishell.setFocus(t.uid)
|
||||||
elseif event.type == 'terminate' then
|
elseif event.type == 'terminate' then
|
||||||
multishell.terminate(t.tabId)
|
multishell.terminate(t.uid)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if event.type == 'quit' then
|
if event.type == 'quit' then
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
local sandboxEnv = { }
|
|
||||||
for k,v in pairs(_ENV) do
|
|
||||||
sandboxEnv[k] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
_G.requireInjector()
|
_G.requireInjector()
|
||||||
|
|
||||||
local Config = require('config')
|
local Config = require('config')
|
||||||
@ -11,7 +6,6 @@ local Util = require('util')
|
|||||||
local colors = _G.colors
|
local colors = _G.colors
|
||||||
local fs = _G.fs
|
local fs = _G.fs
|
||||||
local kernel = _G.kernel
|
local kernel = _G.kernel
|
||||||
local keyboard = _G.device.keyboard
|
|
||||||
local keys = _G.keys
|
local keys = _G.keys
|
||||||
local multishell = _ENV.multishell
|
local multishell = _ENV.multishell
|
||||||
local os = _G.os
|
local os = _G.os
|
||||||
@ -22,34 +16,15 @@ local window = _G.window
|
|||||||
|
|
||||||
local parentTerm = term.current()
|
local parentTerm = term.current()
|
||||||
local w,h = parentTerm.getSize()
|
local w,h = parentTerm.getSize()
|
||||||
local tabs = { }
|
|
||||||
local currentTab
|
|
||||||
local _tabId = 0
|
|
||||||
local overviewId
|
local overviewId
|
||||||
local runningTab
|
|
||||||
local tabsDirty = false
|
local tabsDirty = false
|
||||||
local closeInd = '*'
|
local closeInd = Util.getVersion() >= 1.76 and '\215' or '*'
|
||||||
local downState = { }
|
|
||||||
|
|
||||||
multishell.term = term.current()
|
multishell.term = term.current() --deprecated
|
||||||
|
|
||||||
-- Default label
|
-- redirect kernel output to a window
|
||||||
if not os.getComputerLabel() then
|
kernel.window = window.create(parentTerm, 1, 2, w, h - 1, false)
|
||||||
local id = os.getComputerID()
|
kernel.terminal = kernel.window
|
||||||
if _G.turtle then
|
|
||||||
os.setComputerLabel('turtle_' .. id)
|
|
||||||
elseif _G.pocket then
|
|
||||||
os.setComputerLabel('pocket_' .. id)
|
|
||||||
elseif _G.commands then
|
|
||||||
os.setComputerLabel('command_' .. id)
|
|
||||||
else
|
|
||||||
os.setComputerLabel('computer_' .. id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if Util.getVersion() >= 1.76 then
|
|
||||||
closeInd = '\215'
|
|
||||||
end
|
|
||||||
|
|
||||||
local config = {
|
local config = {
|
||||||
standard = {
|
standard = {
|
||||||
@ -71,10 +46,7 @@ local config = {
|
|||||||
}
|
}
|
||||||
Config.load('multishell', config)
|
Config.load('multishell', config)
|
||||||
|
|
||||||
local _colors = config.standard
|
local _colors = parentTerm.isColor() and config.color or config.standard
|
||||||
if parentTerm.isColor() then
|
|
||||||
_colors = config.color
|
|
||||||
end
|
|
||||||
|
|
||||||
local function redrawMenu()
|
local function redrawMenu()
|
||||||
if not tabsDirty then
|
if not tabsDirty then
|
||||||
@ -83,85 +55,73 @@ local function redrawMenu()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function resumeTab(tab, event, eventData)
|
function multishell.getFocus()
|
||||||
if not tab or coroutine.status(tab.co) == 'dead' then
|
local currentTab = kernel.routines[1]
|
||||||
return
|
return currentTab.uid
|
||||||
end
|
end
|
||||||
|
|
||||||
if not tab.filter or tab.filter == event or event == "terminate" then
|
function multishell.setFocus(tabId)
|
||||||
eventData = eventData or { }
|
return kernel.raise(tabId)
|
||||||
term.redirect(tab.terminal)
|
|
||||||
local previousTab = runningTab
|
|
||||||
runningTab = tab
|
|
||||||
local ok, result = coroutine.resume(tab.co, event, unpack(eventData))
|
|
||||||
tab.terminal = term.current()
|
|
||||||
if ok then
|
|
||||||
tab.filter = result
|
|
||||||
else
|
|
||||||
printError(result)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
runningTab = previousTab
|
function multishell.getTitle(tabId)
|
||||||
|
local tab = kernel.find(tabId)
|
||||||
|
return tab and tab.title
|
||||||
|
end
|
||||||
|
|
||||||
return ok, result
|
function multishell.setTitle(tabId, title)
|
||||||
|
local tab = kernel.find(tabId)
|
||||||
|
if tab then
|
||||||
|
if not tab.isOverview then
|
||||||
|
tab.title = title or ''
|
||||||
|
end
|
||||||
|
redrawMenu()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function selectTab(tab)
|
function multishell.getCurrent()
|
||||||
if not tab then
|
local runningTab = kernel.getCurrent()
|
||||||
for _,ftab in pairs(tabs) do
|
return runningTab and runningTab.uid
|
||||||
if not ftab.hidden then
|
|
||||||
tab = ftab
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if not tab then
|
function multishell.getTab(tabId)
|
||||||
tab = tabs[overviewId]
|
return kernel.find(tabId)
|
||||||
end
|
end
|
||||||
|
|
||||||
if currentTab and currentTab ~= tab then
|
function multishell.terminate(tabId)
|
||||||
currentTab.window.setVisible(false)
|
os.queueEvent('multishell_terminate', tabId)
|
||||||
--if coroutine.status(currentTab.co) == 'suspended' then
|
|
||||||
-- the process that opens a new tab won't get the lose focus event
|
|
||||||
-- os.queueEvent('multishell_notifyfocus', currentTab.tabId)
|
|
||||||
--resumeTab(currentTab, 'multishell_losefocus')
|
|
||||||
--end
|
|
||||||
if tab and not currentTab.hidden then
|
|
||||||
tab.previousTabId = currentTab.tabId
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if tab ~= currentTab then
|
function multishell.getTabs()
|
||||||
currentTab = tab
|
return kernel.routines
|
||||||
tab.window.setVisible(true)
|
|
||||||
Util.clear(keyboard.state) --- reset keyboard state
|
|
||||||
-- why not just queue event with tab ID if we want to notify
|
|
||||||
--resumeTab(tab, 'multishell_focus')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function nextTabId()
|
function multishell.launch( tProgramEnv, sProgramPath, ... )
|
||||||
_tabId = _tabId + 1
|
-- backwards compatibility
|
||||||
return _tabId
|
return multishell.openTab({
|
||||||
|
env = tProgramEnv,
|
||||||
|
path = sProgramPath,
|
||||||
|
args = { ... },
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
local function launchProcess(tab)
|
function multishell.openTab(tab)
|
||||||
tab.tabId = nextTabId()
|
if not tab.title and tab.path then
|
||||||
tab.timestamp = os.clock()
|
tab.title = fs.getName(tab.path)
|
||||||
|
end
|
||||||
|
tab.title = tab.title or 'untitled'
|
||||||
tab.window = window.create(parentTerm, 1, 2, w, h - 1, false)
|
tab.window = window.create(parentTerm, 1, 2, w, h - 1, false)
|
||||||
tab.terminal = tab.window
|
tab.terminal = tab.window
|
||||||
tab.env = Util.shallowCopy(tab.env or sandboxEnv)
|
|
||||||
|
local routine = kernel.newRoutine(tab)
|
||||||
|
|
||||||
tab.co = coroutine.create(function()
|
tab.co = coroutine.create(function()
|
||||||
|
|
||||||
local result, err
|
local result, err
|
||||||
|
|
||||||
if tab.fn then
|
if tab.fn then
|
||||||
result, err = Util.runFunction(tab.env, tab.fn, table.unpack(tab.args or { } ))
|
result, err = Util.runFunction(routine.env, tab.fn, table.unpack(tab.args or { } ))
|
||||||
elseif tab.path then
|
elseif tab.path then
|
||||||
result, err = Util.run(tab.env, tab.path, table.unpack(tab.args or { } ))
|
result, err = Util.run(routine.env, tab.path, table.unpack(tab.args or { } ))
|
||||||
else
|
else
|
||||||
err = 'multishell: invalid tab'
|
err = 'multishell: invalid tab'
|
||||||
end
|
end
|
||||||
@ -179,119 +139,29 @@ local function launchProcess(tab)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
tabs[tab.tabId] = nil
|
|
||||||
if tab == currentTab then
|
|
||||||
local previousTab
|
|
||||||
if tab.previousTabId then
|
|
||||||
previousTab = tabs[tab.previousTabId]
|
|
||||||
if previousTab and previousTab.hidden then
|
|
||||||
previousTab = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
selectTab(previousTab)
|
|
||||||
end
|
|
||||||
redrawMenu()
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
tabs[tab.tabId] = tab
|
kernel.run(routine)
|
||||||
resumeTab(tab)
|
|
||||||
return tab
|
|
||||||
end
|
|
||||||
|
|
||||||
function multishell.getFocus()
|
if tab.focused then
|
||||||
return currentTab.tabId
|
multishell.setFocus(tab.uid)
|
||||||
end
|
|
||||||
|
|
||||||
function multishell.setFocus(tabId)
|
|
||||||
local tab = tabs[tabId]
|
|
||||||
if tab then
|
|
||||||
selectTab(tab)
|
|
||||||
redrawMenu()
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function multishell.getTitle(tabId)
|
|
||||||
local tab = tabs[tabId]
|
|
||||||
if tab then
|
|
||||||
return tab.title
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function multishell.setTitle(tabId, title)
|
|
||||||
local tab = tabs[tabId]
|
|
||||||
if tab then
|
|
||||||
if not tab.isOverview then
|
|
||||||
tab.title = title or ''
|
|
||||||
end
|
|
||||||
redrawMenu()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function multishell.getCurrent()
|
|
||||||
if runningTab then
|
|
||||||
return runningTab.tabId
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function multishell.getTab(tabId)
|
|
||||||
return tabs[tabId]
|
|
||||||
end
|
|
||||||
|
|
||||||
function multishell.terminate(tabId)
|
|
||||||
os.queueEvent('multishell_terminate', tabId)
|
|
||||||
end
|
|
||||||
|
|
||||||
function multishell.getTabs()
|
|
||||||
return tabs
|
|
||||||
end
|
|
||||||
|
|
||||||
function multishell.launch( tProgramEnv, sProgramPath, ... )
|
|
||||||
-- backwards compatibility
|
|
||||||
return multishell.openTab({
|
|
||||||
env = tProgramEnv,
|
|
||||||
path = sProgramPath,
|
|
||||||
args = { ... },
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
function multishell.openTab(tab)
|
|
||||||
if not tab.title and tab.path then
|
|
||||||
tab.title = fs.getName(tab.path)
|
|
||||||
end
|
|
||||||
tab.title = tab.title or 'untitled'
|
|
||||||
|
|
||||||
local previousTerm = term.current()
|
|
||||||
launchProcess(tab)
|
|
||||||
term.redirect(previousTerm)
|
|
||||||
|
|
||||||
if tab.hidden then
|
|
||||||
if coroutine.status(tab.co) == 'dead' or tab.isDead then
|
|
||||||
tab.hidden = false
|
|
||||||
end
|
|
||||||
elseif tab.focused then
|
|
||||||
multishell.setFocus(tab.tabId)
|
|
||||||
else
|
else
|
||||||
redrawMenu()
|
redrawMenu()
|
||||||
end
|
end
|
||||||
|
|
||||||
return tab.tabId
|
return tab.uid
|
||||||
end
|
end
|
||||||
|
|
||||||
function multishell.hideTab(tabId)
|
function multishell.hideTab(tabId)
|
||||||
local tab = tabs[tabId]
|
local tab = kernel.find(tabId)
|
||||||
if tab then
|
if tab then
|
||||||
tab.hidden = true
|
tab.hidden = true
|
||||||
if currentTab.tabId == tabId then
|
|
||||||
selectTab(tabs[currentTab.previousTabId])
|
|
||||||
end
|
|
||||||
redrawMenu()
|
redrawMenu()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function multishell.unhideTab(tabId)
|
function multishell.unhideTab(tabId)
|
||||||
local tab = tabs[tabId]
|
local tab = kernel.find(tabId)
|
||||||
if tab then
|
if tab then
|
||||||
tab.hidden = false
|
tab.hidden = false
|
||||||
redrawMenu()
|
redrawMenu()
|
||||||
@ -299,16 +169,34 @@ function multishell.unhideTab(tabId)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function multishell.getCount()
|
function multishell.getCount()
|
||||||
return Util.size(tabs)
|
return #kernel.routines
|
||||||
end
|
end
|
||||||
|
|
||||||
kernel.hook('multishell_terminate', function(_, eventData)
|
kernel.hook('kernel_focus', function(_, eventData)
|
||||||
local tabId = eventData[1] or -1
|
local previous = eventData[2]
|
||||||
local tab = tabs[tabId]
|
if previous then
|
||||||
|
local routine = kernel.find(previous)
|
||||||
|
if routine and routine.window then
|
||||||
|
routine.window.setVisible(false)
|
||||||
|
if routine.hidden then
|
||||||
|
kernel.lower(previous)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local focused = kernel.find(eventData[1])
|
||||||
|
if focused and focused.window then
|
||||||
|
focused.window.setVisible(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
redrawMenu()
|
||||||
|
end)
|
||||||
|
|
||||||
|
kernel.hook('multishell_terminate', function(_, eventData)
|
||||||
|
local tab = kernel.find(eventData[1])
|
||||||
if tab and not tab.isOverview then
|
if tab and not tab.isOverview then
|
||||||
if coroutine.status(tab.co) ~= 'dead' then
|
if coroutine.status(tab.co) ~= 'dead' then
|
||||||
resumeTab(tab, "terminate")
|
tab:resume("terminate")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
@ -330,10 +218,12 @@ kernel.hook('multishell_redraw', function()
|
|||||||
parentTerm.clearLine()
|
parentTerm.clearLine()
|
||||||
|
|
||||||
local function compareTab(a, b)
|
local function compareTab(a, b)
|
||||||
return a.tabId < b.tabId
|
return a.uid < b.uid
|
||||||
end
|
end
|
||||||
|
|
||||||
for _,tab in pairs(tabs) do
|
local currentTab = kernel.routines[1]
|
||||||
|
|
||||||
|
for _,tab in pairs(kernel.routines) do
|
||||||
if tab.hidden and tab ~= currentTab then
|
if tab.hidden and tab ~= currentTab then
|
||||||
tab.width = 0
|
tab.width = 0
|
||||||
else
|
else
|
||||||
@ -343,18 +233,18 @@ kernel.hook('multishell_redraw', function()
|
|||||||
|
|
||||||
local function width()
|
local function width()
|
||||||
local tw = 0
|
local tw = 0
|
||||||
Util.each(tabs, function(t) tw = tw + t.width end)
|
Util.each(kernel.routines, function(t) tw = tw + t.width end)
|
||||||
return tw
|
return tw
|
||||||
end
|
end
|
||||||
|
|
||||||
while width() > w - 3 do
|
while width() > w - 3 do
|
||||||
local tab = select(2,
|
local tab = select(2,
|
||||||
Util.spairs(tabs, function(a, b) return a.width > b.width end)())
|
Util.spairs(kernel.routines, function(a, b) return a.width > b.width end)())
|
||||||
tab.width = tab.width - 1
|
tab.width = tab.width - 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local tabX = 0
|
local tabX = 0
|
||||||
for _,tab in Util.spairs(tabs, compareTab) do
|
for _,tab in Util.spairs(kernel.routines, compareTab) do
|
||||||
if tab.width > 0 then
|
if tab.width > 0 then
|
||||||
tab.sx = tabX + 1
|
tab.sx = tabX + 1
|
||||||
tab.ex = tabX + tab.width
|
tab.ex = tabX + tab.width
|
||||||
@ -375,7 +265,7 @@ kernel.hook('multishell_redraw', function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if currentTab then
|
if currentTab and currentTab.window then
|
||||||
currentTab.window.restoreCursor()
|
currentTab.window.restoreCursor()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -388,8 +278,8 @@ kernel.hook('term_resize', function(_, eventData)
|
|||||||
|
|
||||||
local windowHeight = h-1
|
local windowHeight = h-1
|
||||||
|
|
||||||
for _,key in pairs(Util.keys(tabs)) do
|
for _,key in pairs(Util.keys(kernel.routines)) do
|
||||||
local tab = tabs[key]
|
local tab = kernel.routines[key]
|
||||||
local x,y = tab.window.getCursorPos()
|
local x,y = tab.window.getCursorPos()
|
||||||
if y > windowHeight then
|
if y > windowHeight then
|
||||||
tab.window.scroll(y - windowHeight)
|
tab.window.scroll(y - windowHeight)
|
||||||
@ -402,69 +292,41 @@ kernel.hook('term_resize', function(_, eventData)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--[[
|
|
||||||
kernel.hook('key_up', function(_, eventData)
|
|
||||||
local code = eventData[1]
|
|
||||||
if not keyboard.state[code] then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
]]
|
|
||||||
|
|
||||||
kernel.hook('mouse_click', function(_, eventData)
|
kernel.hook('mouse_click', function(_, eventData)
|
||||||
local x, y = eventData[2], eventData[3]
|
local x, y = eventData[2], eventData[3]
|
||||||
|
local currentTab = kernel.routines[1]
|
||||||
|
|
||||||
if y == 1 then
|
if y == 1 then
|
||||||
if x == 1 then
|
if x == 1 then
|
||||||
multishell.setFocus(overviewId)
|
multishell.setFocus(overviewId)
|
||||||
elseif x == w then
|
elseif x == w then
|
||||||
if currentTab then
|
if currentTab then
|
||||||
multishell.terminate(currentTab.tabId)
|
multishell.terminate(currentTab.uid)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
for _,tab in pairs(tabs) do
|
for _,tab in pairs(kernel.routines) do
|
||||||
if not tab.hidden and tab.sx then
|
if not tab.hidden and tab.sx then
|
||||||
if x >= tab.sx and x <= tab.ex then
|
if x >= tab.sx and x <= tab.ex then
|
||||||
multishell.setFocus(tab.tabId)
|
multishell.setFocus(tab.uid)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
downState.mouse = nil
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
downState.mouse = currentTab
|
|
||||||
eventData[3] = eventData[3] - 1
|
eventData[3] = eventData[3] - 1
|
||||||
end)
|
end)
|
||||||
|
|
||||||
kernel.hook({ 'mouse_up', 'mouse_drag' }, function(event, eventData)
|
kernel.hook({ 'mouse_up', 'mouse_drag' }, function(_, eventData)
|
||||||
if downState.mouse ~= currentTab then
|
|
||||||
-- don't send mouse up as the mouse click event was on another window
|
|
||||||
if event == 'mouse_up' then
|
|
||||||
downState.mouse = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
return true -- stop propagation
|
|
||||||
end
|
|
||||||
eventData[3] = eventData[3] - 1
|
eventData[3] = eventData[3] - 1
|
||||||
end)
|
end)
|
||||||
|
|
||||||
kernel.hook('mouse_scroll', function(_, eventData)
|
kernel.hook('mouse_scroll', function(_, eventData)
|
||||||
local dir, y = eventData[1], eventData[3]
|
if eventData[3] == 1 then
|
||||||
|
|
||||||
if y == 1 then
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
eventData[3] = eventData[3] - 1
|
||||||
if currentTab.terminal.scrollUp then
|
|
||||||
if dir == -1 then
|
|
||||||
currentTab.terminal.scrollUp()
|
|
||||||
else
|
|
||||||
currentTab.terminal.scrollDown()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
eventData[3] = y - 1
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local function startup()
|
local function startup()
|
||||||
@ -518,44 +380,10 @@ overviewId = multishell.openTab({
|
|||||||
path = 'sys/apps/Overview.lua',
|
path = 'sys/apps/Overview.lua',
|
||||||
isOverview = true,
|
isOverview = true,
|
||||||
})
|
})
|
||||||
tabs[overviewId].title = '+'
|
kernel.find(overviewId).title = '+'
|
||||||
|
|
||||||
multishell.openTab({
|
multishell.openTab({
|
||||||
focused = true,
|
focused = true,
|
||||||
fn = startup,
|
fn = startup,
|
||||||
title = 'Autorun',
|
title = 'Autorun',
|
||||||
})
|
})
|
||||||
|
|
||||||
local currentTabEvents = Util.transpose {
|
|
||||||
'char', 'key', 'key_up',
|
|
||||||
'mouse_click', 'mouse_drag', 'mouse_scroll', 'mouse_up',
|
|
||||||
'paste', 'terminate',
|
|
||||||
}
|
|
||||||
|
|
||||||
while true do
|
|
||||||
local tEventData = { os.pullEventRaw() }
|
|
||||||
local sEvent = table.remove(tEventData, 1)
|
|
||||||
local stopPropagation
|
|
||||||
|
|
||||||
local eventHooks = kernel.hooks[sEvent]
|
|
||||||
if eventHooks then
|
|
||||||
for i = #eventHooks, 1, -1 do
|
|
||||||
stopPropagation = eventHooks[i](sEvent, tEventData)
|
|
||||||
if stopPropagation then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not stopPropagation then
|
|
||||||
if currentTabEvents[sEvent] then
|
|
||||||
resumeTab(currentTab, sEvent, tEventData)
|
|
||||||
|
|
||||||
else
|
|
||||||
-- Passthrough to all processes
|
|
||||||
for _,key in pairs(Util.keys(tabs)) do
|
|
||||||
resumeTab(tabs[key], sEvent, tEventData)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
@ -330,7 +330,7 @@ end
|
|||||||
local tArgs = { ... }
|
local tArgs = { ... }
|
||||||
if #tArgs > 0 then
|
if #tArgs > 0 then
|
||||||
local env = setmetatable(Util.shallowCopy(sandboxEnv), { __index = _G })
|
local env = setmetatable(Util.shallowCopy(sandboxEnv), { __index = _G })
|
||||||
return run(env, ...)
|
return run(_ENV, ...) -- maybe _ENV
|
||||||
end
|
end
|
||||||
|
|
||||||
local Config = require('config')
|
local Config = require('config')
|
||||||
|
@ -2,6 +2,7 @@ _G.requireInjector()
|
|||||||
|
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
|
local kernel = _G.kernel
|
||||||
local keyboard = _G.device.keyboard
|
local keyboard = _G.device.keyboard
|
||||||
local multishell = _ENV.multishell
|
local multishell = _ENV.multishell
|
||||||
|
|
||||||
@ -16,11 +17,10 @@ end)
|
|||||||
|
|
||||||
-- restart tab
|
-- restart tab
|
||||||
keyboard.addHotkey('control-backspace', function()
|
keyboard.addHotkey('control-backspace', function()
|
||||||
local tabs = multishell.getTabs()
|
local uid = multishell.getFocus()
|
||||||
local tabId = multishell.getFocus()
|
local tab = kernel.find(uid)
|
||||||
local tab = tabs[tabId]
|
|
||||||
if not tab.isOverview then
|
if not tab.isOverview then
|
||||||
multishell.terminate(tabId)
|
multishell.terminate(uid)
|
||||||
tab = Util.shallowCopy(tab)
|
tab = Util.shallowCopy(tab)
|
||||||
tab.isDead = false
|
tab.isDead = false
|
||||||
tab.focused = true
|
tab.focused = true
|
||||||
@ -35,7 +35,7 @@ keyboard.addHotkey('control-tab', function()
|
|||||||
local currentTabId = multishell.getFocus()
|
local currentTabId = multishell.getFocus()
|
||||||
|
|
||||||
local function compareTab(a, b)
|
local function compareTab(a, b)
|
||||||
return a.tabId < b.tabId
|
return a.uid < b.uid
|
||||||
end
|
end
|
||||||
for _,tab in Util.spairs(tabs, compareTab) do
|
for _,tab in Util.spairs(tabs, compareTab) do
|
||||||
if not tab.hidden then
|
if not tab.hidden then
|
||||||
@ -44,14 +44,14 @@ keyboard.addHotkey('control-tab', function()
|
|||||||
end
|
end
|
||||||
|
|
||||||
for k,tab in ipairs(visibleTabs) do
|
for k,tab in ipairs(visibleTabs) do
|
||||||
if tab.tabId == currentTabId then
|
if tab.uid == currentTabId then
|
||||||
if k < #visibleTabs then
|
if k < #visibleTabs then
|
||||||
multishell.setFocus(visibleTabs[k + 1].tabId)
|
multishell.setFocus(visibleTabs[k + 1].uid)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if #visibleTabs > 0 then
|
if #visibleTabs > 0 then
|
||||||
multishell.setFocus(visibleTabs[1].tabId)
|
multishell.setFocus(visibleTabs[1].uid)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
local colors = _G.colors
|
local colors = _G.colors
|
||||||
local fs = _G.fs
|
local fs = _G.fs
|
||||||
local http = _G.http
|
local http = _G.http
|
||||||
|
local os = _G.os
|
||||||
|
local shell = _ENV.shell
|
||||||
local term = _G.term
|
local term = _G.term
|
||||||
|
|
||||||
local w, h = term.getSize()
|
local w, h = term.getSize()
|
||||||
@ -32,7 +34,7 @@ term.setCursorPos((w - 18) / 2, h)
|
|||||||
term.write('Loading Opus...')
|
term.write('Loading Opus...')
|
||||||
term.setCursorPos(w, h)
|
term.setCursorPos(w, h)
|
||||||
|
|
||||||
local GIT_REPO = 'kepler155c/opus/develop'
|
local GIT_REPO = 'kepler155c/opus/develop-1.8'
|
||||||
local BASE = 'https://raw.githubusercontent.com/' .. GIT_REPO
|
local BASE = 'https://raw.githubusercontent.com/' .. GIT_REPO
|
||||||
|
|
||||||
local sandboxEnv = setmetatable({ }, { __index = _G })
|
local sandboxEnv = setmetatable({ }, { __index = _G })
|
||||||
@ -53,7 +55,10 @@ end
|
|||||||
local function run(file, ...)
|
local function run(file, ...)
|
||||||
local s, m = loadfile(file, makeEnv())
|
local s, m = loadfile(file, makeEnv())
|
||||||
if s then
|
if s then
|
||||||
return s(...)
|
s, m = pcall(s, ...)
|
||||||
|
if s then
|
||||||
|
return m
|
||||||
|
end
|
||||||
end
|
end
|
||||||
error('Error loading ' .. file .. '\n' .. m)
|
error('Error loading ' .. file .. '\n' .. m)
|
||||||
end
|
end
|
||||||
@ -80,13 +85,70 @@ if fs.exists('sys/apis/injector.lua') then
|
|||||||
else
|
else
|
||||||
-- not local, run the file system directly from git
|
-- not local, run the file system directly from git
|
||||||
_G.requireInjector = runUrl('/sys/apis/injector.lua')
|
_G.requireInjector = runUrl('/sys/apis/injector.lua')
|
||||||
runUrl('/sys/extensions/vfs.lua')
|
runUrl('sys/extensions/vfs.lua')
|
||||||
|
|
||||||
-- install file system
|
-- install file system
|
||||||
fs.mount('', 'gitfs', GIT_REPO)
|
fs.mount('', 'gitfs', GIT_REPO)
|
||||||
end
|
end
|
||||||
|
|
||||||
run('sys/kernel.lua')
|
_G.requireInjector()
|
||||||
|
local Util = require('util')
|
||||||
|
|
||||||
|
-- Default label
|
||||||
|
if not os.getComputerLabel() then
|
||||||
|
local id = os.getComputerID()
|
||||||
|
if _G.turtle then
|
||||||
|
os.setComputerLabel('turtle_' .. id)
|
||||||
|
elseif _G.pocket then
|
||||||
|
os.setComputerLabel('pocket_' .. id)
|
||||||
|
elseif _G.commands then
|
||||||
|
os.setComputerLabel('command_' .. id)
|
||||||
|
else
|
||||||
|
os.setComputerLabel('computer_' .. id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- user environment
|
||||||
|
if not fs.exists('usr/apps') then
|
||||||
|
fs.makeDir('usr/apps')
|
||||||
|
end
|
||||||
|
if not fs.exists('usr/autorun') then
|
||||||
|
fs.makeDir('usr/autorun')
|
||||||
|
end
|
||||||
|
if not fs.exists('usr/etc/fstab') then
|
||||||
|
Util.writeFile('usr/etc/fstab', 'usr gitfs kepler155c/opus-apps/develop-1.8')
|
||||||
|
end
|
||||||
|
if not fs.exists('usr/config/shell') then
|
||||||
|
Util.writeTable('usr/config/shell', {
|
||||||
|
aliases = shell.aliases(),
|
||||||
|
path = 'usr/apps:sys/apps:' .. shell.path(),
|
||||||
|
lua_path = '/sys/apis:/usr/apis',
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- shell environment
|
||||||
|
local config = Util.readTable('usr/config/shell')
|
||||||
|
if config.aliases then
|
||||||
|
for k in pairs(shell.aliases()) do
|
||||||
|
shell.clearAlias(k)
|
||||||
|
end
|
||||||
|
for k,v in pairs(config.aliases) do
|
||||||
|
shell.setAlias(k, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
shell.setPath(config.path)
|
||||||
|
sandboxEnv.LUA_PATH = config.lua_path
|
||||||
|
|
||||||
|
Util.run(makeEnv(), 'sys/kernel.lua')
|
||||||
|
|
||||||
|
-- extensions
|
||||||
|
local dir = 'sys/extensions'
|
||||||
|
for _,file in ipairs(fs.list(dir)) do
|
||||||
|
local s, m = Util.run(makeEnv(), 'sys/apps/shell', fs.combine(dir, file))
|
||||||
|
if not s then
|
||||||
|
error(m)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- install user file systems
|
-- install user file systems
|
||||||
fs.loadTab('usr/etc/fstab')
|
fs.loadTab('usr/etc/fstab')
|
||||||
@ -97,7 +159,25 @@ if args[1] then
|
|||||||
term.clear()
|
term.clear()
|
||||||
term.setCursorPos(1, 1)
|
term.setCursorPos(1, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local cterm = term.current()
|
||||||
|
|
||||||
args[1] = args[1] or 'sys/apps/multishell'
|
args[1] = args[1] or 'sys/apps/multishell'
|
||||||
run('sys/apps/shell', table.unpack(args))
|
local routine = kernel.newRoutine({
|
||||||
|
path = 'sys/apps/shell',
|
||||||
|
args = args
|
||||||
|
})
|
||||||
|
kernel.run(routine)
|
||||||
|
local s, m = pcall(kernel.start)
|
||||||
|
|
||||||
|
term.redirect(cterm)
|
||||||
|
term.setBackgroundColor(colors.black)
|
||||||
|
term.setTextColor(colors.white)
|
||||||
|
term.clear()
|
||||||
|
term.setCursorPos(1, 1)
|
||||||
|
if not s then
|
||||||
|
print('\nCrash detected\n')
|
||||||
|
_G.printError(m)
|
||||||
|
end
|
||||||
|
|
||||||
fs.restore()
|
fs.restore()
|
@ -165,7 +165,7 @@
|
|||||||
run = "Events.lua",
|
run = "Events.lua",
|
||||||
},
|
},
|
||||||
[ "2a4d562b1d9a9c90bdede6fac8ce4f7402462b86" ] = {
|
[ "2a4d562b1d9a9c90bdede6fac8ce4f7402462b86" ] = {
|
||||||
title = "Tabs",
|
title = "Tasks",
|
||||||
category = "System",
|
category = "System",
|
||||||
icon = "\0307 \0303\0317__\0307\031 \
|
icon = "\0307 \0303\0317__\0307\031 \
|
||||||
\0303 \
|
\0303 \
|
||||||
|
@ -30,6 +30,7 @@ local Util = require('util')
|
|||||||
local device = _G.device
|
local device = _G.device
|
||||||
local kernel = _G.kernel
|
local kernel = _G.kernel
|
||||||
local keyboard = _G.device.keyboard
|
local keyboard = _G.device.keyboard
|
||||||
|
local mouse = _G.device.mouse
|
||||||
local os = _G.os
|
local os = _G.os
|
||||||
|
|
||||||
kernel.hook('peripheral', function(_, eventData)
|
kernel.hook('peripheral', function(_, eventData)
|
||||||
@ -74,6 +75,23 @@ kernel.hook({ 'key', 'key_up', 'char', 'paste' }, function(event, eventData)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
kernel.hook({ 'mouse_click', 'mouse_up', 'mouse_drag' }, function(event, eventData)
|
||||||
|
local button = eventData[1]
|
||||||
|
if event == 'mouse_click' then
|
||||||
|
mouse.state[button] = true
|
||||||
|
else
|
||||||
|
if not mouse.state[button] then
|
||||||
|
return true -- ensure mouse ups are only generated if a mouse down was sent
|
||||||
|
end
|
||||||
|
mouse.state[button] = nil
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
kernel.hook('kernel_focus', function()
|
||||||
|
Util.clear(keyboard.state)
|
||||||
|
Util.clear(mouse.state)
|
||||||
|
end)
|
||||||
|
|
||||||
function keyboard.addHotkey(code, fn)
|
function keyboard.addHotkey(code, fn)
|
||||||
keyboard.hotkeys[code] = fn
|
keyboard.hotkeys[code] = fn
|
||||||
end
|
end
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
local kernel = _G.kernel
|
local kernel = _G.kernel
|
||||||
local multishell = _ENV.multishell
|
|
||||||
|
|
||||||
_G.network = { }
|
_G.network = { }
|
||||||
|
|
||||||
kernel.hook('device_attach', function(_, eventData)
|
kernel.hook('device_attach', function(_, eventData)
|
||||||
if eventData[1] == 'wireless_modem' then
|
if eventData[1] == 'wireless_modem' then
|
||||||
local s, m = multishell.openTab({
|
local routine = kernel.newRoutine({
|
||||||
path = 'sys/services/network.lua',
|
path = 'sys/services/network.lua',
|
||||||
hidden = true
|
hidden = true
|
||||||
})
|
})
|
||||||
if not s and m then
|
kernel.run(routine)
|
||||||
debug(m)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
@ -295,8 +295,9 @@ function fs.loadTab(path)
|
|||||||
fs.mount(table.unpack(Util.matches(l)))
|
fs.mount(table.unpack(Util.matches(l)))
|
||||||
end)
|
end)
|
||||||
if not s then
|
if not s then
|
||||||
printError('Mount failed')
|
_G.printError('Mount failed')
|
||||||
printError(l)
|
_G.printError(l)
|
||||||
|
_G.printError(m)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
201
sys/kernel.lua
201
sys/kernel.lua
@ -1,4 +1,4 @@
|
|||||||
local sandboxEnv = setmetatable({ }, { __index = _G })
|
local sandboxEnv = { }
|
||||||
for k,v in pairs(_ENV) do
|
for k,v in pairs(_ENV) do
|
||||||
sandboxEnv[k] = v
|
sandboxEnv[k] = v
|
||||||
end
|
end
|
||||||
@ -8,43 +8,21 @@ _G.requireInjector()
|
|||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
_G.kernel = {
|
_G.kernel = {
|
||||||
hooks = { }
|
UID = 0,
|
||||||
|
hooks = { },
|
||||||
|
routines = { },
|
||||||
|
terminal = _G.term.current(),
|
||||||
}
|
}
|
||||||
|
|
||||||
local kernel = _G.kernel
|
local kernel = _G.kernel
|
||||||
local fs = _G.fs
|
local os = _G.os
|
||||||
local shell = _ENV.shell
|
local term = _G.term
|
||||||
|
|
||||||
-- user environment
|
local focusedRoutineEvents = Util.transpose {
|
||||||
if not fs.exists('usr/apps') then
|
'char', 'key', 'key_up',
|
||||||
fs.makeDir('usr/apps')
|
'mouse_click', 'mouse_drag', 'mouse_scroll', 'mouse_up',
|
||||||
end
|
'paste', 'terminate',
|
||||||
if not fs.exists('usr/autorun') then
|
}
|
||||||
fs.makeDir('usr/autorun')
|
|
||||||
end
|
|
||||||
if not fs.exists('usr/etc/fstab') then
|
|
||||||
Util.writeFile('usr/etc/fstab', 'usr gitfs kepler155c/opus-apps/develop')
|
|
||||||
end
|
|
||||||
if not fs.exists('usr/config/shell') then
|
|
||||||
Util.writeTable('usr/config/shell', {
|
|
||||||
aliases = shell.aliases(),
|
|
||||||
path = 'usr/apps:sys/apps:' .. shell.path(),
|
|
||||||
lua_path = '/sys/apis:/usr/apis',
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- shell environment
|
|
||||||
local config = Util.readTable('usr/config/shell')
|
|
||||||
if config.aliases then
|
|
||||||
for k in pairs(shell.aliases()) do
|
|
||||||
shell.clearAlias(k)
|
|
||||||
end
|
|
||||||
for k,v in pairs(config.aliases) do
|
|
||||||
shell.setAlias(k, v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
shell.setPath(config.path)
|
|
||||||
_G.LUA_PATH = config.lua_path
|
|
||||||
|
|
||||||
-- any function that runs in a kernel hook does not run in
|
-- any function that runs in a kernel hook does not run in
|
||||||
-- a separate coroutine or have a window. an error in a hook
|
-- a separate coroutine or have a window. an error in a hook
|
||||||
@ -73,11 +51,158 @@ function kernel.unhook(event, fn)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- extensions
|
local Routine = { }
|
||||||
local dir = 'sys/extensions'
|
|
||||||
for _,file in ipairs(fs.list(dir)) do
|
function Routine:resume(event, ...)
|
||||||
local s, m = Util.run(sandboxEnv, 'sys/apps/shell', fs.combine(dir, file))
|
if not self.co or coroutine.status(self.co) == 'dead' then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self.filter or self.filter == event or event == "terminate" then
|
||||||
|
term.redirect(self.terminal)
|
||||||
|
|
||||||
|
local previous = kernel.running
|
||||||
|
kernel.running = self -- stupid shell set title
|
||||||
|
local ok, result = coroutine.resume(self.co, event, ...)
|
||||||
|
kernel.running = previous
|
||||||
|
|
||||||
|
self.terminal = term.current()
|
||||||
|
if ok then
|
||||||
|
self.filter = result
|
||||||
|
else
|
||||||
|
_G.printError(result)
|
||||||
|
end
|
||||||
|
if coroutine.status(self.co) == 'dead' then
|
||||||
|
Util.removeByValue(kernel.routines, self)
|
||||||
|
if #kernel.routines > 0 then
|
||||||
|
os.queueEvent('kernel_focus', kernel.routines[1].uid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ok, result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function kernel.getFocused()
|
||||||
|
return kernel.routines[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
function kernel.getCurrent()
|
||||||
|
return kernel.running
|
||||||
|
end
|
||||||
|
|
||||||
|
function kernel.newRoutine(args)
|
||||||
|
kernel.UID = kernel.UID + 1
|
||||||
|
|
||||||
|
args = args or { }
|
||||||
|
|
||||||
|
local routine = setmetatable(args, { __index = Routine })
|
||||||
|
routine.uid = kernel.UID
|
||||||
|
|
||||||
|
return routine
|
||||||
|
end
|
||||||
|
|
||||||
|
function kernel.run(routine)
|
||||||
|
routine.timestamp = os.clock()
|
||||||
|
routine.terminal = routine.terminal or kernel.terminal
|
||||||
|
routine.window = routine.window or kernel.window
|
||||||
|
routine.env = Util.shallowCopy(routine.env or sandboxEnv)
|
||||||
|
|
||||||
|
routine.co = routine.co or coroutine.create(function()
|
||||||
|
local result, err
|
||||||
|
|
||||||
|
if routine.fn then
|
||||||
|
result, err = Util.runFunction(routine.env, routine.fn, table.unpack(routine.args or { } ))
|
||||||
|
elseif routine.path then
|
||||||
|
result, err = Util.run(routine.env, routine.path, table.unpack(routine.args or { } ))
|
||||||
|
else
|
||||||
|
err = 'kernel: invalid routine'
|
||||||
|
end
|
||||||
|
|
||||||
|
if not result and err and err ~= 'Terminated' then
|
||||||
|
_G.printError(tostring(err))
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
table.insert(kernel.routines, routine)
|
||||||
|
|
||||||
|
local previousTerm = term.current()
|
||||||
|
local s, m = routine:resume()
|
||||||
|
term.redirect(previousTerm)
|
||||||
|
|
||||||
|
return s, m
|
||||||
|
end
|
||||||
|
|
||||||
|
function kernel.raise(uid)
|
||||||
|
local routine = Util.find(kernel.routines, 'uid', uid)
|
||||||
|
|
||||||
|
if routine then
|
||||||
|
local previous = kernel.routines[1]
|
||||||
|
if routine ~= previous then
|
||||||
|
Util.removeByValue(kernel.routines, routine)
|
||||||
|
table.insert(kernel.routines, 1, routine)
|
||||||
|
end
|
||||||
|
os.queueEvent('kernel_focus', routine.uid, previous and previous.uid)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function kernel.lower(uid)
|
||||||
|
local routine = Util.find(kernel.routines, 'uid', uid)
|
||||||
|
|
||||||
|
if routine and #kernel.routines > 1 then
|
||||||
|
Util.removeByValue(kernel.routines, routine)
|
||||||
|
table.insert(kernel.routines, routine)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function kernel.find(uid)
|
||||||
|
return Util.find(kernel.routines, 'uid', uid)
|
||||||
|
end
|
||||||
|
|
||||||
|
function kernel.halt()
|
||||||
|
os.queueEvent('kernel_halt')
|
||||||
|
end
|
||||||
|
|
||||||
|
function kernel.event(event, eventData)
|
||||||
|
local stopPropagation
|
||||||
|
|
||||||
|
local eventHooks = kernel.hooks[event]
|
||||||
|
if eventHooks then
|
||||||
|
for i = #eventHooks, 1, -1 do
|
||||||
|
local s, m = pcall(function()
|
||||||
|
stopPropagation = eventHooks[i](event, eventData)
|
||||||
|
end)
|
||||||
if not s then
|
if not s then
|
||||||
error(m)
|
error(m)
|
||||||
end
|
end
|
||||||
|
if stopPropagation then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not stopPropagation then
|
||||||
|
if focusedRoutineEvents[event] then
|
||||||
|
local active = kernel.routines[1]
|
||||||
|
if active then
|
||||||
|
active:resume(event, table.unpack(eventData))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Passthrough to all processes
|
||||||
|
for _,routine in pairs(Util.shallowCopy(kernel.routines)) do
|
||||||
|
routine:resume(event, table.unpack(eventData))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function kernel.start()
|
||||||
|
repeat
|
||||||
|
local eventData = { os.pullEventRaw() }
|
||||||
|
local event = table.remove(eventData, 1)
|
||||||
|
kernel.event(event, eventData)
|
||||||
|
until event == 'kernel_halt' or not kernel.routines[1]
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
if device.wireless_modem then
|
if _G.device.wireless_modem then
|
||||||
|
|
||||||
_G.requireInjector()
|
_G.requireInjector()
|
||||||
local Config = require('config')
|
local Config = require('config')
|
||||||
@ -7,11 +7,8 @@ if device.wireless_modem then
|
|||||||
Config.load('gps', config)
|
Config.load('gps', config)
|
||||||
|
|
||||||
if config.host and type(config.host) == 'table' then
|
if config.host and type(config.host) == 'table' then
|
||||||
|
_ENV._APP_TITLE = 'GPS Daemon'
|
||||||
multishell.setTitle(multishell.getCurrent(), 'GPS Daemon')
|
os.run(_ENV, '/rom/programs/gps', 'host', config.host.x, config.host.y, config.host.z)
|
||||||
|
|
||||||
os.run(getfenv(1), '/rom/programs/gps', 'host', config.host.x, config.host.y, config.host.z)
|
|
||||||
|
|
||||||
print('GPS daemon stopped')
|
print('GPS daemon stopped')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -3,26 +3,41 @@ _G.requireInjector()
|
|||||||
local Terminal = require('terminal')
|
local Terminal = require('terminal')
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
|
local kernel = _G.kernel
|
||||||
local keyboard = _G.device.keyboard
|
local keyboard = _G.device.keyboard
|
||||||
local multishell = _ENV.multishell
|
local multishell = _ENV.multishell
|
||||||
local os = _G.os
|
local os = _G.os
|
||||||
local term = _G.term
|
local term = _G.term
|
||||||
|
|
||||||
multishell.setTitle(multishell.getCurrent(), 'Debug')
|
_ENV._APP_TITLE = 'Debug'
|
||||||
|
|
||||||
term.redirect(Terminal.scrollable(term.current(), 50))
|
term.redirect(Terminal.scrollable(term.current(), 50))
|
||||||
|
|
||||||
local tabId = multishell.getCurrent()
|
local tabId = multishell.getCurrent()
|
||||||
local terminal = term.current()
|
|
||||||
local previousId
|
local previousId
|
||||||
|
|
||||||
_G.debug = function(pattern, ...)
|
_G.debug = function(pattern, ...)
|
||||||
local oldTerm = term.current()
|
local oldTerm = term.current()
|
||||||
term.redirect(terminal)
|
term.redirect(kernel.terminal)
|
||||||
Util.print(pattern, ...)
|
Util.print(pattern, ...)
|
||||||
term.redirect(oldTerm)
|
term.redirect(oldTerm)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
kernel.hook('mouse_scroll', function(_, eventData)
|
||||||
|
local dir, y = eventData[1], eventData[3]
|
||||||
|
|
||||||
|
if y > 1 then
|
||||||
|
local currentTab = kernel.routines[1]
|
||||||
|
if currentTab.terminal.scrollUp then
|
||||||
|
if dir == -1 then
|
||||||
|
currentTab.terminal.scrollUp()
|
||||||
|
else
|
||||||
|
currentTab.terminal.scrollDown()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
print('Debug started')
|
print('Debug started')
|
||||||
print('Press ^d to activate debug window')
|
print('Press ^d to activate debug window')
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ local Util = require('util')
|
|||||||
|
|
||||||
local device = _G.device
|
local device = _G.device
|
||||||
local fs = _G.fs
|
local fs = _G.fs
|
||||||
local multishell = _ENV.multishell
|
|
||||||
local network = _G.network
|
local network = _G.network
|
||||||
local os = _G.os
|
local os = _G.os
|
||||||
local printError = _G.printError
|
local printError = _G.printError
|
||||||
@ -14,7 +13,7 @@ if not device.wireless_modem then
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
multishell.setTitle(multishell.getCurrent(), 'Net Daemon')
|
_ENV._APP_TITLE = 'Net Daemon'
|
||||||
|
|
||||||
print('Net daemon started')
|
print('Net daemon started')
|
||||||
|
|
||||||
|
@ -6,10 +6,9 @@
|
|||||||
* background read buffering
|
* background read buffering
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
local multishell = _ENV.multishell
|
|
||||||
local os = _G.os
|
local os = _G.os
|
||||||
|
|
||||||
multishell.setTitle(multishell.getCurrent(), 'Net transport')
|
_ENV._APP_TITLE = 'Net transport'
|
||||||
|
|
||||||
local computerId = os.getComputerID()
|
local computerId = os.getComputerID()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user