Drone package update

Drone Console: fix bugs. better helper library. (function move added)
Drone Bios: fix wait() bugs. smaller and more readable core.
Drone Radar: a radar program which can track multiple drones.
Drone Flash: Drone BIOS flash program. Better than `flash`. Shrink code.
This commit is contained in:
Kirigaya Kazuto 2018-11-30 03:05:33 +08:00
parent 546ecf39a1
commit 360678c75d
5 changed files with 247 additions and 57 deletions

View File

@ -58,6 +58,13 @@
"libgpu","libevent","simple_data_structure"
}
},
["shrink"]={
title="Shrink",
info="Shrink string by removing useless spaces.",
files={
"shrink.lua"
}
},
["drone"]={
title="Drone",
info="Drone console and bios",
@ -65,10 +72,12 @@
contact="1362050620@qq.com",
files={
["programs/drone/drone_bios.lua"]="drone_bios.lua",
["programs/drone/drone_console.lua"]="drone_console.lua"
["programs/drone/drone_console.lua"]="drone_console.lua",
["programs/drone/drone_radar.lua"]="drone_radar.lua",
["programs/drone/drone_flash.lua"]="drone_flash.lua"
},
requires={
"libevent"
"libevent", "shrink"
}
},
["smartstorage"]={

View File

@ -1,6 +1,6 @@
drone_version="Drone v3.3b"
drone=component.proxy(component.list("drone")())
modem=component.proxy(component.list("modem")())
drone_version="Drone v3.2"
drone.setStatusText(drone_version .. '\n' .. modem.address)
modem.open(98)
handlers={}
@ -8,39 +8,67 @@ timers={}
wake_list={}
handlers["_anything"]={}
handle_event=function(e)
if(handlers[e[1]]) then for i,tb in pairs(handlers[e[1]]) do coroutine.resume(tb.co,i,e) end end
for i,tb in pairs(handlers["_anything"]) do coroutine.resume(tb.co,i,e) end
if(handlers[e[1]]) then
for i,tb in pairs(handlers[e[1]]) do
coroutine.resume(tb.co,i,e)
end
end
for i,tb in pairs(handlers["_anything"]) do
coroutine.resume(tb.co,i,e)
end
end
sleep=function(sec)
local this,flag=coroutine.running()
table.insert(wake_list,{id=0,tm=computer.uptime()+sec,co=this})
local this_id=coroutine.yield()
table.remove(wake_list,this_id)
table.insert(wake_list,{id=0,tm=computer.uptime()+sec,co=coroutine.running()})
table.remove(wake_list,coroutine.yield())
end
cancel=function(id)
if(timers[id]) then for i,t in ipairs(wake_list) do if(t.id==id) then table.remove(wake_list,i) break end end timers[id]=nil return true
else return false end
cancel=function(id,wid)
if(wid) then
table.remove(wake_list,wid)
else
for i,t in ipairs(wake_list) do
if(t.id==id) then
table.remove(wake_list,i)
break
end
end
end
if(timers[id]) then
timers[id]=nil
return true
else
return false
end
end
timer=function(sec,fn,times)
local next=computer.uptime()+sec
local id=table.insert(timers,{cb=fn,intv=sec,times=times})
table.insert(wake_list,{tm=next,id=id,co=coroutine.create(function(this_id)
table.insert(timers,{cb=fn,intv=sec,times=times})
local id=#timers
table.insert(wake_list,{tm=computer.uptime()+sec,id=id,co=coroutine.create(function(wid)
while true do
pcall(fn)
local this_tb=timers[this.id]
if(this_tb.times>0) then this_tb.times=this_tb.times-1
if(this_tb.times<1) then timer[wake_list[this_id].id]=nil table.remove(wake_list,this_id) return
else this.tm=computer.uptime()+this_tb.intv this_id=coroutine.yield() end
pcall(fn)
local tb=timers[id]
if(tb.times<0 or tb.times>1) then
tb.times,tb.tm=tb.times-1,computer.uptime()+tb.intv
wid=coroutine.yield()
else
cancel(id,wid)
return
end
end
end)})
return id
end
ignore=function(name,id)
handlers[name][id]=nil
if(handlers[name][id]) then
handlers[name][id]=nil
return true
else
return false
end
end
listen=function(name,cb)
if(handlers[name]==nil) then handlers[name]={} end
if(handlers[name]==nil) then
handlers[name]={}
end
table.insert(handlers[name],{co=coroutine.create(function(i,e)
while true do
local ok,res=pcall(cb,e)
@ -54,28 +82,27 @@ listen=function(name,cb)
return #handlers[name]
end
wait=function(sec,name)
if(sec==nil and name==nil) then sec=-1
elseif(sec==nil and name~=nil) then sec=-1
elseif(sec~=nil and name==nil) then if(type(sec)=="string") then name=sec sec=-1 end end
local this,flag=coroutine.running()
if(sec>=0) then
table.insert(wake_list,{id=0,tm=computer.uptime()+sec,co=this})
else
table.insert(wake_list,{id=0,tm=math.huge,co=this})
end
local id
if(name~=nil) then
id=listen(name,function(e) if(e[1]==name) then coroutine.resume(this,-1,e) return false end end)
else
id=listen("_anything",function(e) coroutine.resume(this,-1,e) return false end)
end
local this_id,e=coroutine.yield()
if(this_id==-1) then
for idx,t in ipairs(wake_list) do if(t.co==this) then table.remove(wake_list,idx) end end
if(name==nil and type(sec)=="string") then name=sec sec=nil end
sec=sec and computer.uptime()+sec or math.huge
local this=coroutine.running()
table.insert(wake_list,{id=0,tm=sec,co=this})
name=name or "_anything"
local id=listen(name,function(e)
coroutine.resume(this,-1,e)
return false
end)
local wid,e=coroutine.yield()
ignore(name,id)
if(wid==-1) then
for i,t in ipairs(wake_list) do
if(t.co==this) then
table.remove(wake_list,i)
break
end
end
return e
else
ignore(id)
table.remove(wake_list,this_id)
table.remove(wake_list,wid)
return nil
end
end
@ -83,25 +110,26 @@ listen("modem_message",function(e)
local snd=e[3]
local tag=e[6]
local cmd=e[7]
if(tag~=nil and cmd~=nil and tag=='execute_command') then
local ok,err=pcall(function()
local f=load(cmd)
local cmdok,cmdresult=pcall(f)
if(not cmdok) then
modem.send(snd,99,"Failed to execute: " .. cmdresult)
if(tag and tag=='execute_command' and cmd) then
local f,err=load(cmd)
if(f) then
local ok,err=pcall(f)
if(not ok) then
modem.send(snd,99,"CallError: " .. res)
else
modem.send(snd,99,cmdresult)
modem.send(snd,99,res)
end
end)
if(not ok) then
modem.send(snd,99,"Command Execute Failed: " .. err)
else
modem.send(snd,99,"SyntaxError: " .. err)
end
end
end)
while true do
local max_wait,max_id=math.huge,0
for i,v in ipairs(wake_list) do
if(v.tm<max_wait) then max_wait,max_id=v.tm,i end
if(v.tm<max_wait) then
max_wait,max_id=v.tm,i
end
end
local e
if(max_wait==math.huge) then

View File

@ -108,7 +108,7 @@ function helper.setRadar(enable)
end
helper.target_drone=''
function helper.install_step1()
modem.broadcast(98,"modem.send('" .. modem.address .. "',99,'hide_msg','prepare_for_install')")
modem.broadcast(98,"execute_command","modem.send('" .. modem.address .. "',99,'hide_msg','prepare_for_install')")
while true do
local e=WaitEvent(5,"modem_message")
if(e==nil) then
@ -126,8 +126,12 @@ function helper.install_step1()
return false
end
helper.drone_lib=[==[
drone_lib_version='DroneLib v0.1'
drone_lib_version='DroneLib v0.1.1'
move=function(x,y,z,t)
t=t or 5
drone.move(x,y,z)
while drone.getOffset()>1 do sleep(t) end
end
return drone_lib_version .. " successfully installed."
]==]
function helper.install_step2()
@ -135,7 +139,7 @@ function helper.install_step2()
SetResponse("[Local] Install step 2: About to perform installation on " .. helper.target_drone)
os.sleep(1)
SetResponse("[Local] Install step 2: Sending data to " .. helper.target_drone)
modem.send(helper.target_drone,98,helper.drone_lib)
modem.send(helper.target_drone,98,"execute_command",helper.drone_lib)
end
end

View File

@ -0,0 +1,44 @@
-- Drone Flash
-- Created by Kiritow
local component=require('component')
local shrink=require('shrink')
require('libevent')
print("Please insert new eeprom. (Or press Ctrl+C if the eeprom is already inserted.)")
while true do
local e=WaitMultipleEvent("interrupted","component_added")
if(e.event=="interrupted" or (e.event=="component_added" and e.componentType=="eeprom")) then
break
end
end
print("[Working] Reading drone bios from disk...")
local f=io.open("drone_bios.lua","r")
if(not f) then
print("[Error] Unable to open drone_bios.lua.")
return
end
local data=f:read("a")
f:close()
print("Original data size: " .. string.len(data))
print("[Working] Syntax checking...")
local xt={}
local fn,err=load(data,"DroneBios","t",xt)
if(not fn) then
print("Found syntax error: " .. err)
return
end
print("[Working] Getting DroneBios version...")
pcall(fn)
local drone_bios_version=xt['drone_version']
if(not drone_bios_version) then
print("[Error] Unable to get version tag.")
return
end
print("Version tag: " .. drone_bios_version)
print("[Working] Shrinking...")
data=shrink(data)
print("Shrank data size: " .. string.len(data))
print("[Working] Writing to eeprom...")
component.eeprom.set(data)
print("[Working] Setting eeprom label...")
component.eeprom.setLabel(drone_bios_version)
print("[Done] Remember to insert the original eeprom!")

View File

@ -0,0 +1,105 @@
-- Drone Radar
-- Created by Kiritow.
local component=require('component')
local computer=require('computer')
local term=require('term')
local text=require('text')
require("libevent")
local radar_version="Drone Radar v0.1.3"
local modem=component.modem
local gpu=term.gpu()
local function status(msg)
local w,h=gpu.getResolution()
gpu.set(1,h,"Status: " .. msg)
end
term.clear()
print("Drone Radar")
print("Checking hardware...")
if(modem==nil) then
print("This program requires a modem component to work")
return
end
print("Opening modem port...")
if(not modem.open(99)) then
if(modem.isOpen(99)) then
print("Port 99 is already opened.")
else
print("Unable to open port 99.")
return
end
end
print("Adding timer...")
local broadcast_intv=8
local timer=AddTimer(broadcast_intv,function()
modem.broadcast(98,"execute_command","modem.send('" .. modem.address .. "',99,'radar_info',drone.getOffset(),computer.energy())")
end,-1)
print("Adding listener...")
local tb_drone={}
local listener=AddEventListener("modem_message",function(e)
if(e.port==99 and e.data[1]=='radar_info') then
tb_drone[e.senderAddress]={
distance=e.distance,
offset=e.data[2],
energy=e.data[3],
update=computer.uptime()
}
PushEvent("radar_gui_update")
end
end)
local function show_tb(tb)
local maxLen={}
for idx,v in ipairs(tb) do
for nidx,val in ipairs(v) do
if(not maxLen[nidx] or maxLen[nidx]<string.len(val)) then
maxLen[nidx]=string.len(val)
end
end
end
for idx,v in ipairs(tb) do
for nidx,val in ipairs(v) do
v[nidx]=text.padRight(val,maxLen[nidx])
end
print(table.concat(v," "))
end
end
term.clear()
print(radar_version)
while true do
term.setCursor(1,2)
local now=computer.uptime()
local show={}
table.insert(show,{"Address","Status","Distance","Offset","Energy"})
for addr,tb in pairs(tb_drone) do
local newt={string.sub(addr,1,8),"[Missing]",string.format("%.1f",tb.distance),string.format("%.1f",tb.offset),string.format("%.1f",tb.energy)}
if(now-tb.update<broadcast_intv) then
if(tb.offset<1) then
newt[2]="[OK]"
else
newt[2]="[Flying]"
end
end
table.insert(show,newt)
if(now-tb.update>broadcast_intv*2.5) then
tb_drone[addr]=nil
end
end
show_tb(show)
local e=WaitMultipleEvent("interrupted","radar_gui_update")
if(e.event=="interrupted") then break end
end
term.clear()
print("Stopping listener...")
RemoveEventListener(listener)
print("Stopping timer...")
RemoveTimer(timer)
print("Closing port...")
modem.close(99)