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
Inconsistent type checking with single vs. multiple constructors #511
Comments
And how would someone, at a high level, go disabling type checks for overloading checks? |
Note that what I'm asking for is: what would you like to see on Also, as a side note I can imagine incompatibilities rise specifically when going with the "objects bound by toLua" part, since the metatable implementation is wildly incompatible. This might be a good time for me to make an overridable checker function a user can take up to change how userdata specifically (that is, C++-bound types) are checked. That is, before we do any of sol2's checks, simply pass the stack index, handler, etc. to a user-defined "sol::stack::userdata_checker" that can be explicitly specialized for your needs (like, say, returning "yes, this type is totally fine" 100% of the time or using some I would imagine that would be the low-level solution you could use, barring any high-level |
I should also probably mention it's not inconsistent: when dealing with multiple overloads, we have to do type-checking / arity-checking in order to find the right function. If you define |
Thanks for the quick response! I'm quite new to sol, so am unaware of how such a change interacts with the broader picture. A way to add a custom checker sounds perfect. It would mean figuring out how tolua verifies types and finding a way to hook into that. But that sounds like a worthwhile exercise for a more clean extensible solution. However, an "arity checking only" solution sounds much easier to implement, has some performance benefits, and would suit my purposes for now. I would argue that if |
The checker bit might actually be a bit harder to do: sure, we can override the default check but what about the casting operation? Right now we return If http://sol2.readthedocs.io/en/latest/tutorial/customization.html - https://github.com/ThePhD/sol2/blob/develop/examples/customization.cpp |
Unfortunately for my case, I'm trying to use sol for my own types (I'm really impressed by the simplicity, features and performance), whereas Urho3D uses (the seemingly abandoned) tolua++ for it's types. There seems to be some compatibility between the two, at least, since as I say, a single constructor (or multiple constructors with my hack) works. I.e. a correctly formed (tolua bound) object is passed to my (sol bound) constructor. I'll take a look at the customization points, to see what might be possible. |
I added some new customization points, that are much more flexible than the others. They're documented in various places, but the example probably explains it best. Pull from the latest, then check out this example: https://github.com/ThePhD/sol2/blob/develop/examples/interop/kaguya.cpp Replace the kaguya-specific logic with logic for Other information: If you figure out how to do |
I wanted to make sure this logic was solid, so I went and made 2 more examples. So now we test @satoren's kaguya, @vapourismo's Luwra, and @vinniefalco's LuaBridge, all which can be integrated into sol2: https://github.com/ThePhD/sol2/tree/develop/examples/interop It seems like the toLua logic for userdata stuff would be a great example aside from those 3 because it's data-compatible with sol2, meaning you can likely omit the |
This looks great! It may take me some time to figure out how to add such an interface for tolua. It looks like I need to use tolua's |
OK, I'm right on the edge of what I can understand of the Lua C API, but it appears as if the type checking in tolua is somewhat simple. tolua generates binding code with strings embedded for checking against the string representation of the metatables. E.g. some code generated for Urho3D's bindings for the
The So the best I think I can do in your new Does that sound about right? |
Look at
|
Good point. I need to experiment. The first problem I've come across is that it appears
|
Good, catch, I can fix that now. |
Yey! I got it working. It would be nice to not have to also implement the getter, which I essentially just lifted from the sol code. I also haven't handled the potential case of nested/namespaced classes. In Urho3D, none of the Lua API is namespaced and in the tolua documentation there is no mention of nested classes or namespaces. So I don't know if it's a limitation of tolua or just what the Urho3D devs decided. I'll try to mock up a test case, but tolua is a bit more involved that the other examples, since it's a command line utility that generates cpp files from bespoke ".pkg" files, which you then embed in your program. The checker/getter code I've come up with is
|
I think you can just use |
I did try |
@feltech Try the latest and remove your Also, this is the example I ended up writing (but can't really test, mostly because I don't want to build a fresh toLua): https://github.com/ThePhD/sol2/blob/develop/examples/interop/tolua.cpp |
Excellent! Works like a charm. Example also looks good to me. Thanks a lot for all your work, and the speed with which you resolved this! |
You're welcome. Best of Luck. |
I'm not really sure how to produce a simple test case, since my experience of this problem hinges on using two separate Lua binding libraries together. I'm also not sure whether this is a bug or feature request.
When only a single
sol::constructors
is defined in anew_usertype
call, the code path goes directly tooverload_match_arity_single<Fx, I, ...
. If multiple are defined, the code path starts atoverload_match_arity_single<Fx, Fx1, Fxs...
. In the first instance, there are no type checks - as long as the arity matches, the function matches. In the second case there are both arity and type checks.The case I've come across is whilst using a game library (Urho3D), which uses tolua for C++/Lua bindings. I want to pass tolua-bound type to my sol-bound constructor. This works fine as long as I only have a single constructor, since there are no type checks. As soon as I add a second constructor it fails because of the type checking.
A simple fix I hacked in was to redefine as follows
That is, not to immediately flag an error when no function fully matches (types + arity), but to return an "error code" of
numeric_limits<lua_Integer>::max()
. If this is returned, do one last ditch effort to check if the arity matches regardless of whether the types match. Otherwise flag a Lua error as before. This is then consistent with if a single constructor is called.I know practically nothing of such low level Lua stuff, so I'm sure there's a better way. But it works.
The text was updated successfully, but these errors were encountered: