mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
implement main_reference as per @eliasdaler's suggestions
This commit is contained in:
parent
72143a494b
commit
8d828ac47b
|
@ -14,8 +14,8 @@ FixNamespaceComments: true
|
|||
ColumnLimit: 0
|
||||
AlignAfterOpenBracket: DontAlign # uses ContinuationIndentWidth for this instead
|
||||
AccessModifierOffset: -5 # do not push public: or private: around
|
||||
#AlignConsecutiveAssignments: true
|
||||
#AlignConsecutiveDeclarations: true
|
||||
#AlignConsecutiveAssignments: true # affects more than what's expected: do not use
|
||||
#AlignConsecutiveDeclarations: true # affects more than what's expected: do not use
|
||||
|
||||
# Type Alignment
|
||||
DerivePointerAlignment: false
|
||||
|
@ -29,7 +29,6 @@ ReflowComments: true
|
|||
|
||||
# Macros
|
||||
AlignEscapedNewlines: Left
|
||||
SortIncludes: false
|
||||
IndentPPDirectives: None
|
||||
|
||||
# Functions
|
||||
|
@ -38,6 +37,8 @@ AlwaysBreakAfterReturnType: None
|
|||
BreakConstructorInitializers: BeforeComma
|
||||
ConstructorInitializerIndentWidth: 0
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
|
||||
# Classes
|
||||
BreakBeforeInheritanceComma: false
|
||||
|
@ -66,7 +67,6 @@ AllowShortLoopsOnASingleLine: false
|
|||
AllowShortCaseLabelsOnASingleLine: false
|
||||
IndentCaseLabels: false
|
||||
|
||||
|
||||
# Spaces
|
||||
SpaceAfterCStyleCast: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
|
@ -81,6 +81,7 @@ MaxEmptyLinesToKeep: 1
|
|||
|
||||
# OCD
|
||||
SortUsingDeclarations: true
|
||||
SortIncludes: false
|
||||
|
||||
---
|
||||
Language: Cpp
|
||||
|
|
|
@ -18,6 +18,8 @@ working with multiple Lua threads
|
|||
|
||||
You can mitigate some of the pressure of using coroutines and threading by using the ``lua_xmove`` constructors that sol implements. Simply keep a reference to your ``sol::state_view`` or ``sol::state`` or the target ``lua_State*`` pointer, and pass it into the constructor along with the object you want to copy. Note that there is also some implicit ``lua_xmove`` checks that are done for copy and move assignment operators as well, as noted :ref:`at the reference constructor explanations<lua_xmove-note>`.
|
||||
|
||||
Furthermore, for every single ``sol::reference`` derived type, there exists a version prefixed with the word ``main_``, such as ``sol::main_table``, ``sol::main_function``, ``sol::main_object`` and similar. These classes, on construction, assignment and other operations, forcibly obtain the ``lua_State*`` associated with the main thread, if possible. Using these classes will allow your code to be immune when a wrapped coroutine or a lua thread is set to ``nil`` and then garbage-collected.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: transfer from state function
|
||||
:name: state-transfer
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -760,7 +760,7 @@ namespace sol {
|
|||
}
|
||||
|
||||
static void add_insert_after(std::false_type, lua_State* L, T&, stack_object) {
|
||||
luaL_error(L, "cannot call 'add' on type '%s': no suitable insert/push_back C++ functions", sol::detail::demangle<T>().data());
|
||||
luaL_error(L, "cannot call 'add' on type '%s': no suitable insert/push_back C++ functions", detail::demangle<T>().data());
|
||||
}
|
||||
|
||||
static void add_insert_after(std::true_type, lua_State*, T& self, stack_object value, iterator& at) {
|
||||
|
@ -1020,7 +1020,7 @@ namespace sol {
|
|||
auto& src = get_src(L);
|
||||
stack::push(L, next<ip>);
|
||||
stack::push<user<iter>>(L, src, deferred_traits::begin(L, src));
|
||||
stack::push(L, sol::lua_nil);
|
||||
stack::push(L, lua_nil);
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
|
|
@ -346,7 +346,7 @@ namespace sol {
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
struct pusher<T, std::enable_if_t<meta::all<is_container<meta::unqualified_t<T>>, meta::neg<meta::any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>>>>::value>> {
|
||||
struct pusher<T, std::enable_if_t<meta::all<is_container<meta::unqualified_t<T>>, meta::neg<is_lua_reference<meta::unqualified_t<T>>>>::value>> {
|
||||
typedef meta::unqualified_t<T> C;
|
||||
|
||||
static int push(lua_State* L, const T& cont) {
|
||||
|
@ -361,7 +361,7 @@ namespace sol {
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
struct pusher<T*, std::enable_if_t<meta::all<is_container<meta::unqualified_t<T>>, meta::neg<meta::any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>>>>::value>> {
|
||||
struct pusher<T*, std::enable_if_t<meta::all<is_container<meta::unqualified_t<T>>, meta::neg<is_lua_reference<meta::unqualified_t<T>>>>::value>> {
|
||||
typedef std::add_pointer_t<meta::unqualified_t<std::remove_pointer_t<T>>> C;
|
||||
|
||||
static int push(lua_State* L, T* cont) {
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
#include "thread.hpp"
|
||||
|
||||
namespace sol {
|
||||
class coroutine : public reference {
|
||||
template <typename base_t>
|
||||
class basic_coroutine : public base_t {
|
||||
private:
|
||||
call_status stats = call_status::yielded;
|
||||
|
||||
|
@ -66,41 +67,43 @@ 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)) {
|
||||
using base_t::lua_state;
|
||||
|
||||
basic_coroutine() noexcept = default;
|
||||
basic_coroutine(const basic_coroutine&) noexcept = default;
|
||||
basic_coroutine(basic_coroutine&&) noexcept = default;
|
||||
basic_coroutine& operator=(const basic_coroutine&) noexcept = default;
|
||||
basic_coroutine& operator=(basic_coroutine&&) noexcept = default;
|
||||
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_coroutine>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_coroutine(T&& r)
|
||||
: base_t(std::forward<T>(r)) {
|
||||
}
|
||||
coroutine(lua_nil_t r)
|
||||
: reference(r) {
|
||||
basic_coroutine(lua_nil_t r)
|
||||
: base_t(r) {
|
||||
}
|
||||
coroutine(const stack_reference& r) noexcept
|
||||
: coroutine(r.lua_state(), r.stack_index()) {
|
||||
basic_coroutine(const stack_reference& r) noexcept
|
||||
: basic_coroutine(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
coroutine(stack_reference&& r) noexcept
|
||||
: coroutine(r.lua_state(), r.stack_index()) {
|
||||
basic_coroutine(stack_reference&& r) noexcept
|
||||
: basic_coroutine(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
template <typename T, meta::enable<meta::neg<std::is_integral<meta::unqualified_t<T>>>, meta::neg<std::is_same<T, ref_index>>> = meta::enabler>
|
||||
coroutine(lua_State* L, T&& r)
|
||||
: coroutine(L, sol::ref_index(r.registry_index())) {
|
||||
template <typename T, meta::enable<meta::neg<is_lua_index<meta::unqualified_t<T>>>> = meta::enabler>
|
||||
basic_coroutine(lua_State* L, T&& r)
|
||||
: base_t(L, std::forward<T>(r)) {
|
||||
}
|
||||
coroutine(lua_State* L, int index = -1)
|
||||
: reference(L, index) {
|
||||
basic_coroutine(lua_State* L, int index = -1)
|
||||
: base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
constructor_handler handler{};
|
||||
stack::check<coroutine>(L, index, handler);
|
||||
stack::check<basic_coroutine>(lua_state(), index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
coroutine(lua_State* L, ref_index index)
|
||||
: reference(L, index) {
|
||||
basic_coroutine(lua_State* L, ref_index index)
|
||||
: base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<coroutine>(L, -1, handler);
|
||||
stack::check<basic_coroutine>(lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
|
@ -114,7 +117,7 @@ namespace sol {
|
|||
}
|
||||
|
||||
bool runnable() const noexcept {
|
||||
return valid()
|
||||
return base_t::valid()
|
||||
&& (status() == call_status::yielded);
|
||||
}
|
||||
|
||||
|
@ -134,8 +137,8 @@ namespace sol {
|
|||
|
||||
template <typename... Ret, typename... Args>
|
||||
decltype(auto) call(Args&&... args) {
|
||||
push();
|
||||
int pushcount = stack::multi_push(lua_state(), std::forward<Args>(args)...);
|
||||
base_t::push();
|
||||
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
|
||||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -49,10 +49,11 @@ namespace sol {
|
|||
basic_environment(lua_State* L, new_table nt)
|
||||
: base_t(L, std::move(nt)) {
|
||||
}
|
||||
basic_environment(lua_State* L, new_table t, const reference& fallback)
|
||||
template <bool b>
|
||||
basic_environment(lua_State* L, new_table t, const basic_reference<b>& fallback)
|
||||
: basic_environment(L, std::move(t)) {
|
||||
sol::stack_table mt(L, sol::new_table(0, 1));
|
||||
mt.set(sol::meta_function::index, fallback);
|
||||
stack_table mt(L, new_table(0, 1));
|
||||
mt.set(meta_function::index, fallback);
|
||||
this->set(metatable_key, mt);
|
||||
mt.pop();
|
||||
}
|
||||
|
@ -65,7 +66,8 @@ namespace sol {
|
|||
#endif // Safety
|
||||
lua_pop(this->lua_state(), 2);
|
||||
}
|
||||
basic_environment(env_t, const reference& extraction_target)
|
||||
template <bool b>
|
||||
basic_environment(env_t, const basic_reference<b>& extraction_target)
|
||||
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
constructor_handler handler{};
|
||||
|
@ -137,7 +139,7 @@ namespace sol {
|
|||
this_environment()
|
||||
: env(nullopt) {
|
||||
}
|
||||
this_environment(sol::environment e)
|
||||
this_environment(environment e)
|
||||
: env(std::move(e)) {
|
||||
}
|
||||
this_environment(const this_environment&) = default;
|
||||
|
@ -194,8 +196,8 @@ namespace sol {
|
|||
return this_environment();
|
||||
}
|
||||
|
||||
sol::stack_reference f(L, -1);
|
||||
sol::environment env(sol::env_key, f);
|
||||
stack_reference f(L, -1);
|
||||
environment env(env_key, f);
|
||||
if (!env.valid()) {
|
||||
lua_settop(L, pre_stack_size);
|
||||
return this_environment();
|
||||
|
|
|
@ -26,11 +26,18 @@
|
|||
|
||||
namespace sol {
|
||||
|
||||
class reference;
|
||||
template <bool b>
|
||||
class basic_reference;
|
||||
using reference = basic_reference<false>;
|
||||
using main_reference = basic_reference<true>;
|
||||
class stack_reference;
|
||||
|
||||
struct proxy_base_tag;
|
||||
template <typename Super>
|
||||
struct proxy_base;
|
||||
template <typename Table, typename Key>
|
||||
struct proxy;
|
||||
|
||||
template <typename T>
|
||||
class usertype;
|
||||
template <typename T>
|
||||
|
@ -40,16 +47,21 @@ namespace sol {
|
|||
template <bool b>
|
||||
using table_core = basic_table_core<b, reference>;
|
||||
template <bool b>
|
||||
using main_table_core = basic_table_core<b, main_reference>;
|
||||
template <bool b>
|
||||
using stack_table_core = basic_table_core<b, stack_reference>;
|
||||
template <typename T>
|
||||
using basic_table = basic_table_core<false, T>;
|
||||
typedef table_core<false> table;
|
||||
typedef table_core<true> global_table;
|
||||
typedef main_table_core<false> main_table;
|
||||
typedef main_table_core<true> main_global_table;
|
||||
typedef stack_table_core<false> stack_table;
|
||||
typedef stack_table_core<true> stack_global_table;
|
||||
template <typename base_t>
|
||||
struct basic_environment;
|
||||
using environment = basic_environment<reference>;
|
||||
using main_environment = basic_environment<main_reference>;
|
||||
using stack_environment = basic_environment<stack_reference>;
|
||||
template <typename T, bool>
|
||||
class basic_function;
|
||||
|
@ -57,6 +69,8 @@ namespace sol {
|
|||
class basic_protected_function;
|
||||
using unsafe_function = basic_function<reference, false>;
|
||||
using safe_function = basic_protected_function<reference, false, reference>;
|
||||
using main_unsafe_function = basic_function<main_reference, false>;
|
||||
using main_safe_function = basic_protected_function<main_reference, false, reference>;
|
||||
using stack_unsafe_function = basic_function<stack_reference, false>;
|
||||
using stack_safe_function = basic_protected_function<stack_reference, false, reference>;
|
||||
using stack_aligned_unsafe_function = basic_function<stack_reference, true>;
|
||||
|
@ -66,10 +80,12 @@ namespace sol {
|
|||
using stack_aligned_protected_function = stack_aligned_safe_function;
|
||||
#ifdef SOL_SAFE_FUNCTIONS
|
||||
using function = protected_function;
|
||||
using main_function = main_protected_function;
|
||||
using stack_function = stack_protected_function;
|
||||
using stack_aligned_function = stack_aligned_safe_function;
|
||||
#else
|
||||
using function = unsafe_function;
|
||||
using main_function = main_unsafe_function;
|
||||
using stack_function = stack_unsafe_function;
|
||||
using stack_aligned_function = stack_aligned_unsafe_function;
|
||||
#endif
|
||||
|
@ -79,25 +95,39 @@ namespace sol {
|
|||
struct protected_function_result;
|
||||
using safe_function_result = protected_function_result;
|
||||
using unsafe_function_result = function_result;
|
||||
|
||||
template <typename base_t>
|
||||
class basic_object;
|
||||
template <typename base_t>
|
||||
class basic_userdata;
|
||||
template <typename base_t>
|
||||
class basic_lightuserdata;
|
||||
template <typename base_t>
|
||||
class basic_coroutine;
|
||||
template <typename base_t>
|
||||
class basic_thread;
|
||||
|
||||
using object = basic_object<reference>;
|
||||
using stack_object = basic_object<stack_reference>;
|
||||
using userdata = basic_userdata<reference>;
|
||||
using stack_userdata = basic_userdata<stack_reference>;
|
||||
using lightuserdata = basic_lightuserdata<reference>;
|
||||
using thread = basic_thread<reference>;
|
||||
using coroutine = basic_coroutine<reference>;
|
||||
using main_object = basic_object<main_reference>;
|
||||
using main_userdata = basic_userdata<main_reference>;
|
||||
using main_lightuserdata = basic_lightuserdata<main_reference>;
|
||||
using stack_object = basic_object<stack_reference>;
|
||||
using stack_userdata = basic_userdata<stack_reference>;
|
||||
using stack_lightuserdata = basic_lightuserdata<stack_reference>;
|
||||
class coroutine;
|
||||
class thread;
|
||||
using stack_thread = basic_thread<stack_reference>;
|
||||
using stack_coroutine = basic_coroutine<stack_reference>;
|
||||
|
||||
struct variadic_args;
|
||||
struct variadic_results;
|
||||
struct stack_count;
|
||||
struct this_state;
|
||||
struct this_main_state;
|
||||
struct this_environment;
|
||||
|
||||
template <typename T>
|
||||
struct as_table_t;
|
||||
template <typename T>
|
||||
|
|
|
@ -77,8 +77,8 @@ namespace sol {
|
|||
|
||||
template <typename... Args, typename... Ret>
|
||||
static std::function<Signature> get_std_func(types<Ret...>, types<Args...>, lua_State* L, int index) {
|
||||
sol::function f(L, index);
|
||||
auto fx = [ f, L, index ](Args && ... args) -> meta::return_type_t<Ret...> {
|
||||
unsafe_function f(L, index);
|
||||
auto fx = [ f = std::move(f), L, index ](Args && ... args) -> meta::return_type_t<Ret...> {
|
||||
return f.call<Ret...>(std::forward<Args>(args)...);
|
||||
};
|
||||
return std::move(fx);
|
||||
|
@ -86,8 +86,8 @@ namespace sol {
|
|||
|
||||
template <typename... FxArgs>
|
||||
static std::function<Signature> get_std_func(types<void>, types<FxArgs...>, lua_State* L, int index) {
|
||||
sol::function f(L, index);
|
||||
auto fx = [f, L, index](FxArgs&&... args) -> void {
|
||||
unsafe_function f(L, index);
|
||||
auto fx = [f = std::move(f), L, index](FxArgs&&... args) -> void {
|
||||
f(std::forward<FxArgs>(args)...);
|
||||
};
|
||||
return std::move(fx);
|
||||
|
|
|
@ -196,12 +196,12 @@ namespace sol {
|
|||
}
|
||||
#endif // noexcept function type
|
||||
|
||||
template <typename Fx, typename... Args, meta::disable<meta::any<std::is_base_of<reference, meta::unqualified_t<Fx>>, std::is_base_of<stack_reference, meta::unqualified_t<Fx>>>> = meta::enabler>
|
||||
template <typename Fx, typename... Args, meta::disable<is_lua_reference<meta::unqualified_t<Fx>>> = meta::enabler>
|
||||
static void select(lua_State* L, Fx&& fx, Args&&... args) {
|
||||
select_function(std::is_function<std::remove_pointer_t<meta::unqualified_t<Fx>>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, meta::enable<meta::any<std::is_base_of<reference, meta::unqualified_t<Fx>>, std::is_base_of<stack_reference, meta::unqualified_t<Fx>>>> = meta::enabler>
|
||||
template <typename Fx, meta::enable<is_lua_reference<meta::unqualified_t<Fx>>> = meta::enabler>
|
||||
static void select(lua_State* L, Fx&& fx) {
|
||||
stack::push(L, std::forward<Fx>(fx));
|
||||
}
|
||||
|
@ -309,10 +309,10 @@ namespace sol {
|
|||
template <typename F, typename G>
|
||||
struct pusher<property_wrapper<F, G>, std::enable_if_t<!std::is_void<F>::value && !std::is_void<G>::value>> {
|
||||
static int push(lua_State* L, property_wrapper<F, G>&& pw) {
|
||||
return stack::push(L, sol::overload(std::move(pw.read), std::move(pw.write)));
|
||||
return stack::push(L, overload(std::move(pw.read), std::move(pw.write)));
|
||||
}
|
||||
static int push(lua_State* L, const property_wrapper<F, G>& pw) {
|
||||
return stack::push(L, sol::overload(pw.read, pw.write));
|
||||
return stack::push(L, overload(pw.read, pw.write));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
namespace sol {
|
||||
|
||||
template <typename R = reference, bool should_pop = !std::is_base_of<stack_reference, R>::value, typename T>
|
||||
template <typename R = reference, bool should_pop = !is_stack_based<R>::value, typename T>
|
||||
R make_reference(lua_State* L, T&& value) {
|
||||
int backpedal = stack::push(L, std::forward<T>(value));
|
||||
R r = stack::get<R>(L, -backpedal);
|
||||
|
@ -42,7 +42,7 @@ namespace sol {
|
|||
return r;
|
||||
}
|
||||
|
||||
template <typename T, typename R = reference, bool should_pop = !std::is_base_of<stack_reference, R>::value, typename... Args>
|
||||
template <typename T, typename R = reference, bool should_pop = !is_stack_based<R>::value, typename... Args>
|
||||
R make_reference(lua_State* L, Args&&... args) {
|
||||
int backpedal = stack::push<T>(L, std::forward<Args>(args)...);
|
||||
R r = stack::get<R>(L, -backpedal);
|
||||
|
@ -71,7 +71,7 @@ namespace sol {
|
|||
basic_object(T&& r)
|
||||
: base_t(std::forward<T>(r)) {
|
||||
}
|
||||
template <typename T, meta::enable_any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>> = meta::enabler>
|
||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_object(lua_State* L, T&& r)
|
||||
: base_t(L, std::forward<T>(r)) {
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ namespace sol {
|
|||
}
|
||||
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)...)) {
|
||||
: basic_object(std::integral_constant<bool, !is_stack_based<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
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace sol {
|
|||
|
||||
template <bool b, typename target_t = reference>
|
||||
struct protected_handler {
|
||||
typedef std::is_base_of<stack_reference, target_t> is_stack;
|
||||
typedef is_stack_based<target_t> is_stack;
|
||||
const target_t& target;
|
||||
int stackindex;
|
||||
|
||||
|
@ -81,11 +81,12 @@ namespace sol {
|
|||
template <typename base_t, bool aligned = false, typename handler_t = reference>
|
||||
class basic_protected_function : public base_t {
|
||||
public:
|
||||
typedef std::is_base_of<stack_reference, handler_t> is_stack_handler;
|
||||
typedef is_stack_based<handler_t> is_stack_handler;
|
||||
|
||||
static handler_t get_default_handler(lua_State* L) {
|
||||
if (is_stack_handler::value || L == nullptr)
|
||||
return handler_t(L, lua_nil);
|
||||
L = is_main_threaded<base_t>::value ? main_thread(L, L) : L;
|
||||
lua_getglobal(L, detail::default_handler_name());
|
||||
auto pp = stack::pop_n(L, 1);
|
||||
return handler_t(L, -1);
|
||||
|
@ -96,13 +97,14 @@ namespace sol {
|
|||
if (ref.lua_state() == nullptr) {
|
||||
return;
|
||||
}
|
||||
lua_State* L = ref.lua_state();
|
||||
if (!ref.valid()) {
|
||||
lua_pushnil(ref.lua_state());
|
||||
lua_setglobal(ref.lua_state(), detail::default_handler_name());
|
||||
lua_pushnil(L);
|
||||
lua_setglobal(L, detail::default_handler_name());
|
||||
}
|
||||
else {
|
||||
ref.push();
|
||||
lua_setglobal(ref.lua_state(), detail::default_handler_name());
|
||||
lua_setglobal(L, detail::default_handler_name());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,11 +237,11 @@ namespace sol {
|
|||
: basic_protected_function(detail::force_cast<base_t>(p), std::forward<Handler>(eh)) {
|
||||
}
|
||||
|
||||
template <typename T, meta::enable<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>> = meta::enabler>
|
||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_protected_function(lua_State* L, T&& r)
|
||||
: basic_protected_function(L, std::forward<T>(r), get_default_handler(L)) {
|
||||
}
|
||||
template <typename T, meta::enable_any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>> = meta::enabler>
|
||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_protected_function(lua_State* L, T&& r, handler_t eh)
|
||||
: base_t(L, std::forward<T>(r)), error_handler(std::move(eh)) {
|
||||
}
|
||||
|
@ -251,7 +253,7 @@ namespace sol {
|
|||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, index, handler);
|
||||
stack::check<basic_protected_function>(lua_state(), index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(lua_State* L, absolute_index index)
|
||||
|
@ -261,7 +263,7 @@ namespace sol {
|
|||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, index, handler);
|
||||
stack::check<basic_protected_function>(lua_state(), index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(lua_State* L, raw_index index)
|
||||
|
@ -271,7 +273,7 @@ namespace sol {
|
|||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, index, handler);
|
||||
stack::check<basic_protected_function>(lua_state(), index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(lua_State* L, ref_index index)
|
||||
|
|
|
@ -77,12 +77,12 @@ namespace sol {
|
|||
return *this;
|
||||
}
|
||||
|
||||
template <typename U, meta::enable<meta::neg<is_lua_reference<meta::unwrap_unqualified_t<U>>>, meta::is_callable<meta::unwrap_unqualified_t<U>>> = meta::enabler>
|
||||
template <typename U, meta::enable<meta::neg<is_lua_reference_or_proxy<meta::unwrap_unqualified_t<U>>>, meta::is_callable<meta::unwrap_unqualified_t<U>>> = meta::enabler>
|
||||
proxy& operator=(U&& other) {
|
||||
return set_function(std::forward<U>(other));
|
||||
}
|
||||
|
||||
template <typename U, meta::disable<meta::neg<is_lua_reference<meta::unwrap_unqualified_t<U>>>, meta::is_callable<meta::unwrap_unqualified_t<U>>> = meta::enabler>
|
||||
template <typename U, meta::disable<meta::neg<is_lua_reference_or_proxy<meta::unwrap_unqualified_t<U>>>, meta::is_callable<meta::unwrap_unqualified_t<U>>> = meta::enabler>
|
||||
proxy& operator=(U&& other) {
|
||||
return set(std::forward<U>(other));
|
||||
}
|
||||
|
@ -194,11 +194,25 @@ namespace sol {
|
|||
return right.valid();
|
||||
}
|
||||
|
||||
template <bool b>
|
||||
template <typename Super>
|
||||
basic_reference<b>& basic_reference<b>::operator=(proxy_base<Super>&& r) {
|
||||
*this = r.template operator basic_reference<b>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <bool b>
|
||||
template <typename Super>
|
||||
basic_reference<b>& basic_reference<b>::operator=(const proxy_base<Super>& r) {
|
||||
*this = r.template operator basic_reference<b>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
namespace stack {
|
||||
template <typename Table, typename Key>
|
||||
struct pusher<proxy<Table, Key>> {
|
||||
static int push(lua_State* L, const proxy<Table, Key>& p) {
|
||||
sol::reference r = p;
|
||||
reference r = p;
|
||||
return r.push(L);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -152,10 +152,23 @@ namespace sol {
|
|||
} const global_{};
|
||||
struct no_safety_tag {
|
||||
} const no_safety{};
|
||||
|
||||
template <bool b>
|
||||
inline lua_State* pick_main_thread(lua_State* L, lua_State* backup_if_unsupported = nullptr) {
|
||||
(void)L;
|
||||
(void)backup_if_unsupported;
|
||||
if (b) {
|
||||
return main_thread(L, backup_if_unsupported);
|
||||
}
|
||||
return L;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
class reference {
|
||||
template <bool main_only = false>
|
||||
class basic_reference {
|
||||
private:
|
||||
template <bool o_main_only>
|
||||
friend class basic_reference;
|
||||
lua_State* luastate = nullptr; // non-owning
|
||||
int ref = LUA_NOREF;
|
||||
|
||||
|
@ -166,9 +179,58 @@ namespace sol {
|
|||
return luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
template <bool r_main_only>
|
||||
void copy_assign(const basic_reference<r_main_only>& r) {
|
||||
if (valid()) {
|
||||
deref();
|
||||
}
|
||||
if (r.ref == LUA_REFNIL) {
|
||||
luastate = detail::pick_main_thread < main_only && !r_main_only >(r.lua_state(), r.lua_state());
|
||||
ref = LUA_REFNIL;
|
||||
return;
|
||||
}
|
||||
if (r.ref == LUA_NOREF) {
|
||||
ref = LUA_NOREF;
|
||||
return;
|
||||
}
|
||||
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||
r.push(lua_state());
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
return;
|
||||
}
|
||||
luastate = detail::pick_main_thread < main_only && !r_main_only >(r.lua_state(), r.lua_state());
|
||||
ref = r.copy();
|
||||
}
|
||||
|
||||
template <bool r_main_only>
|
||||
void move_assign(basic_reference<r_main_only>&& r) {
|
||||
if (valid()) {
|
||||
deref();
|
||||
}
|
||||
if (r.ref == LUA_REFNIL) {
|
||||
luastate = detail::pick_main_thread<main_only && !r_main_only>(r.lua_state(), r.lua_state());
|
||||
ref = LUA_REFNIL;
|
||||
return;
|
||||
}
|
||||
if (r.ref == LUA_NOREF) {
|
||||
ref = LUA_NOREF;
|
||||
return;
|
||||
}
|
||||
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||
r.push(lua_state());
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
return;
|
||||
}
|
||||
|
||||
luastate = detail::pick_main_thread < main_only && !r_main_only >(r.lua_state(), r.lua_state());
|
||||
ref = r.ref;
|
||||
r.ref = LUA_NOREF;
|
||||
r.luastate = nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
reference(lua_State* L, detail::global_tag) noexcept
|
||||
: luastate(L) {
|
||||
basic_reference(lua_State* L, detail::global_tag) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
lua_pushglobaltable(lua_state());
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
@ -182,18 +244,19 @@ namespace sol {
|
|||
}
|
||||
|
||||
public:
|
||||
reference() noexcept = default;
|
||||
reference(lua_nil_t) noexcept
|
||||
: reference() {
|
||||
basic_reference() noexcept = default;
|
||||
basic_reference(lua_nil_t) noexcept
|
||||
: basic_reference() {
|
||||
}
|
||||
reference(const stack_reference& r) noexcept
|
||||
: reference(r.lua_state(), r.stack_index()) {
|
||||
basic_reference(const stack_reference& r) noexcept
|
||||
: basic_reference(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
reference(stack_reference&& r) noexcept
|
||||
: reference(r.lua_state(), r.stack_index()) {
|
||||
basic_reference(stack_reference&& r) noexcept
|
||||
: basic_reference(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
reference(lua_State* L, const reference& r) noexcept
|
||||
: luastate(L) {
|
||||
template <bool r_main_only>
|
||||
basic_reference(lua_State* L, const basic_reference<r_main_only>& r) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
if (r.ref == LUA_REFNIL) {
|
||||
ref = LUA_REFNIL;
|
||||
return;
|
||||
|
@ -209,8 +272,10 @@ namespace sol {
|
|||
}
|
||||
ref = r.copy();
|
||||
}
|
||||
reference(lua_State* L, reference&& r) noexcept
|
||||
: luastate(L) {
|
||||
|
||||
template <bool r_main_only>
|
||||
basic_reference(lua_State* L, basic_reference<r_main_only>&& r) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
if (r.ref == LUA_REFNIL) {
|
||||
ref = LUA_REFNIL;
|
||||
return;
|
||||
|
@ -228,8 +293,9 @@ namespace sol {
|
|||
r.ref = LUA_NOREF;
|
||||
r.luastate = nullptr;
|
||||
}
|
||||
reference(lua_State* L, const stack_reference& r) noexcept
|
||||
: luastate(L) {
|
||||
|
||||
basic_reference(lua_State* L, const stack_reference& r) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
if (lua_state() == nullptr || r.lua_state() == nullptr || r.get_type() == type::none) {
|
||||
ref = LUA_NOREF;
|
||||
return;
|
||||
|
@ -244,83 +310,72 @@ namespace sol {
|
|||
r.push(lua_state());
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
}
|
||||
reference(lua_State* L, int index = -1) noexcept
|
||||
: luastate(L) {
|
||||
basic_reference(lua_State* L, int index = -1) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
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);
|
||||
basic_reference(lua_State* L, ref_index index) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
lua_rawgeti(lua_state(), LUA_REGISTRYINDEX, index.index);
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
}
|
||||
reference(lua_State* L, lua_nil_t) noexcept
|
||||
: luastate(L) {
|
||||
basic_reference(lua_State* L, lua_nil_t) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
}
|
||||
|
||||
~reference() noexcept {
|
||||
~basic_reference() noexcept {
|
||||
if (lua_state() == nullptr || ref == LUA_NOREF)
|
||||
return;
|
||||
deref();
|
||||
}
|
||||
|
||||
reference(const reference& o) noexcept
|
||||
: luastate(o.luastate), ref(o.copy()) {
|
||||
basic_reference(const basic_reference& o) noexcept
|
||||
: luastate(o.lua_state()), ref(o.copy()) {
|
||||
}
|
||||
|
||||
reference(reference&& o) noexcept
|
||||
: luastate(o.luastate), ref(o.ref) {
|
||||
basic_reference(basic_reference&& o) noexcept
|
||||
: luastate(o.lua_state()), ref(o.ref) {
|
||||
o.luastate = nullptr;
|
||||
o.ref = LUA_NOREF;
|
||||
}
|
||||
|
||||
reference& operator=(reference&& r) noexcept {
|
||||
if (valid()) {
|
||||
deref();
|
||||
basic_reference(const basic_reference<!main_only>& o) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only && !main_only>(o.lua_state(), o.lua_state())), ref(o.copy()) {
|
||||
}
|
||||
if (r.ref == LUA_REFNIL) {
|
||||
luastate = r.lua_state();
|
||||
ref = LUA_REFNIL;
|
||||
return *this;
|
||||
|
||||
basic_reference(basic_reference<!main_only>&& o) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only && !main_only>(o.lua_state(), o.lua_state())), ref(o.ref) {
|
||||
o.luastate = nullptr;
|
||||
o.ref = LUA_NOREF;
|
||||
}
|
||||
if (r.ref == LUA_NOREF) {
|
||||
ref = LUA_NOREF;
|
||||
return *this;
|
||||
}
|
||||
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||
r.push(lua_state());
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
|
||||
basic_reference& operator=(basic_reference&& r) noexcept {
|
||||
move_assign(std::move(r));
|
||||
return *this;
|
||||
}
|
||||
|
||||
luastate = r.lua_state();
|
||||
ref = r.ref;
|
||||
r.ref = LUA_NOREF;
|
||||
r.luastate = nullptr;
|
||||
basic_reference& operator=(const basic_reference& r) noexcept {
|
||||
copy_assign(r);
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference& operator=(const reference& r) noexcept {
|
||||
if (valid()) {
|
||||
deref();
|
||||
}
|
||||
if (r.ref == LUA_REFNIL) {
|
||||
luastate = r.lua_state();
|
||||
ref = LUA_REFNIL;
|
||||
basic_reference& operator=(basic_reference<!main_only>&& r) noexcept {
|
||||
move_assign(std::move(r));
|
||||
return *this;
|
||||
}
|
||||
if (r.ref == LUA_NOREF) {
|
||||
ref = LUA_NOREF;
|
||||
return *this;
|
||||
}
|
||||
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||
r.push(lua_state());
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
return *this;
|
||||
}
|
||||
luastate = r.lua_state();
|
||||
ref = r.copy();
|
||||
|
||||
basic_reference& operator=(const basic_reference<!main_only>& r) noexcept {
|
||||
copy_assign(r);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Super>
|
||||
basic_reference& operator=(proxy_base<Super>&& r);
|
||||
|
||||
template <typename Super>
|
||||
basic_reference& operator=(const proxy_base<Super>& r);
|
||||
|
||||
int push() const noexcept {
|
||||
return push(lua_state());
|
||||
}
|
||||
|
@ -368,29 +423,35 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
inline bool operator==(const reference& l, const reference& r) {
|
||||
template <bool lb, bool rb>
|
||||
inline bool operator==(const basic_reference<lb>& l, const basic_reference<rb>& r) {
|
||||
auto ppl = stack::push_pop(l);
|
||||
auto ppr = stack::push_pop(r);
|
||||
return lua_compare(l.lua_state(), -1, -2, LUA_OPEQ) == 1;
|
||||
}
|
||||
|
||||
inline bool operator!=(const reference& l, const reference& r) {
|
||||
template <bool lb, bool rb>
|
||||
inline bool operator!=(const basic_reference<lb>& l, const basic_reference<rb>& r) {
|
||||
return !operator==(l, r);
|
||||
}
|
||||
|
||||
inline bool operator==(const reference& lhs, const lua_nil_t&) {
|
||||
template <bool lb>
|
||||
inline bool operator==(const basic_reference<lb>& lhs, const lua_nil_t&) {
|
||||
return !lhs.valid();
|
||||
}
|
||||
|
||||
inline bool operator==(const lua_nil_t&, const reference& rhs) {
|
||||
template <bool rb>
|
||||
inline bool operator==(const lua_nil_t&, const basic_reference<rb>& rhs) {
|
||||
return !rhs.valid();
|
||||
}
|
||||
|
||||
inline bool operator!=(const reference& lhs, const lua_nil_t&) {
|
||||
template <bool lb>
|
||||
inline bool operator!=(const basic_reference<lb>& lhs, const lua_nil_t&) {
|
||||
return lhs.valid();
|
||||
}
|
||||
|
||||
inline bool operator!=(const lua_nil_t&, const reference& rhs) {
|
||||
template <bool rb>
|
||||
inline bool operator!=(const lua_nil_t&, const basic_reference<rb>& rhs) {
|
||||
return rhs.valid();
|
||||
}
|
||||
} // namespace sol
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace sol {
|
|||
}
|
||||
auto fit = functions.find(accessorkey);
|
||||
if (fit != functions.cend()) {
|
||||
sol::object& func = fit->second;
|
||||
object& func = fit->second;
|
||||
if (is_index) {
|
||||
return stack::push(L, func);
|
||||
}
|
||||
|
@ -525,7 +525,7 @@ namespace sol {
|
|||
stack_reference metabehind(L, -1);
|
||||
stack::set_field(L, meta_function::type, type_table, metabehind.stack_index());
|
||||
if (umx.callconstructfunc.valid()) {
|
||||
stack::set_field(L, sol::meta_function::call_function, umx.callconstructfunc, metabehind.stack_index());
|
||||
stack::set_field(L, meta_function::call_function, umx.callconstructfunc, metabehind.stack_index());
|
||||
}
|
||||
if (umx.secondarymeta) {
|
||||
stack::set_field(L, meta_function::index,
|
||||
|
@ -560,7 +560,7 @@ namespace sol {
|
|||
stack_reference metabehind(L, -1);
|
||||
stack::set_field(L, meta_function::type, type_table, metabehind.stack_index());
|
||||
if (umx.callconstructfunc.valid()) {
|
||||
stack::set_field(L, sol::meta_function::call_function, umx.callconstructfunc, metabehind.stack_index());
|
||||
stack::set_field(L, meta_function::call_function, umx.callconstructfunc, metabehind.stack_index());
|
||||
}
|
||||
// use indexing function
|
||||
stack::set_field(L, meta_function::index,
|
||||
|
|
|
@ -185,7 +185,12 @@ namespace sol {
|
|||
template <bool check_args = stack_detail::default_check_arguments, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<meta::neg<std::is_void<Ret0>>::value>>
|
||||
inline int call_into_lua(types<Ret0, Ret...>, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
||||
decltype(auto) r = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||
typedef is_stack_based<meta::unqualified_t<decltype(r)>> is_stack;
|
||||
typedef meta::unqualified_t<decltype(r)> R;
|
||||
typedef meta::any<is_stack_based<R>,
|
||||
std::is_same<R, absolute_index>,
|
||||
std::is_same<R, ref_index>,
|
||||
std::is_same<R, raw_index>>
|
||||
is_stack;
|
||||
if (clean_stack && !is_stack::value) {
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
|
|
|
@ -184,6 +184,15 @@ namespace stack {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
struct checker<this_main_state, type::poly, C> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State*, int, Handler&&, record& tracking) {
|
||||
tracking.use(0);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
struct checker<this_environment, type::poly, C> {
|
||||
template <typename Handler>
|
||||
|
|
|
@ -245,7 +245,7 @@ namespace sol {
|
|||
template <typename T, typename... Args>
|
||||
inline int multi_push(lua_State* L, T&& t, Args&&... args) {
|
||||
int pushcount = push(L, std::forward<T>(t));
|
||||
void(sol::detail::swallow{(pushcount += sol::stack::push(L, std::forward<Args>(args)), 0)...});
|
||||
void(detail::swallow{(pushcount += stack::push(L, std::forward<Args>(args)), 0)...});
|
||||
return pushcount;
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,7 @@ namespace sol {
|
|||
template <typename T, typename... Args>
|
||||
inline int multi_push_reference(lua_State* L, T&& t, Args&&... args) {
|
||||
int pushcount = push_reference(L, std::forward<T>(t));
|
||||
void(sol::detail::swallow{(pushcount += sol::stack::push_reference(L, std::forward<Args>(args)), 0)...});
|
||||
void(detail::swallow{(pushcount += stack::push_reference(L, std::forward<Args>(args)), 0)...});
|
||||
return pushcount;
|
||||
}
|
||||
|
||||
|
|
|
@ -330,7 +330,7 @@ namespace stack {
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
struct getter<T, std::enable_if_t<std::is_base_of<reference, T>::value || std::is_base_of<stack_reference, T>::value>> {
|
||||
struct getter<T, std::enable_if_t<is_lua_reference<T>::value>> {
|
||||
static T get(lua_State* L, int index, record& tracking) {
|
||||
tracking.use(1);
|
||||
return T(L, index);
|
||||
|
@ -569,7 +569,15 @@ namespace stack {
|
|||
struct getter<this_state> {
|
||||
static this_state get(lua_State* L, int, record& tracking) {
|
||||
tracking.use(0);
|
||||
return this_state{L};
|
||||
return this_state( L );
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct getter<this_main_state> {
|
||||
static this_main_state get(lua_State* L, int, record& tracking) {
|
||||
tracking.use(0);
|
||||
return this_main_state( main_thread(L, L) );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ namespace stack {
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
struct pusher<T*, meta::disable_if_t<meta::any<is_container<meta::unqualified_t<T>>, std::is_function<meta::unqualified_t<T>>, std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>>::value>> {
|
||||
struct pusher<T*, meta::disable_if_t<meta::any<is_container<meta::unqualified_t<T>>, std::is_function<meta::unqualified_t<T>>, is_lua_reference<meta::unqualified_t<T>>>::value>> {
|
||||
template <typename... Args>
|
||||
static int push(lua_State* L, Args&&... args) {
|
||||
return pusher<detail::as_pointer_tag<T>>{}.push(L, std::forward<Args>(args)...);
|
||||
|
@ -315,7 +315,7 @@ namespace stack {
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
struct pusher<T, std::enable_if_t<std::is_base_of<reference, T>::value || std::is_base_of<stack_reference, T>::value>> {
|
||||
struct pusher<T, std::enable_if_t<is_lua_reference<T>::value>> {
|
||||
static int push(lua_State* L, const T& ref) {
|
||||
return ref.push(L);
|
||||
}
|
||||
|
@ -852,6 +852,13 @@ namespace stack {
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pusher<this_main_state> {
|
||||
static int push(lua_State*, const this_main_state&) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pusher<new_table> {
|
||||
static int push(lua_State* L, const new_table& nt) {
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace sol {
|
|||
: unique_base(luaL_newstate(), lua_close), state_view(unique_base::get()) {
|
||||
set_panic(panic);
|
||||
lua_CFunction f = c_call<decltype(&detail::default_traceback_error_handler), &detail::default_traceback_error_handler>;
|
||||
protected_function::set_default_handler(sol::object(lua_state(), in_place, f));
|
||||
protected_function::set_default_handler(object(lua_state(), in_place, f));
|
||||
stack::register_main_thread(unique_base::get());
|
||||
stack::luajit_exception_handler(unique_base::get());
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ namespace sol {
|
|||
: unique_base(lua_newstate(alfunc, alpointer), lua_close), state_view(unique_base::get()) {
|
||||
set_panic(panic);
|
||||
lua_CFunction f = c_call<decltype(&detail::default_traceback_error_handler), &detail::default_traceback_error_handler>;
|
||||
protected_function::set_default_handler(sol::object(lua_state(), in_place, f));
|
||||
protected_function::set_default_handler(object(lua_state(), in_place, f));
|
||||
stack::register_main_thread(unique_base::get());
|
||||
stack::luajit_exception_handler(unique_base::get());
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace sol {
|
|||
return kb;
|
||||
}
|
||||
|
||||
inline protected_function_result script_pass_on_error(lua_State*, sol::protected_function_result result) {
|
||||
inline protected_function_result script_pass_on_error(lua_State*, protected_function_result result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -377,7 +377,7 @@ namespace sol {
|
|||
}
|
||||
|
||||
template <typename E>
|
||||
function_result unsafe_script(const string_view& code, const sol::basic_environment<E>& env, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
|
||||
function_result unsafe_script(const string_view& code, const basic_environment<E>& env, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
|
||||
detail::typical_chunk_name_t basechunkname = {};
|
||||
const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
|
||||
int index = lua_gettop(L);
|
||||
|
@ -402,7 +402,7 @@ namespace sol {
|
|||
}
|
||||
|
||||
template <typename E>
|
||||
function_result unsafe_script_file(const std::string& filename, const sol::basic_environment<E>& env, load_mode mode = load_mode::any) {
|
||||
function_result unsafe_script_file(const std::string& filename, const basic_environment<E>& env, load_mode mode = load_mode::any) {
|
||||
int index = lua_gettop(L);
|
||||
if (luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str())) {
|
||||
lua_error(L);
|
||||
|
|
|
@ -73,9 +73,9 @@ namespace sol {
|
|||
auto pp = stack::push_pop(*this);
|
||||
stack::push(base_t::lua_state(), lua_nil);
|
||||
while (lua_next(base_t::lua_state(), -2)) {
|
||||
sol::object key(base_t::lua_state(), -2);
|
||||
sol::object value(base_t::lua_state(), -1);
|
||||
std::pair<sol::object&, sol::object&> keyvalue(key, value);
|
||||
object key(base_t::lua_state(), -2);
|
||||
object value(base_t::lua_state(), -1);
|
||||
std::pair<object&, object&> keyvalue(key, value);
|
||||
auto pn = stack::pop_n(base_t::lua_state(), 1);
|
||||
fx(keyvalue);
|
||||
}
|
||||
|
@ -86,8 +86,8 @@ namespace sol {
|
|||
auto pp = stack::push_pop(*this);
|
||||
stack::push(base_t::lua_state(), lua_nil);
|
||||
while (lua_next(base_t::lua_state(), -2)) {
|
||||
sol::object key(base_t::lua_state(), -2);
|
||||
sol::object value(base_t::lua_state(), -1);
|
||||
object key(base_t::lua_state(), -2);
|
||||
object value(base_t::lua_state(), -1);
|
||||
auto pn = stack::pop_n(base_t::lua_state(), 1);
|
||||
fx(key, value);
|
||||
}
|
||||
|
@ -204,13 +204,13 @@ namespace sol {
|
|||
basic_table_core(stack_reference&& r)
|
||||
: basic_table_core(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
template <typename T, meta::enable_any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>> = meta::enabler>
|
||||
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_table_core(lua_State* L, T&& r)
|
||||
: basic_table_core(L, std::forward<T>(r)) {
|
||||
}
|
||||
basic_table_core(lua_State* L, new_table nt)
|
||||
: base_t(L, (lua_createtable(L, nt.sequence_hint, nt.map_hint), -1)) {
|
||||
if (!std::is_base_of<stack_reference, base_type>::value) {
|
||||
if (!is_stack_based<meta::unqualified_t<base_type>>::value) {
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
@ -454,7 +454,7 @@ namespace sol {
|
|||
|
||||
template <typename Fx>
|
||||
void for_each(Fx&& fx) const {
|
||||
typedef meta::is_invokable<Fx(std::pair<sol::object, sol::object>)> is_paired;
|
||||
typedef meta::is_invokable<Fx(std::pair<object, object>)> is_paired;
|
||||
for_each(is_paired(), std::forward<Fx>(fx));
|
||||
}
|
||||
|
||||
|
|
102
sol/thread.hpp
102
sol/thread.hpp
|
@ -29,6 +29,10 @@ namespace sol {
|
|||
struct lua_thread_state {
|
||||
lua_State* L;
|
||||
|
||||
lua_thread_state(lua_State* Ls)
|
||||
: L(Ls) {
|
||||
}
|
||||
|
||||
lua_State* lua_state() const noexcept {
|
||||
return L;
|
||||
}
|
||||
|
@ -53,7 +57,7 @@ namespace sol {
|
|||
struct getter<lua_thread_state> {
|
||||
lua_thread_state get(lua_State* L, int index, record& tracking) {
|
||||
tracking.use(1);
|
||||
lua_thread_state lts{lua_tothread(L, index)};
|
||||
lua_thread_state lts( lua_tothread(L, index) );
|
||||
return lts;
|
||||
}
|
||||
};
|
||||
|
@ -62,8 +66,8 @@ namespace sol {
|
|||
struct check_getter<lua_thread_state> {
|
||||
template <typename 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) {
|
||||
lua_thread_state lts( lua_tothread(L, index) );
|
||||
if (lts.lua_state() == nullptr) {
|
||||
handler(L, index, type::thread, type_of(L, index), "value is not a valid thread type");
|
||||
return nullopt;
|
||||
}
|
||||
|
@ -87,50 +91,59 @@ namespace sol {
|
|||
}
|
||||
} // namespace stack
|
||||
|
||||
class thread : public reference {
|
||||
template <typename base_t>
|
||||
class basic_thread : public base_t {
|
||||
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)) {
|
||||
using base_t::lua_state;
|
||||
|
||||
basic_thread() noexcept = default;
|
||||
basic_thread(const basic_thread&) = default;
|
||||
basic_thread(basic_thread&&) = default;
|
||||
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_thread>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_thread(T&& r)
|
||||
: base_t(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;
|
||||
thread& operator=(thread&&) = default;
|
||||
template <typename T, meta::enable<meta::neg<std::is_integral<meta::unqualified_t<T>>>, meta::neg<std::is_same<T, ref_index>>> = meta::enabler>
|
||||
thread(lua_State* L, T&& r)
|
||||
: thread(L, sol::ref_index(r.registry_index())) {
|
||||
basic_thread(const stack_reference& r)
|
||||
: basic_thread(r.lua_state(), r.stack_index()){};
|
||||
basic_thread(stack_reference&& r)
|
||||
: basic_thread(r.lua_state(), r.stack_index()){};
|
||||
basic_thread& operator=(const basic_thread&) = default;
|
||||
basic_thread& operator=(basic_thread&&) = default;
|
||||
template <typename T, meta::enable<meta::neg<is_lua_index<meta::unqualified_t<T>>>> = meta::enabler>
|
||||
basic_thread(lua_State* L, T&& r)
|
||||
: basic_thread(L, std::forward<T>(r)) {
|
||||
}
|
||||
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) {
|
||||
basic_thread(lua_State* L, int index = -1)
|
||||
: base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
type_assert(L, -1, type::thread);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_thread>(lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
thread(lua_State* L, lua_State* actualthread)
|
||||
: thread(L, lua_thread_state{actualthread}) {
|
||||
}
|
||||
thread(lua_State* L, sol::this_state actualthread)
|
||||
: thread(L, lua_thread_state{actualthread.L}) {
|
||||
}
|
||||
thread(lua_State* L, lua_thread_state actualthread)
|
||||
: reference(L, -stack::push(L, actualthread)) {
|
||||
basic_thread(lua_State* L, ref_index index)
|
||||
: base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
type_assert(L, -1, type::thread);
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_thread>(lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
basic_thread(lua_State* L, lua_State* actualthread)
|
||||
: basic_thread(L, lua_thread_state{ actualthread }) {
|
||||
}
|
||||
basic_thread(lua_State* L, this_state actualthread)
|
||||
: basic_thread(L, lua_thread_state{ actualthread.L }) {
|
||||
}
|
||||
basic_thread(lua_State* L, lua_thread_state actualthread)
|
||||
: base_t(L, -stack::push(L, actualthread)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_thread>(lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
if (!is_stack_based<base_t>::value) {
|
||||
lua_pop(lua_state(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
state_view state() const {
|
||||
|
@ -153,23 +166,28 @@ namespace sol {
|
|||
lua_State* lthread = thread_state();
|
||||
thread_status lstat = static_cast<thread_status>(lua_status(lthread));
|
||||
if (lstat != thread_status::ok && lua_gettop(lthread) == 0) {
|
||||
// No thing on the thread's stack means its dead
|
||||
// No thing on the basic_thread's stack means its dead
|
||||
return thread_status::dead;
|
||||
}
|
||||
return lstat;
|
||||
}
|
||||
|
||||
thread create() {
|
||||
basic_thread create() {
|
||||
return create(lua_state());
|
||||
}
|
||||
|
||||
static thread create(lua_State* L) {
|
||||
static basic_thread create(lua_State* L) {
|
||||
lua_newthread(L);
|
||||
thread result(L);
|
||||
basic_thread result(L);
|
||||
if (!is_stack_based<base_t>::value) {
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
typedef basic_thread<reference> thread;
|
||||
typedef basic_thread<stack_reference> stack_thread;
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_THREAD_HPP
|
||||
|
|
|
@ -491,6 +491,31 @@ namespace sol {
|
|||
|
||||
struct this_state {
|
||||
lua_State* L;
|
||||
|
||||
this_state(lua_State* Ls)
|
||||
: L(Ls) {
|
||||
}
|
||||
|
||||
operator lua_State*() const noexcept {
|
||||
return lua_state();
|
||||
}
|
||||
|
||||
lua_State* operator->() const noexcept {
|
||||
return lua_state();
|
||||
}
|
||||
|
||||
lua_State* lua_state() const noexcept {
|
||||
return L;
|
||||
}
|
||||
};
|
||||
|
||||
struct this_main_state {
|
||||
lua_State* L;
|
||||
|
||||
this_main_state(lua_State* Ls)
|
||||
: L(Ls) {
|
||||
}
|
||||
|
||||
operator lua_State*() const noexcept {
|
||||
return lua_state();
|
||||
}
|
||||
|
@ -831,7 +856,7 @@ namespace sol {
|
|||
struct lua_type_of<std::nullptr_t> : std::integral_constant<type, type::lua_nil> {};
|
||||
|
||||
template <>
|
||||
struct lua_type_of<sol::error> : std::integral_constant<type, type::string> {};
|
||||
struct lua_type_of<error> : std::integral_constant<type, type::string> {};
|
||||
|
||||
template <bool b, typename Base>
|
||||
struct lua_type_of<basic_table_core<b, Base>> : std::integral_constant<type, type::table> {};
|
||||
|
@ -851,8 +876,8 @@ namespace sol {
|
|||
template <typename T>
|
||||
struct lua_type_of<as_table_t<T>> : std::integral_constant<type, type::table> {};
|
||||
|
||||
template <>
|
||||
struct lua_type_of<reference> : std::integral_constant<type, type::poly> {};
|
||||
template <bool b>
|
||||
struct lua_type_of<basic_reference<b>> : std::integral_constant<type, type::poly> {};
|
||||
|
||||
template <>
|
||||
struct lua_type_of<stack_reference> : std::integral_constant<type, type::poly> {};
|
||||
|
@ -923,6 +948,9 @@ namespace sol {
|
|||
template <>
|
||||
struct lua_type_of<this_state> : std::integral_constant<type, type::poly> {};
|
||||
|
||||
template <>
|
||||
struct lua_type_of<this_main_state> : std::integral_constant<type, type::poly> {};
|
||||
|
||||
template <>
|
||||
struct lua_type_of<this_environment> : std::integral_constant<type, type::poly> {};
|
||||
|
||||
|
@ -1009,6 +1037,7 @@ namespace sol {
|
|||
&& detail::has_internal_marker<lua_type_of<meta::unqualified_t<T>>>::value
|
||||
&& !detail::has_internal_marker<lua_size<meta::unqualified_t<T>>>::value)
|
||||
|| std::is_base_of<reference, meta::unqualified_t<T>>::value
|
||||
|| std::is_base_of<main_reference, meta::unqualified_t<T>>::value
|
||||
|| std::is_base_of<stack_reference, meta::unqualified_t<T>>::value
|
||||
|| meta::is_specialization_of<std::tuple, meta::unqualified_t<T>>::value
|
||||
|| meta::is_specialization_of<std::pair, meta::unqualified_t<T>>::value> {};
|
||||
|
@ -1016,9 +1045,20 @@ namespace sol {
|
|||
template <typename T>
|
||||
struct is_lua_reference : std::integral_constant<bool,
|
||||
std::is_base_of<reference, meta::unqualified_t<T>>::value
|
||||
|| std::is_base_of<stack_reference, meta::unqualified_t<T>>::value
|
||||
|| std::is_base_of<main_reference, meta::unqualified_t<T>>::value
|
||||
|| std::is_base_of<stack_reference, meta::unqualified_t<T>>::value> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_lua_reference_or_proxy : std::integral_constant<bool,
|
||||
is_lua_reference<meta::unqualified_t<T>>::value
|
||||
|| meta::is_specialization_of<proxy, meta::unqualified_t<T>>::value> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_main_threaded : std::is_base_of<main_reference, T> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_stack_based : std::is_base_of<stack_reference, T> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_lua_primitive<T*> : std::true_type {};
|
||||
template <>
|
||||
|
@ -1052,6 +1092,8 @@ namespace sol {
|
|||
template <>
|
||||
struct is_transparent_argument<this_state> : std::true_type {};
|
||||
template <>
|
||||
struct is_transparent_argument<this_main_state> : std::true_type {};
|
||||
template <>
|
||||
struct is_transparent_argument<this_environment> : std::true_type {};
|
||||
template <>
|
||||
struct is_transparent_argument<variadic_args> : std::true_type {};
|
||||
|
@ -1069,13 +1111,6 @@ namespace sol {
|
|||
template <>
|
||||
struct is_lua_index<upvalue_index> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_stack_based : std::is_base_of<stack_reference, T> {};
|
||||
template <>
|
||||
struct is_stack_based<raw_index> : std::true_type {};
|
||||
template <>
|
||||
struct is_stack_based<absolute_index> : std::true_type {};
|
||||
|
||||
template <typename Signature>
|
||||
struct lua_bind_traits : meta::bind_traits<Signature> {
|
||||
private:
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace sol {
|
|||
basic_userdata(stack_reference&& r)
|
||||
: basic_userdata(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
template <typename T, meta::enable_any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>> = meta::enabler>
|
||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_userdata(lua_State* L, T&& r)
|
||||
: base_t(L, std::forward<T>(r)) {
|
||||
}
|
||||
|
|
|
@ -210,8 +210,7 @@ namespace sol {
|
|||
}
|
||||
} // namespace usertype_detail
|
||||
|
||||
namespace stack {
|
||||
namespace stack_detail {
|
||||
namespace stack { namespace stack_detail {
|
||||
template <typename T>
|
||||
struct undefined_metatable {
|
||||
typedef meta::all<meta::neg<std::is_pointer<T>>, std::is_destructible<T>> is_destructible;
|
||||
|
@ -231,6 +230,16 @@ namespace sol {
|
|||
usertype_detail::insert_default_registrations<P>(l, index, fx);
|
||||
usertype_detail::make_destructor<T>(l, index);
|
||||
luaL_setfuncs(L, l, 0);
|
||||
|
||||
// __type table
|
||||
lua_createtable(L, 0, 2);
|
||||
const std::string& name = detail::demangle<T>();
|
||||
lua_pushlstring(L, name.c_str(), name.size());
|
||||
lua_setfield(L, -2, "name");
|
||||
lua_CFunction is_func = &usertype_detail::is_check<T>;
|
||||
lua_pushcclosure(L, is_func, 0);
|
||||
lua_setfield(L, -2, "is");
|
||||
lua_setfield(L, -2, to_string(meta_function::type).c_str());
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
|
|
@ -252,10 +252,10 @@ namespace sol {
|
|||
std::string& accessor = maybeaccessor.value();
|
||||
auto preexistingit = functions.find(accessor);
|
||||
if (preexistingit == functions.cend()) {
|
||||
functions.emplace_hint(preexistingit, std::move(accessor), sol::object(L, 3));
|
||||
functions.emplace_hint(preexistingit, std::move(accessor), object(L, 3));
|
||||
}
|
||||
else {
|
||||
preexistingit->second = sol::object(L, 3);
|
||||
preexistingit->second = object(L, 3);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ namespace sol {
|
|||
}
|
||||
else {
|
||||
target = preexistingit->second.runtime_target;
|
||||
runtime[target] = sol::object(L, 3);
|
||||
runtime[target] = object(L, 3);
|
||||
preexistingit->second = call_information(&runtime_object_call, &runtime_new_index, target);
|
||||
}
|
||||
};
|
||||
|
@ -468,7 +468,7 @@ namespace sol {
|
|||
case meta_function::garbage_collect:
|
||||
if (destructfunc != nullptr) {
|
||||
#ifdef SOL_NO_EXCEPTIONS
|
||||
throw sol::error("sol: 2 separate garbage_collect functions were set on this type. Please specify only 1 sol::meta_function::gc type AND wrap the function in a sol::destruct call, as shown by the documentation and examples");
|
||||
throw error("sol: 2 separate garbage_collect functions were set on this type. Please specify only 1 sol::meta_function::gc type AND wrap the function in a sol::destruct call, as shown by the documentation and examples");
|
||||
#else
|
||||
assert(false && "sol: 2 separate garbage_collect functions were set on this type. Please specify only 1 sol::meta_function::gc type AND wrap the function in a sol::destruct call, as shown by the documentation and examples");
|
||||
#endif
|
||||
|
|
|
@ -281,3 +281,93 @@ co = nil
|
|||
std::string s = t[1];
|
||||
REQUIRE(s == "SOME_TABLE");
|
||||
}
|
||||
|
||||
TEST_CASE("coroutines/main transfer", "check that copy and move assignment constructors using main-forced types work") {
|
||||
const std::string code = R"(
|
||||
-- main thread - L1
|
||||
-- co - L2
|
||||
-- co2 - L3
|
||||
|
||||
x = co_test.new("x")
|
||||
local co = coroutine.wrap(
|
||||
function()
|
||||
local t = co_test.new("t")
|
||||
local co2 = coroutine.wrap(
|
||||
function()
|
||||
local t2 = { "SOME_TABLE" }
|
||||
t:copy_store(t2) -- t2 = [L3], t.obj = [L2]
|
||||
end
|
||||
)
|
||||
|
||||
co2()
|
||||
co2 = nil
|
||||
|
||||
collectgarbage() -- t2 ref in t remains valid!
|
||||
|
||||
x:store(t:get()) -- t.obj = [L2], x.obj = [L1]
|
||||
end
|
||||
)
|
||||
|
||||
co()
|
||||
co = nil
|
||||
collectgarbage()
|
||||
)";
|
||||
|
||||
struct co_test_implicit {
|
||||
std::string identifier;
|
||||
sol::main_reference obj;
|
||||
|
||||
co_test_implicit(sol::this_state L, std::string id) : identifier(id), obj(L, sol::lua_nil) {
|
||||
|
||||
}
|
||||
|
||||
void store(sol::table ref) {
|
||||
// main_reference does the state shift implicitly
|
||||
obj = std::move(ref);
|
||||
lua_State* Lmain = sol::main_thread(ref.lua_state());
|
||||
REQUIRE(obj.lua_state() == Lmain);
|
||||
}
|
||||
|
||||
void copy_store(sol::table ref) {
|
||||
// main_reference does the state shift implicitly
|
||||
obj = ref;
|
||||
lua_State* Lmain = sol::main_thread(ref.lua_state());
|
||||
REQUIRE(obj.lua_state() == Lmain);
|
||||
}
|
||||
|
||||
sol::reference get() {
|
||||
return obj;
|
||||
}
|
||||
|
||||
~co_test_implicit() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::coroutine, sol::lib::base);
|
||||
|
||||
lua.new_usertype<co_test_implicit>("co_test",
|
||||
sol::constructors<co_test_implicit(sol::this_state, std::string)>(),
|
||||
"store", &co_test_implicit::store,
|
||||
"copy_store", &co_test_implicit::copy_store,
|
||||
"get", &co_test_implicit::get
|
||||
);
|
||||
|
||||
|
||||
auto r = lua.safe_script(code);
|
||||
REQUIRE(r.valid());
|
||||
|
||||
co_test_implicit& ct = lua["x"];
|
||||
|
||||
lua_State* Lmain1 = lua.lua_state();
|
||||
lua_State* Lmain2 = sol::main_thread(lua);
|
||||
lua_State* Lmain3 = ct.get().lua_state();
|
||||
REQUIRE(Lmain1 == Lmain2);
|
||||
REQUIRE(Lmain1 == Lmain3);
|
||||
|
||||
sol::table t = ct.get();
|
||||
REQUIRE(t.size() == 1);
|
||||
std::string s = t[1];
|
||||
REQUIRE(s == "SOME_TABLE");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user