Add registry constructors to tug things right out of the registry, and add a main_thread getter to aid in Joynet dev

This commit is contained in:
ThePhD 2016-12-10 00:25:25 -05:00
parent c6110e5711
commit edeb81a7e1
16 changed files with 249 additions and 23 deletions

View File

@ -20,8 +20,11 @@ members
:caption: constructor: reference
reference(lua_State* L, int index = -1);
reference(lua_State* L, ref_index index);
template <typename Object>
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

View File

@ -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<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<thread>` and :doc:`coroutines<coroutine>`).
.. 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
-------

View File

@ -0,0 +1,19 @@
binary size, compile time
=========================
getting good final product out of sol2
--------------------------------------
For individiauls who use :doc:`usertypes<api/usertype>` 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<api/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.

View File

@ -33,6 +33,7 @@ get going:
tutorial/all-the-things
tutorial/tutorial-top
errors
compilation
features
usertypes
traits

View File

@ -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<basic_function>(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<basic_function>(L, -1, type_panic);
#endif // Safety
}
template<typename... Args>
function_result operator()(Args&&... args) const {
@ -9299,6 +9328,12 @@ namespace sol {
stack::check<basic_protected_function>(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<basic_protected_function>(L, -1, type_panic);
#endif // Safety
}
template<typename... Args>
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 <typename Super>
basic_object(const proxy_base<Super>& r) noexcept : basic_object(r.operator basic_object()) {}
template <typename Super>
basic_object(proxy_base<Super>&& r) noexcept : basic_object(r.operator basic_object()) {}
template <typename Super>
basic_object& operator=(const proxy_base<Super>& r) { this->operator=(r.operator basic_object()); return *this; }
template <typename Super>
basic_object& operator=(proxy_base<Super>&& 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 <typename T, typename... Args>
basic_object(lua_State* L, in_place_type_t<T>, Args&&... args) noexcept : basic_object(std::integral_constant<bool, !std::is_base_of<stack_reference, base_t>::value>(), L, -stack::push<T>(L, std::forward<Args>(args)...)) {}
template <typename T, typename... Args>
basic_object(lua_State* L, in_place_t, T&& arg, Args&&... args) noexcept : basic_object(L, in_place<T>, std::forward<T>(arg), std::forward<Args>(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 <typename Super>
basic_object& operator=(const proxy_base<Super>& r) { this->operator=(r.operator basic_object()); return *this; }
template <typename Super>
basic_object& operator=(proxy_base<Super>&& r) { this->operator=(r.operator basic_object()); return *this; }
template<typename T>
decltype(auto) as() const {
@ -11838,6 +11874,12 @@ namespace sol {
stack::check<basic_table_core>(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<basic_table_core>(L, -1, type_panic);
#endif // Safety
}
iterator begin() const {
return iterator(*this);
@ -12790,7 +12832,8 @@ namespace sol {
template <>
struct getter<lua_thread_state> {
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<lua_thread_state> {
template <typename Handler>
optional<lua_thread_state> get(lua_State* L, int index, Handler&& handler) {
optional<lua_thread_state> 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<lua_thread_state>(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 <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, thread>>, std::is_base_of<reference, meta::unqualified_t<T>>> = meta::enabler>
thread(T&& r) : reference(std::forward<T>(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 <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, coroutine>>, std::is_base_of<reference, meta::unqualified_t<T>>> = meta::enabler>
coroutine(T&& r) : reference(std::forward<T>(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<coroutine>(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<coroutine>(L, -1, type_panic);
#endif // Safety
}
call_status status() const noexcept {
return stats;

View File

@ -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 <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, coroutine>>, std::is_base_of<reference, meta::unqualified_t<T>>> = meta::enabler>
coroutine(T&& r) : reference(std::forward<T>(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<coroutine>(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<coroutine>(L, -1, type_panic);
#endif // Safety
}
call_status status() const noexcept {
return stats;

View File

@ -86,6 +86,12 @@ namespace sol {
stack::check<basic_function>(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<basic_function>(L, -1, type_panic);
#endif // Safety
}
template<typename... Args>
function_result operator()(Args&&... args) const {

View File

@ -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 <typename Super>
basic_object(const proxy_base<Super>& r) noexcept : basic_object(r.operator basic_object()) {}
template <typename Super>
basic_object(proxy_base<Super>&& r) noexcept : basic_object(r.operator basic_object()) {}
template <typename Super>
basic_object& operator=(const proxy_base<Super>& r) { this->operator=(r.operator basic_object()); return *this; }
template <typename Super>
basic_object& operator=(proxy_base<Super>&& 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 <typename T, typename... Args>
basic_object(lua_State* L, in_place_type_t<T>, Args&&... args) noexcept : basic_object(std::integral_constant<bool, !std::is_base_of<stack_reference, base_t>::value>(), L, -stack::push<T>(L, std::forward<Args>(args)...)) {}
template <typename T, typename... Args>
basic_object(lua_State* L, in_place_t, T&& arg, Args&&... args) noexcept : basic_object(L, in_place<T>, std::forward<T>(arg), std::forward<Args>(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 <typename Super>
basic_object& operator=(const proxy_base<Super>& r) { this->operator=(r.operator basic_object()); return *this; }
template <typename Super>
basic_object& operator=(proxy_base<Super>&& r) { this->operator=(r.operator basic_object()); return *this; }
template<typename T>
decltype(auto) as() const {

View File

@ -166,6 +166,12 @@ namespace sol {
stack::check<basic_protected_function>(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<basic_protected_function>(L, -1, type_panic);
#endif // Safety
}
template<typename... Args>
protected_function_result operator()(Args&&... args) const {

View File

@ -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();

View File

@ -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;

View File

@ -179,6 +179,12 @@ namespace sol {
stack::check<basic_table_core>(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<basic_table_core>(L, -1, type_panic);
#endif // Safety
}
iterator begin() const {
return iterator(*this);

View File

@ -48,7 +48,8 @@ namespace sol {
template <>
struct getter<lua_thread_state> {
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<lua_thread_state> {
template <typename Handler>
optional<lua_thread_state> get(lua_State* L, int index, Handler&& handler) {
optional<lua_thread_state> 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<lua_thread_state>(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 <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, thread>>, std::is_base_of<reference, meta::unqualified_t<T>>> = meta::enabler>
thread(T&& r) : reference(std::forward<T>(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 }) {}

View File

@ -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) {}

View File

@ -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
}
};

34
test_storage.cpp Normal file
View File

@ -0,0 +1,34 @@
#define SOL_CHECK_ARGUMENTS
#include <catch.hpp>
#include <sol.hpp>
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);
}
}