sol2
sol2 copied to clipboard
Can sol::property work on single lua variables?
I have written the following test code to check if a "free" lua variable can benefit from sol::property :
float k = 1.0f; float Getk() { return 2.0f * k; } void Setk(float val) { k = val; }
int main() { sol::state lua; lua.open_libraries(sol::lib::base);
lua.set("y", sol::property(&Getk, &Setk));
const auto& code = R"(
y=200
print(y)
)";
lua.script(code);
return 0;
}
Apparently, it doesn't work (result prints 200 instead of double that). Am I doing something wrong, or is this something beyond the scope of sol::property ? Any way to emulate this functionality on single lua variables?
If you use a code like this:
print(y, type(y))
y=200
print(y, type(y))
you can see the following output:
function: 0x1a046a0 function
200 number
As you can see, y is a function and by assigning 200 to it you change its type.
To make the code behave as you expect, you would need to call y as it is a function.
print(y, type(y))
y(200) -- Set value
print(y(), type(y)) -- Get value
This code should print the following
function: 0x1a04530 function
400.0 function
In general, magic related to assignment and similar is limited to tables and userdata as most things are implemented through the use of metatables that can be attached to them. If you wanted a simple syntax you would need to have some kind of userdata or table that has a metatable that then handles directing assignment into a function call to the sol::property generated function. I think in many language bindings this is a requirement, for example in Java-C interop you likely always need a Java class for any function iirc.
If you dont want to have an object and are ok with using a global variable, you could try to add a metatable to the _G global table. This would allow your original lua code to work as expected, but only when using the global variable:
sol::state lua;
lua.open_libraries(sol::lib::base);
sol::table T = lua.script(R"(
local T = {}
local function index(G, k)
if T[k] then
return T[k]()
else
return rawget(G, k)
end
end
local function newindex(G, k, v)
if T[k] then
return T[k](v)
else
return rawset(G, k, v)
end
end
setmetatable(_G, {__index = index, __newindex = newindex })
return T
)");
T.set("y", sol::property(&Getk, &Setk));
const auto& code = R"(
y = 200
print(y) -- prints 400.0
)";
lua.script(code);