Можно ли получить доступ к свойствам и функциям пользовательских данных?
Я хочу вернуть экземпляр класса Java как userdata в мой скрипт lua. Можно ли получить доступ к свойствам и функциям этого экземпляра из lua?
Вот так
local car = Car.getNew()
print(car.hasHonked)
car:honk()
print(car.hasHonked)
Это моя попытка решить проблему
Ява (сокращенно)
public class CarModule extends TwoArgFunction {
String moduleName = "Car";
public LuaValue call(LuaValue modname, LuaValue env) {
LuaValue library = new LuaTable();
library.set("getNew", new getNew());
env.set(moduleName, library);
return library;
}
static class getNew extends ZeroArgFunction {
@Override
public LuaValue call() {
return LuaValue.userdataOf(new Car());
}
}
}
public class Car {
private int count;
@Override
public String toString() {
return "Hello World";
}
public void honk() {
count++;
}
public int getHonks() {
return count;
}
}
Lua
local car = Car.getNew()
print(car) -- foo.bar.lua.module.CarModule$Car@1ef7fe8e
print(type(car)) -- = userdata
print(car.honk) -- = nil
print(car.getHonks) -- = nil
print(car:honk) -- = LuaError: function arguments expected
print(car:getHonks) -- = LuaError: function arguments expected
print(tostring(car)) -- = Hello World
car:honk() -- = LuaError: attempt to call nil
car:getHonks() -- = LuaError: attempt to call nil
Редактировать:
Нашел ответ здесь
Вместо
return LuaValue.userdataOf(new Car());
Я должен использовать
return CoerceJavaToLua.coerce(new Car());
1 ответ
Вы можете попробовать связать доступ к car.hasHonked
к функции, которая возвращает значение из Java. Я не использовал luaj, поэтому я не могу комментировать, как именно это будет сделано с ним, но вот тот же принцип, что и с lua. Все, что вам нужно сделать, это заменить функцию __index на то, что обращается к вашим переменным. Код использует метатаблицы, чтобы разрешить связывание не найденных ключей с функцией.
Car = {}
function Car.__index(table, key)
print(Car, table, key)
return "the java value according to key"
end
function Car.getNew()
return setmetatable({}, Car) -- sets metatable for userdata or table
end
local car = Car.getNew()
print(car.hasHonked)
-- prints:
-- table: 0xa64f80 table: 0xa6e370 hasHonked
-- the java value according to key
Другим вариантом может быть просто использование функций, как показано ниже. Эти функции будут вызывать Java и возвращать реальное значение Java.
car = {}
function car.getHonked()
return "the java value"
end