mirror of
https://github.com/20kdc/OC-KittenOS.git
synced 2024-11-23 10:58:06 +11:00
Magic to decrease app-claw memory usage (Another R2 candidate)
This commit is contained in:
parent
5fda45b663
commit
5ae3a6019d
@ -8,9 +8,10 @@ local event = require("event")(neo)
|
|||||||
local neoux, err = require("neoux")
|
local neoux, err = require("neoux")
|
||||||
if not neoux then error(err) end
|
if not neoux then error(err) end
|
||||||
neoux = neoux(event, neo)
|
neoux = neoux(event, neo)
|
||||||
local claw = require("claw")()
|
local claw = require("app-claw-core")()
|
||||||
|
local clawcsi = require("app-claw-csi")
|
||||||
|
|
||||||
local source = "http://20kdc.duckdns.org/neo/"
|
local source = "http://20kdc.duckdns.org/neo/DEV/"
|
||||||
local disks = neo.requireAccess("c.filesystem", "searching disks for packages")
|
local disks = neo.requireAccess("c.filesystem", "searching disks for packages")
|
||||||
local primaryDisk = disks.primary
|
local primaryDisk = disks.primary
|
||||||
local primaryINet = neo.requestAccess("c.internet")
|
local primaryINet = neo.requestAccess("c.internet")
|
||||||
@ -101,7 +102,7 @@ end
|
|||||||
-- Beginning Of The App (well, the actual one)
|
-- Beginning Of The App (well, the actual one)
|
||||||
|
|
||||||
local genCurrent, genPrimary, genPackage, primaryWindow
|
local genCurrent, genPrimary, genPackage, primaryWindow
|
||||||
local windows = 1
|
local running = true
|
||||||
|
|
||||||
-- primary
|
-- primary
|
||||||
local primarySearchTx = ""
|
local primarySearchTx = ""
|
||||||
@ -134,7 +135,7 @@ local function primaryWindowRegenCore()
|
|||||||
local gen, gens = genCurrent()
|
local gen, gens = genCurrent()
|
||||||
return 25, 12, "claw", neoux.tcwindow(25, 12, gen, function (w)
|
return 25, 12, "claw", neoux.tcwindow(25, 12, gen, function (w)
|
||||||
w.close()
|
w.close()
|
||||||
windows = windows - 1
|
running = false
|
||||||
end, 0xFF8F00, 0, gens)
|
end, 0xFF8F00, 0, gens)
|
||||||
end
|
end
|
||||||
local function primaryWindowRegen()
|
local function primaryWindowRegen()
|
||||||
@ -153,7 +154,7 @@ for pass = 1, 3 do
|
|||||||
nam = v.address
|
nam = v.address
|
||||||
end
|
end
|
||||||
if nam then
|
if nam then
|
||||||
local ok, r = claw.addSource(nam, fsSrc(v), (not v.isReadOnly()) and fsDst(v))
|
local ok, r = clawcsi(claw, nam, fsSrc(v), (not v.isReadOnly()) and fsDst(v))
|
||||||
if not ok and nam == "local" then
|
if not ok and nam == "local" then
|
||||||
claw.unlock()
|
claw.unlock()
|
||||||
error(r)
|
error(r)
|
||||||
@ -162,10 +163,15 @@ for pass = 1, 3 do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- No longer needed
|
||||||
|
disks = nil
|
||||||
|
|
||||||
if primaryINet then
|
if primaryINet then
|
||||||
checked(claw.addSource, "inet", download)
|
checked(clawcsi, claw, "inet", download)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
clawcsi = nil
|
||||||
|
|
||||||
primaryList = claw.getList()
|
primaryList = claw.getList()
|
||||||
|
|
||||||
-- Sections
|
-- Sections
|
||||||
@ -197,6 +203,14 @@ function genPrimary()
|
|||||||
if ent then
|
if ent then
|
||||||
local enttx = describe(ent)
|
local enttx = describe(ent)
|
||||||
table.insert(elems, neoux.tcbutton(1, i + 1, unicode.safeTextFormat(enttx), function (w)
|
table.insert(elems, neoux.tcbutton(1, i + 1, unicode.safeTextFormat(enttx), function (w)
|
||||||
|
-- FREE UP MEMORY NOW
|
||||||
|
elems = {}
|
||||||
|
w.reset(25, 12, "claw", function (ev)
|
||||||
|
if ev == "close" then
|
||||||
|
w.close()
|
||||||
|
running = false
|
||||||
|
end
|
||||||
|
end)
|
||||||
packageId = ent
|
packageId = ent
|
||||||
genCurrent = genPackage
|
genCurrent = genPackage
|
||||||
primaryWindowRegen()
|
primaryWindowRegen()
|
||||||
@ -302,10 +316,9 @@ function genPackage()
|
|||||||
primaryWindowRegen()
|
primaryWindowRegen()
|
||||||
end)
|
end)
|
||||||
}
|
}
|
||||||
local srcs = claw.getSources()
|
for k, v in ipairs(claw.sourceList) do
|
||||||
for k, v in ipairs(srcs) do
|
|
||||||
local lI = claw.getInfo(packageId, v[1])
|
local lI = claw.getInfo(packageId, v[1])
|
||||||
local row = 12 + k - #srcs
|
local row = 12 + k - #(claw.sourceList)
|
||||||
local pfx = " "
|
local pfx = " "
|
||||||
if lI then
|
if lI then
|
||||||
pfx = "v" .. string.format("%04i", lI.v) .. " "
|
pfx = "v" .. string.format("%04i", lI.v) .. " "
|
||||||
@ -327,7 +340,7 @@ end
|
|||||||
genCurrent = genPrimary
|
genCurrent = genPrimary
|
||||||
primaryWindow = neoux.create(primaryWindowRegenCore())
|
primaryWindow = neoux.create(primaryWindowRegenCore())
|
||||||
|
|
||||||
while windows > 0 do
|
while running do
|
||||||
event.pull()
|
event.pull()
|
||||||
end
|
end
|
||||||
claw.unlock()
|
claw.unlock()
|
||||||
|
@ -174,7 +174,8 @@ return {
|
|||||||
},
|
},
|
||||||
files = {
|
files = {
|
||||||
"apps/app-claw.lua",
|
"apps/app-claw.lua",
|
||||||
"libs/claw.lua"
|
"libs/app-claw-core.lua",
|
||||||
|
"libs/app-claw-csi.lua"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
["neo-meta"] = {
|
["neo-meta"] = {
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
-- This is released into the public domain.
|
-- This is released into the public domain.
|
||||||
-- No warranty is provided, implied or otherwise.
|
-- No warranty is provided, implied or otherwise.
|
||||||
|
|
||||||
-- claw: assistant to app-claw
|
-- app-claw-core: assistant to app-claw
|
||||||
-- should only ever be one app-claw at a time
|
-- should only ever be one app-claw at a time
|
||||||
|
-- USING THIS LIBRARY OUTSIDE OF APP-CLAW IS A BAD IDEA.
|
||||||
|
-- SO DON'T DO IT.
|
||||||
|
|
||||||
|
-- Also serves to provide a mutex.
|
||||||
|
|
||||||
local lock = false
|
local lock = false
|
||||||
|
|
||||||
return function ()
|
return function ()
|
||||||
if lock then
|
if lock then
|
||||||
error("libclaw safety lock in use")
|
error("libclaw safety lock in use")
|
||||||
@ -12,6 +18,7 @@ return function ()
|
|||||||
local sourceList = {}
|
local sourceList = {}
|
||||||
local sources = {}
|
local sources = {}
|
||||||
-- 1 2 3 4 5 6
|
-- 1 2 3 4 5 6
|
||||||
|
-- source ents: src dst index
|
||||||
-- dst entries: writeFile(fn), mkdir(fn), exists(fn), isDirectory(fn), remove(fn), rename(fna, fnb)
|
-- dst entries: writeFile(fn), mkdir(fn), exists(fn), isDirectory(fn), remove(fn), rename(fna, fnb)
|
||||||
-- writeFile(fn) -> function (data/nil to close)
|
-- writeFile(fn) -> function (data/nil to close)
|
||||||
local function saveInfo(dn)
|
local function saveInfo(dn)
|
||||||
@ -25,21 +32,78 @@ return function ()
|
|||||||
if not _ then return false, r end
|
if not _ then return false, r end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
local remove, installTo
|
local remove, installTo, expandCSI, compressCSI
|
||||||
|
local function expandS(v)
|
||||||
|
return v:sub(2, v:byte(1) + 1), v:sub(v:byte(1) + 2)
|
||||||
|
end
|
||||||
|
local function expandT(v)
|
||||||
|
local t = {}
|
||||||
|
local n = v:byte(1)
|
||||||
|
v = v:sub(2)
|
||||||
|
for i = 1, n do
|
||||||
|
t[i], v = expandS(v)
|
||||||
|
end
|
||||||
|
return t, v
|
||||||
|
end
|
||||||
|
local function compressT(x)
|
||||||
|
local b = string.char(#x)
|
||||||
|
for _, v in ipairs(x) do
|
||||||
|
b = b .. string.char(#v) .. v
|
||||||
|
end
|
||||||
|
return b
|
||||||
|
end
|
||||||
|
local function expandCSI(v)
|
||||||
|
local t = {}
|
||||||
|
local k
|
||||||
|
k, v = expandS(v)
|
||||||
|
t.desc, v = expandS(v)
|
||||||
|
t.v = (v:byte(1) * 256) + v:byte(2)
|
||||||
|
v = v:sub(3)
|
||||||
|
t.dirs, v = expandT(v)
|
||||||
|
t.files, v = expandT(v)
|
||||||
|
t.deps, v = expandT(v)
|
||||||
|
return k, t, v
|
||||||
|
end
|
||||||
|
local function compressCSI(k, v)
|
||||||
|
local nifo = string.char(#k) .. k
|
||||||
|
nifo = nifo .. string.char(math.min(255, #v.desc)) .. v.desc:sub(1, 255)
|
||||||
|
nifo = nifo .. string.char(math.floor(v.v / 256), v.v % 256)
|
||||||
|
nifo = nifo .. compressT(v.dirs)
|
||||||
|
nifo = nifo .. compressT(v.files)
|
||||||
|
nifo = nifo .. compressT(v.deps)
|
||||||
|
return nifo
|
||||||
|
end
|
||||||
|
local function findPkg(idx, pkg, del)
|
||||||
|
del = del and ""
|
||||||
|
idx = sources[idx][3]
|
||||||
|
while #idx > 0 do
|
||||||
|
local k, d
|
||||||
|
k, d, idx = expandCSI(idx)
|
||||||
|
if del then
|
||||||
|
if k == pkg then
|
||||||
|
return d, del .. idx
|
||||||
|
end
|
||||||
|
del = del .. compressCSI(k, d)
|
||||||
|
else
|
||||||
|
if k == pkg then return d end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
-- NOTE: Functions in this must return something due to the checked-call wrapper,
|
-- NOTE: Functions in this must return something due to the checked-call wrapper,
|
||||||
-- but should all use error() for consistency.
|
-- but should all use error() for consistency.
|
||||||
-- Operations
|
-- Operations
|
||||||
installTo = function (dstName, pkg, srcName, checked, yielder)
|
installTo = function (dstName, pkg, srcName, checked, yielder)
|
||||||
local installed = {pkg}
|
|
||||||
local errs = {}
|
local errs = {}
|
||||||
if srcName == dstName then
|
if srcName == dstName then
|
||||||
error("Invalid API use")
|
error("Invalid API use")
|
||||||
end
|
end
|
||||||
-- preliminary checks
|
-- preliminary checks
|
||||||
|
local srcPkg = findPkg(srcName, pkg, false)
|
||||||
|
assert(srcPkg)
|
||||||
if checked then
|
if checked then
|
||||||
for _, v in ipairs(sources[srcName][3][pkg].deps) do
|
for _, v in ipairs(srcPkg.deps) do
|
||||||
if not sources[dstName][3][v] then
|
if not findPkg(dstName, v) then
|
||||||
if not sources[srcName][3][v] then
|
if not findPkg(srcName, v) then
|
||||||
table.insert(errs, pkg .. " depends on " .. v .. "\n")
|
table.insert(errs, pkg .. " depends on " .. v .. "\n")
|
||||||
elseif #errs == 0 then
|
elseif #errs == 0 then
|
||||||
installTo(dstName, v, srcName, checked, yielder)
|
installTo(dstName, v, srcName, checked, yielder)
|
||||||
@ -51,12 +115,14 @@ return function ()
|
|||||||
end
|
end
|
||||||
-- Files from previous versions to get rid of
|
-- Files from previous versions to get rid of
|
||||||
local ignFiles = {}
|
local ignFiles = {}
|
||||||
if sources[dstName][3][pkg] then
|
local oldDst = findPkg(dstName, pkg)
|
||||||
for _, v in ipairs(sources[dstName][3][pkg].files) do
|
if oldDst then
|
||||||
|
for _, v in ipairs(oldDst.files) do
|
||||||
ignFiles[v] = true
|
ignFiles[v] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _, v in ipairs(sources[srcName][3][pkg].files) do
|
oldDst = nil
|
||||||
|
for _, v in ipairs(srcPkg.files) do
|
||||||
if not ignFiles[v] then
|
if not ignFiles[v] then
|
||||||
if sources[dstName][2][3](v) then
|
if sources[dstName][2][3](v) then
|
||||||
table.insert(errs, v .. " already exists (corrupt system?)")
|
table.insert(errs, v .. " already exists (corrupt system?)")
|
||||||
@ -66,13 +132,13 @@ return function ()
|
|||||||
if #errs > 0 then
|
if #errs > 0 then
|
||||||
error(table.concat(errs))
|
error(table.concat(errs))
|
||||||
end
|
end
|
||||||
for _, v in ipairs(sources[srcName][3][pkg].dirs) do
|
for _, v in ipairs(srcPkg.dirs) do
|
||||||
sources[dstName][2][2](v)
|
sources[dstName][2][2](v)
|
||||||
if not sources[dstName][2][4](v) then
|
if not sources[dstName][2][4](v) then
|
||||||
error("Unable to create directory " .. v)
|
error("Unable to create directory " .. v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _, v in ipairs(sources[srcName][3][pkg].files) do
|
for _, v in ipairs(srcPkg.files) do
|
||||||
local tmpOut, r, ok = sources[dstName][2][1](v .. ".claw-tmp")
|
local tmpOut, r, ok = sources[dstName][2][1](v .. ".claw-tmp")
|
||||||
ok = tmpOut
|
ok = tmpOut
|
||||||
if ok then
|
if ok then
|
||||||
@ -82,31 +148,40 @@ return function ()
|
|||||||
yielder()
|
yielder()
|
||||||
else
|
else
|
||||||
-- Cleanup...
|
-- Cleanup...
|
||||||
for _, v in ipairs(sources[srcName][3][pkg].files) do
|
for _, v in ipairs(srcPkg.files) do
|
||||||
sources[dstName][2][5](v .. ".claw-tmp")
|
sources[dstName][2][5](v .. ".claw-tmp")
|
||||||
end
|
end
|
||||||
error(r)
|
error(r)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- PAST THIS POINT, ERRORS CORRUPT!
|
-- PAST THIS POINT, ERRORS CORRUPT!
|
||||||
sources[dstName][3][pkg] = nil
|
-- Remove package from DB
|
||||||
|
local oldDst2, oldDst3 = findPkg(dstName, pkg, true)
|
||||||
|
sources[dstName][3] = oldDst3 or sources[dstName][3]
|
||||||
|
oldDst2, oldDst3 = nil
|
||||||
saveInfo(dstName)
|
saveInfo(dstName)
|
||||||
|
-- Delete old files
|
||||||
for k, _ in pairs(ignFiles) do
|
for k, _ in pairs(ignFiles) do
|
||||||
yielder()
|
yielder()
|
||||||
sources[dstName][2][5](k)
|
sources[dstName][2][5](k)
|
||||||
end
|
end
|
||||||
for _, v in ipairs(sources[srcName][3][pkg].files) do
|
-- Create new files
|
||||||
|
for _, v in ipairs(srcPkg.files) do
|
||||||
yielder()
|
yielder()
|
||||||
sources[dstName][2][6](v .. ".claw-tmp", v)
|
sources[dstName][2][6](v .. ".claw-tmp", v)
|
||||||
end
|
end
|
||||||
sources[dstName][3][pkg] = sources[srcName][3][pkg]
|
-- Insert into DB
|
||||||
|
sources[dstName][3] = sources[dstName][3] .. compressCSI(pkg, srcPkg)
|
||||||
saveInfo(dstName)
|
saveInfo(dstName)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
remove = function (dstName, pkg, checked)
|
remove = function (dstName, pkg, checked)
|
||||||
if checked then
|
if checked then
|
||||||
local errs = {}
|
local errs = {}
|
||||||
for dpsName, dpsV in pairs(sources[dstName][3]) do
|
local buf = sources[dstName][3]
|
||||||
|
while #buf > 0 do
|
||||||
|
local dpsName, dpsV
|
||||||
|
dpsName, dpsV, buf = expandCSI(buf)
|
||||||
for _, v in ipairs(dpsV.deps) do
|
for _, v in ipairs(dpsV.deps) do
|
||||||
if v == pkg then
|
if v == pkg then
|
||||||
table.insert(errs, dpsName .. " depends on " .. pkg .. "\n")
|
table.insert(errs, dpsName .. " depends on " .. pkg .. "\n")
|
||||||
@ -117,10 +192,12 @@ return function ()
|
|||||||
return nil, table.concat(errs)
|
return nil, table.concat(errs)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _, v in ipairs(sources[dstName][3][pkg].files) do
|
local dstPkg, nbuf = findPkg(dstName, pkg, true)
|
||||||
|
assert(dstPkg, "Package wasn't installed")
|
||||||
|
for _, v in ipairs(dstPkg.files) do
|
||||||
sources[dstName][2][5](v)
|
sources[dstName][2][5](v)
|
||||||
end
|
end
|
||||||
sources[dstName][3][pkg] = nil
|
sources[dstName][3] = nbuf
|
||||||
saveInfo(dstName)
|
saveInfo(dstName)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -128,50 +205,39 @@ return function ()
|
|||||||
-- Gets the latest info, or if given a source just gives that source's info.
|
-- Gets the latest info, or if given a source just gives that source's info.
|
||||||
-- Do not modify output.
|
-- Do not modify output.
|
||||||
getInfo = function (pkg, source, oldest)
|
getInfo = function (pkg, source, oldest)
|
||||||
if source then return sources[source][3][pkg] end
|
if source then return findPkg(source, pkg) end
|
||||||
local bestI = {
|
local bestI = {
|
||||||
v = -1,
|
v = -1,
|
||||||
desc = "An unknown package.",
|
desc = "An unknown package.",
|
||||||
deps = {}
|
deps = {}
|
||||||
}
|
}
|
||||||
if oldest then bestI.v = 10000 end
|
if oldest then bestI.v = 10000 end
|
||||||
for _, v in pairs(sources) do
|
for k, v in pairs(sources) do
|
||||||
if v[3][pkg] then
|
local pkgv = findPkg(k, pkg)
|
||||||
if ((not oldest) and (v[3][pkg].v > bestI.v)) or (oldest and (v[3][pkg].v > bestI.v)) then
|
if pkgv then
|
||||||
bestI = v[3][pkg]
|
if ((not oldest) and (pkgv.v > bestI.v)) or (oldest and (pkgv.v > bestI.v)) then
|
||||||
|
bestI = pkgv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return bestI
|
return bestI
|
||||||
end,
|
end,
|
||||||
-- Provides an ordered list of sources, with writable.
|
sources = sources,
|
||||||
-- Do not modify output.
|
sourceList = sourceList,
|
||||||
getSources = function ()
|
|
||||||
return sourceList
|
|
||||||
end,
|
|
||||||
-- NOTE: If a source is writable, it's added anyway despite any problems.
|
|
||||||
addSource = function (name, src, dst)
|
|
||||||
local ifo = ""
|
|
||||||
local ifok, e = src("data/app-claw/local.lua", function (t)
|
|
||||||
ifo = ifo .. (t or "")
|
|
||||||
return true
|
|
||||||
end)
|
|
||||||
e = e or "local.lua parse error"
|
|
||||||
ifo = ifok and require("serial").deserialize(ifo)
|
|
||||||
if not (dst or ifo) then return false, e end
|
|
||||||
table.insert(sourceList, {name, not not dst})
|
|
||||||
sources[name] = {src, dst, ifo or {}}
|
|
||||||
return not not ifo, e
|
|
||||||
end,
|
|
||||||
remove = remove,
|
remove = remove,
|
||||||
installTo = installTo,
|
installTo = installTo,
|
||||||
|
expandCSI = expandCSI,
|
||||||
|
compressCSI = compressCSI,
|
||||||
|
|
||||||
-- Gets a total list of packages, as a table of strings. You can modify output.
|
-- Gets a total list of packages, as a table of strings. You can modify output.
|
||||||
getList = function ()
|
getList = function ()
|
||||||
local n = {}
|
local n = {}
|
||||||
local seen = {}
|
local seen = {}
|
||||||
for k, v in pairs(sources) do
|
for k, v in pairs(sources) do
|
||||||
for kb, vb in pairs(v[3]) do
|
local p3 = v[3]
|
||||||
|
while #p3 > 0 do
|
||||||
|
local kb, _, nx = expandCSI(p3)
|
||||||
|
p3 = nx
|
||||||
if not seen[kb] then
|
if not seen[kb] then
|
||||||
seen[kb] = true
|
seen[kb] = true
|
||||||
table.insert(n, kb)
|
table.insert(n, kb)
|
28
code/libs/app-claw-csi.lua
Normal file
28
code/libs/app-claw-csi.lua
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-- This is released into the public domain.
|
||||||
|
-- No warranty is provided, implied or otherwise.
|
||||||
|
|
||||||
|
-- app-claw-csi: addSource function
|
||||||
|
-- USING THIS LIBRARY OUTSIDE OF APP-CLAW IS A BAD IDEA.
|
||||||
|
-- SO DON'T DO IT.
|
||||||
|
|
||||||
|
-- NOTE: If a source is writable, it's added anyway despite any problems.
|
||||||
|
return function (claw, name, src, dst)
|
||||||
|
local ifo = ""
|
||||||
|
local ifok, e = src("data/app-claw/local.lua", function (t)
|
||||||
|
ifo = ifo .. (t or "")
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
e = e or "local.lua parse error"
|
||||||
|
ifo = ifok and require("serial").deserialize(ifo)
|
||||||
|
if not (dst or ifo) then return false, e end
|
||||||
|
table.insert(claw.sourceList, {name, not not dst})
|
||||||
|
local nifo = ifo or ""
|
||||||
|
if type(nifo) == "table" then
|
||||||
|
nifo = ""
|
||||||
|
for k, v in pairs(ifo) do
|
||||||
|
nifo = nifo .. claw.compressCSI(k, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
claw.sources[name] = {src, dst, nifo}
|
||||||
|
return not not ifo, e
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user