• <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>
            隨筆 - 505  文章 - 1034  trackbacks - 0
            <2008年3月>
            2425262728291
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345


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

            常用鏈接

            留言簿(94)

            隨筆分類(649)

            隨筆檔案(505)

            相冊

            BCB

            Crytek

            • crymod
            • Crytek's Offical Modding Portal

            Game Industry

            OGRE

            other

            Programmers

            Qt

            WOW Stuff

            搜索

            •  

            積分與排名

            • 積分 - 911585
            • 排名 - 14

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜

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

            Lua 簡易調(diào)試器


            云風(fēng)大哥寫的,果然牛人啊!現(xià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


            可以這樣測試一下:

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


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

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


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

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

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

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

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

            下一步打算做單步執(zhí)行 :D
            posted on 2007-05-03 07:14 七星重劍 閱讀(2676) 評論(0)  編輯 收藏 引用 所屬分類: PL--c/c++
            久久久久久久亚洲精品| 蜜桃麻豆www久久国产精品| 久久精品亚洲AV久久久无码| 久久99国产精品尤物| 亚洲成av人片不卡无码久久| 久久99久久99精品免视看动漫| 久久国产精品无码HDAV| 亚洲国产成人久久笫一页| 日本三级久久网| 国产99久久精品一区二区| 久久这里只有精品18| 无码国内精品久久人妻蜜桃| 久久精品国产男包| 成人久久免费网站| 伊人久久大香线蕉综合影院首页| 久久er国产精品免费观看2| 久久综合狠狠综合久久| 久久久久99精品成人片牛牛影视| 久久精品国产亚洲精品2020| 久久综合视频网站| 国产精品99久久久久久董美香 | 99久久精品免费观看国产| 国产91色综合久久免费分享| 久久人妻AV中文字幕| 日韩十八禁一区二区久久| 亚洲综合精品香蕉久久网97| 久久午夜羞羞影院免费观看| 亚洲日韩中文无码久久| 亚洲人成无码网站久久99热国产| 狠狠综合久久综合中文88| 亚洲精品tv久久久久| 国产午夜福利精品久久| 亚洲成色999久久网站| 精品综合久久久久久97超人| 久久精品蜜芽亚洲国产AV| 色综合久久无码中文字幕| 国产成人精品三上悠亚久久| 99久久国产亚洲综合精品| 色噜噜狠狠先锋影音久久| 久久成人精品视频| 国产精品久久久久一区二区三区|