ThePhD / sol2

Sol3 (sol2 v3.0) - a C++ <-> Lua API wrapper with advanced features and top notch performance - is here, and it's great! Documentation:
http://sol2.rtfd.io/
MIT License
4.2k stars 516 forks source link

C++ get all members of sol:: table #1376

Closed Eunsolfs closed 2 years ago

Eunsolfs commented 2 years ago

I encountered a thorny problem when using c++ with sol2

I import the c++ function with sol:: table as a parameter into Lua, and try to get the sol:: table parameter from the Lua file and pass it to the c++ function. The c++ function is responsible for unpacking the sol:: table, converting the contents of the table into different types of parameters according to my needs, and passing it to another c++ function But I found that I couldn't get every element of sol:: table

The code is as follows:

bool lua_func(sol::table tab) { // i don't know how to unpacking the tab //and converting the contents of the table into different types of parameters according to my needs //tab ={1, 2, "c", 1.2} // how can I fulfill this requirement ? I really need your help! int a; int b; string c; double d; //some operations to unpacking the tab //and converting the contents of the table into different types of parameters according to my needs funA(a, b, c, d); } bool funA(int a, int b, std::string c, double sim){ //some operation.... return true; }

skaarj1989 commented 2 years ago

something like this?

tab.for_each([](const sol::object &key, const sol::object &value) {
  // use key.as<std::string>() or value.get_type()
});
Eunsolfs commented 2 years ago

I finally came up with a way to fill my needs, but this solution is not beautiful, or it is clumsy. The following is the solution: The premise of using this method is that I clearly know what type of data is stored in the table and the amount of data.

//lua -> tab = {1, 2,"str1", "str2", 0.55};
std::tuple<int, int, string, string, double> table2fmcfp(sol::table tab) {
    int a, b;
    string c, d;
    double e;
    int index = 1;
    if (lua_getTableLenth(tab) == 5) {
        tab.for_each([&](sol::object const& key, sol::object const& value) {
            if (index == 1) {
                a = value.as<int>();
            }
            else if (index == 2) {
                b = value.as<int>();
            }
            else if (index == 3) {
                c = value.as<std::string>();
            }
            else if (index == 4) {
                d = value.as<std::string>();
            }
            else if (index == 5) {
                e = value.as<double>();
            }
            index++;
        });
    }
    return std::make_tuple(a, b, c, d, e);
}

Maybe the developers in your team can improve this method and put it into the future sol2 function. In this way, not only complete the for_each loop and avoid accidents, finally help users to get the values in the table they want to get

Rochet2 commented 2 years ago

Here are some alternative ways to achieve the same. However, if a user passes wrong data into the function the error messages are somewhat messy.

https://godbolt.org/z/W436vE791

```cpp #define SOL_ALL_SAFETIES_ON 1 #include #include #include #include bool funA(int a, int b, std::string c, double sim){ std::cout << a << " " << b << " " << c << " " << sim << std::endl; return true; } bool lua_func_1(sol::table tab) { int a = tab[1]; int b = tab[2]; std::string c = tab[3]; double d = tab[4]; return funA(a,b,c,d); } bool lua_func_2(sol::table tab, sol::this_state s) { sol::state_view lua(s); std::tuple params = lua["table"]["unpack"](tab); return std::apply(funA, params); } template std::tuple table_to_tuple(sol::table& tab) { const auto unpack_table = [] (sol::table& tab, std::index_sequence) { return std::make_tuple( tab[Is+1]... ); }; return unpack_table(tab, std::make_index_sequence{}); } bool lua_func_3(sol::table tab) { return std::apply(funA, table_to_tuple(tab)); } int main() { sol::state lua; lua.open_libraries(); lua["lua_func_1"] = lua_func_1; lua["lua_func_2"] = lua_func_2; lua["lua_func_3"] = lua_func_3; lua.script("lua_func_1({1, 2, 'c', 1.2})"); lua.script("lua_func_2({1, 2, 'c', 1.2})"); lua.script("lua_func_3({1, 2, 'c', 1.2})"); return 0; } ```
Eunsolfs commented 2 years ago

thank you very much!

---- Replied Message ---- | From | @.> | | Date | 07/03/2022 19:38 | | To | @.> | | Cc | @.**@.> | | Subject | Re: [ThePhD/sol2] C++ get all members of sol:: table (Issue #1376) |

Here are some alternative ways to achieve the same. However, if a user passes wrong data into the function the error messages are somewhat messy.

https://godbolt.org/z/W436vE791

defineSOL_ALL_SAFETIES_ON1

include<sol/sol.hpp>

include

include

includeboolfunA(int a, int b, std::string c, double sim){

std::cout << a << "" << b << "" << c << "" << sim << std::endl;
returntrue;

}

boollua_func_1(sol::table tab) { int a = tab[1]; int b = tab[2]; std::string c = tab[3]; double d = tab[4]; returnfunA(a,b,c,d); }

boollua_func_2(sol::table tab, sol::this_state s) { sol::state_view lua(s); std::tuple<int, int, std::string, double> params = lua["table"]"unpack"; returnstd::apply(funA, params); }

template std::tuple<T...> table_to_tuple(sol::table& tab) { constauto unpack_table = [] (sol::table& tab, std::index_sequence) { return std::make_tuple<T...>( tab[Is+1]... ); }; returnunpack_table(tab, std::make_index_sequence<sizeof...(T)>{}); } boollua_func_3(sol::table tab) { returnstd::apply(funA, table_to_tuple<int, int, std::string, double>(tab)); }

intmain() { sol::state lua; lua.open_libraries();

lua["lua_func_1"] = lua_func_1;
lua["lua_func_2"] = lua_func_2;
lua["lua_func_3"] = lua_func_3;

lua.script("lua_func_1({1, 2, 'c', 1.2})");
lua.script("lua_func_2({1, 2, 'c', 1.2})");
lua.script("lua_func_3({1, 2, 'c', 1.2})");
return0;

}

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>