ComputerCraft

ComputerCraft

21M Downloads

Suggestion - userdata

boq opened this issue ยท 7 comments

commented

Note: I'm starting this discussion to check, if it would be accepted, before I start implementing it - so it's not exactly suggestion, but RFC

Userdata in pure Lua is data opaque for language, but accessible by C code. I think such concept would still be useful in CC - addons would be able to return custom data and transparently pass it through interpreter. For example, it would be useful for wrapping ItemStack - peripherals may want to operate directly on in (instead of some serialization to native Lua types). This proposal is composed of two parts:

IUserdata interface
This marker interface (no methods) causes type converter to pass values unchanged (both directions). While in Lua domain, values can still have metatable attached (via org.luaj.vm2.LuaUserdata type).

'Native' libs
To make anything useful with userdata user must have access to native methods provided by peripheral. New method would be added to IComputerAccess:

public void mountLib(String id, ILuaObject object);

Method would add new library either to global scope or to something like lib.[id]. Inside that library would be methods used to operate on userdata (so for example, in ItemStack scenario, wrapper that sets metatable and various methods used in there, like getSize(), etc).

commented

Does the native access really need to happen? It should work perfectly fine without, no?

commented

Alternative would be adding method like getItemStackMetamethods to peripheral. Sure, it's doable, but it's only weakly related to peripheral and more to type itself. Also, access to lib-like almost-global object would be easier for user.

commented

Hmm. I am kinda unsure of usefulness of this whole thing to the user. If i am getting it right this would allow to pass data from one peripheral to other right?

commented

That's basic idea. But I also want to be able to add _index in metatable (or other metamethods), so it is possible to return values that are similar to native ones.

As a addon author, there are certain things that I want to hide from user (or serialization would be impractical), but still be able to use in addon. Native access is just way to control what interface user sees.

commented

A userdata object could simply have the same getMethodNames and callMethod that an IPeripheral has. Returning such an object would give the Lua side a userdata object with methods on it, passing that back into a peripheral function would then pass the very same object as one of the arguments, and could be checked using instanceof MyUserdata... I don't see any problem there.

commented

Well, we already have ILuaObject, why don't we use that?

Since during conversion it's unpacked into LuaTable with LuaFunctions - initial identity of object is hidden behind two layers of Lua objects.

Maybe we can rework ILuaObject to use metafunction _index instead and unpeel it at call to peripheral? That's one solution, but switching from table to singular function may cause slight side-effects.

Cloning ILuaObject interface to IUserdataObject? Duplication is never good.

Anyway I think native library idea has use outside of userdata support (for example, to provide general use library?). It can also provide constructors for userdata, while ILuaObject approach can at most provide prototype/clone functionality.

commented

Just changing how ILuaObject works and is handled might be nice.