From dc2493e7525bb7633f697ef10f72b72b46222249 Mon Sep 17 00:00:00 2001 From: Andy Belle-Isle Date: Fri, 30 Aug 2019 00:45:36 -0400 Subject: Forget what I said, I just need to change git attributes to mark for vendor --- lib/sol2/examples/interop/LuaBridge/CMakeLists.txt | 69 +++++++ .../interop/LuaBridge/source/LuaBridge.cpp | 116 +++++++++++ lib/sol2/examples/interop/kaguya/CMakeLists.txt | 68 +++++++ lib/sol2/examples/interop/kaguya/source/kaguya.cpp | 124 ++++++++++++ lib/sol2/examples/interop/luwra/CMakeLists.txt | 68 +++++++ lib/sol2/examples/interop/luwra/source/luwra.cpp | 110 +++++++++++ lib/sol2/examples/interop/tolua/CMakeLists.txt | 68 +++++++ lib/sol2/examples/interop/tolua/source/Player.h | 20 ++ lib/sol2/examples/interop/tolua/source/Player.pkg | 8 + lib/sol2/examples/interop/tolua/source/tolua.cpp | 97 +++++++++ .../examples/interop/tolua/source/tolua_Player.h | 217 +++++++++++++++++++++ 11 files changed, 965 insertions(+) create mode 100644 lib/sol2/examples/interop/LuaBridge/CMakeLists.txt create mode 100644 lib/sol2/examples/interop/LuaBridge/source/LuaBridge.cpp create mode 100644 lib/sol2/examples/interop/kaguya/CMakeLists.txt create mode 100644 lib/sol2/examples/interop/kaguya/source/kaguya.cpp create mode 100644 lib/sol2/examples/interop/luwra/CMakeLists.txt create mode 100644 lib/sol2/examples/interop/luwra/source/luwra.cpp create mode 100644 lib/sol2/examples/interop/tolua/CMakeLists.txt create mode 100644 lib/sol2/examples/interop/tolua/source/Player.h create mode 100644 lib/sol2/examples/interop/tolua/source/Player.pkg create mode 100644 lib/sol2/examples/interop/tolua/source/tolua.cpp create mode 100644 lib/sol2/examples/interop/tolua/source/tolua_Player.h (limited to 'lib/sol2/examples/interop') diff --git a/lib/sol2/examples/interop/LuaBridge/CMakeLists.txt b/lib/sol2/examples/interop/LuaBridge/CMakeLists.txt new file mode 100644 index 0000000..6417f76 --- /dev/null +++ b/lib/sol2/examples/interop/LuaBridge/CMakeLists.txt @@ -0,0 +1,69 @@ +# # # # sol3 +# The MIT License (MIT) +# +# Copyright (c) 2013-2019 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. + +# # # sol3 interop Examples - luabridge + +find_package(LuaBridgeBuild) + +function (make_luabridge_interop_example target_library example_suffix) + set(example_name luabridge_interop_example) + set(example_name "${example_name}${example_suffix}") + + add_executable(${example_name} source/LuaBridge.cpp) + target_link_libraries(${example_name} + PRIVATE ${LUA_LIBRARIES} ${LUABRIDGE_LIBRARIES} + ${target_library} sol2::assert) + + if (MSVC) + target_compile_options(${example_name} + PRIVATE /std:c++latest /EHsc "$<$:/MDd>" + "$<$:/MD>" + "$<$:/MD>" + "$<$:/MD>") + target_compile_definitions(${example_name} + PRIVATE /W1 + UNICODE _UNICODE + _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE) + else() + target_compile_options(${example_name} + PRIVATE -std=c++1z -w + -Wno-unknown-warning -Wno-unknown-warning-option) + endif() + + if (CMAKE_DL_LIBS) + target_link_libraries(${example_name} PRIVATE ${CMAKE_DL_LIBS}) + endif() + + if (SOL2_TESTS_INTEROP_EXAMPLES) + add_test(NAME ${example_name} COMMAND ${example_name}) + endif() +endfunction() + +if (SOL2_INTEROP_EXAMPLES) + make_luabridge_interop_example(sol2::sol2 "") +endif() +if (SOL2_INTEROP_EXAMPLES_SINGLE) + make_luabridge_interop_example(sol2::sol2_single ".single") +endif() +if (SOL2_INTEROP_EXAMPLES_SINGLE_GENERATED) + make_luabridge_interop_example(sol2::sol2_single_generated ".single.generated") +endif() diff --git a/lib/sol2/examples/interop/LuaBridge/source/LuaBridge.cpp b/lib/sol2/examples/interop/LuaBridge/source/LuaBridge.cpp new file mode 100644 index 0000000..81a9199 --- /dev/null +++ b/lib/sol2/examples/interop/LuaBridge/source/LuaBridge.cpp @@ -0,0 +1,116 @@ +#define SOL_ALL_SAFETIES_ON 1 +#define SOL_ENABLE_INTEROP 1 // MUST be defined to use interop features +#include + +#include + +#include +#include + +// LuaBridge, +// no longer maintained, by VinnieFalco: +// https://github.com/vinniefalco/LuaBridge + +struct A { + + A(int v) + : v_(v) { + } + + void print() { + std::cout << "called A::print" << std::endl; + } + + int value() const { + return v_; + } + +private: + int v_ = 50; +}; + +template +inline bool sol_lua_interop_check(sol::types, lua_State* L, int relindex, sol::type index_type, Handler&& handler, sol::stack::record& tracking) { + // just marking unused parameters for no compiler warnings + (void)index_type; + (void)handler; + tracking.use(1); + int index = lua_absindex(L, relindex); + T* corrected = luabridge::Userdata::get(L, index, true); + return corrected != nullptr; +} + +template +inline std::pair sol_lua_interop_get(sol::types t, lua_State* L, int relindex, void* unadjusted_pointer, sol::stack::record& tracking) { + (void)unadjusted_pointer; + int index = lua_absindex(L, relindex); + if (!sol_lua_interop_check(t, L, index, sol::type::userdata, sol::no_panic, tracking)) { + return { false, nullptr }; + } + T* corrected = luabridge::Userdata::get(L, index, true); + return { true, corrected }; +} + +void register_sol_stuff(lua_State* L) { + // grab raw state and put into state_view + // state_view is cheap to construct + sol::state_view lua(L); + // bind and set up your things: everything is entirely self-contained + lua["f"] = sol::overload( + [](A& from_luabridge) { + std::cout << "calling 1-argument version with luabridge-created A { " << from_luabridge.value() << " }" << std::endl; + c_assert(from_luabridge.value() == 24); + }, + [](A& from_luabridge, int second_arg) { + std::cout << "calling 2-argument version with luabridge-created A { " << from_luabridge.value() << " } and integer argument of " << second_arg << std::endl; + c_assert(from_luabridge.value() == 24); + c_assert(second_arg == 5); + }); +} + +void check_with_sol(lua_State* L) { + sol::state_view lua(L); + A& obj = lua["obj"]; + (void)obj; + c_assert(obj.value() == 24); +} + +int main(int, char* []) { + + std::cout << "=== interop example (LuaBridge) ===" << std::endl; + std::cout << "code modified from LuaBridge's examples: https://github.com/vinniefalco/LuaBridge" << std::endl; + + struct closer { + void operator()(lua_State* L) { + lua_close(L); + } + }; + + std::unique_ptr state(luaL_newstate()); + lua_State* L = state.get(); + luaL_openlibs(L); + + luabridge::getGlobalNamespace(L) + .beginNamespace("test") + .beginClass("A") + .addConstructor() + .addFunction("print", &A::print) + .addFunction("value", &A::value) + .endClass() + .endNamespace(); + + register_sol_stuff(L); + + + if (luaL_dostring(L, R"( +obj = test.A(24) +f(obj) -- call 1 argument version +f(obj, 5) -- call 2 argument version +)")) { + lua_error(L); + } + + check_with_sol(L); + + return 0; +} \ No newline at end of file diff --git a/lib/sol2/examples/interop/kaguya/CMakeLists.txt b/lib/sol2/examples/interop/kaguya/CMakeLists.txt new file mode 100644 index 0000000..0b01061 --- /dev/null +++ b/lib/sol2/examples/interop/kaguya/CMakeLists.txt @@ -0,0 +1,68 @@ +# # # # sol3 +# The MIT License (MIT) +# +# Copyright (c) 2013-2019 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. + +# # # sol3 interop Examples - kaguya + +find_package(KaguyaBuild) + +function (make_kaguya_interop_example target_library example_suffix) + set(example_name kaguya_interop_example) + set(example_name "${example_name}${example_suffix}") + + add_executable(${example_name} source/kaguya.cpp) + target_link_libraries(${example_name} + PRIVATE ${LUA_LIBRARIES} ${KAGUYA_LIBRARIES} + ${target_library} sol2::assert) + + if (MSVC) + target_compile_options(${example_name} + PRIVATE /W1 /std:c++latest /EHsc "$<$:/MDd>" + "$<$:/MD>" + "$<$:/MD>" + "$<$:/MD>") + target_compile_definitions(${example_name} + PRIVATE UNICODE _UNICODE + _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE) + else() + target_compile_options(${example_name} + PRIVATE -std=c++1z -w + -Wno-unknown-warning -Wno-unknown-warning-option) + endif() + + if (CMAKE_DL_LIBS) + target_link_libraries(${example_name} PRIVATE ${CMAKE_DL_LIBS}) + endif() + + if (SOL2_TESTS_INTEROP_EXAMPLES) + add_test(NAME ${example_name} COMMAND ${example_name}) + endif() +endfunction() + +if (SOL2_INTEROP_EXAMPLES) + make_kaguya_interop_example(sol2::sol2 "") +endif() +if (SOL2_INTEROP_EXAMPLES_SINGLE) + make_kaguya_interop_example(sol2::sol2_single ".single") +endif() +if (SOL2_INTEROP_EXAMPLES_SINGLE_GENERATED) + make_kaguya_interop_example(sol2::sol2_single_generated ".single.generated") +endif() diff --git a/lib/sol2/examples/interop/kaguya/source/kaguya.cpp b/lib/sol2/examples/interop/kaguya/source/kaguya.cpp new file mode 100644 index 0000000..ce81ff8 --- /dev/null +++ b/lib/sol2/examples/interop/kaguya/source/kaguya.cpp @@ -0,0 +1,124 @@ +#include + +#define SOL_ALL_SAFETIES_ON 1 +#define SOL_ENABLE_INTEROP 1 // MUST be defined to use interop features +#include + +#include +#include + +// kaguya code lifted from README.md, +// written by satoren: +// https://github.com/satoren/kaguya +// Copyright satoren +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +struct ABC { + ABC() + : v_(0) { + } + ABC(int value) + : v_(value) { + } + int value() const { + return v_; + } + void setValue(int v) { + v_ = v; + } + void overload1() { + std::cout << "call overload1" << std::endl; + } + void overload2(int) { + std::cout << "call overload2" << std::endl; + } + +private: + int v_; +}; + +template +inline bool sol_lua_interop_check(sol::types, lua_State* L, int relindex, sol::type index_type, Handler&& handler, sol::stack::record& tracking) { + // just marking unused parameters for no compiler warnings + (void)index_type; + (void)handler; + // using 1 element + tracking.use(1); + int index = lua_absindex(L, relindex); + // use kaguya's own detail wrapper check to see if it's correct + bool is_correct_type = kaguya::detail::object_wrapper_type_check(L, index); + return is_correct_type; +} + +template +inline std::pair sol_lua_interop_get(sol::types, lua_State* L, int relindex, void* unadjusted_pointer, sol::stack::record& tracking) { + // you may not need to specialize this method every time: + // some libraries are compatible with sol2's layout + + // kaguya's storage of data is incompatible with sol's + // it stores the data directly in the pointer, not a pointer inside of the `void*` + // therefore, leave the raw userdata pointer as-is, + // if it's of the right type + int index = lua_absindex(L, relindex); + if (!kaguya::detail::object_wrapper_type_check(L, index)) { + return { false, nullptr }; + } + // using 1 element + tracking.use(1); + kaguya::ObjectWrapperBase* base = kaguya::object_wrapper(L, index); + return { true, static_cast(base->get()) }; +} + +void register_sol_stuff(lua_State* L) { + // grab raw state and put into state_view + // state_view is cheap to construct + sol::state_view lua(L); + // bind and set up your things: everything is entirely self-contained + lua["f"] = sol::overload( + [](ABC& from_kaguya) { + std::cout << "calling 1-argument version with kaguya-created ABC { " << from_kaguya.value() << " }" << std::endl; + c_assert(from_kaguya.value() == 24); + }, + [](ABC& from_kaguya, int second_arg) { + std::cout << "calling 2-argument version with kaguya-created ABC { " << from_kaguya.value() << " } and integer argument of " << second_arg << std::endl; + c_assert(from_kaguya.value() == 24); + c_assert(second_arg == 5); + }); +} + +void check_with_sol(lua_State* L) { + sol::state_view lua(L); + ABC& obj = lua["obj"]; + (void)obj; + c_assert(obj.value() == 24); +} + +int main(int, char* []) { + + std::cout << "=== interop example (kaguya) ===" << std::endl; + std::cout << "(code lifted from kaguya's README examples: https://github.com/satoren/kaguya)" << std::endl; + + kaguya::State state; + + state["ABC"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addFunction("get_value", &ABC::value) + .addFunction("set_value", &ABC::setValue) + .addOverloadedFunctions("overload", &ABC::overload1, &ABC::overload2) + .addStaticFunction("nonmemberfun", [](ABC* self, int) { return 1; })); + + + register_sol_stuff(state.state()); + + state.dostring(R"( +obj = ABC.new(24) +f(obj) -- call 1 argument version +f(obj, 5) -- call 2 argument version +)"); + + check_with_sol(state.state()); + + return 0; +} \ No newline at end of file diff --git a/lib/sol2/examples/interop/luwra/CMakeLists.txt b/lib/sol2/examples/interop/luwra/CMakeLists.txt new file mode 100644 index 0000000..2753812 --- /dev/null +++ b/lib/sol2/examples/interop/luwra/CMakeLists.txt @@ -0,0 +1,68 @@ +# # # # sol3 +# The MIT License (MIT) +# +# Copyright (c) 2013-2019 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. + +# # # sol3 interop Examples - luwra + +find_package(LuwraBuild) + +function (make_luwra_interop_example target_library example_suffix) + set(example_name luwra_interop_example) + set(example_name "${example_name}${example_suffix}") + + add_executable(${example_name} source/luwra.cpp) + target_link_libraries(${example_name} + PRIVATE ${LUA_LIBRARIES} ${LUWRA_LIBRARIES} + ${target_library} sol2::assert) + + if (MSVC) + target_compile_options(${example_name} + PRIVATE /std:c++latest /EHsc "$<$:/MDd>" + "$<$:/MD>" + "$<$:/MD>" + "$<$:/MD>") + target_compile_definitions(${example_name} + PRIVATE /W1 UNICODE _UNICODE + _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE) + else() + target_compile_options(${example_name} + PRIVATE -std=c++1z -w + -Wno-unknown-warning -Wno-unknown-warning-option) + endif() + + if (CMAKE_DL_LIBS) + target_link_libraries(${example_name} PRIVATE ${CMAKE_DL_LIBS}) + endif() + + if (SOL2_TESTS_INTEROP_EXAMPLES) + add_test(NAME ${example_name} COMMAND ${example_name}) + endif() +endfunction() + +if (SOL2_INTEROP_EXAMPLES) + make_luwra_interop_example(sol2::sol2 "") +endif() +if (SOL2_INTEROP_EXAMPLES_SINGLE) + make_luwra_interop_example(sol2::sol2_single ".single") +endif() +if (SOL2_INTEROP_EXAMPLES_SINGLE_GENERATED) + make_luwra_interop_example(sol2::sol2_single_generated ".single.generated") +endif() \ No newline at end of file diff --git a/lib/sol2/examples/interop/luwra/source/luwra.cpp b/lib/sol2/examples/interop/luwra/source/luwra.cpp new file mode 100644 index 0000000..2a12f6c --- /dev/null +++ b/lib/sol2/examples/interop/luwra/source/luwra.cpp @@ -0,0 +1,110 @@ +#define SOL_ALL_SAFETIES_ON 1 +#define SOL_ENABLE_INTEROP 1 // MUST be defined to use interop features +#include + +#include + +#include +#include + +// luwra, +// another C++ wrapper library: +// https://github.com/vapourismo/luwra + +struct ABC { + ABC() + : v_(0) { + } + ABC(int value) + : v_(value) { + } + int value() const { + return v_; + } + void setValue(int v) { + v_ = v; + } + void overload1() { + std::cout << "call overload1" << std::endl; + } + void overload2(int) { + std::cout << "call overload2" << std::endl; + } + +private: + int v_; +}; + +template +inline bool sol_lua_interop_check(sol::types, lua_State* L, int relindex, sol::type index_type, Handler&& handler, sol::stack::record& tracking) { + // just marking unused parameters for no compiler warnings + (void)index_type; + (void)handler; + // using 1 element + tracking.use(1); + int index = lua_absindex(L, relindex); + if (lua_getmetatable(L, index) == 1) { + luaL_getmetatable(L, luwra::internal::UserTypeReg::name.c_str()); + bool is_correct_type = lua_rawequal(L, -2, -1) == 1; + lua_pop(L, 2); + return is_correct_type; + } + return false; +} + +template +inline std::pair sol_lua_interop_get(sol::types t, lua_State* L, int relindex, void* unadjusted_pointer, sol::stack::record& tracking) { + // you may not need to specialize this method every time: + // some libraries are compatible with sol3's layout + int index = lua_absindex(L, relindex); + if (!sol_lua_interop_check(t, L, index, sol::type::userdata, sol::no_panic, tracking)) { + return { false, nullptr }; + } + return { true, static_cast(unadjusted_pointer) }; +} + +void register_sol_stuff(lua_State* L) { + // grab raw state and put into state_view + // state_view is cheap to construct + sol::state_view lua(L); + // bind and set up your things: everything is entirely self-contained + lua["f"] = sol::overload( + [](ABC& from_luwra) { + std::cout << "calling 1-argument version with luwra-created ABC { " << from_luwra.value() << " }" << std::endl; + c_assert(from_luwra.value() == 24); + }, + [](ABC& from_luwra, int second_arg) { + std::cout << "calling 2-argument version with luwra-created ABC { " << from_luwra.value() << " } and integer argument of " << second_arg << std::endl; + c_assert(from_luwra.value() == 24); + c_assert(second_arg == 5); + }); +} + +void check_with_sol(lua_State* L) { + sol::state_view lua(L); + ABC& obj = lua["obj"]; + (void)obj; + c_assert(obj.value() == 24); +} + +int main(int, char* []) { + + std::cout << "=== interop example (luwra) ===" << std::endl; + std::cout << "code modified from luwra's documentation examples: https://github.com/vapourismo/luwra" << std::endl; + + luwra::StateWrapper state; + + state.registerUserType("ABC", { LUWRA_MEMBER(ABC, value), LUWRA_MEMBER(ABC, setValue) }, {}); + + register_sol_stuff(state); + + state.runString(R"( +obj = ABC(24) +f(obj) -- call 1 argument version +f(obj, 5) -- call 2 argument version +)"); + + check_with_sol(state); + + return 0; +} \ No newline at end of file diff --git a/lib/sol2/examples/interop/tolua/CMakeLists.txt b/lib/sol2/examples/interop/tolua/CMakeLists.txt new file mode 100644 index 0000000..75f94cc --- /dev/null +++ b/lib/sol2/examples/interop/tolua/CMakeLists.txt @@ -0,0 +1,68 @@ +# # # # sol3 +# The MIT License (MIT) +# +# Copyright (c) 2013-2019 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. + +# # # sol3 interop Examples - tolua + +find_package(ToLuappBuild REQUIRED) + +function(make_tolua_interop_example target_library example_suffix) + set(example_name tolua_interop_example) + set(example_name "${example_name}${example_suffix}") + + add_executable(${example_name} source/tolua.cpp) + target_link_libraries(${example_name} + PRIVATE sol2::assert + ${LUA_LIBRARIES} ${TOLUAPP_LIBRARIES} ${target_library}) + + if (MSVC) + target_compile_options(${example_name} + PRIVATE /std:c++latest /EHsc "$<$:/MDd>" + "$<$:/MD>" + "$<$:/MD>" + "$<$:/MD>") + target_compile_definitions(${example_name} + PRIVATE /W1 UNICODE _UNICODE + _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE) + else() + target_compile_options(${example_name} + PRIVATE -std=c++1z -w + -Wno-unknown-warning -Wno-unknown-warning-option) + endif() + + if (CMAKE_DL_LIBS) + target_link_libraries(${example_name} PRIVATE ${CMAKE_DL_LIBS}) + endif() + + if (SOL2_TESTS_INTEROP_EXAMPLES) + add_test(NAME ${example_name} COMMAND ${example_name}) + endif() +endfunction() + +if (SOL2_INTEROP_EXAMPLES) + make_tolua_interop_example(sol2::sol2 "") +endif() +if (SOL2_INTEROP_EXAMPLES_SINGLE) + make_tolua_interop_example(sol2::sol2_single ".single") +endif() +if (SOL2_INTEROP_EXAMPLES_SINGLE_GENERATED) + make_tolua_interop_example(sol2::sol2_single_generated ".single.generated") +endif() diff --git a/lib/sol2/examples/interop/tolua/source/Player.h b/lib/sol2/examples/interop/tolua/source/Player.h new file mode 100644 index 0000000..7d8148c --- /dev/null +++ b/lib/sol2/examples/interop/tolua/source/Player.h @@ -0,0 +1,20 @@ +#ifndef PLAYER_H +#define PLAYER_H + +class Player { +private: + int m_health; + +public: + Player() + : m_health(0) { + } + void setHealth(int health) { + m_health = health; + } + int getHealth() const { + return m_health; + } +}; + +#endif // PLAYER_H diff --git a/lib/sol2/examples/interop/tolua/source/Player.pkg b/lib/sol2/examples/interop/tolua/source/Player.pkg new file mode 100644 index 0000000..e6c3fab --- /dev/null +++ b/lib/sol2/examples/interop/tolua/source/Player.pkg @@ -0,0 +1,8 @@ +$#include "Player.h" + +class Player { + Player(); + ~Player(); + void setHealth(int _health); + int getHealth(); +}; diff --git a/lib/sol2/examples/interop/tolua/source/tolua.cpp b/lib/sol2/examples/interop/tolua/source/tolua.cpp new file mode 100644 index 0000000..d413e27 --- /dev/null +++ b/lib/sol2/examples/interop/tolua/source/tolua.cpp @@ -0,0 +1,97 @@ +#define SOL_ALL_SAFETIES_ON 1 +#define SOL_ENABLE_INTEROP 1 // MUST be defined to use interop features +#include + +#include "Player.h" +#include +// pick or replace the include +// with whatever generated file you've created +#include "tolua_Player.h" + +#include +#include + +// tolua code lifted from some blog, if the link dies +// I don't know where else you're gonna find the reference, +// http://usefulgamedev.weebly.com/tolua-example.html + + +/* NOTE: there is no sol_lua_interop_get here, + because tolua types are -- thankfully -- memory-compatible + in most cases with sol. + Please check other examples like kaguya or LuaBribe for an example + of how to also write the getter for your type*/ +template +inline bool sol_lua_interop_check(sol::types, lua_State* L, int relindex, sol::type index_type, Handler&& handler, sol::stack::record& tracking) { + tracking.use(1); + // just marking unused parameters for no compiler warnings + (void)index_type; + (void)handler; + int index = lua_absindex(L, relindex); + std::string name = sol::detail::short_demangle(); + tolua_Error tolua_err{}; + int r = tolua_isusertype(L, index, name.c_str(), 0, &tolua_err); + if (r == 0) { + // tolua seems to leave garbage on the stack + // when the check fails + // thanks, tolua + lua_pop(L, 2); + return false; + } + return true; +} + +void register_sol_stuff(lua_State* L) { + // grab raw state and put into state_view + // state_view is cheap to construct + sol::state_view lua(L); + // bind and set up your things: everything is entirely self-contained + lua["f"] = sol::overload( + [](Player& from_tolua) { + std::cout << "calling 1-argument version with tolua-created Player { health:" << from_tolua.getHealth() << " }" << std::endl; + c_assert(from_tolua.getHealth() == 4); + }, + [](Player& from_tolua, int second_arg) { + std::cout << "calling 2-argument version with tolua-created Player { health: " << from_tolua.getHealth() << " } and integer argument of " << second_arg << std::endl; + c_assert(from_tolua.getHealth() == 4); + c_assert(second_arg == 5); + }); +} + +void check_with_sol(lua_State* L) { + sol::state_view lua(L); + Player& obj = lua["obj"]; + (void)obj; + c_assert(obj.getHealth() == 4); +} + +int main(int, char* []) { + + std::cout << "=== interop example (tolua) ===" << std::endl; + std::cout << "(code lifted from a sol2 user's use case: https://github.com/ThePhD/sol2/issues/511#issuecomment-331729884)" << std::endl; + + lua_State* L = luaL_newstate(); + + luaL_openlibs(L); // initalize all lua standard library functions + tolua_open(L); // initalize tolua + tolua_Player_open(L); // make Player class accessible from LUA + + + register_sol_stuff(L); + + const auto code = R"( +obj = Player:new() +obj:setHealth(4) + +f(obj) -- call 1 argument version +f(obj, 5) -- call 2 argument version +)"; + + if (luaL_dostring(L, code)) { + lua_error(L); // crash on error + } + + check_with_sol(L); + + return 0; +} \ No newline at end of file diff --git a/lib/sol2/examples/interop/tolua/source/tolua_Player.h b/lib/sol2/examples/interop/tolua/source/tolua_Player.h new file mode 100644 index 0000000..8a4fa14 --- /dev/null +++ b/lib/sol2/examples/interop/tolua/source/tolua_Player.h @@ -0,0 +1,217 @@ +/* +** Lua binding: Player +** Generated automatically by tolua++-1.0.93-lua53 on Sat Feb 10 08:48:53 2018. +*/ + +#ifndef __cplusplus +#include "stdlib.h" +#endif +#include "string.h" + +#include "tolua++.h" + +/* Exported function */ +TOLUA_API int tolua_Player_open (lua_State* tolua_S); + +#include "Player.h" + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Player (lua_State* tolua_S) +{ + Player* self = (Player*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} +#endif + + +/* function to register type */ +static void tolua_reg_types (lua_State* tolua_S) +{ + tolua_usertype(tolua_S,"Player"); +} + +/* method: new of class Player */ +#ifndef TOLUA_DISABLE_tolua_Player_Player_new00 +static int tolua_Player_Player_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Player",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Player* tolua_ret = (Player*) Mtolua_new((Player)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Player"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Player */ +#ifndef TOLUA_DISABLE_tolua_Player_Player_new00_local +static int tolua_Player_Player_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Player",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Player* tolua_ret = (Player*) Mtolua_new((Player)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Player"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class Player */ +#ifndef TOLUA_DISABLE_tolua_Player_Player_delete00 +static int tolua_Player_Player_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Player",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Player* self = (Player*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: setHealth of class Player */ +#ifndef TOLUA_DISABLE_tolua_Player_Player_setHealth00 +static int tolua_Player_Player_setHealth00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Player",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Player* self = (Player*) tolua_tousertype(tolua_S,1,0); + int _health = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'setHealth'", NULL); +#endif + { + self->setHealth(_health); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'setHealth'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: getHealth of class Player */ +#ifndef TOLUA_DISABLE_tolua_Player_Player_getHealth00 +static int tolua_Player_Player_getHealth00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Player",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Player* self = (Player*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'getHealth'", NULL); +#endif + { + int tolua_ret = (int) self->getHealth(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'getHealth'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* Open function */ +TOLUA_API int tolua_Player_open (lua_State* tolua_S) +{ + tolua_open(tolua_S); + tolua_reg_types(tolua_S); + tolua_module(tolua_S,NULL,0); + tolua_beginmodule(tolua_S,NULL); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Player","Player","",tolua_collect_Player); + #else + tolua_cclass(tolua_S,"Player","Player","",NULL); + #endif + tolua_beginmodule(tolua_S,"Player"); + tolua_function(tolua_S,"new",tolua_Player_Player_new00); + tolua_function(tolua_S,"new_local",tolua_Player_Player_new00_local); + tolua_function(tolua_S,".call",tolua_Player_Player_new00_local); + tolua_function(tolua_S,"delete",tolua_Player_Player_delete00); + tolua_function(tolua_S,"setHealth",tolua_Player_Player_setHealth00); + tolua_function(tolua_S,"getHealth",tolua_Player_Player_getHealth00); + tolua_endmodule(tolua_S); + tolua_endmodule(tolua_S); + return 1; +} + + +#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501 + TOLUA_API int luaopen_Player (lua_State* tolua_S) { + return tolua_Player_open(tolua_S); +}; +#endif + -- cgit v1.2.3