diff --git a/docs/source/api/reference.rst b/docs/source/api/reference.rst index 37886dc2..57869de7 100644 --- a/docs/source/api/reference.rst +++ b/docs/source/api/reference.rst @@ -20,8 +20,11 @@ members :caption: constructor: reference reference(lua_State* L, int index = -1); + reference(lua_State* L, ref_index index); + template + reference(Object&& o); -Creates a reference from the Lua stack at the specified index, saving it into the metatable registry. This constructor is exposed on all types that derive from ``sol::reference``. +The first constructor creates a reference from the Lua stack at the specified index, saving it into the metatable registry. The second attemtps to register something that already exists in the registry. The third attempts to reference a pre-existing object and create a reference to it. These constructors are exposed on all types that derive from ``sol::reference``, meaning that you can grab tables, functions, and coroutines from the registry, stack, or from other objects easily. .. code-block:: cpp :caption: function: push referred-to element from the stack diff --git a/docs/source/api/thread.rst b/docs/source/api/thread.rst index e5372ccd..b7349d97 100644 --- a/docs/source/api/thread.rst +++ b/docs/source/api/thread.rst @@ -13,6 +13,21 @@ a separate state that can contain and run functions A CPU thread is not always equivalent to a new thread in Lua: ``std::this_thread::get_id()`` can be the same for 2 callbacks that have 2 distinct Lua threads. In order to know which thread a callback was called in, hook into :doc:`sol::this_state` from your Lua callback and then construct a ``sol::thread``, passing in the ``sol::this_state`` for both the first and last arguments. Then examine the results of the status and ``is_...`` calls below. +free function +------------- + +.. code-block:: cpp + :caption: function: main_thread + + main_thread(lua_State* current, lua_State* backup_if_bad_platform = nullptr); + +The function ``sol::main_thread( ... )`` retrieves the main thread of the application on Lua 5.2 and above *only*. It is designed for code that needs to be multithreading-aware (e.g., uses multiple :doc:`threads` and :doc:`coroutines`). + +.. warning:: + + This code function will be present in Lua 5.1/LuaJIT, but only have proper behavior when given a single argument on Lua 5.2 and beyond. Lua 5.1 does not support retrieving the main thread from its registry, and therefore it is entirely suggested if you are writing cross-platform Lua code that you must store the main thread of your application in some global storage accessible somewhere. Then, pass this item into the ``sol::main_thread( possibly_thread_state, my_actual_main_state )`` and it will select that ``my_actual_main_state`` every time. If you are not going to use Lua 5.1 / LuaJIT, you can ignore the last parameter. + + members ------- diff --git a/docs/source/compilation.rst b/docs/source/compilation.rst new file mode 100644 index 00000000..7041c465 --- /dev/null +++ b/docs/source/compilation.rst @@ -0,0 +1,19 @@ +binary size, compile time +========================= +getting good final product out of sol2 +-------------------------------------- + +For individiauls who use :doc:`usertypes` a lot, they can find their compilation times increase. This is due to C++11 and C++14 not having very good facilities for handling template parameters and variadic template parameters. There are a few things in cutting-edge C++17 and C++Next that sol can use, but the problem is many people cannot work with the latest and greatest: therefore, we have to use older techniques that result in a fair amount of redundant function specializations that can be subject to the pickiness of the compiler's inlining and other such techniques. + +Here are some notes on achieving better compile-times without sacrificing too much performance: + +* When you bind lots of usertypes, put them all in a *single* translation unit (one C++ file) so that it is not recompiled multiple times over, only to be discarded later by the linker. + - Remember that the usertype binding ends up being serialized into the Lua state, so you never need them to appear in a header and cause that same compilation overhead for every compiled unit in your project. +* For extremely large usertypes, consider using :doc:`simple_usertype`. + - It performs much more work at runtime rather than compile-time, and should still give comparative performance (but it loses out in some cases for variable bindings or when you bind all functions to a usertype). +* If you are developing a shared library, restrict your overall surface area by specifically and explicitly marking functions as visible and exported and letting everything else as hidden or invisible by default + + +The next step for Sol from a developer standpoint is to formally make the library a C++17 one. This would mean using Fold Expressions and several other things which will reduce compilation time drastically. Unfortunately, that means also boosting compiler requirements. While most wouldn't care, others are very slow to upgrade: finding the balance is difficult, and often we have to opt for backwards compatibility and fixes for bad / older compilers (of which there are many in the codebase already). + +Hopefully, as things progress, we move things forward. diff --git a/docs/source/index.rst b/docs/source/index.rst index ca523339..77fb8fdf 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -33,6 +33,7 @@ get going: tutorial/all-the-things tutorial/tutorial-top errors + compilation features usertypes traits diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index 58bb0510..cf0f4138 100644 --- a/single/sol/sol.hpp +++ b/single/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 2016-12-06 15:59:21.255479 UTC -// This header was generated with sol v2.15.4 (revision 16152c7) +// Generated 2016-12-10 04:29:58.120585 UTC +// This header was generated with sol v2.15.5 (revision c6110e5) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -3146,6 +3146,12 @@ namespace sol { operator int() const { return index; } }; + struct ref_index { + int index; + ref_index(int idx) : index(idx) {} + operator int() const { return index; } + }; + struct lightuserdata_value { void* value; lightuserdata_value(void* data) : value(data) {} @@ -3753,6 +3759,7 @@ namespace sol { stack_reference(lua_State* L, int i) noexcept : L(L), index(lua_absindex(L, i)) {} stack_reference(lua_State* L, absolute_index i) noexcept : L(L), index(i) {} stack_reference(lua_State* L, raw_index i) noexcept : L(L), index(i) {} + stack_reference(lua_State* L, ref_index i) noexcept = delete; stack_reference(stack_reference&& o) noexcept = default; stack_reference& operator=(stack_reference&&) noexcept = default; stack_reference(const stack_reference&) noexcept = default; @@ -3878,6 +3885,10 @@ namespace sol { lua_pushvalue(lua_state(), index); ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); } + reference(lua_State* L, ref_index index) noexcept : luastate(L) { + lua_rawgeti(L, LUA_REGISTRYINDEX, index.index); + ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); + } ~reference() noexcept { deref(); @@ -3995,6 +4006,12 @@ namespace sol { basic_userdata(lua_State* L, int index = -1) : base_t(L, index) { #ifdef SOL_CHECK_ARGUMENTS type_assert(L, index, type::userdata); +#endif // Safety + } + basic_userdata(lua_State* L, ref_index index) : base_t(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + type_assert(L, -1, type::userdata); #endif // Safety } }; @@ -4021,6 +4038,12 @@ namespace sol { basic_lightuserdata(lua_State* L, int index = -1) : base_t(L, index) { #ifdef SOL_CHECK_ARGUMENTS type_assert(L, index, type::lightuserdata); +#endif // Safety + } + basic_lightuserdata(lua_State* L, ref_index index) : base_t(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + type_assert(L, -1, type::lightuserdata); #endif // Safety } }; @@ -8990,6 +9013,12 @@ namespace sol { stack::check(L, index, type_panic); #endif // Safety } + basic_function(lua_State* L, ref_index index) : base_t(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + stack::check(L, -1, type_panic); +#endif // Safety + } template function_result operator()(Args&&... args) const { @@ -9299,6 +9328,12 @@ namespace sol { stack::check(L, index, type_panic); #endif // Safety } + basic_protected_function(lua_State* L, ref_index index, reference eh = get_default_handler()) : base_t(L, index), error_handler(std::move(eh)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + stack::check(L, -1, type_panic); +#endif // Safety + } template protected_function_result operator()(Args&&... args) const { @@ -9694,25 +9729,26 @@ namespace sol { basic_object(lua_nil_t r) : base_t(r) {} basic_object(const basic_object&) = default; basic_object(basic_object&&) = default; - basic_object& operator=(const basic_object&) = default; - basic_object& operator=(basic_object&&) = default; - basic_object& operator=(const base_t& b) { base_t::operator=(b); return *this; } - basic_object& operator=(base_t&& b) { base_t::operator=(std::move(b)); return *this; } basic_object(const stack_reference& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {} basic_object(stack_reference&& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {} template basic_object(const proxy_base& r) noexcept : basic_object(r.operator basic_object()) {} template basic_object(proxy_base&& r) noexcept : basic_object(r.operator basic_object()) {} - template - basic_object& operator=(const proxy_base& r) { this->operator=(r.operator basic_object()); return *this; } - template - basic_object& operator=(proxy_base&& r) { this->operator=(r.operator basic_object()); return *this; } basic_object(lua_State* L, int index = -1) noexcept : base_t(L, index) {} + basic_object(lua_State* L, ref_index index) noexcept : base_t(L, index) {} template basic_object(lua_State* L, in_place_type_t, Args&&... args) noexcept : basic_object(std::integral_constant::value>(), L, -stack::push(L, std::forward(args)...)) {} template basic_object(lua_State* L, in_place_t, T&& arg, Args&&... args) noexcept : basic_object(L, in_place, std::forward(arg), std::forward(args)...) {} + basic_object& operator=(const basic_object&) = default; + basic_object& operator=(basic_object&&) = default; + basic_object& operator=(const base_t& b) { base_t::operator=(b); return *this; } + basic_object& operator=(base_t&& b) { base_t::operator=(std::move(b)); return *this; } + template + basic_object& operator=(const proxy_base& r) { this->operator=(r.operator basic_object()); return *this; } + template + basic_object& operator=(proxy_base&& r) { this->operator=(r.operator basic_object()); return *this; } template decltype(auto) as() const { @@ -11838,6 +11874,12 @@ namespace sol { stack::check(L, index, type_panic); #endif // Safety } + basic_table_core(lua_State* L, ref_index index) : base_t(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + stack::check(L, -1, type_panic); +#endif // Safety + } iterator begin() const { return iterator(*this); @@ -12790,7 +12832,8 @@ namespace sol { template <> struct getter { - lua_thread_state get(lua_State* L, int index = -1) { + lua_thread_state get(lua_State* L, int index, record& tracking) { + tracking.use(1); lua_thread_state lts{ lua_tothread(L, index) }; return lts; } @@ -12799,23 +12842,38 @@ namespace sol { template <> struct check_getter { template - optional get(lua_State* L, int index, Handler&& handler) { + optional get(lua_State* L, int index, Handler&& handler, record& tracking) { lua_thread_state lts{ lua_tothread(L, index) }; if (lts.L == nullptr) { handler(L, index, type::thread, type_of(L, index)); return nullopt; } + tracking.use(1); return lts; } }; } +#if SOL_LUA_VERSION < 502 + inline lua_State* main_thread(lua_State* L, lua_State* backup_if_unsupported = nullptr) { + return backup_if_unsupported; + } +#else + inline lua_State* main_thread(lua_State* L, lua_State* = nullptr) { + lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); + lua_thread_state s = stack::pop(L); + return s.L; + } +#endif // Lua 5.2+ has the main thread getter + class thread : public reference { public: thread() noexcept = default; thread(const thread&) = default; thread(thread&&) = default; + template , thread>>, std::is_base_of>> = meta::enabler> + thread(T&& r) : reference(std::forward(r)) {} thread(const stack_reference& r) : thread(r.lua_state(), r.stack_index()) {}; thread(stack_reference&& r) : thread(r.lua_state(), r.stack_index()) {}; thread& operator=(const thread&) = default; @@ -12823,6 +12881,12 @@ namespace sol { thread(lua_State* L, int index = -1) : reference(L, index) { #ifdef SOL_CHECK_ARGUMENTS type_assert(L, index, type::thread); +#endif // Safety + } + thread(lua_State* L, ref_index index) : reference(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + type_assert(L, -1, type::thread); #endif // Safety } thread(lua_State* L, lua_State* actualthread) : thread(L, lua_thread_state{ actualthread }) {} @@ -12920,12 +12984,25 @@ namespace sol { public: coroutine() noexcept = default; coroutine(const coroutine&) noexcept = default; + coroutine(coroutine&&) noexcept = default; coroutine& operator=(const coroutine&) noexcept = default; + coroutine& operator=(coroutine&&) noexcept = default; + template , coroutine>>, std::is_base_of>> = meta::enabler> + coroutine(T&& r) : reference(std::forward(r)) {} + coroutine(lua_nil_t r) : reference(r) {} + coroutine(const stack_reference& r) noexcept : coroutine(r.lua_state(), r.stack_index()) {} + coroutine(stack_reference&& r) noexcept : coroutine(r.lua_state(), r.stack_index()) {} coroutine(lua_State* L, int index = -1) : reference(L, index) { #ifdef SOL_CHECK_ARGUMENTS stack::check(L, index, type_panic); #endif // Safety } + coroutine(lua_State* L, ref_index index) : reference(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + stack::check(L, -1, type_panic); +#endif // Safety + } call_status status() const noexcept { return stats; diff --git a/sol/coroutine.hpp b/sol/coroutine.hpp index 4abfa78e..667f6529 100644 --- a/sol/coroutine.hpp +++ b/sol/coroutine.hpp @@ -72,12 +72,25 @@ namespace sol { public: coroutine() noexcept = default; coroutine(const coroutine&) noexcept = default; + coroutine(coroutine&&) noexcept = default; coroutine& operator=(const coroutine&) noexcept = default; + coroutine& operator=(coroutine&&) noexcept = default; + template , coroutine>>, std::is_base_of>> = meta::enabler> + coroutine(T&& r) : reference(std::forward(r)) {} + coroutine(lua_nil_t r) : reference(r) {} + coroutine(const stack_reference& r) noexcept : coroutine(r.lua_state(), r.stack_index()) {} + coroutine(stack_reference&& r) noexcept : coroutine(r.lua_state(), r.stack_index()) {} coroutine(lua_State* L, int index = -1) : reference(L, index) { #ifdef SOL_CHECK_ARGUMENTS stack::check(L, index, type_panic); #endif // Safety } + coroutine(lua_State* L, ref_index index) : reference(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + stack::check(L, -1, type_panic); +#endif // Safety + } call_status status() const noexcept { return stats; diff --git a/sol/function.hpp b/sol/function.hpp index d69a8251..2d8c20b3 100644 --- a/sol/function.hpp +++ b/sol/function.hpp @@ -86,6 +86,12 @@ namespace sol { stack::check(L, index, type_panic); #endif // Safety } + basic_function(lua_State* L, ref_index index) : base_t(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + stack::check(L, -1, type_panic); +#endif // Safety + } template function_result operator()(Args&&... args) const { diff --git a/sol/object.hpp b/sol/object.hpp index ab9f47cd..b1fe2863 100644 --- a/sol/object.hpp +++ b/sol/object.hpp @@ -90,25 +90,26 @@ namespace sol { basic_object(lua_nil_t r) : base_t(r) {} basic_object(const basic_object&) = default; basic_object(basic_object&&) = default; - basic_object& operator=(const basic_object&) = default; - basic_object& operator=(basic_object&&) = default; - basic_object& operator=(const base_t& b) { base_t::operator=(b); return *this; } - basic_object& operator=(base_t&& b) { base_t::operator=(std::move(b)); return *this; } basic_object(const stack_reference& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {} basic_object(stack_reference&& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {} template basic_object(const proxy_base& r) noexcept : basic_object(r.operator basic_object()) {} template basic_object(proxy_base&& r) noexcept : basic_object(r.operator basic_object()) {} - template - basic_object& operator=(const proxy_base& r) { this->operator=(r.operator basic_object()); return *this; } - template - basic_object& operator=(proxy_base&& r) { this->operator=(r.operator basic_object()); return *this; } basic_object(lua_State* L, int index = -1) noexcept : base_t(L, index) {} + basic_object(lua_State* L, ref_index index) noexcept : base_t(L, index) {} template basic_object(lua_State* L, in_place_type_t, Args&&... args) noexcept : basic_object(std::integral_constant::value>(), L, -stack::push(L, std::forward(args)...)) {} template basic_object(lua_State* L, in_place_t, T&& arg, Args&&... args) noexcept : basic_object(L, in_place, std::forward(arg), std::forward(args)...) {} + basic_object& operator=(const basic_object&) = default; + basic_object& operator=(basic_object&&) = default; + basic_object& operator=(const base_t& b) { base_t::operator=(b); return *this; } + basic_object& operator=(base_t&& b) { base_t::operator=(std::move(b)); return *this; } + template + basic_object& operator=(const proxy_base& r) { this->operator=(r.operator basic_object()); return *this; } + template + basic_object& operator=(proxy_base&& r) { this->operator=(r.operator basic_object()); return *this; } template decltype(auto) as() const { diff --git a/sol/protected_function.hpp b/sol/protected_function.hpp index 583a8dd9..7abe599a 100644 --- a/sol/protected_function.hpp +++ b/sol/protected_function.hpp @@ -166,6 +166,12 @@ namespace sol { stack::check(L, index, type_panic); #endif // Safety } + basic_protected_function(lua_State* L, ref_index index, reference eh = get_default_handler()) : base_t(L, index), error_handler(std::move(eh)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + stack::check(L, -1, type_panic); +#endif // Safety + } template protected_function_result operator()(Args&&... args) const { diff --git a/sol/reference.hpp b/sol/reference.hpp index 732506ad..1093f247 100644 --- a/sol/reference.hpp +++ b/sol/reference.hpp @@ -98,6 +98,10 @@ namespace sol { lua_pushvalue(lua_state(), index); ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); } + reference(lua_State* L, ref_index index) noexcept : luastate(L) { + lua_rawgeti(L, LUA_REGISTRYINDEX, index.index); + ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); + } ~reference() noexcept { deref(); diff --git a/sol/stack_reference.hpp b/sol/stack_reference.hpp index d590c3b0..e7505c83 100644 --- a/sol/stack_reference.hpp +++ b/sol/stack_reference.hpp @@ -39,6 +39,7 @@ namespace sol { stack_reference(lua_State* L, int i) noexcept : L(L), index(lua_absindex(L, i)) {} stack_reference(lua_State* L, absolute_index i) noexcept : L(L), index(i) {} stack_reference(lua_State* L, raw_index i) noexcept : L(L), index(i) {} + stack_reference(lua_State* L, ref_index i) noexcept = delete; stack_reference(stack_reference&& o) noexcept = default; stack_reference& operator=(stack_reference&&) noexcept = default; stack_reference(const stack_reference&) noexcept = default; diff --git a/sol/table_core.hpp b/sol/table_core.hpp index 87000587..3a37097e 100644 --- a/sol/table_core.hpp +++ b/sol/table_core.hpp @@ -179,6 +179,12 @@ namespace sol { stack::check(L, index, type_panic); #endif // Safety } + basic_table_core(lua_State* L, ref_index index) : base_t(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + stack::check(L, -1, type_panic); +#endif // Safety + } iterator begin() const { return iterator(*this); diff --git a/sol/thread.hpp b/sol/thread.hpp index 9ac5736e..c1395b31 100644 --- a/sol/thread.hpp +++ b/sol/thread.hpp @@ -48,7 +48,8 @@ namespace sol { template <> struct getter { - lua_thread_state get(lua_State* L, int index = -1) { + lua_thread_state get(lua_State* L, int index, record& tracking) { + tracking.use(1); lua_thread_state lts{ lua_tothread(L, index) }; return lts; } @@ -57,23 +58,38 @@ namespace sol { template <> struct check_getter { template - optional get(lua_State* L, int index, Handler&& handler) { + optional get(lua_State* L, int index, Handler&& handler, record& tracking) { lua_thread_state lts{ lua_tothread(L, index) }; if (lts.L == nullptr) { handler(L, index, type::thread, type_of(L, index)); return nullopt; } + tracking.use(1); return lts; } }; } +#if SOL_LUA_VERSION < 502 + inline lua_State* main_thread(lua_State* L, lua_State* backup_if_unsupported = nullptr) { + return backup_if_unsupported; + } +#else + inline lua_State* main_thread(lua_State* L, lua_State* = nullptr) { + lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); + lua_thread_state s = stack::pop(L); + return s.L; + } +#endif // Lua 5.2+ has the main thread getter + class thread : public reference { public: thread() noexcept = default; thread(const thread&) = default; thread(thread&&) = default; + template , thread>>, std::is_base_of>> = meta::enabler> + thread(T&& r) : reference(std::forward(r)) {} thread(const stack_reference& r) : thread(r.lua_state(), r.stack_index()) {}; thread(stack_reference&& r) : thread(r.lua_state(), r.stack_index()) {}; thread& operator=(const thread&) = default; @@ -81,6 +97,12 @@ namespace sol { thread(lua_State* L, int index = -1) : reference(L, index) { #ifdef SOL_CHECK_ARGUMENTS type_assert(L, index, type::thread); +#endif // Safety + } + thread(lua_State* L, ref_index index) : reference(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + type_assert(L, -1, type::thread); #endif // Safety } thread(lua_State* L, lua_State* actualthread) : thread(L, lua_thread_state{ actualthread }) {} diff --git a/sol/types.hpp b/sol/types.hpp index b2e38b49..e8817f97 100644 --- a/sol/types.hpp +++ b/sol/types.hpp @@ -194,6 +194,12 @@ namespace sol { operator int() const { return index; } }; + struct ref_index { + int index; + ref_index(int idx) : index(idx) {} + operator int() const { return index; } + }; + struct lightuserdata_value { void* value; lightuserdata_value(void* data) : value(data) {} diff --git a/sol/userdata.hpp b/sol/userdata.hpp index 6a4098f1..6f451c98 100644 --- a/sol/userdata.hpp +++ b/sol/userdata.hpp @@ -47,6 +47,12 @@ namespace sol { basic_userdata(lua_State* L, int index = -1) : base_t(L, index) { #ifdef SOL_CHECK_ARGUMENTS type_assert(L, index, type::userdata); +#endif // Safety + } + basic_userdata(lua_State* L, ref_index index) : base_t(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + type_assert(L, -1, type::userdata); #endif // Safety } }; @@ -73,6 +79,12 @@ namespace sol { basic_lightuserdata(lua_State* L, int index = -1) : base_t(L, index) { #ifdef SOL_CHECK_ARGUMENTS type_assert(L, index, type::lightuserdata); +#endif // Safety + } + basic_lightuserdata(lua_State* L, ref_index index) : base_t(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + type_assert(L, -1, type::lightuserdata); #endif // Safety } }; diff --git a/test_storage.cpp b/test_storage.cpp new file mode 100644 index 00000000..7708e53c --- /dev/null +++ b/test_storage.cpp @@ -0,0 +1,34 @@ +#define SOL_CHECK_ARGUMENTS + +#include +#include + +TEST_CASE("storage/registry=construction", "ensure entries from the registry can be retrieved") { + const auto& script = R"( +function f() + return 2 +end +)"; + + sol::state lua; + sol::function f = lua["f"]; + sol::reference r = lua["f"]; + sol::function regf(lua, sol::ref_index(f.registry_index())); + sol::reference regr(lua, sol::ref_index(f.registry_index())); + bool isequal = f == r; + REQUIRE(isequal); + isequal = f == regf; + REQUIRE(isequal); + isequal = f == regr; + REQUIRE(isequal); +} + +TEST_CASE("storage/main-thread", "ensure round-tripping and pulling out thread data even on 5.1 with a backup works") { + sol::state lua; + { + sol::stack_guard g(lua); + lua_State* orig = lua; + lua_State* ts = sol::main_thread(lua); + REQUIRE(ts == orig); + } +}