lua-users home
lua-l archive

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

> Hi all (especially Nick Trout and Jon Belmonte who have been trying to
> drag me to use lua for quite a while now),

Finally... ;-)

> Well, version 5 has finally got the features I need it seems, so I'm
> to give it a go.

Yes, it does seem to have come on rather a lot since version 4.
Practically tailored for writing games now.

> I may have read the documentation wrong, but I don't like the way lua
> all lua co-routines/functions have access to the global scope.
> Is there a way to have multiple global scopes, so I don't have to
> about script writers breaking other people's data or accessing stuff
> shouldn't?  I'd like to keep these "global" scopes local to each
> (and
> have multiple coroutines running within the same "space" on an

Here is an example in Lua script. I find it easier to work with this
than the C API and stacks etc. You can always convert it later...
(Thanks to Peter anyway)

-- this bit operates as you would expect:

g = 1

function foo()
    local a = 1
    while a<=3 do
        print('co', a, g)  -- output
        a = a+1
        g = g+1

co = coroutine.create(foo)
while coroutine.resume(co) do

Output is:
co	1	1
co	2	2
co	3	3

--------------------------------- Example 2 ------------------------

Now we move into "foospace". Here we create our global variable space
"vars" and a function getg to control access. We first look in our
"local global" space for our variable and then fall back on the real
global space if a variable isn't found there (i.e. "return
rawget(vars,n) or rawget(_G,n)")

g = 1

function foospace()
    local vars = { g=100 }
    local getg = function(t,n) return rawget(vars,n) or rawget(_G,n) end
    local foo = function ()
        local a = 1
        g2 = 200 -- new global
        while a<=3 do
            print('co', a, g, g2)  -- output
            a = a+1
            g = g+1
    setfenv(foo, setmetatable(vars, { __index=getg }))

co = coroutine.create(foospace)
while coroutine.resume(co) do
print(g,g2) -- see if global scope changed.

Output is:
co	1	100	200
co	2	101	200
co	3	102	200
1	nil  -- ie. We didn't touch the real global scope.

You can pretty much set up any environment you could imagine really. The
great thing is you can create function to create your coroutine and it
returns it tailored to its use. You could restrict creation of new
objects using __newindex. I'm pretty new to setfenv() since it's not
really been in the scope of our project. So using the above style you
wouldn't need multiple lua_States - which may or may not be a
disadvantage. We're using one lua_State for each (mutually exclusive)
"mission" which allows easy tidy up and the mission shouldn't really be
affecting the global world state - and if so you should know about it.

I've been working on a tutorial. Hope the following material is useful:

and more generally:

> Also, if this is possible, what kind of overhead (memory
> footprint/creation
> time) does the lua_state structure have? (I presume I'll need
multiples of
> these)

They're quite small. I don't know what's more efficient, multiple
lua_States or one lua_State with multiple coroutines. One might be more
memory efficient and the other less computationally expensive?

> Bear in mind this stuff might be in the documentation and I just
> got
> there yet, be kind with me. :-)

Have a look at the tutorial and if there's anything missing give me a