Comments (15)
Yeah there is no special way to declare enums as types and the only way is still the old way (a stack specialization is required). The underlying type usage is just to simplify passing enums from c++ down to lua.
I'm fine having a more structured type definition for enums, where a c++ enum could be mapped to a lua one, and offer more transparent bidirectional conversion. Will look into it, thanks for reporting !
from luabridge3.
Ah, I see, then I will continue to use stack specializations.
And I guess you can close this issue whenever you feel like it.
from luabridge3.
Oh, right, one thing that would be definitely nice to fix is that case when you use it as std::map
key and similar, because, like I described, there is no error message at all, and would be nice to have something similar to error you get when you try to use it as function call argument, thus at least you understand what's going on wrong more clearly.
from luabridge3.
I'm working on adding proper enum support in the library
from luabridge3.
It's kind of difficult to chose a single way to handle this, because depending on the use case this could get implemented in different ways (which might also have performance considerations).
There are two possibilities:
-
treat C++ enums as integers, and map them to lua as such. it will work but passing any unrelated lua integer to a C++ function taking an enum, it will work (even if the integer conversion can't assume a valid enum value). This is the fastest, but also the less secure (UB is just behind the corner).
-
treat C++ as userdata. Enums will have their own type on the lua side so they can be checked (you can's just
call(1)
from lua to a method exposed in C++ that takes acall(enum_type value)
, you need to use a valid userdata. This is the safest (in term of type safety) but also the slowest.
I'm considering allowing both.
from luabridge3.
I've pushed both wrappers for Stack, see #56
In the meanwhile i'll add docs, it would be nice if you could check if they help.
from luabridge3.
After trying more with the second solution, i think there are some caveats when working with lua tables and the enums are userdata, because they all have a separate address in lua land and equality is performed raw (no metamethods), so two instances of those enums objects in lua cannot be used as keys in a table (the will never match). Will investigate.
from luabridge3.
It doesn't seem we can workaround this with enums as separate types with their own userdata:
The indexing of tables follows the definition of raw equality in the language. The expressions a[i] and a[j]
denote the same table element if and only if i and j are raw equal (that is, equal without metamethods).
In particular, floats with integral values are equal to their respective integers (e.g., 1.0 == 1). To avoid
ambiguities, any float with integral value used as a key is converted to its respective integer. For instance,
if you write a[2.0] = true, the actual key inserted into the table will be the integer 2. (On the other hand, 2
and "2" are different Lua values and therefore denote different table entries.)
Full userdata cannot be used for indexing (every time you create an "instance" of the userdata, it will be a different object only raw equal to itself), so your example will never work when enums are mapped to userdata:
std::map<Enum, std::string> testEnumMap = {
{ ONE, "ONE" },
{ TWO, "TWO" },
{ THREE, "THREE" }
};
We could use lightuserdata by hashing the enum type + value, but there are hight chances of hash collisions between enums.
from luabridge3.
Ok, so as I understand, first solution, i.e. "treat C++ enums as integers" would be in favor right now?
Yeah, second one sounded a bit more more correct to me, I'd say, but if it's problematic, then first also works for me no problem.
If, thanks to stack specializations, type conversion will always work fine when calling something Lua => C++, then it sounds good enough.
from luabridge3.
See this discussion http://lua-users.org/lists/lua-l/2007-01/msg00126.html apparently the only way is to implement a userdata cache in the form of weak table in the registry that will return references to existing userdata instances when they are already there, or being populated when not there. Sounds interesting but it's also a bit demanding both in term of space and time complexity.
from luabridge3.
I see. Despite that I'm not too good in Lua C API internals, I understand more or less what is discussed there.
Well, okay, I leave this entirely up to you to decide. If you find time to experiment with this userdata cache, then it has a chance to provide some decent outcome or at least some useful experience, I guess. Alternatively, like I said, using stack specializations is not a problem for me personally, although yeah, it's a bit of additional manual work, but not too much.
from luabridge3.
I found a way to make sure the conversion can be made. It's a bit more tedious, but i've now moved the enum wrapper class for stack into the library, so you should write:
enum class MyEnum
{
A,
B,
C
};
template <>
struct luabridge::Stack<EnumType> : luabridge::Enum<EnumType,
EnumType::A,
EnumType::B,
EnumType::C>
{
};
This way i can check in Stack::get that the passed integer is convertible to one of the mapped enum values, and if not present raise a lua error.
from luabridge3.
Just tested, works great, thanks for your efforts!
Couple minor things.
I had to add #include <system_error>
, because otherwise I had error : no type named 'error_code' in namespace 'std'
.
And in docs I noticed in the sentence "This will map the enum to an integer to as int16_t" second "to" is probably not needed.
And also formatting is bit broken there, because heading "2.10 - lua_State" starts inside block of code.
from luabridge3.
Yeah i noticed i did some mistakes in the manual, will try to fix them asap
from luabridge3.
from luabridge3.
Related Issues (20)
- Enhancement Request: Custom error function for `lua_pcall`. HOT 11
- Error C3861 (using with Luau) HOT 3
- Can I cast types inside Lua? HOT 4
- Duplicate symbols on Win32 with default __stdcall HOT 9
- Debug names of C functions for Luau HOT 8
- Extensible class bug with inheritance
- Add support for addStaticIndexMetamethod and addStaticNewIndexMetamethod
- Using LuaBridge3 in a precompiled header on MSVC leads to an internal compiler error HOT 2
- Use of std::shared_ptr on classes without `std::enable_shared_from_this` HOT 1
- Stateful lambdas registered as functions loose state HOT 2
- Compile error with Cfunc property getter/setter HOT 2
- std::vector to 0-based Lua table HOT 5
- MSC Warning C4146 HOT 2
- How to expose C++ data (a vector, in this case) to Lua without making a copy? HOT 2
- Does LuaBridge3 Support Android for SDL2-based Games? HOT 2
- Passing a Lua Table (LuaRef) as an argument to C++ function HOT 1
- How to get the name of a Lua variable? HOT 2
- Comparison Issue Between `uint64_t` in C++ and Numeric Constant in Lua HOT 8
- NAI run lua code in string from cpp
- Explicit inclusion of `#include <stdint.h>`. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from luabridge3.