From b6326e87e86c2228f5e365b5348e581ec5f0cea1 Mon Sep 17 00:00:00 2001 From: payonel Date: Sat, 2 Apr 2016 13:03:02 -0700 Subject: [PATCH] delay load, term, and grep fixed Delayload is lighter weight now. Improving method reuse and reducing boot costs about about 1.5k term had some crashes and improper behavior. This fixed tab complete for 5.3 lua archs, term palette use, and missing tab complete hints. Term blinking now also supports setCursorBlink(false). grep had a bug where patterns looking for start-of-line text would find in-line matches as well. --- .../opencomputers/loot/OpenOS/bin/grep.lua | 10 +-- .../opencomputers/loot/OpenOS/bin/sh.lua | 1 + .../opencomputers/loot/OpenOS/lib/package.lua | 54 ++++----------- .../opencomputers/loot/OpenOS/lib/term.lua | 65 ++++++++++++------- .../loot/OpenOS/lib/tools/delayLookup.lua | 33 ++++++++++ .../loot/OpenOS/lib/tools/delayParse.lua | 25 ++++--- 6 files changed, 106 insertions(+), 82 deletions(-) create mode 100644 src/main/resources/assets/opencomputers/loot/OpenOS/lib/tools/delayLookup.lua diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/grep.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/grep.lua index f21235bfc..9015b4fc6 100644 --- a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/grep.lua +++ b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/grep.lua @@ -279,11 +279,11 @@ local function test(m,p) write(':', COLON_COLOR) needs_line_num = nil end - local p=m_only and '' or m.line:sub(last_index,(i or 0)-1) + local s=m_only and '' or m.line:sub(last_index,(i or 0)-1) local g=i and m.line:sub(i,j) or '' - if i==1 then g=trim_front(g) elseif last_index==1 then p=trim_front(p) end - if j==slen then g=trim_back(g) elseif not i then p=trim_back(p) end - write(p) + if i==1 then g=trim_front(g) elseif last_index==1 then s=trim_front(s) end + if j==slen then g=trim_back(g) elseif not i then s=trim_back(s) end + write(s) write(g, MATCH_COLOR) empty_line = false last_index = (j or slen)+1 @@ -291,7 +291,7 @@ local function test(m,p) write("\n") empty_line = true needs_filename, needs_line_num = include_filename, print_line_num - end + elseif p:find("^^") then break end end if not empty_line then write("\n") end end diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/sh.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/sh.lua index 19b2bfe4b..3e49df267 100644 --- a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/sh.lua +++ b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/sh.lua @@ -30,6 +30,7 @@ if #args == 0 and (io.stdin.tty or options.i) and not options.c then local foreground = gpu.setForeground(0xFF0000) term.write(sh.expand(os.getenv("PS1") or "$ ")) gpu.setForeground(foreground) + term.setCursorBlink(true) local command = term.read(history, nil, sh.hintHandler) if not command then io.write("exit\n") diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/lib/package.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/lib/package.lua index 326cda9f3..3a3c68645 100644 --- a/src/main/resources/assets/opencomputers/loot/OpenOS/lib/package.lua +++ b/src/main/resources/assets/opencomputers/loot/OpenOS/lib/package.lua @@ -58,45 +58,18 @@ local function preloadSearcher(module) end end -local function delay_index(tbl,key) - local z = getmetatable(tbl) - local method = z.methods[tbl][key] - if method then - if not z.cache[tbl][key] then - local file = io.open(z.path,"r") - if file then - file:seek("set", method[1]) - local loaded = load("return function"..file:read(method[2]), "=delayed-"..key,"t",z.env) - assert(loaded,"failed to load "..key) - z.cache[tbl][key] = loaded() - file:close() - --lazy_protect(key, z.cache[key]) - end - end - return z.cache[tbl][key] - end +local delay_data = {} +local delay_tools = setmetatable({},{__mode="v"}) + +package.delay_data = delay_data + +function delay_data.__index(tbl,key) + local lookup = delay_tools.lookup or loadfile("/lib/tools/delayLookup.lua") + delay_tools.lookup = lookup + return lookup(delay_data, tbl, key) end -local function delay_newindex(tbl,key,value) - local z = getmetatable(tbl) - z.methods[tbl][key] = nil - rawset(tbl,key,value) -end -local function delay_pairs(tbl) - local set,k,v = {} - while true do - k,v = next(tbl,k) - if not k then break end - set[k] = v - end - local z = getmetatable(tbl) - for k in pairs(z.methods[tbl]) do - if not set[k] then - set[k] = function(...)return delay_index(tbl,k)(...)end - end - end - return pairs(set) -end -local weak_cache = setmetatable({},{__mode="v"}) +delay_data.__pairs = delay_data.__index -- nil key acts like pairs + function delaySearcher(module) if not delayed[module] then return "\tno field package.delayed['" .. module .. "']" @@ -105,8 +78,9 @@ function delaySearcher(module) if not filepath then return reason end - weak_cache.parser = weak_cache.parser or loadfile("/lib/tools/delayParse.lua") - local loader, reason = weak_cache.parser(filepath,delay_index,delay_newindex,delay_pairs) + local parser = delay_tools.parser or loadfile("/lib/tools/delayParse.lua") + delay_tools.parser = parser + local loader, reason = parser(filepath,delay_data) return loader, reason end diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/lib/term.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/lib/term.lua index c57d4db49..a9db7a1dc 100644 --- a/src/main/resources/assets/opencomputers/loot/OpenOS/lib/term.lua +++ b/src/main/resources/assets/opencomputers/loot/OpenOS/lib/term.lua @@ -54,38 +54,52 @@ function term.isAvailable(w) return w and not not (w.gpu and w.screen) end -function term.internal.pull(input, c, off, p, ...) - local w=W() +function term.internal.pull(input, c, off, t, ...) + t=t or math.huge + if t < 0 then return end + local w,unpack=W(),table.unpack local d,h,dx,dy,x,y=term.getViewport(w) local out = (x<1 or x>d or y<1 or y>h) - if not w.blink or (not input and out) or type(p) == "number" then - return event.pull(p,...) - end - local gpu=w.gpu - if out then + if input and out then input:move(0) y=w.y input:scroll() end x,y=w.x+dx,w.y+dy - c=c or {gpu.getBackground(),gpu.getForeground(),gpu.get(x,y)} - if not off then - gpu.setForeground(c[1]) - gpu.setBackground(c[2]) - end - gpu.set(x,y,c[3]) - gpu.setForeground(c[2]) - gpu.setBackground(c[1]) - local a={pcall(event.pull,0.5,p,...)} - if #a>1 then + local gpu + + if input or not out then + gpu=w.gpu + local sf,sb=gpu.setForeground,gpu.setBackground + c=c or {{gpu.getBackground()},{gpu.getForeground()},gpu.get(x,y)} + local c11,c12 = unpack(c[1]) + local c21,c22 = unpack(c[2]) + if not off then + sf(c11,c12) + sb(c21,c22) + end gpu.set(x,y,c[3]) - return select(2,table.unpack(a)) + sb(c11,c12) + sf(c21,c22) end - return term.internal.pull(input,c,not off,p,...) + + local a={pcall(event.pull,math.min(t,0.5),...)} + + if #a>1 or t<.5 then + if gpu then + gpu.set(x,y,c[3]) + end + return select(2,unpack(a)) + end + local blinking = w.blink + if input then blinking = input.blink end + return term.internal.pull(input,c,blinking and not off,t-0.5,...) end -function term.pull(...) - return term.internal.pull(nil,nil,nil,...) +function term.pull(p,...) + local a,t = {p,...} + if type(p) == "number" then t = table.remove(a,1) end + return term.internal.pull(nil,nil,nil,t,table.unpack(a)) end function term.read(history,dobreak,hintHandler,pwchar,filter) @@ -202,10 +216,11 @@ function term.readKeyboard(ops) local filter = ops.filter and function(i) return term.internal.filter(ops.filter,i) end or term.internal.nop local pwchar = ops.pwchar and function(i) return term.internal.mask(ops.pwchar,i) end or term.internal.nop local history,db,hints={list=ops,index=0},ops.dobreak,{handler=ops.hintHandler} - term.setCursorBlink(true) local w=W() local draw=io.stdin.tty and term.drawText or term.internal.nop local input={w=w,promptx=w.x,prompty=w.y,index=0,data="",mask=pwchar} + input.blink = ops.blink + if input.blink == nil then input.blink = w.blink end if ops.nowrap then term.internal.build_horizontal_reader(input) else @@ -350,6 +365,10 @@ function term.setCursorBlink(enabled) W().blink=enabled end +function term.getCursorBlink() + return W().blink +end + function term.bind(gpu, screen, kb, window) window = window or W() window.gpu = gpu or window.gpu @@ -480,7 +499,7 @@ function --[[@delayloaded-start@]] term.internal.tab(input,hints) hints.cache.i=-1 end local c=hints.cache - c.i=(c.i+1)%#c + c.i=(c.i+1)%math.max(#c,1) local next=c[c.i+1] if next then local tail = unicode.wlen(input.data) - input.index - 1 diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/lib/tools/delayLookup.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/lib/tools/delayLookup.lua new file mode 100644 index 000000000..c0e049b0f --- /dev/null +++ b/src/main/resources/assets/opencomputers/loot/OpenOS/lib/tools/delayLookup.lua @@ -0,0 +1,33 @@ +local data,tbl,key = ... +local z = data[tbl] + +if key then -- index + local method = z.methods[key] + local cache = z.cache[key] + if method and not cache then + local file = io.open(z.path,"r") + if file then + file:seek("set", method[1]) + local loaded = load("return function"..file:read(method[2]), "=delayed-"..key,"t",z.env) + file:close() + assert(loaded,"failed to load "..key) + cache = loaded() + --lazy_protect(key, cache) + z.cache[key] = cache + end + end + return cache +else -- pairs + local set,k,v = {} + while true do + k,v = next(tbl,k) + if not k then break end + set[k] = v + end + for k in pairs(z.methods) do + if not set[k] then + set[k] = function(...)return tbl[k](...)end + end + end + return pairs(set) +end diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/lib/tools/delayParse.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/lib/tools/delayParse.lua index a6aa80dda..50d89ae38 100644 --- a/src/main/resources/assets/opencomputers/loot/OpenOS/lib/tools/delayParse.lua +++ b/src/main/resources/assets/opencomputers/loot/OpenOS/lib/tools/delayParse.lua @@ -1,4 +1,4 @@ -local filepath,delay_index,delay_newindex,delay_pairs = ... +local filepath,delay_data = ... local file, reason = io.open(filepath, "r") if not file then return reason @@ -45,23 +45,20 @@ local library, local_env = loader() if library then local_env = local_env or {} local_env[lib_name] = library - local mt = - { - methods={}, - cache={}, - env=setmetatable(local_env, {__index=_G}), - path=filepath, - __pairs=delay_pairs, - __index=delay_index, - __newindex=delay_newindex, - } + + local env = setmetatable(local_env, {__index=_G}) for path,pack in pairs(methods) do local target = library for name in path:gmatch("[^%.]+") do target = target[name] end - mt.methods[target]=pack - mt.cache[target]={} - setmetatable(target, mt) + delay_data[target] = + { + methods = pack, + cache = {}, + env = env, + path = filepath + } + setmetatable(target, delay_data) end return function()return library end, filepath