-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compare LuaRef
s referencing Lua functions in C++ code
#61
Comments
LuaRef comparison operators will use lua_compare and will invoke metamethods. I'm not sure functions can be compared with that, and for sure they can't have a I will see if i can make it work somehow. |
If i replace your set with an unordered_set it works no problem. Is there a reason you need ordering ? |
No, I don't need |
Hm, I just realized that if you wrote it works with |
== works on functions, but < not |
You can do this, but lua_pointer will return nullptr for trivial types: struct LuaRefLess
{
bool operator()(const luabridge::LuaRef& x, const luabridge::LuaRef& y) const
{
x.push();
auto lhs = lua_topointer(x.state(), -1);
y.push();
auto rhs = lua_topointer(y.state(), -1);
return lhs < rhs;
}
};
TEST_F(LuaRefTests, SetComparatorOperatorLessThan)
{
std::set<luabridge::LuaRef, LuaRefLess> eventHandlers;
auto subscribe = [&eventHandlers](luabridge::LuaRef handler)
{
if (handler.isFunction())
eventHandlers.insert(handler);
};
auto trigger = [&eventHandlers]
{
for (auto handler : eventHandlers)
handler();
};
luabridge::getGlobalNamespace(L)
.addFunction("subscribe", subscribe)
.addFunction("trigger", trigger);
runLua(R"(
a = function()
print('Hello')
end
b = a
subscribe(a)
subscribe(b)
subscribe("wrong")
subscribe(function()
print('World')
end)
)");
trigger();
} |
Yep, I just checked and turns out there's no issue at all, looks like comparison for equality works already under the hood and thus I can delete LuaRef-functions from C++ container no problem. My bad, I misinterpreted the error, or rather haven't researched it enough. Additionally, I just checked in the intepreter and figured out this error comes from Lua itself, not from LuaBridge, as I assumed before, so yeah, this is how it is:
Ok, thank you for your attention in any case, and I'm closing this issue then. |
#65 < This could fix your issue and be more safe at the same time, as lua_compare might raise a lua error (and trigger the panic handler). |
By looking at the changes I assume you compare pointer values there. I wanted to suggest the same, because initially I supposed pointers increase in value as function variables get initialized, but then I noticed it's not always the case, probably because of GC, so I started to think it's not that good idea as it seems that simple |
I'm also not sure, but i also don't want that a call in c++ on luarefs will trigger the panic handler |
Here I am again, and this time it's more of a question rather than an issue.
Let's get straight to practical example with this one. So, there may be various needs to store Lua functions as
LuaRef
s on the C++ side, but I guess one of most common reasons is to establish some event subscription from scripts to events happening in C++.A naive example may look like this:
And then in Lua:
And here first function is added okay, but as soon as another one is attempted to be added, I get this error:
attempt to compare two function values
. As I understand, that's because internallystd::set
attempts to check function uniqueness compared to already added to that set and that gets to comparison ofLuaRef
s and somewhere inside LuaBridge code this is determined as incorrect operation.Ability to compare functions is important in this concept, because as soon as you need to remove a function from event handlers collection, you need some way to identify this function. In Lua functions may be compared easily because I assume they're some kind of pointers, i.e. function variable can be printed as
function: 0000024a923ade90
and thus same such values may be considered equal. So it's possible to store event handlers in Lua in form of table where function itself may even be a table key, so it can be like:In C++, as I understand, we don't have a simple possibility to compare
LuaRef
s which are actually referencing function, is this correct?In my code I already implemented a workaround where I have special
Function
class that wrapsLuaRef
, has unique ID per instance, and providesoperator==
that compares IDs of passed instances, so it can be used instd::set
.But this means in scripts I have to additionally wrap Lua function into that
Function
class I bind. So it's like:But this means that wrapping everywhere in scripts. Maybe more elegant solution is possible?
The text was updated successfully, but these errors were encountered: