[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: R: Re: How to export associative arrays to an embedded lua script?
- From: "linuxfan@..." <linuxfan@...>
- Date: Mon, 12 Oct 2015 14:08:23 +0200 (CEST)
Hi list (or table?)!
I'm still evaluating how to expose my pascal
tables to lua scripts.
So far, I understand that I have to use
metatables linked to a table or to userdata. On the argument the manual
is a bit ambiguous; it says "Tables and full userdata have individual
metatables [other types share a metatable per type]". If all light
userdata share the same metatable, I could have problems in the future.
Moreover, I am not sure that lua scripts can "subscript" a light
userdata the same way as a table. Supposing that I create a few global
variables named "env", "gui"..., all of type light userdata, and I link
a metatable on them, can I write in lua
env.language = "en"
if gui.
touch = "up" then ... end
and so on? If yes, this could be the way,
but what if I will need more classes and/or different tables? Full
metadata could do, if they behave like light userdata (if light
userdata do what I want). I could store my pointers in the memory
allocated by lua - no problem. So, what I want to know is the question
above, plus some warning about difficulties I am not aware of.
Remember, main storage must be done in host application, not scripts.
Some tables will be read-only, some other will have special processing
(rising events when accessed), and so on. But I must add that I am not
afraid about scripts doing wrong things. Scripts will have to comply
with a series of rules (for example, NOT change the metatable
associated with host values).
I would like to add some thoughts on
your comments. Dirk said that Lua doesn't really know the name of a
table it pushes on the stack. But if I create a table and assign it a
name via lua_setglobal(), that table has a name, and lua knows it
(because lua translates the source code in byte code through the name
of that table). I think that if a table named "env" exists,
env2 =
env
will point to the same table, so it will have the same internal
"pointer", and the same metatable; the global table will still contain
a link from "env" to the pointer value, and one more link "env2" with
the same value. I could even scan the whole global table and get the
name from the pointer (not efficient, ok). This is where the lua manual
is a little ambiguous; it says that "every value can have a metatable",
but what about two identical values?
Anyway, I made a quick try
storing the lua value for my just created tables, and they work as
expected. Dirk said that this is not a good idea, because lua doesn't
assure the pointer stays valid, perhaps after a garbage collection. I
don't see why lua should move a table to a different address, while
there are global variables referencing that table, but who knows. In
this case, all the ideas about storing the lua value somewhere (the
registry included) fail. A __index host function should only rely on
the table value it has got on the stack, but it could look up a key -
inside- that table. The only problem is that a lua script could modify
that value, but my lua scripts *should not* do it.
This idea was from
Philipp, and I want to say that is a quick and easy one; I am not
concerned about collisions: table keys are "well known" keys, and it
would be an error to access other keys.
After talking about light
userdata (see my question before), Dirk talks about freepascal. Yes, my
project uses Delphi *and* freepascal. Actually, I took the freepascal
bindings and they work nicely under delphi.
Rena offered 4 ways.
(1
Store the table name in the metatable). Nice and straightforward, I
have to think about it.
(2 Map a value->tablename in the registry).
Doesn't work if it is true that reference to a table can become
invalid.
(3 Keep the name in an upvalue). I've still to understand
what an upvalue is. If upvalues are contexts for closures, then it is
another nice solution to think about.
(4 Use userdata instead). I must
investigate userdata, I suspect that they are not perfect for what I
want. It was subtle the mention to C switch statement, as Boris also
did. I will have no more than 8-9 tables, so any switch statement is
faster than a lookup in a lua table.
After having received a reply to
my question at the beginning (how compares a metatable attached to a
userdata instead of attached to a table), I will go ahead and will let
you know.
Salutations again, sorry for the long message,
Linuxfan