JakobOvrum/LuaD

A way to pass structs by reference?

aubade opened this issue · 6 comments

Given that class object support is still rudimentary, I'm looking for ways of easily sharing data between my program and Lua scripts. At the moment I'm looking at storing data in structs, but I'm bumping up against some limitations:

First, it seems that there's no way to pass a struct by reference to a Lua function. I've also tried putting getter and setter methods on the struct, in case that made a difference, and it didn't seem to.

Second, LuaD doesn't seem to be able to register a pointer-to-struct as a data type, and you can't pass one to a Lua function without that.

The most reliable way I've found of using LuaD with operations on references is passing delegates. Everything else is copied into the LuaD garbage collector and must be retrieved. I'm also wondering about the explanation behind this

It feels hackish as all get out and hurts me a bit, but following your hint, I put together a quick template to generate a getter/setter proxy that can be passed to and changed from a Lua function:
https://gist.github.com/aubade/9646827

I still hope something more elegant is possible at the LuaD level.

Oh so you're basically passing every member of a struct as a delegate. Quite nice if you ask me! I wonder if this would work for an HTTPServerRequest / HTTPServerResponse objects from vibe.d, that could allow for some lua websites with a D back-end which could be really great

Thinking about it some more, you could probably have more success avoiding a transfer of D types to Lua and setting up that Proxy to generate the getter/setters that convert back and forth using LuaObject. ie. for POD it makes it much more intuitive to use, you recursively deconstruct D types so that key= identifier, value= value, and create a LuaTable object using this information. I had a script using this nested ability over here:

https://github.com/globecsys/spee.d/blob/master/examples/luadebugger/config.lua
https://github.com/globecsys/spee.d/blob/master/spd/system/bootdata.d

LuaD will support passing structs by reference, through the same mechanism as class instances (i.e. member functions use : and whatnot). The problem is how to best present that option. I have a feeling that simply recognizing pointers to structs (which is trivial) is extremely error-prone, as most structs are stack-allocated. Ideas are much appreciated.

Oh so you're basically passing every member of a struct as a delegate. Quite nice if you ask me! I wonder if this would work for an HTTPServerRequest / HTTPServerResponse objects from vibe.d, that could allow for some lua websites with a D back-end which could be really great

Once module marshalling is done, the idea is that you can just do:

import somelib;

lua["somelib"] = LuaModule!somelib;

And then everything will be recursively marshalled appropriately. Some things will have to be ignored or have a changed interface (e.g. ref/out parameters) due to Lua's simpler type system, though. Instead of providing a changed interface (like using multiple return values for ref/out), I think it's probably better to just leave it to the user to manually push these parts of the interface.

The first idea that pops into my head is that, generally, you're going to be using very specific structs as references (At least I am)--The first thing that jumps to mind is a UDA that tells LuaD that the particular struct is sutiable for referencing. It still puts the onus on the user to make sure that they don't toss any stack-allocated things LuaD's way, but it at least makes us think first.