青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 505  文章 - 1034  trackbacks - 0
<2008年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910


子曾經(jīng)曰過(guò):編程無(wú)他,唯手熟爾!

常用鏈接

留言簿(94)

隨筆分類(649)

隨筆檔案(505)

相冊(cè)

BCB

Crytek

  • crymod
  • Crytek's Offical Modding Portal

Game Industry

OGRE

other

Programmers

Qt

WOW Stuff

搜索

  •  

積分與排名

  • 積分 - 921912
  • 排名 - 14

最新隨筆

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

現(xiàn)在做網(wǎng)絡(luò)游戲項(xiàng)目,很多東西策劃經(jīng)常變,比如懸浮提示之類的,寫在c++代碼里的,改了每次都得編譯一下,很痛苦!
所以現(xiàn)在很多游戲邏輯都放在lua腳本里面(準(zhǔn)確的說(shuō)是嵌在xml里面的lua),但是沒(méi)法單步調(diào)試了,只能靠打日志和注釋掉某行的做法來(lái)定位問(wèn)題,又很痛苦了!今天搜到了一個(gè)東東,那個(gè)驚喜啊!

Lua 簡(jiǎn)易調(diào)試器


云風(fēng)大哥寫的,果然牛人啊!現(xiàn)在我沒(méi)空看,先放到這兒,有空了研究下!嘿嘿
 一個(gè)簡(jiǎn)單的調(diào)試系統(tǒng):

---------------------------
--  bp.lua
---------------------------
 
local type=type
local tostring=tostring
local print=print
local setmetatable=setmetatable
local getfenv=getfenv
local ipairs=ipairs
local pairs=pairs
local xpcall=xpcall
local error=error
 
local table_insert=table.insert
local table_concat=table.concat
local debug=debug
 
module "bp"
 
local nil_value={}
 
local function traversal_r(tbl,num)
num = num or 64
local ret={}
local function insert(v)
table_insert(ret,v)
if #ret>num then
error()
end
end
local function traversal(e)
if e==nil_value or e==nil then
insert("nil,")
elseif type(e)=="table" then
insert("{")
local maxn=0
for i,v in ipairs(e) do
traversal(v)
maxn=i
end
for k,v in pairs(e) do
if not (type(k)=="number" and k>0 and k<=maxn) then
if type(k)=="number" then
insert("["..k.."]=")
else
insert(tostring(k).."=")
end
traversal(v)
end
end
insert("}")
elseif type(e)=="string" then
insert('"'..e..'",')
else
insert(tostring(e))
insert(",")
end
end
 
local err=xpcall(
function() traversal(tbl) end,
function() end
)
if not err then
table_insert(ret,"...")
end
 
return table_concat(ret)
end
 
function print_r(tbl,num)
print(traversal_r(tbl,num))
end
 
local function init_local(tbl,level)
local n=1
local index={}
while true do
local name,value=debug.getlocal(level,n)
if not name then
break
end
 
if name~="(*temporary)" then
if value==nil then
value=nil_value
end
tbl[name]=value
index["."..name]=n
end
 
n=n+1
end
setmetatable(tbl,{__index=index})
return tbl
end
 
local function init_upvalue(tbl,func)
local n=1
local index={}
while true do
local name,value=debug.getupvalue(func,n)
if not name then
break
end
 
if value==nil then
value=nil_value
end
tbl[name]=value
index["."..name]=n
 
n=n+1
end
setmetatable(tbl,{__index=index})
return tbl
end
 
 
function dbg(level)
level=level and level+2 or 2
 
local lv=init_local({},level+1)
local func=debug.getinfo(level,"f").func
local uv=init_upvalue({},func)
local _L={}
setmetatable(_L,{
__index=function(_,k)
local ret=lv[k]
return ret~=nil_value and ret or nil
end,
__newindex=function(_,k,v)
if lv[k] then
lv[k]= v~= nil and nil_value or v
debug.setlocal(level+3,lv["."..k],v)
else
print("error:invalid local name:",k)
end
end,
__tostring=function(_)
return traversal_r(lv)
end
})
print("_L=",traversal_r(lv))
local _U={}
setmetatable(_U,{
__index=function(_,k)
local ret=uv[k]
return ret~=nil_value and ret or nil
end,
__newindex=function(_,k,v)
if uv[k] then
uv[k]= v~= nil and nil_value or v
debug.setupvalue(func,uv["."..k],v)
else
print("error:invalid upvalue name",k)
end
end,
__tostring=function(_)
return traversal_r(uv)
end
})
print("_U=",traversal_r(uv))
 
local _G=getfenv(level)
_G._L,_G._U=_L,_U
debug.debug()
_G._L,_G._U=nil,nil
end
 
 
local _bp_list={}
local _bp_desc={}
 
local function bp_list_name(name)
local t=type(_bp_desc[name])
print("["..name.."]",_bp_list[name] and "on" or "off")
if t=="table" then
for _,v in ipairs(_bp_desc[name]) do
print("----",v)
end
elseif t=="string" then
print("---",_bp_desc[name])
end
end
 
local function bp_list(name)
if name then
bp_list_name(name)
else
for k,v in pairs(_bp_list) do
bp_list_name(k)
end
end
end
 
local _bp_unnamed={}
local _bp_unnamed_desc={}
local _bp_unnamed_index={}
local _bp_index=1
do
local weak={__mode="kv"}
setmetatable(_bp_unnamed,weak)
setmetatable(_bp_unnamed_desc,{__mode="k"})
setmetatable(_bp_unnamed_index,weak)
end
 
local function bp_add_index()
local info=debug.getinfo(3,"Slf")
local func=info.func
if _bp_unnamed[info.func]==nil then
local desc=info.source.."("..info.currentline..")"
_bp_unnamed[func]=true
_bp_unnamed_desc[func]=desc
_bp_unnamed_index[func]=_bp_index
_bp_unnamed_index[_bp_index]=func
_bp_index=_bp_index+1
end
return _bp_unnamed[func],_bp_unnamed_index[func]
end
 
local _bp_named={}
local _bp_named_desc={}
 
local function bp_add_name(name)
local info=debug.getinfo(3,"Sl")
local desc=info.source.."("..info.currentline..")"
if _bp_named[name]==nil then
_bp_named[name]=false
end
 
local tbl=_bp_named_desc[name]
if tbl then
tbl[desc] = true
else
_bp_named_desc[name]={ [desc] = true }
end
 
return _bp_named[name],name
end
 
local function bp_show(n)
if type(n)=="number" then
local func=_bp_unnamed_index[n]
if func==nil then
error "invalid break point id"
end
print("break point:",n,
_bp_unnamed[func] and "on" or "off",
_bp_unnamed_desc[func]
)
else
print("break point:",n,_bp_named[n] and "on" or "off")
if _bp_named_desc[n] then
for k,v in pairs(_bp_named_desc[n]) do
print("",k)
end
else
print("tundefined")
end
end
end
 
local function bp_show_all()
for k,_ in pairs(_bp_unnamed) do
bp_show(_bp_unnamed_index[k])
end
for k,_ in pairs(_bp_named) do
bp_show(k)
end
end
 
function bp(n)
local trigger,name
if n==nil then
trigger,name=bp_add_index()
else
trigger,name=bp_add_name(n)
end
 
if trigger then
bp_show(name)
dbg(1)
else
_bp_list[name]=false
end
end
 
function trigger(n,on)
on = on~=false
if type(n)=="number" then
local func=_bp_unnamed_index[n]
if func==nil then
error "invalid break point id"
end
_bp_unnamed[func]=on
else
_bp_named[n]=on
end
end
 
function list(v)
if v then
bp_show(v)
else
bp_show_all()
end
end
 
function error_handle(msg)
print(msg)
dbg(1)
end


可以這樣測(cè)試一下:

require "bp"
 
function foo(arg)
bp.bp()    -- 設(shè)置一個(gè)匿名斷點(diǎn)
return arg+1
end
 
=foo(0)    -- 輸出 foo(0) 
 


運(yùn)行后會(huì)進(jìn)入調(diào)試控制臺(tái):
可以發(fā)現(xiàn)斷點(diǎn)被編了號(hào)(1 號(hào))并被觸發(fā),局部變量放在 _L 這張表里可以直接操作,upvalue 放在了 _U 表中 。

break point:    1       on      =stdin(2)
_L=     {arg=0,}
_U=     {}


我們可以改一下 arg 的值,如 _L.arg=1 然后 cont 退出控制臺(tái)。可以發(fā)現(xiàn) foo 函數(shù)返回了 2 。
這種匿名斷點(diǎn)添加方便,而且斷點(diǎn)跟隨邏輯而不是和代碼行做映射。也就是說(shuō),同一個(gè) function 的不同實(shí)例(不同的 closure )可以有不同 id 的斷點(diǎn),單獨(dú)控制。

我們也可以使用具名斷點(diǎn),方法是 bp.bp "bpname"
具名斷點(diǎn)缺省是 disable 狀態(tài)的。如果需要激活可以用 bp.trigger "bpname" 。
給斷點(diǎn)起名字的好處是,可以給一組斷點(diǎn)起同一個(gè)名字,這樣可以批量開(kāi)關(guān)。

bp.trigger(name,true/false) 用于開(kāi)關(guān)斷點(diǎn),name 可以是字符串也可以是 id 。

列出所有斷點(diǎn)可以用 bp.list()
也可以用 bp.list(name) 來(lái)列出一個(gè)斷點(diǎn)的狀態(tài),name 可以是字符串也可以是 id 。

還有一種方式,就是把調(diào)試控制臺(tái)用在錯(cuò)誤處理函數(shù)中,這樣函數(shù)一出錯(cuò)就自動(dòng)切入控制臺(tái)。
方法是 xpcall(some_function,bp.error_handle)

下一步打算做單步執(zhí)行 :D
posted on 2007-05-03 07:14 七星重劍 閱讀(2689) 評(píng)論(0)  編輯 收藏 引用 所屬分類: PL--c/c++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美黄色大片网站| 99精品久久久| 蜜臀91精品一区二区三区| 欧美影院成人| 久久久久久亚洲精品杨幂换脸| 欧美影院久久久| 久久久九九九九| 你懂的国产精品| 欧美日本中文字幕| 国产精品一区在线播放| 国内在线观看一区二区三区 | 日韩系列在线| 一本色道久久综合亚洲二区三区| 一区二区三区欧美在线观看| 欧美一区二区黄| 美日韩免费视频| 国产精品福利在线观看| 在线成人av| 99这里只有精品| 久久国产综合精品| 一区二区欧美视频| 亚洲精品在线三区| 香蕉免费一区二区三区在线观看| 久久精品亚洲| 亚洲精品专区| 欧美一区二区在线免费播放| 久久精品91久久香蕉加勒比| 一区二区国产精品| 亚洲国产成人久久综合一区| 亚洲午夜av在线| 久久综合九色综合欧美就去吻 | 久久精品网址| 欧美性视频网站| 亚洲国产小视频在线观看| 亚洲综合大片69999| 欧美黄在线观看| 欧美专区在线观看| 欧美日韩另类视频| 亚洲福利专区| 乱人伦精品视频在线观看| 亚洲在线一区| 国产精品国产三级国产a| 亚洲精品黄色| 欧美承认网站| 美女精品一区| 在线看不卡av| 欧美sm视频| 久久久久久久久久久久久女国产乱| 国产精品扒开腿爽爽爽视频| 欧美视频一区二区三区…| 亚洲精华国产欧美| 美女视频黄 久久| 久久久久久9| 影音先锋久久精品| 欧美肥婆bbw| 理论片一区二区在线| 海角社区69精品视频| 久久久xxx| 欧美在线日韩| 国模吧视频一区| 久久一区二区三区国产精品| 欧美中文日韩| 亚洲第一中文字幕| 欧美国产综合视频| 欧美激情精品久久久六区热门| 最新国产成人在线观看| 亚洲精品乱码久久久久久蜜桃91| 久久尤物电影视频在线观看| 亚洲高清不卡一区| 最新国产成人在线观看| 欧美日韩免费观看一区=区三区| 亚洲视频在线观看三级| 亚洲天堂黄色| 黄色亚洲精品| 亚洲精品日产精品乱码不卡| 国产精品第三页| 久久精品国产免费观看| 老牛国产精品一区的观看方式| 亚洲精品一区二区网址| 亚洲免费av电影| 国产一级久久| 亚洲精品1234| 欧美制服丝袜第一页| 久久精品女人的天堂av| 久久久久久久综合| 亚洲国产清纯| 一区二区三区久久| 国产综合香蕉五月婷在线| 欧美激情综合色| 欧美亚洲成人网| 老鸭窝亚洲一区二区三区| 欧美成人小视频| 欧美一区二区三区啪啪| 久久一区激情| 亚洲你懂的在线视频| 久久频这里精品99香蕉| 亚洲无吗在线| 久久这里有精品视频| 亚洲一区二区三区影院| 久久黄金**| 亚洲一区免费| 欧美jizz19hd性欧美| 性色av香蕉一区二区| 嫩草成人www欧美| 久久米奇亚洲| 国产精品亚洲成人| 亚洲国产日韩欧美综合久久| 国产色综合网| 亚洲美女啪啪| 1024成人| 欧美在线播放高清精品| 亚洲女优在线| 欧美片第1页综合| 欧美freesex交免费视频| 国产精品一区久久久| 亚洲精品美女在线| 黄色日韩网站视频| 性色av一区二区三区在线观看| 欧美电影资源| 亚洲肉体裸体xxxx137| 在线观看日韩av电影| 欧美一级精品大片| 亚洲先锋成人| 欧美午夜精品久久久久久孕妇| 亚洲高清不卡在线观看| 亚洲高清久久网| 久久久久久色| 每日更新成人在线视频| 国产一区二区精品久久| 欧美亚洲三级| 欧美亚洲一区三区| 欧美日韩一区二区高清| 99国产精品一区| 亚洲婷婷在线| 欧美日韩精品在线视频| 亚洲久色影视| 亚洲深夜福利视频| 欧美日韩天堂| 中日韩美女免费视频网站在线观看| 亚洲永久网站| 欧美日韩国产综合一区二区| 亚洲精品国产精品国自产在线| 日韩视频不卡中文| 欧美日韩免费网站| 亚洲性线免费观看视频成熟| 欧美在线综合| 在线播放亚洲一区| 欧美激情一区二区三区全黄| 最新国产乱人伦偷精品免费网站| 久久久久久久999| 亚洲精品在线观| 鲁大师影院一区二区三区| 久热综合在线亚洲精品| 1024亚洲| 欧美国产在线观看| 夜夜嗨av一区二区三区网页| 亚洲欧美日韩一区二区在线 | 日韩视频在线免费观看| 麻豆成人小视频| 亚洲精品一区二区三区av| 在线视频你懂得一区| 国产精品老牛| 久久久精品一品道一区| 欧美激情一区二区三区不卡| 亚洲一区二区三区精品在线观看| 国产精品久久国产精品99gif| 午夜精品理论片| 亚洲高清一区二区三区| 亚洲亚洲精品在线观看| 国产精品久久久久久亚洲调教| 久久动漫亚洲| 亚洲韩国精品一区| 欧美一区免费| 99视频热这里只有精品免费| 国产午夜精品视频| 欧美日本不卡视频| 亚洲视频导航| 欧美77777| 羞羞答答国产精品www一本 | 国产精品久久久爽爽爽麻豆色哟哟| 欧美在线视频导航| 夜夜夜久久久| 欧美成人午夜激情视频| 午夜精品久久久久久久久久久| 亚洲国内在线| 黄色精品一区二区| 国产精品私房写真福利视频| 欧美99在线视频观看| 久久成人在线| 亚洲免费视频成人| 一区二区三区视频在线观看| 欧美高清视频在线播放| 久久九九有精品国产23| 亚洲欧美日韩国产| 这里只有精品电影| 亚洲第一页在线| 久久噜噜噜精品国产亚洲综合 | 欧美亚洲一区三区| 亚洲私人影吧| 中文亚洲视频在线|