lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



Could we implement it in lua‘s C source code ?
I hava the same need as Ricky, and now thinking a method
to solve it in lua's source code.
 
2010-03-25

bravefly

发件人: Pierre-Yves_Gérardy
发送时间: 2010-03-25  17:34:35
收件人: Lua list
抄送:
主题: Re: Cleaning up specific lua scripts
I'm glad I could help :-)
You could add a collectgarbage() call at the end of cleanLevel().
That said, the setfenv() solution is probably more elegant and more robust.
local protectMT = {__newindex=error}
local levelMT = {index=_G}
local MTindex
local function protectTable(tbl,index)
    for k,v in pairs(tbl) do
        if
            type(v)==table and
            getmetatable(v) ~= protectMT -- prevents from getting lost in
        then                             -- circular references.
            index[k]={getmetatable(v),{})
            protectTable(v,index[k][2])
            setmetatable(v,protectMT)
        end
    end
end
local function unprotectTable(tbl,index)
    for k,v in pairs(tbl) do
         if type(v)=="table" then
              setmetatable(v,index[k][1])
              unprotectTable(v,index[k][2])
        end
    end
end
local loadLevel = function(levelpath)
    local levelenv=setmetatable({},levelMT)
    local levelcode=loadfile(levelpath)
    setfenv(levelcode,levelenv)
    protectTable(_G,MTindex)
    -- it's now impossible to add or modify any global, or any
subtable of a global.
    local ret = levelcode()
    unprotectTable(_G,MTindex)
    return ret
end
To give back the control from a level, return from it's main chunk
(e.g., return true on level completion and false on death).
local success = loadlevel(level1)
collectgarbage()
if success then
    loadNextLevel()
else
    restartLevel()
end
The above code is not tested and may contain syntax or semantic
errors, but you get the idea :-)
Cheers,
-- Pierre-Yves
On Thu, Mar 25, 2010 at 09:14, Ricky Haggett <ricky@honeyslug.com> wrote:
> Pierre,
>
> This is a simpler and more elegant version of what I implemented yesterday afternoon, which also seemed to do the job, albeit with more fuss..  I'm definitely going to upgrade to your code today..
>
> Thanks,
>
> Ricky
>
> -----Original Message-----
> From: lua-bounces@bazar2.conectiva.com.br [mailto:lua-bounces@bazar2.conectiva.com.br] On Behalf Of Pierre-Yves Gérardy
> Sent: 24 March 2010 19:27
> To: Lua list
> Subject: Re: Cleaning up specific lua scripts
>
> On Wed, Mar 24, 2010 at 12:30, Ricky Haggett <ricky@honeyslug.com> wrote:
>> Yep, we could store a table of all of the functions / tables within a
>> specific level script, but it would be awkward for the designers to
>> maintain, and a potential source of error...
>
> You could also do it the other way around:
> after you've loaded your global scripts do
>
> globals={}
>
> function cleanLevel()
>    for k,_ in pairs(_G) do
>        if not globals[k] then _G[k] = nil
>    end
> end
>
> for k,_ in pairs(_G) do
>    globals[k]=true
> end
>
> globals will index all globals present at that point (including itself
> and cleanlevel() ), and cleanLevel() will only delete the globals not
> referenced there. Case solved :-)
>
> Cheers,
> -- Pierre-Yves
>
> No virus found in this incoming message.
> Checked by AVG - www.avg.com
> Version: 9.0.791 / Virus Database: 271.1.1/2767 - Release Date: 03/24/10 07:33:00
>
>