diff --git a/include/sol/usertype_storage.hpp b/include/sol/usertype_storage.hpp index 65f97701..349c0645 100644 --- a/include/sol/usertype_storage.hpp +++ b/include/sol/usertype_storage.hpp @@ -444,6 +444,7 @@ namespace sol { namespace u_detail { storage.clear(); string_keys.clear(); auxiliary_keys.clear(); + string_keys_storage.clear(); } template diff --git a/single/include/sol/config.hpp b/single/include/sol/config.hpp index ac613d74..eac9d1f0 100644 --- a/single/include/sol/config.hpp +++ b/single/include/sol/config.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2020-12-30 02:56:57.400161 UTC -// This header was generated with sol v3.2.3 (revision b9115623) +// Generated 2020-12-30 14:35:06.977732 UTC +// This header was generated with sol v3.2.3 (revision f7d99b05) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_CONFIG_HPP diff --git a/single/include/sol/forward.hpp b/single/include/sol/forward.hpp index 345f2268..3ffce1d9 100644 --- a/single/include/sol/forward.hpp +++ b/single/include/sol/forward.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2020-12-30 02:56:57.318161 UTC -// This header was generated with sol v3.2.3 (revision b9115623) +// Generated 2020-12-30 14:35:06.965732 UTC +// This header was generated with sol v3.2.3 (revision f7d99b05) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP diff --git a/single/include/sol/sol.hpp b/single/include/sol/sol.hpp index 27a41253..f31d9079 100644 --- a/single/include/sol/sol.hpp +++ b/single/include/sol/sol.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2020-12-30 02:56:53.623397 UTC -// This header was generated with sol v3.2.3 (revision b9115623) +// Generated 2020-12-30 14:35:06.134327 UTC +// This header was generated with sol v3.2.3 (revision f7d99b05) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -22414,6 +22414,7 @@ namespace sol { namespace u_detail { storage.clear(); string_keys.clear(); auxiliary_keys.clear(); + string_keys_storage.clear(); } template diff --git a/tests/regression_tests/simple/source/1096 - functions binding wrong.cpp b/tests/regression_tests/simple/source/1096 - functions binding wrong.cpp index 76e8dd2e..642202c4 100644 --- a/tests/regression_tests/simple/source/1096 - functions binding wrong.cpp +++ b/tests/regression_tests/simple/source/1096 - functions binding wrong.cpp @@ -39,4 +39,4 @@ unsigned int regression_1096() { } } return accumulated_errors; -} \ No newline at end of file +} diff --git a/tests/runtime_tests/source/usertypes.unregister.cpp b/tests/runtime_tests/source/usertypes.unregister.cpp index 0c652f53..f797cddd 100644 --- a/tests/runtime_tests/source/usertypes.unregister.cpp +++ b/tests/runtime_tests/source/usertypes.unregister.cpp @@ -25,17 +25,27 @@ #include -struct unregister_me { - double b = 5.5; - std::string f_val = "registered"; +inline namespace sol2_tests_usertypes_unregister { + struct unregister_me { + double b = 5.5; + std::string f_val = "registered"; - unregister_me() { - } + unregister_me() { + } - std::string f() { - return f_val; - } -}; + std::string f() { + return f_val; + } + }; + + struct goddamnit {}; + + struct state_pointer_and_registration { + sol::state* lua_ptr; + bool* registered_ptr; + }; + +} TEST_CASE("usertypes/unregister", "make sure that a class can still be bound but that it becomes completely unregistered") { const sol::string_view line1 = "assert(u:f() == 'registered')"; @@ -145,3 +155,88 @@ TEST_CASE("usertypes/unregister", "make sure that a class can still be bound but REQUIRE(u.f() == "registered"); } } + +TEST_CASE("usertypes/unregister multiple states", "guarantee unregistration can happen from multiple states without interfering with the originals") { + sol::state lua0; + bool lua0_registered = false; + lua0.open_libraries(sol::lib::base); + lua0.new_usertype("goddamnit", "a", sol::property([i=0](){ return i; })); + + sol::state lua1; + bool lua1_registered = false; + lua1.open_libraries(sol::lib::base); + lua1.new_usertype("goddamnit", "a", sol::property([i=1](){ return i; })); + + sol::state lua2; + bool lua2_registered = false; + lua2.open_libraries(sol::lib::base); + lua2.new_usertype("goddamnit", "a", sol::property([i=2](){ return i; })); + + state_pointer_and_registration states[] = { { &lua0, &lua0_registered }, { &lua1, &lua1_registered }, { &lua2, &lua2_registered } }; + const std::size_t number_of_states = std::size(states); + + auto prove = [](sol::state& lua, const bool& is_registered, std::size_t state_index) { + std::string code = "val = gdi.a\nprint(val)"; + if (is_registered) { + sol::optional maybe_error = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE_FALSE(maybe_error.has_value()); + sol::optional maybe_val = lua["val"]; + REQUIRE(maybe_val.has_value()); + const std::size_t& val = *maybe_val; + REQUIRE(val == state_index); + } + else { + sol::optional maybe_error = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(maybe_error.has_value()); + const sol::error& error = *maybe_error; + std::string err = error.what(); + REQUIRE((err.find("attempt to index") != std::string::npos) || (err.find("gdi") != std::string::npos)); + } + }; + + for (std::size_t i = 0; i < number_of_states; ++i) { + state_pointer_and_registration& repr = states[i]; + sol::state& lua = *repr.lua_ptr; + bool& is_registered = *repr.registered_ptr; + + lua["gdi"] = goddamnit{}; + is_registered = true; + + prove(lua, is_registered, i); + } + { + sol::metatable goddamnit_usertype0 = lua0["goddamnit"]; + goddamnit_usertype0.unregister(); + lua0_registered = false; + } + for (std::size_t i = 0; i < number_of_states; ++i) { + state_pointer_and_registration& repr = states[i]; + sol::state& lua = *repr.lua_ptr; + bool& is_registered = *repr.registered_ptr; + + prove(lua, is_registered, i); + } + { + sol::usertype goddamnit_usertype1 = lua1["goddamnit"]; + goddamnit_usertype1.unregister(); + lua1_registered = false; + } + for (std::size_t i = 0; i < number_of_states; ++i) { + state_pointer_and_registration& repr = states[i]; + sol::state& lua = *repr.lua_ptr; + bool& is_registered = *repr.registered_ptr; + + prove(lua, is_registered, i); + } + { + lua0.new_usertype("goddamnit", "a", sol::property([i=0](){ return i; })); + lua0_registered = true; + } + for (std::size_t i = 0; i < number_of_states; ++i) { + state_pointer_and_registration& repr = states[i]; + sol::state& lua = *repr.lua_ptr; + bool& is_registered = *repr.registered_ptr; + + prove(lua, is_registered, i); + } +} diff --git a/tests/runtime_tests/source/variadics.cpp b/tests/runtime_tests/source/variadics.cpp index 90a3dc99..7d9d7b3d 100644 --- a/tests/runtime_tests/source/variadics.cpp +++ b/tests/runtime_tests/source/variadics.cpp @@ -317,3 +317,35 @@ local obj3 = foo3.new(0, 1, 2) sol::script_pass_on_error); REQUIRE_FALSE(maybe_err.has_value()); } + +TEST_CASE("variadics/overloads with fallbacks", + "Test that 'fuzzy' types like optional and variadic_args can coexist and have optional numbers of arguments passed to them") { + + sol::state lua; + lua.open_libraries(sol::lib::base); + + auto test = lua[u8"test"].get_or_create(); + auto derp = test[u8"derp"].get_or_create(); + + derp[u8"herp"] + = sol::overload([](sol::this_state, const std::string_view&, const std::string_view&, const std::string_view&, sol::optional) { return 1; }, + [](const std::string_view&, const std::string_view&, sol::function, sol::optional) { return 2; }, + [](sol::this_state, sol::variadic_args) { return 3; }); + + const std::string_view code = R"( +assert(test.derp.herp('str1', 'str2', 'str3') == 1); +assert(test.derp.herp('str1', 'str2', 'str3', 42) == 1); +assert(test.derp.herp('str1', 'str2', 'str3', nil) == 1); + +assert(test.derp.herp('str1', 'str2', function(r) end) == 2); +assert(test.derp.herp('str1', 'str2', function(r) end, 42) == 2); +assert(test.derp.herp('str1', 'str2', function(r) end, nil) == 2); + +assert(test.derp.herp('str1', 'str2', 'str3', {}) == 3); +assert(test.derp.herp('str1', 'str2', function(r) end, {}) == 3); +assert(test.derp.herp(1, 2, 3, 4, 5, 6, 7) == 3); +assert(test.derp.herp('str1', 'str2', 'str3', 'str4') == 3); +)"; + sol::optional maybe_error = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE_FALSE(maybe_error.has_value()); +}