svc-virtudev: virtual devices for KittenOS NEO

This commit is contained in:
20kdc 2020-03-28 00:32:16 +00:00
parent 7680aa7579
commit fab88f137c
6 changed files with 239 additions and 6 deletions

View File

@ -251,6 +251,24 @@ return {
"docs/repoauthors/app-slaunch"
},
},
["svc-virtudev"] = {
desc = "a clone of vcomponent",
v = 0,
deps = {
"neo",
"zzz-license-pd"
},
dirs = {
"apps",
"docs",
"docs/repoauthors"
},
files = {
"apps/svc-virtudev.lua",
"apps/app-vdrslamp.lua",
"docs/repoauthors/svc-virtudev"
},
},
-- libraries
["lib-knbs"] = {
desc = "NBS reader/writer library",

View File

@ -6,9 +6,5 @@
cp ocemu.cfg.default ocemu.cfg && rm -rf c1-sda c1-sdb
mkdir c1-sda c1-sdb
echo -n c1-sda > c1-eeprom/data.bin
cd ..
cp -r code/* laboratory/c1-sdb/
cp -r repository/* laboratory/c1-sdb/
lua claw/clawconv.lua laboratory/c1-sdb/data/app-claw/ < claw/code-claw.lua > /dev/null
lua claw/clawconv.lua laboratory/c1-sdb/data/app-claw/ < claw/repo-claw.lua >> /dev/null
cp -r laboratory/c1-sdb/* laboratory/c1-sda/
./update.sh

11
laboratory/update.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
# This is released into the public domain.
# No warranty is provided, implied or otherwise.
cd ..
cp -r code/* laboratory/c1-sdb/
cp -r repository/* laboratory/c1-sdb/
lua claw/clawconv.lua laboratory/c1-sdb/data/app-claw/ < claw/code-claw.lua > /dev/null
lua claw/clawconv.lua laboratory/c1-sdb/data/app-claw/ < claw/repo-claw.lua >> /dev/null
cp -r laboratory/c1-sdb/* laboratory/c1-sda/

View File

@ -0,0 +1,49 @@
-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
-- svc-vdrslamp.lua : Virtual Redstone Lamp
-- Authors: 20kdc
local vdev = neo.requireAccess("x.svc.virtudev", "lamp dev")
local evr = neo.requireAccess("x.neo.pub.window", "the lamp")
local wnd = evr(12, 6)
local bLine = (" "):rep(12)
local function blank()
return 0
end
local total = 0
vdev.install({
type = "redstone",
address = "vdrslamp-" .. neo.pid,
slot = 0,
getWakeThreshold = blank,
setWakeThreshold = blank,
getInput = blank,
getOutput = function (i)
return total
end,
setOutput = function (i, v)
total = v
wnd.setSize(12, 6)
end
})
while true do
local e = {coroutine.yield()}
if e[1] == "x.neo.pub.window" then
if e[3] == "close" then
-- the ignorance of unregistration is deliberate
-- a working impl. will properly recover
return
elseif e[3] == "line" then
local bg = 0xFFFFFF
if total == 0 then bg = 0 end
wnd.span(1, e[4], bLine, bg, bg)
end
end
end

View File

@ -0,0 +1,156 @@
-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
-- svc-virtudev.lua : Virtual Device interface
-- Authors: 20kdc
local ic = neo.requireAccess("x.neo.pub.base", "to lock x.svc.virtudev")
-- this is a pretty powerful permission, and PROBABLY EXPLOITABLE
ic.lockPerm("x.svc.virtudev")
local r = neo.requireAccess("r.svc.virtudev", "api endpoint")
local root = neo.requireAccess("k.root", "the ability to modify the component API")
local proxies = {}
local types = {}
local function uninstall(k)
proxies[k] = nil
types[k] = nil
root.computer.pushSignal("component_removed", k, types[k])
end
local users = {}
local userCount = 0
r(function (pkg, pid, sendSig)
local userAddresses = {}
users[pid] = userAddresses
userCount = userCount + 1
return {
install = function (proxy)
local proxyAddress = proxy.address
local proxyType = proxy.type
assert(type(proxyAddress) == "string")
assert(type(proxyType) == "string")
assert(not proxies[proxyAddress], "proxy address in use: " .. proxyAddress)
proxies[proxyAddress] = proxy
types[proxyAddress] = proxyType
userAddresses[proxyAddress] = true
root.computer.pushSignal("component_added", proxyAddress, proxyType)
return function (a, ...)
root.computer.pushSignal(a, proxyAddress, ...)
end
end,
uninstall = function (k)
if userAddresses[k] then
uninstall(k)
userAddresses[k] = nil
end
end
}
end)
local componentProxyRaw = root.component.proxy
local componentTypeRaw = root.component.type
local componentMethodsRaw = root.component.methods
local componentFieldsRaw = root.component.fields
local componentDocRaw = root.component.doc
local componentInvokeRaw = root.component.invoke
local componentListRaw = root.component.list
root.component.proxy = function (address)
if proxies[address] then
return proxies[address]
end
return componentProxyRaw(address)
end
root.component.type = function (address)
if types[address] then
return types[address]
end
return componentTypeRaw(address)
end
local function methodsFieldsHandler(address, methods)
if proxies[address] then
local mt = {}
for k, v in pairs(proxies[address]) do
if (type(v) == "function") == methods then
mt[k] = true
end
end
return mt
end
if methods then
return componentMethodsRaw(address)
else
return componentFieldsRaw(address)
end
end
root.component.methods = function (address) return methodsFieldsHandler(address, true) end
root.component.fields = function (address) return methodsFieldsHandler(address, false) end
root.component.doc = function (address, method)
if proxies[address] then
return tostring(proxies[address][method])
end
return componentDocRaw(address, method)
end
root.component.invoke = function (address, method, ...)
if proxies[address] then
return proxies[address][method](...)
end
return componentInvokeRaw(address, method, ...)
end
root.component.list = function (f, e)
local iter = componentListRaw(f, e)
local ended = false
local others = {}
for k, v in pairs(types) do
if (f == v) or ((not e) and v:find(f, 1, true)) then
table.insert(others, {k, v})
end
end
return function ()
if not ended then
local a, t = iter()
if not a then
ended = true
else
return a, t
end
end
-- at end of that, so what about others
local ent = table.remove(others, 1)
if ent then
return table.unpack(ent)
end
end
end
while true do
local e1, e2, e3 = coroutine.yield()
if e1 == "k.procdie" then
if users[e3] then
for k, _ in pairs(users[e3]) do
uninstall(k)
end
users[e3] = nil
userCount = userCount - 1
if userCount == 0 then
break
end
end
end
end
root.component.proxy = componentProxyRaw
root.component.type = componentTypeRaw
root.component.methods = componentMethodsRaw
root.component.fields = componentFieldsRaw
root.component.doc = componentDocRaw
root.component.invoke = componentInvokeRaw
root.component.list = componentListRaw

View File

@ -0,0 +1,3 @@
repository/apps/svc-virtudev.lua: 20kdc, Public Domain
repository/apps/app-vdrslamp.lua: 20kdc, Public Domain