[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Problems with LUA 5.02 and user objects
- From: Romulo Bahiense <romulo@...>
- Date: Wed, 05 Apr 2006 12:15:07 -0300
Hi,
jdarling@eonclash.com wrote:
> Sorry for duplicate messages on the same topic, but by chance do you
> still have some sample Delphi code lying around of how you wrapped up
> objects?
Sorry for the delay. I'm quite busy fighting a disturbing hardware problem.
About your problem, I don't have at hand one isolated example for your,
because it is a bit entangled with my closed library.
But a solution I use is something like:
One table containing the class' methods, ieg:
TFooMethods = {
bar = <cfunction>,
baz = <cfunction>,
...
}
(This table is populated on the luaopen_mylibrary function)
And the object's (userdata's) metamethod is a function that:
Check if the requested name is a RTTI property. If it is, then return it
as you was doing with your example. If it is not, then it will get that
TFooMethods table from the registry and return it's value on the key
specified by the first meta __index argument.
An example (again, not tested) would be:
function lua__index(L: PLuaState): Integer; cdecl;
var
Obj: TObject;
outvar: Variant;
begin
Result:= 1;
// Get a Delphi object from Lua world
Obj:= GetObjFromLuaStack(L, 1);
// Check if the field name is a property of that object
if GetVCLProp(Obj, lua_tostring(L, 2), outvar) then
PushLuaVariant(L, outvar)
else
begin
// If it is not, get the (Obj.ClassName+'Methods')
// table from registry
lua_pushstring(L, Obj.ClassName+'Methods');
lua_gettable(L, LUA_REGISTRYINDEX);
if lua_istable(L, -1) then
begin
// If it is a table, then get it's value
lua_pushvalue(L, 2);
lua_gettable(L, -2)
end
else
// Otherwise, push nil (nothing can be found with the
// specified field name)
lua_pushnil(L);
end;
end;
And the functions in the TFooMethods table would be something like:
function lua_TFoo_bar(L: PLuaState): integer; cdecl;
begin
Result:= 0;
with GetTFooFromLuaStack(L, 1) do
Bar(lua_tostring(L, 2));
end;
But this approach requires you to create one Lua C Function for each
method in your class. This may sound bad, but from my experience, it is
better that way -- less mess in your code and more performance in
runtime. Plus, you are able to write more specialized code to interface
with Lua, taking advantage of it's nature of dynamic types, anonymous
functions (first-class values) and multiple return values.
A problem you may find is that you can't use RTTI's published methods
(a.k.a. events). This is a pain the neck. A solution would be to
implement some kind of RTTIJIT or TPC (Tinny Pascal Compiler ^^), but I
don't have the knowledge nor the time, yet :)
Good luck!
--rb