mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Fixes #588
Tentatively supports (?) #589 with sol::yielding and sol::yielding_t Added Catch as a cmake module
This commit is contained in:
parent
eca9ec46fd
commit
67116a67f9
|
@ -69,29 +69,25 @@ endif()
|
|||
|
||||
# # # General project flags
|
||||
if (MSVC)
|
||||
add_definitions(/DUNICODE /D_UNICODE /D_SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING /D_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING /D_CRT_SECURE_NO_WARNINGS /D_CRT_SECURE_NO_DEPRECATE)
|
||||
add_definitions(/DUNICODE /D_UNICODE /D_CRT_SECURE_NO_WARNINGS /D_CRT_SECURE_NO_DEPRECATE)
|
||||
# Warning level, exceptions
|
||||
add_compile_options(/W4 /EHsc)
|
||||
if (NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(/MP)
|
||||
endif()
|
||||
else()
|
||||
if (IS_X86)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
|
||||
endif()
|
||||
add_compile_options(-Wno-unknown-warning -Wno-unknown-warning-option -Wall -Wextra -Wpedantic -pedantic -pedantic-errors)
|
||||
endif()
|
||||
|
||||
# # # General project output locations
|
||||
if (IS_X86 OR CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/x86/lib")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/x86/bin")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/x86/bin")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x86/lib")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x86/bin")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x86/bin")
|
||||
else()
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/x64/lib")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/x64/bin")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/x64/bin")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x64/lib")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x64/bin")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x64/bin")
|
||||
endif()
|
||||
|
||||
# # # Modules
|
||||
|
|
10
appveyor.yml
10
appveyor.yml
|
@ -47,6 +47,8 @@ environment:
|
|||
# apparently, I can't quite make LLVM work right now...
|
||||
#- LUA_VERSION: 5.3.4
|
||||
# LLVM_VERSION: 4.0.0
|
||||
- LUA_VERSION: 5.3.4
|
||||
MINGW_VERSION: 7.2.0
|
||||
- LUA_VERSION: 5.3.4
|
||||
MINGW_VERSION: 6.3.0
|
||||
- LUA_VERSION: luajit-2.0.5
|
||||
|
@ -56,8 +58,8 @@ environment:
|
|||
- LUA_VERSION: 5.3.4
|
||||
- LUA_VERSION: 5.2.4
|
||||
- LUA_VERSION: 5.1.5
|
||||
#- LUA_VERSION: luajit-2.0.5
|
||||
#- LUA_VERSION: luajit-2.1.0-beta3
|
||||
- LUA_VERSION: luajit-2.0.5
|
||||
- LUA_VERSION: luajit-2.1.0-beta3
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
|
@ -82,6 +84,8 @@ matrix:
|
|||
LUA_VERSION: 5.2.4
|
||||
- platform: x86
|
||||
LUA_VERSION: 5.1.5
|
||||
- platform: x86
|
||||
MINGW_VERSION: 7.2.0
|
||||
# Get rid of redundant Visual Studio 2015 builds
|
||||
- image: Visual Studio 2015
|
||||
LUA_VERSION: 5.1.5
|
||||
|
@ -107,6 +111,7 @@ init:
|
|||
- set llvm_path=
|
||||
- if "%MINGW_VERSION%"=="5.3.0" (set mingw_path=C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin)
|
||||
- if "%MINGW_VERSION%"=="6.3.0" (if "%PLATFORM%"=="x64" (set mingw_path=C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin) else ( set mingw_path=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin))
|
||||
- if "%MINGW_VERSION%"=="6.3.0" (if "%PLATFORM%"=="x64" (set mingw_path=C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin) else ( set mingw_path=C:\mingw-w64\i686-7.2.0-posix-seh-rt_v5-rev1\mingw32\bin))
|
||||
- if "%LLVM_VERSION%"=="4.0.0" (set llvm_path=C:\Program Files\LLVM\bin)
|
||||
- if "%PLATFORM%"=="x64" (set python_path=C:\Python36-x64)
|
||||
- set PATH=%python_path%;%PATH%
|
||||
|
@ -128,6 +133,7 @@ init:
|
|||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" (set CMAKE_GENERATOR=Visual Studio 14 2015%arch%&&set parallelism=/maxcpucount&&set logger=/verbosity:quiet /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll")
|
||||
- if "%MINGW_VERSION%"=="5.3.0" (set CMAKE_GENERATOR=Ninja&&set parallelism= &&set logger= &&set build_type=-DCMAKE_BUILD_TYPE=Release&&set build_compiler=-DCMAKE_CXX_COMPILER=g++.exe -DCMAKE_C_COMPILER=gcc.exe)
|
||||
- if "%MINGW_VERSION%"=="6.3.0" (set CMAKE_GENERATOR=Ninja&&set parallelism= &&set logger= &&set build_type=-DCMAKE_BUILD_TYPE=Release&&set build_compiler=-DCMAKE_CXX_COMPILER=g++.exe -DCMAKE_C_COMPILER=gcc.exe)
|
||||
- if "%MINGW_VERSION%"=="7.2.0" (set CMAKE_GENERATOR=Ninja&&set parallelism= &&set logger= &&set build_type=-DCMAKE_BUILD_TYPE=Release&&set build_compiler=-DCMAKE_CXX_COMPILER=g++.exe -DCMAKE_C_COMPILER=gcc.exe)
|
||||
- if "%LLVM_VERSION%"=="4.0.0" (set CMAKE_GENERATOR=Ninja&&set parallelism= &&set logger= &&set build_type=-DCMAKE_BUILD_TYPE=Release&&set build_compiler=-DCMAKE_CXX_COMPILER=clang-cl.exe -DCMAKE_C_COMPILER=clang-cl.exe)
|
||||
# # Last printouts
|
||||
# print out generator information
|
||||
|
|
79
cmake/Modules/FindCatch.cmake
Normal file
79
cmake/Modules/FindCatch.cmake
Normal file
|
@ -0,0 +1,79 @@
|
|||
# # # # sol2
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2017 Rapptz, ThePhD, and contributors
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
# the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
include(ExternalProject)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
include(Common/Core)
|
||||
|
||||
# # Base variables
|
||||
if (CATCH_VERSION)
|
||||
set(catch_version ${CATCH_VERSION})
|
||||
else()
|
||||
set(catch_version 2.0.1)
|
||||
endif()
|
||||
|
||||
set(catch_lib catch_lib_${catch_version})
|
||||
|
||||
# # Useful locations
|
||||
set(catch_build_toplevel "${CMAKE_BINARY_DIR}/vendor/catch_${catch_version}")
|
||||
set(catch_include_dirs "${catch_build_toplevel}")
|
||||
|
||||
# # catch library sources
|
||||
set(catch_sources catch.hpp)
|
||||
prepend(catch_sources "${catch_build_toplevel}/" ${catch_sources})
|
||||
|
||||
# # External project to get sources
|
||||
ExternalProject_Add(CATCH_BUILD_SOURCE
|
||||
BUILD_IN_SOURCE TRUE
|
||||
BUILD_ALWAYS FALSE
|
||||
DOWNLOAD_NO_EXTRACT TRUE
|
||||
URL https://github.com/catchorg/Catch2/releases/download/v${catch_version}/catch.hpp
|
||||
TLS_VERIFY TRUE
|
||||
PREFIX ${catch_build_toplevel}
|
||||
SOURCE_DIR ${catch_build_toplevel}
|
||||
DOWNLOAD_DIR ${catch_build_toplevel}
|
||||
TMP_DIR "${catch_build_toplevel}-tmp"
|
||||
STAMP_DIR "${catch_build_toplevel}-stamp"
|
||||
INSTALL_DIR "${catch_build_toplevel}/local"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
TEST_COMMAND ""
|
||||
BUILD_BYPRODUCTS "${catch_sources}")
|
||||
|
||||
add_library(${catch_lib} INTERFACE)
|
||||
add_dependencies(${catch_lib} CATCH_BUILD_SOURCE)
|
||||
target_include_directories(${catch_lib} INTERFACE ${catch_include_dirs})
|
||||
|
||||
if (MSVC)
|
||||
target_add_compile_options(${catch_lib} INTERFACE
|
||||
/D_SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING)
|
||||
endif()
|
||||
|
||||
set(CATCH_FOUND TRUE)
|
||||
set(CATCH_LIBRARIES ${catch_lib})
|
||||
set(CATCH_INCLUDE_DIRS ${catch_include_dirs})
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Catch
|
||||
FOUND_VAR CATCH_FOUND
|
||||
REQUIRED_VARS CATCH_LIBRARIES CATCH_INCLUDE_DIRS
|
||||
VERSION_VAR catch_version)
|
|
@ -285,11 +285,9 @@ set_target_properties(${liblua}
|
|||
LIBRARY_OUTPUT_NAME ${LUA_BUILD_LIBNAME}
|
||||
ARCHIVE_OUTPUT_NAME ${LUA_BUILD_LIBNAME})
|
||||
target_include_directories(${liblua}
|
||||
PRIVATE ${LUA_VANILLA_SOURCE_DIR}
|
||||
PUBLIC ${LUA_VANILLA_SOURCE_DIR})
|
||||
target_compile_definitions(${liblua}
|
||||
PUBLIC LUA_COMPAT_ALL ${LUA_VANILLA_DLL_DEFINE}
|
||||
PRIVATE LUA_COMPAT_ALL ${LUA_VANILLA_DLL_DEFINE})
|
||||
PUBLIC LUA_COMPAT_ALL ${LUA_VANILLA_DLL_DEFINE})
|
||||
if (MSVC)
|
||||
target_compile_options(${liblua}
|
||||
PRIVATE /W1)
|
||||
|
@ -298,8 +296,8 @@ else()
|
|||
PRIVATE -w)
|
||||
endif()
|
||||
if (WIN32)
|
||||
#target_compile_definitions(${liblua}
|
||||
# PRIVATE LUA_USE_WINDOWS)
|
||||
target_compile_definitions(${liblua}
|
||||
PRIVATE LUA_USE_WINDOWS)
|
||||
else()
|
||||
target_compile_definitions(${liblua}
|
||||
PRIVATE LUA_USE_LINUX)
|
||||
|
|
|
@ -65,9 +65,17 @@ function(make_require_from_dll_example target_lib is_single)
|
|||
target_link_libraries(${example_lib_name} PRIVATE ${LUA_LIBRARIES})
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(${example_lib_name} PUBLIC ${LUA_LIBRARIES})
|
||||
if (lua_lib_type MATCHES "STATIC")
|
||||
target_link_libraries(${example_lib_name} PRIVATE ${LUA_LIBRARIES})
|
||||
set_target_properties(${example_lib_name} PROPERTIES
|
||||
WINDOWS_EXPORT_ALL_SYMBOLS TRUE
|
||||
LINK_FLAGS "/OPT:NOREF /WHOLEARCHIVE:lua-5.2.4.lib")
|
||||
else()
|
||||
target_link_libraries(${example_lib_name} PRIVATE ${LUA_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
target_link_libraries(${example_lib_name} PRIVATE ${target_lib})
|
||||
target_include_directories(${example_lib_name} PUBLIC "${LUA_INCLUDE_DIRS}")
|
||||
|
||||
# add executable target that represents require_from_dll program
|
||||
add_executable(${example_name} ${require_from_dll_sources})
|
||||
|
|
|
@ -28,10 +28,15 @@
|
|||
#include "stack.hpp"
|
||||
#include "function_result.hpp"
|
||||
#include "thread.hpp"
|
||||
#include "protected_handler.hpp"
|
||||
|
||||
namespace sol {
|
||||
template <typename base_t>
|
||||
class basic_coroutine : public base_t {
|
||||
public:
|
||||
typedef reference handler_t;
|
||||
handler_t error_handler;
|
||||
|
||||
private:
|
||||
call_status stats = call_status::yielded;
|
||||
|
||||
|
@ -59,53 +64,130 @@ namespace sol {
|
|||
protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) {
|
||||
int firstreturn = 1;
|
||||
luacall(n, LUA_MULTRET);
|
||||
int poststacksize = lua_gettop(lua_state());
|
||||
int poststacksize = lua_gettop(this->lua_state());
|
||||
int returncount = poststacksize - (firstreturn - 1);
|
||||
if (error()) {
|
||||
return protected_function_result(lua_state(), lua_absindex(lua_state(), -1), 1, returncount, status());
|
||||
if (error_handler.valid()) {
|
||||
string_view err = stack::get<string_view>(this->lua_state(), poststacksize);
|
||||
error_handler.push();
|
||||
stack::push(this->lua_state(), err);
|
||||
lua_call(lua_state(), 1, 1);
|
||||
}
|
||||
return protected_function_result(this->lua_state(), lua_absindex(this->lua_state(), -1), 1, returncount, status());
|
||||
}
|
||||
return protected_function_result(lua_state(), firstreturn, returncount, returncount, status());
|
||||
return protected_function_result(this->lua_state(), firstreturn, returncount, returncount, status());
|
||||
}
|
||||
|
||||
public:
|
||||
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)) {
|
||||
basic_coroutine() = default;
|
||||
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_coroutine>>, meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>, meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_coroutine(T&& r) noexcept
|
||||
: base_t(std::forward<T>(r)), error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
|
||||
#ifdef SOL_SAFE_REFERENCES
|
||||
if (!is_function<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_coroutine>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
basic_coroutine(lua_nil_t r)
|
||||
: base_t(r) {
|
||||
basic_coroutine(const basic_coroutine&) = default;
|
||||
basic_coroutine& operator=(const basic_coroutine&) = default;
|
||||
basic_coroutine(basic_coroutine&&) = default;
|
||||
basic_coroutine& operator=(basic_coroutine&&) = default;
|
||||
basic_coroutine(const basic_function<base_t>& b)
|
||||
: basic_coroutine(b, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(b.lua_state())) {
|
||||
}
|
||||
basic_coroutine(const stack_reference& r) noexcept
|
||||
: basic_coroutine(r.lua_state(), r.stack_index()) {
|
||||
basic_coroutine(basic_function<base_t>&& b)
|
||||
: basic_coroutine(std::move(b), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(b.lua_state())) {
|
||||
}
|
||||
basic_coroutine(stack_reference&& r) noexcept
|
||||
: basic_coroutine(r.lua_state(), r.stack_index()) {
|
||||
basic_coroutine(const basic_function<base_t>& b, handler_t eh)
|
||||
: base_t(b), error_handler(std::move(eh)) {
|
||||
}
|
||||
basic_coroutine(basic_function<base_t>&& b, handler_t eh)
|
||||
: base_t(std::move(b)), error_handler(std::move(eh)) {
|
||||
}
|
||||
basic_coroutine(const stack_reference& r)
|
||||
: basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
|
||||
}
|
||||
basic_coroutine(stack_reference&& r)
|
||||
: basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
|
||||
}
|
||||
basic_coroutine(const stack_reference& r, handler_t eh)
|
||||
: basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
|
||||
}
|
||||
basic_coroutine(stack_reference&& r, handler_t eh)
|
||||
: basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
|
||||
}
|
||||
|
||||
template <typename Super>
|
||||
basic_coroutine(const proxy_base<Super>& p)
|
||||
: basic_coroutine(p, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
|
||||
}
|
||||
template <typename Super>
|
||||
basic_coroutine(proxy_base<Super>&& p)
|
||||
: basic_coroutine(std::move(p), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
|
||||
}
|
||||
template <typename Proxy, typename Handler, meta::enable<std::is_base_of<proxy_base_tag, meta::unqualified_t<Proxy>>, meta::neg<is_lua_index<meta::unqualified_t<Handler>>>> = meta::enabler>
|
||||
basic_coroutine(Proxy&& p, Handler&& eh)
|
||||
: basic_coroutine(detail::force_cast<base_t>(p), std::forward<Handler>(eh)) {
|
||||
}
|
||||
|
||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_coroutine(lua_State* L, T&& r)
|
||||
: base_t(L, std::forward<T>(r)) {
|
||||
: basic_coroutine(L, std::forward<T>(r), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
|
||||
}
|
||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_coroutine(lua_State* L, T&& r, handler_t eh)
|
||||
: base_t(L, std::forward<T>(r)), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_SAFE_REFERENCES
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_coroutine>(lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
basic_coroutine(lua_nil_t n)
|
||||
: base_t(n), error_handler(n) {
|
||||
}
|
||||
|
||||
basic_coroutine(lua_State* L, int index = -1)
|
||||
: base_t(L, index) {
|
||||
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
|
||||
}
|
||||
basic_coroutine(lua_State* L, int index, handler_t eh)
|
||||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_coroutine>(lua_state(), index, handler);
|
||||
stack::check<basic_coroutine>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_coroutine(lua_State* L, absolute_index index)
|
||||
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
|
||||
}
|
||||
basic_coroutine(lua_State* L, absolute_index index, handler_t eh)
|
||||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_coroutine>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_coroutine(lua_State* L, raw_index index)
|
||||
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
|
||||
}
|
||||
basic_coroutine(lua_State* L, raw_index index, handler_t eh)
|
||||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_coroutine>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_coroutine(lua_State* L, ref_index index)
|
||||
: base_t(L, index) {
|
||||
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
|
||||
}
|
||||
basic_coroutine(lua_State* L, ref_index index, handler_t eh)
|
||||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_SAFE_REFERENCES
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
|
|
|
@ -39,50 +39,51 @@ namespace sol {
|
|||
|
||||
struct call_indicator {};
|
||||
} // namespace function_detail
|
||||
|
||||
namespace stack {
|
||||
template <typename... Sigs>
|
||||
struct pusher<function_sig<Sigs...>> {
|
||||
template <typename... Sig, typename Fx, typename... Args>
|
||||
template <bool is_yielding, typename... Sig, typename Fx, typename... Args>
|
||||
static void select_convertible(std::false_type, types<Sig...>, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
typedef std::remove_pointer_t<std::decay_t<Fx>> clean_fx;
|
||||
typedef function_detail::functor_function<clean_fx> F;
|
||||
set_fx<F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
typedef function_detail::functor_function<clean_fx, is_yielding> F;
|
||||
set_fx<false, F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename R, typename... A, typename Fx, typename... Args>
|
||||
template <bool is_yielding, typename R, typename... A, typename Fx, typename... Args>
|
||||
static void select_convertible(std::true_type, types<R(A...)>, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
using fx_ptr_t = R (*)(A...);
|
||||
fx_ptr_t fxptr = detail::unwrap(std::forward<Fx>(fx));
|
||||
select_function(std::true_type(), L, fxptr, std::forward<Args>(args)...);
|
||||
select_function<is_yielding>(std::true_type(), L, fxptr, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename R, typename... A, typename Fx, typename... Args>
|
||||
template <bool is_yielding, typename R, typename... A, typename Fx, typename... Args>
|
||||
static void select_convertible(types<R(A...)> t, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
typedef std::decay_t<meta::unwrap_unqualified_t<Fx>> raw_fx_t;
|
||||
typedef R (*fx_ptr_t)(A...);
|
||||
typedef std::is_convertible<raw_fx_t, fx_ptr_t> is_convertible;
|
||||
select_convertible(is_convertible(), t, L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
select_convertible<is_yielding>(is_convertible(), t, L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, typename... Args>
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
static void select_convertible(types<>, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
typedef meta::function_signature_t<meta::unwrap_unqualified_t<Fx>> Sig;
|
||||
select_convertible(types<Sig>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
select_convertible<is_yielding>(types<Sig>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, typename T, typename... Args>
|
||||
template <bool is_yielding, typename Fx, typename T, typename... Args>
|
||||
static void select_reference_member_variable(std::false_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
|
||||
typedef std::remove_pointer_t<std::decay_t<Fx>> clean_fx;
|
||||
typedef function_detail::member_variable<meta::unwrap_unqualified_t<T>, clean_fx> F;
|
||||
set_fx<F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
typedef function_detail::member_variable<meta::unwrap_unqualified_t<T>, clean_fx, is_yielding> F;
|
||||
set_fx<false, F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, typename T, typename... Args>
|
||||
template <bool is_yielding, typename Fx, typename T, typename... Args>
|
||||
static void select_reference_member_variable(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
|
||||
typedef std::decay_t<Fx> dFx;
|
||||
dFx memfxptr(std::forward<Fx>(fx));
|
||||
auto userptr = detail::ptr(std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
lua_CFunction freefunc = &function_detail::upvalue_member_variable<std::decay_t<decltype(*userptr)>, meta::unqualified_t<Fx>>::call;
|
||||
lua_CFunction freefunc = &function_detail::upvalue_member_variable<std::decay_t<decltype(*userptr)>, meta::unqualified_t<Fx>, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
|
@ -91,49 +92,51 @@ namespace sol {
|
|||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
|
||||
template <typename Fx, typename... Args>
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
static void select_member_variable(std::false_type, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
select_convertible(types<Sigs...>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
select_convertible<is_yielding>(types<Sigs...>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, typename T, typename... Args, meta::disable<meta::is_specialization_of<function_detail::class_indicator, meta::unqualified_t<T>>> = meta::enabler>
|
||||
template <bool is_yielding, typename Fx, typename T, typename... Args, meta::disable<meta::is_specialization_of<function_detail::class_indicator, meta::unqualified_t<T>>> = meta::enabler>
|
||||
static void select_member_variable(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
|
||||
typedef meta::boolean<meta::is_specialization_of<std::reference_wrapper, meta::unqualified_t<T>>::value || std::is_pointer<T>::value> is_reference;
|
||||
select_reference_member_variable(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
select_reference_member_variable<is_yielding>(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, typename C>
|
||||
template <bool is_yielding, typename Fx, typename C>
|
||||
static void select_member_variable(std::true_type, lua_State* L, Fx&& fx, function_detail::class_indicator<C>) {
|
||||
lua_CFunction freefunc = &function_detail::upvalue_this_member_variable<C, Fx>::call;
|
||||
lua_CFunction freefunc = &function_detail::upvalue_this_member_variable<C, Fx, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::stack_detail::push_as_upvalues(L, fx);
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
|
||||
template <typename Fx>
|
||||
template <bool is_yielding, typename Fx>
|
||||
static void select_member_variable(std::true_type, lua_State* L, Fx&& fx) {
|
||||
typedef typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type C;
|
||||
lua_CFunction freefunc = &function_detail::upvalue_this_member_variable<C, Fx>::call;
|
||||
lua_CFunction freefunc = &function_detail::upvalue_this_member_variable<C, Fx, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::stack_detail::push_as_upvalues(L, fx);
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
|
||||
template <typename Fx, typename T, typename... Args>
|
||||
template <bool is_yielding, typename Fx, typename T, typename... Args>
|
||||
static void select_reference_member_function(std::false_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
|
||||
typedef std::decay_t<Fx> clean_fx;
|
||||
typedef function_detail::member_function<meta::unwrap_unqualified_t<T>, clean_fx> F;
|
||||
set_fx<F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
typedef function_detail::member_function<meta::unwrap_unqualified_t<T>, clean_fx, is_yielding> F;
|
||||
set_fx<false, F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, typename T, typename... Args>
|
||||
template <bool is_yielding, typename Fx, typename T, typename... Args>
|
||||
static void select_reference_member_function(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
|
||||
typedef std::decay_t<Fx> dFx;
|
||||
dFx memfxptr(std::forward<Fx>(fx));
|
||||
auto userptr = detail::ptr(std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
lua_CFunction freefunc = &function_detail::upvalue_member_function<std::decay_t<decltype(*userptr)>, meta::unqualified_t<Fx>>::call;
|
||||
lua_CFunction freefunc = &function_detail::upvalue_member_function<std::decay_t<decltype(*userptr)>, meta::unqualified_t<Fx>, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
|
@ -142,45 +145,47 @@ namespace sol {
|
|||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
|
||||
template <typename Fx, typename... Args>
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
static void select_member_function(std::false_type, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
select_member_variable(meta::is_member_object<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
select_member_variable<is_yielding>(meta::is_member_object<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, typename T, typename... Args, meta::disable<meta::is_specialization_of<function_detail::class_indicator, meta::unqualified_t<T>>> = meta::enabler>
|
||||
template <bool is_yielding, typename Fx, typename T, typename... Args, meta::disable<meta::is_specialization_of<function_detail::class_indicator, meta::unqualified_t<T>>> = meta::enabler>
|
||||
static void select_member_function(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
|
||||
typedef meta::boolean<meta::is_specialization_of<std::reference_wrapper, meta::unqualified_t<T>>::value || std::is_pointer<T>::value> is_reference;
|
||||
select_reference_member_function(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
select_reference_member_function<is_yielding>(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, typename C>
|
||||
template <bool is_yielding, typename Fx, typename C>
|
||||
static void select_member_function(std::true_type, lua_State* L, Fx&& fx, function_detail::class_indicator<C>) {
|
||||
lua_CFunction freefunc = &function_detail::upvalue_this_member_function<C, Fx>::call;
|
||||
lua_CFunction freefunc = &function_detail::upvalue_this_member_function<C, Fx, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::stack_detail::push_as_upvalues(L, fx);
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
|
||||
template <typename Fx>
|
||||
template <bool is_yielding, typename Fx>
|
||||
static void select_member_function(std::true_type, lua_State* L, Fx&& fx) {
|
||||
typedef typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type C;
|
||||
lua_CFunction freefunc = &function_detail::upvalue_this_member_function<C, Fx>::call;
|
||||
lua_CFunction freefunc = &function_detail::upvalue_this_member_function<C, Fx, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::stack_detail::push_as_upvalues(L, fx);
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
|
||||
template <typename Fx, typename... Args>
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
static void select_function(std::false_type, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
select_member_function(std::is_member_function_pointer<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
select_member_function<is_yielding>(std::is_member_function_pointer<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, typename... Args>
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
static void select_function(std::true_type, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
std::decay_t<Fx> target(std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
lua_CFunction freefunc = &function_detail::upvalue_free_function<Fx>::call;
|
||||
lua_CFunction freefunc = &function_detail::upvalue_free_function<Fx, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
|
@ -188,29 +193,34 @@ namespace sol {
|
|||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
|
||||
template <bool is_yielding>
|
||||
static void select_function(std::true_type, lua_State* L, lua_CFunction f) {
|
||||
// TODO: support yielding
|
||||
stack::push(L, f);
|
||||
}
|
||||
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
template <bool is_yielding>
|
||||
static void select_function(std::true_type, lua_State* L, detail::lua_CFunction_noexcept f) {
|
||||
// TODO: support yielding
|
||||
stack::push(L, f);
|
||||
}
|
||||
#endif // noexcept function type
|
||||
|
||||
template <typename Fx, typename... Args, meta::disable<is_lua_reference<meta::unqualified_t<Fx>>> = meta::enabler>
|
||||
template <bool is_yielding, 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)...);
|
||||
select_function<is_yielding>(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<is_lua_reference<meta::unqualified_t<Fx>>> = meta::enabler>
|
||||
template <bool is_yielding, typename Fx, meta::enable<is_lua_reference<meta::unqualified_t<Fx>>> = meta::enabler>
|
||||
static void select(lua_State* L, Fx&& fx) {
|
||||
// TODO: hoist into lambda in this case??
|
||||
stack::push(L, std::forward<Fx>(fx));
|
||||
}
|
||||
|
||||
template <typename Fx, typename... Args>
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
static void set_fx(lua_State* L, Args&&... args) {
|
||||
lua_CFunction freefunc = function_detail::call<meta::unqualified_t<Fx>, 2>;
|
||||
lua_CFunction freefunc = function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
|
@ -218,12 +228,36 @@ namespace sol {
|
|||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static int push(lua_State* L, Args&&... args) {
|
||||
template <typename Arg0, typename... Args, meta::disable<std::is_same<detail::yield_tag_t, meta::unqualified_t<Arg0>>> = meta::enabler>
|
||||
static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
|
||||
// Set will always place one thing (function) on the stack
|
||||
select(L, std::forward<Args>(args)...);
|
||||
select<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static int push(lua_State* L, detail::yield_tag_t, Args&&... args) {
|
||||
// Set will always place one thing (function) on the stack
|
||||
select<true>(L, std::forward<Args>(args)...);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct pusher<yielding_t<T>> {
|
||||
template <typename... Args>
|
||||
static int push(lua_State* L, const yielding_t<T>& f, Args&&... args) {
|
||||
pusher<function_sig<>> p{};
|
||||
(void)p;
|
||||
return p.push(L, detail::yield_tag, f.func, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static int push(lua_State* L, yielding_t<T>&& f, Args&&... args) {
|
||||
pusher<function_sig<>> p{};
|
||||
(void)p;
|
||||
return p.push(L, detail::yield_tag, f.func, std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Args>
|
||||
|
@ -257,7 +291,9 @@ namespace sol {
|
|||
struct pusher<Signature, std::enable_if_t<std::is_member_pointer<Signature>::value>> {
|
||||
template <typename F, typename... Args>
|
||||
static int push(lua_State* L, F&& f, Args&&... args) {
|
||||
return pusher<function_sig<>>{}.push(L, std::forward<F>(f), std::forward<Args>(args)...);
|
||||
pusher<function_sig<>> p{};
|
||||
(void)p;
|
||||
return p.push(L, std::forward<F>(f), std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -352,25 +388,25 @@ namespace sol {
|
|||
struct pusher<factory_wrapper<Functions...>> {
|
||||
static int push(lua_State* L, const factory_wrapper<Functions...>& fw) {
|
||||
typedef function_detail::overloaded_function<0, Functions...> F;
|
||||
pusher<function_sig<>>{}.set_fx<F>(L, fw.functions);
|
||||
pusher<function_sig<>>{}.set_fx<false, F>(L, fw.functions);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int push(lua_State* L, factory_wrapper<Functions...>&& fw) {
|
||||
typedef function_detail::overloaded_function<0, Functions...> F;
|
||||
pusher<function_sig<>>{}.set_fx<F>(L, std::move(fw.functions));
|
||||
pusher<function_sig<>>{}.set_fx<false, F>(L, std::move(fw.functions));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const factory_wrapper<Functions...>& set, function_detail::call_indicator) {
|
||||
typedef function_detail::overloaded_function<1, Functions...> F;
|
||||
pusher<function_sig<>>{}.set_fx<F>(L, set.functions);
|
||||
pusher<function_sig<>>{}.set_fx<false, F>(L, set.functions);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int push(lua_State* L, factory_wrapper<Functions...>&& set, function_detail::call_indicator) {
|
||||
typedef function_detail::overloaded_function<1, Functions...> F;
|
||||
pusher<function_sig<>>{}.set_fx<F>(L, std::move(set.functions));
|
||||
pusher<function_sig<>>{}.set_fx<false, F>(L, std::move(set.functions));
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -30,10 +30,16 @@
|
|||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template <typename Fx, int start = 1>
|
||||
template <typename Fx, int start = 1, bool is_yielding = false>
|
||||
inline int call(lua_State* L) {
|
||||
Fx& fx = stack::get<user<Fx>>(L, upvalue_index(start));
|
||||
return fx(L);
|
||||
int nr = fx(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace sol::function_detail
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template <typename Func>
|
||||
template <typename Func, bool is_yielding>
|
||||
struct functor_function {
|
||||
typedef std::decay_t<meta::unwrap_unqualified_t<Func>> function_type;
|
||||
function_type fx;
|
||||
|
@ -39,7 +39,13 @@ namespace function_detail {
|
|||
}
|
||||
|
||||
int call(lua_State* L) {
|
||||
return call_detail::call_wrapped<void, true, false>(L, fx);
|
||||
int nr = call_detail::call_wrapped<void, true, false>(L, fx);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
|
@ -48,7 +54,7 @@ namespace function_detail {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function>
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct member_function {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef meta::function_return_t<function_type> return_type;
|
||||
|
@ -62,7 +68,13 @@ namespace function_detail {
|
|||
}
|
||||
|
||||
int call(lua_State* L) {
|
||||
return call_detail::call_wrapped<T, true, false, -1>(L, invocation, detail::unwrap(detail::deref(member)));
|
||||
int nr = call_detail::call_wrapped<T, true, false, -1>(L, invocation, detail::unwrap(detail::deref(member)));
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
|
@ -71,7 +83,7 @@ namespace function_detail {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function>
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct member_variable {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef typename meta::bind_traits<function_type>::return_type return_type;
|
||||
|
@ -86,14 +98,23 @@ namespace function_detail {
|
|||
}
|
||||
|
||||
int call(lua_State* L) {
|
||||
M mem = detail::unwrap(detail::deref(member));
|
||||
switch (lua_gettop(L)) {
|
||||
case 0:
|
||||
return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
|
||||
case 1:
|
||||
return call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
|
||||
default:
|
||||
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||
int nr;
|
||||
{
|
||||
M mem = detail::unwrap(detail::deref(member));
|
||||
switch (lua_gettop(L)) {
|
||||
case 0:
|
||||
nr = call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
|
||||
case 1:
|
||||
nr = call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
|
||||
default:
|
||||
nr = luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||
}
|
||||
}
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template <typename Function>
|
||||
template <typename Function, bool is_yielding>
|
||||
struct upvalue_free_function {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef meta::bind_traits<function_type> traits_type;
|
||||
|
@ -40,7 +40,13 @@ namespace function_detail {
|
|||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
return detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
|
@ -48,7 +54,7 @@ namespace function_detail {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function>
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct upvalue_member_function {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef lua_bind_traits<function_type> traits_type;
|
||||
|
@ -67,7 +73,13 @@ namespace function_detail {
|
|||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
return detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
|
@ -75,7 +87,7 @@ namespace function_detail {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function>
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct upvalue_member_variable {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef lua_bind_traits<function_type> traits_type;
|
||||
|
@ -101,7 +113,13 @@ namespace function_detail {
|
|||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
return detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
|
@ -109,8 +127,8 @@ namespace function_detail {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function>
|
||||
struct upvalue_member_variable<T, readonly_wrapper<Function>> {
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct upvalue_member_variable<T, readonly_wrapper<Function>, is_yielding> {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef lua_bind_traits<function_type> traits_type;
|
||||
|
||||
|
@ -133,7 +151,13 @@ namespace function_detail {
|
|||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
return detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
|
@ -141,7 +165,7 @@ namespace function_detail {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function>
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct upvalue_this_member_function {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef lua_bind_traits<function_type> traits_type;
|
||||
|
@ -155,7 +179,13 @@ namespace function_detail {
|
|||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
return detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
|
@ -163,7 +193,7 @@ namespace function_detail {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function>
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct upvalue_this_member_variable {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
|
||||
|
@ -183,7 +213,13 @@ namespace function_detail {
|
|||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
return detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
|
@ -191,8 +227,8 @@ namespace function_detail {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function>
|
||||
struct upvalue_this_member_variable<T, readonly_wrapper<Function>> {
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct upvalue_this_member_variable<T, readonly_wrapper<Function>, is_yielding> {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef lua_bind_traits<function_type> traits_type;
|
||||
|
||||
|
@ -210,7 +246,13 @@ namespace function_detail {
|
|||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
return detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
|
|
|
@ -28,86 +28,23 @@
|
|||
#include "stack.hpp"
|
||||
#include "protected_function_result.hpp"
|
||||
#include "unsafe_function.hpp"
|
||||
#include "protected_handler.hpp"
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
inline const char (&default_handler_name())[9] {
|
||||
static const char name[9] = "sol.\xF0\x9F\x94\xA9";
|
||||
return name;
|
||||
}
|
||||
|
||||
template <bool b, typename target_t = reference>
|
||||
struct protected_handler {
|
||||
typedef is_stack_based<target_t> is_stack;
|
||||
const target_t& target;
|
||||
int stackindex;
|
||||
|
||||
protected_handler(std::false_type, const target_t& target)
|
||||
: target(target), stackindex(0) {
|
||||
if (b) {
|
||||
stackindex = lua_gettop(target.lua_state()) + 1;
|
||||
target.push();
|
||||
}
|
||||
}
|
||||
|
||||
protected_handler(std::true_type, const target_t& target)
|
||||
: target(target), stackindex(0) {
|
||||
if (b) {
|
||||
stackindex = target.stack_index();
|
||||
}
|
||||
}
|
||||
|
||||
protected_handler(const target_t& target)
|
||||
: protected_handler(is_stack(), target) {
|
||||
}
|
||||
|
||||
bool valid() const noexcept {
|
||||
return b;
|
||||
}
|
||||
|
||||
~protected_handler() {
|
||||
if (!is_stack::value && stackindex != 0) {
|
||||
lua_remove(target.lua_state(), stackindex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename base_t, typename T>
|
||||
basic_function<base_t> force_cast(T& p) {
|
||||
return p;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <typename base_t, bool aligned = false, typename handler_t = reference>
|
||||
class basic_protected_function : public base_t {
|
||||
public:
|
||||
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);
|
||||
return detail::get_default_handler<handler_t, is_main_threaded<base_t>::value>(L);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void set_default_handler(const T& ref) {
|
||||
if (ref.lua_state() == nullptr) {
|
||||
return;
|
||||
}
|
||||
lua_State* L = ref.lua_state();
|
||||
if (!ref.valid()) {
|
||||
lua_pushnil(L);
|
||||
lua_setglobal(L, detail::default_handler_name());
|
||||
}
|
||||
else {
|
||||
ref.push();
|
||||
lua_setglobal(L, detail::default_handler_name());
|
||||
}
|
||||
detail::set_default_handler(ref.lua_state(), ref);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
108
sol/protected_handler.hpp
Normal file
108
sol/protected_handler.hpp
Normal file
|
@ -0,0 +1,108 @@
|
|||
// sol2
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2017 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_PROTECTED_HANDLER_HPP
|
||||
#define SOL_PROTECTED_HANDLER_HPP
|
||||
|
||||
#include "reference.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "protected_function_result.hpp"
|
||||
#include "unsafe_function.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
inline const char(&default_handler_name())[9]{
|
||||
static const char name[9] = "sol.\xF0\x9F\x94\xA9";
|
||||
return name;
|
||||
}
|
||||
|
||||
template <bool b, typename target_t = reference>
|
||||
struct protected_handler {
|
||||
typedef is_stack_based<target_t> is_stack;
|
||||
const target_t& target;
|
||||
int stackindex;
|
||||
|
||||
protected_handler(std::false_type, const target_t& target)
|
||||
: target(target), stackindex(0) {
|
||||
if (b) {
|
||||
stackindex = lua_gettop(target.lua_state()) + 1;
|
||||
target.push();
|
||||
}
|
||||
}
|
||||
|
||||
protected_handler(std::true_type, const target_t& target)
|
||||
: target(target), stackindex(0) {
|
||||
if (b) {
|
||||
stackindex = target.stack_index();
|
||||
}
|
||||
}
|
||||
|
||||
protected_handler(const target_t& target)
|
||||
: protected_handler(is_stack(), target) {
|
||||
}
|
||||
|
||||
bool valid() const noexcept {
|
||||
return b;
|
||||
}
|
||||
|
||||
~protected_handler() {
|
||||
if (!is_stack::value && stackindex != 0) {
|
||||
lua_remove(target.lua_state(), stackindex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename base_t, typename T>
|
||||
basic_function<base_t> force_cast(T& p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
template <typename Reference, bool is_main_ref = false>
|
||||
static Reference get_default_handler(lua_State* L) {
|
||||
if (is_stack_based<Reference>::value || L == nullptr)
|
||||
return Reference(L, lua_nil);
|
||||
L = is_main_ref ? main_thread(L, L) : L;
|
||||
lua_getglobal(L, default_handler_name());
|
||||
auto pp = stack::pop_n(L, 1);
|
||||
return Reference(L, -1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void set_default_handler(lua_State* L, const T& ref) {
|
||||
if (L == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (!ref.valid()) {
|
||||
lua_pushnil(L);
|
||||
lua_setglobal(L, default_handler_name());
|
||||
}
|
||||
else {
|
||||
ref.push(L);
|
||||
lua_setglobal(L, default_handler_name());
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_PROTECTED_HANDLER_HPP
|
|
@ -146,7 +146,11 @@ namespace sol {
|
|||
}
|
||||
|
||||
int push() const noexcept {
|
||||
return get<reference>().push(lua_state());
|
||||
return push(this->lua_state());
|
||||
}
|
||||
|
||||
int push(lua_State* L) const noexcept {
|
||||
return get<reference>().push(L);
|
||||
}
|
||||
|
||||
type get_type() const {
|
||||
|
|
|
@ -200,6 +200,9 @@ namespace sol {
|
|||
|
||||
struct unchecked_t {};
|
||||
const unchecked_t unchecked = unchecked_t{};
|
||||
|
||||
struct yield_tag_t {};
|
||||
const yield_tag_t yield_tag = yield_tag_t{};
|
||||
} // namespace detail
|
||||
|
||||
struct lua_nil_t {};
|
||||
|
@ -224,6 +227,30 @@ namespace sol {
|
|||
struct no_metatable_t {};
|
||||
const no_metatable_t no_metatable = {};
|
||||
|
||||
template <typename T>
|
||||
struct yielding_t {
|
||||
T func;
|
||||
|
||||
yielding_t() = default;
|
||||
yielding_t(const yielding_t&) = default;
|
||||
yielding_t(yielding_t&&) = default;
|
||||
yielding_t& operator=(const yielding_t&) = default;
|
||||
yielding_t& operator=(yielding_t&&) = default;
|
||||
template <typename Arg, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Arg>, yielding_t>>, meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<Arg>>>> = meta::enabler>
|
||||
yielding_t(Arg&& arg)
|
||||
: func(std::forward<Arg>(arg)) {
|
||||
}
|
||||
template <typename Arg0, typename Arg1, typename... Args>
|
||||
yielding_t(Arg0&& arg0, Arg1&& arg1, Args&&... args)
|
||||
: func(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
inline yielding_t<std::decay_t<F>> yielding(F&& f) {
|
||||
return yielding_t<std::decay_t<F>>(std::forward<F>(f));
|
||||
}
|
||||
|
||||
typedef std::remove_pointer_t<lua_CFunction> lua_CFunction_ref;
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
|
||||
# # # # sol2 tests
|
||||
|
||||
find_package(CATCH 2.0.1 REQUIRED)
|
||||
|
||||
file(GLOB SOL2_TEST_SOURCES test*.cpp)
|
||||
source_group(test_sources FILES ${SOL2_TEST_SOURCES})
|
||||
file(DOWNLOAD https://github.com/catchorg/Catch2/releases/download/v2.0.1/catch.hpp ${CMAKE_BINARY_DIR}/vendor/Catch/include/catch.hpp)
|
||||
#file(DOWNLOAD https://github.com/catchorg/Catch2/releases/download/v1.11.0/catch.hpp ${CMAKE_BINARY_DIR}/vendor/Catch/include/catch.hpp)
|
||||
|
||||
function(CREATE_TEST test_target_name test_name is_single)
|
||||
if (is_single)
|
||||
|
@ -46,8 +46,6 @@ function(CREATE_TEST test_target_name test_name is_single)
|
|||
target_link_libraries(${test_target_name} sol2)
|
||||
endif()
|
||||
|
||||
target_include_directories(${test_target_name}
|
||||
PRIVATE "${LUA_INCLUDE_DIR}" "${CMAKE_BINARY_DIR}/vendor/Catch/include/")
|
||||
if (MSVC)
|
||||
if (NOT CMAKE_COMPILER_ID MATCHES "Clang")
|
||||
target_compile_options(${test_target_name}
|
||||
|
@ -63,9 +61,22 @@ function(CREATE_TEST test_target_name test_name is_single)
|
|||
endif()
|
||||
target_compile_features(${test_target_name}
|
||||
PRIVATE ${CXX_FEATURES})
|
||||
# if CMAKE_DL_LIBS is empty, then that just resolves to nothingness
|
||||
if (CMAKE_DL_LIBS)
|
||||
target_link_libraries(${test_target_name}
|
||||
${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
target_link_libraries(${test_target_name}
|
||||
Threads::Threads ${LUA_LIBRARIES} ${CMAKE_DL_LIBS})
|
||||
Threads::Threads ${LUA_LIBRARIES} ${CATCH_LIBRARIES})
|
||||
|
||||
if (IS_X86)
|
||||
target_compile_options(${test_target_name} BEFORE PRIVATE -m32)
|
||||
endif()
|
||||
|
||||
if(MINGW AND IS_X86)
|
||||
#set_target_properties(${test_target_name}
|
||||
# PROPERTIES
|
||||
# LINK_FLAGS -static-libstdc++)
|
||||
endif()
|
||||
|
||||
add_test(NAME ${test_name} COMMAND ${test_target_name})
|
||||
install(TARGETS ${test_target_name} RUNTIME DESTINATION bin)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
struct pre_main {
|
||||
pre_main() {
|
||||
#ifdef SOL2_CI
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _MSC_VER
|
||||
_set_abort_behavior(0, _WRITE_ABORT_MSG);
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -530,3 +530,55 @@ end
|
|||
REQUIRE(s4 == 0);
|
||||
REQUIRE(s5 == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("coroutines/yielding", "test that a sol2 bound function can yield when marked yieldable") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::coroutine);
|
||||
|
||||
int i = 0;
|
||||
auto func = [&i]() {
|
||||
++i;
|
||||
return i;
|
||||
};
|
||||
|
||||
struct h {
|
||||
int x = 500;
|
||||
int func() const {
|
||||
return x;
|
||||
}
|
||||
} hobj{};
|
||||
|
||||
lua["f"] = sol::yielding(func);
|
||||
lua["g"] = sol::yielding([]() { return 300; });
|
||||
lua["h"] = sol::yielding(&h::func);
|
||||
lua["hobj"] = &hobj;
|
||||
|
||||
sol::string_view code = R"(
|
||||
co1 = coroutine.create(f)
|
||||
success1, value1 = coroutine.resume(co1)
|
||||
co2 = coroutine.create(g)
|
||||
success2, value2 = coroutine.resume(co2)
|
||||
co3 = coroutine.create(function()
|
||||
h(hobj)
|
||||
end)
|
||||
success3, value3 = coroutine.resume(co3)
|
||||
)";
|
||||
|
||||
auto result = lua.safe_script(code);
|
||||
REQUIRE(result.valid());
|
||||
|
||||
bool success1 = lua["success1"];
|
||||
int value1 = lua["value1"];
|
||||
REQUIRE(success1);
|
||||
REQUIRE(value1 == 1);
|
||||
|
||||
bool success2 = lua["success2"];
|
||||
int value2 = lua["value2"];
|
||||
REQUIRE(success2);
|
||||
REQUIRE(value2 == 300);
|
||||
|
||||
bool success3 = lua["success3"];
|
||||
int value3 = lua["value3"];
|
||||
REQUIRE(success3);
|
||||
REQUIRE(value3 == 500);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#ifndef SOL_TEST_SOL_HPP
|
||||
#define SOL_TEST_SOL_HPP
|
||||
|
||||
#ifndef SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#endif // SOL_CHECK_ARGUMENTS
|
||||
|
@ -60,3 +63,5 @@ struct test_stack_guard {
|
|||
endtop = lua_gettop(L);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SOL_TEST_SOL_HPP
|
||||
|
|
Loading…
Reference in New Issue
Block a user