Closed learn-more closed 1 year ago
What you are after cannot exactly be done without some workarounds. Here are some alternatives what you try.
1) You can have a table/userdata that uses the __index
and __newindex
metamethods to get and set the value. This basically calls just functions that get/set the value on C++ side.
Using sol you can basically for example make a dummy struct that acts as the userdata. The userdata then can get/set the value when you assign to a member of it.
See how speed
variable is used in this example between lua and c++ and how it is bound using sol2: https://sol2.readthedocs.io/en/latest/tutorial/cxx-in-lua.html
Here is an example: https://godbolt.org/z/GTEohYEez
2) With some work you can try fake it so that the variable works only in global scope. You can do it with a similar trick as the first approach, but you abuse the global _G
table so that when accessing global variables, the metamethods get and set the c++ value.
3) Use the first approach, but choose some other API. For example this kind of API is possible:
print(Var()) -- get
print(Var(56)) --set
What you are after cannot exactly be done without some workarounds. Here are some alternatives what you try.
- You can have a table/userdata that uses the
__index
and__newindex
metamethods to get and set the value. This basically calls just functions that get/set the value on C++ side. Using sol you can basically for example make a dummy struct that acts as the userdata. The userdata then can get/set the value when you assign to a member of it. See howspeed
variable is used in this example between lua and c++ and how it is bound using sol2: https://sol2.readthedocs.io/en/latest/tutorial/cxx-in-lua.html Here is an example: https://godbolt.org/z/GTEohYEez- With some work you can try fake it so that the variable works only in global scope. You can do it with a similar trick as the first approach, but you abuse the global
_G
table so that when accessing global variables, the metamethods get and set the c++ value.- Use the first approach, but choose some other API. For example this kind of API is possible:
print(Var()) -- get print(Var(56)) --set
Thanks for your detailed answer! I have been trying to get 3 working, but all that I could find were examples how to do that on a custom usertype, not on a global var.
Sample seems to be the closest to what I want, is that something that could be useful for the docs?
I have been trying to get 3 working, but all that I could find were examples how to do that on a custom usertype, not on a global var.
You can either define a function or you can define a usertype that uses the __call
metamethod.
I was first thinking about using the metamethods, but realized that they are not needed.
Here is an example for the third approach by using functions only: https://godbolt.org/z/59jMMEorj As you may see, it works for any type of primitive.
template<typename T>
auto Wrap(T& reference) {
return [&](std::variant<T, sol::lua_nil_t> value) -> sol::optional<T> {
if (const T* pValue = std::get_if<T>(&value)) {
reference = *pValue;
return {};
} else {
return reference;
}
};
}
// lua["luaVariableName"] = Wrap(someVariable); // Expose the C++ variable to lua through the Wrap function
The Wrap function takes a reference and makes a lambda that gets/sets the value based on if the parameter is nil or correct type value. This lambda that it returns is then exposed to lua where you call it to get/set the value. It also throws an error if you input invalid value, but its not so nice:
expected anything, received number: value does not fit any type present in the variant (bad argument into 'sol::optional<std::__cxx11::basic_string<char> >(std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, sol::lua_nil_t>)')
ps. Feels like implementing react hooks with sol here ... const [value, valueSetter] = useState(42); valueSetter(24);
😃
Thank you!
Is there a way to bind a lua variable to a c++ variable, so that when the lua variable is updated, the c++ variable follows?
Example code:
I was really hoping that the c++
printf
would result inVar1=1
orVar2=2
, but they print asVar1=0
andVar2=0
.