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" "libgpu","libevent","simple_data_structure"
} }
}, },
["shrink"]={
title="Shrink",
info="Shrink string by removing useless spaces.",
files={
"shrink.lua"
}
},
["drone"]={ ["drone"]={
title="Drone", title="Drone",
info="Drone console and bios", info="Drone console and bios",
@ -65,10 +72,12 @@
contact="1362050620@qq.com", contact="1362050620@qq.com",
files={ files={
["programs/drone/drone_bios.lua"]="drone_bios.lua", ["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={ requires={
"libevent" "libevent", "shrink"
} }
}, },
["smartstorage"]={ ["smartstorage"]={

View File

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

View File

@ -108,7 +108,7 @@ function helper.setRadar(enable)
end end
helper.target_drone='' helper.target_drone=''
function helper.install_step1() 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 while true do
local e=WaitEvent(5,"modem_message") local e=WaitEvent(5,"modem_message")
if(e==nil) then if(e==nil) then
@ -126,8 +126,12 @@ function helper.install_step1()
return false return false
end end
helper.drone_lib=[==[ 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." return drone_lib_version .. " successfully installed."
]==] ]==]
function helper.install_step2() 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) SetResponse("[Local] Install step 2: About to perform installation on " .. helper.target_drone)
os.sleep(1) os.sleep(1)
SetResponse("[Local] Install step 2: Sending data to " .. helper.target_drone) 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
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)