From b9f57f1f283fd76c8f3c48abbb3a6e0d91c737a1 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 12 Oct 2019 21:07:06 -0700 Subject: [PATCH] Revert "Build System Updated" --- .gitignore | 1 - BUILD.md | 64 - CMakeLists.txt | 500 ++--- client_files/CMakeLists.txt | 2 +- client_files/export/CMakeLists.txt | 2 +- client_files/import/CMakeLists.txt | 2 +- cmake/DependencyHelperMSVC.cmake | 94 - cmake/FindEQLua51.cmake | 124 ++ cmake/FindLua51.cmake | 91 - cmake/FindMariaDB.cmake | 87 - cmake/FindmbedTLS.cmake | 93 - common/CMakeLists.txt | 2 +- common/useperl.h | 4 - eqlaunch/CMakeLists.txt | 2 +- hc/CMakeLists.txt | 8 +- libs/luabind/CMakeLists.txt | 87 +- libs/luabind/CMakeSettings.json | 54 - libs/luabind/luabind/adopt_policy.hpp | 175 +- libs/luabind/luabind/back_reference.hpp | 132 +- libs/luabind/luabind/back_reference_fwd.hpp | 10 +- libs/luabind/luabind/class.hpp | 907 +++++--- libs/luabind/luabind/class_info.hpp | 9 +- libs/luabind/luabind/config.hpp | 63 +- libs/luabind/luabind/container_policy.hpp | 175 +- libs/luabind/luabind/copy_policy.hpp | 71 +- libs/luabind/luabind/dependency_policy.hpp | 134 +- .../{call_shared.hpp => calc_arity.hpp} | 70 +- libs/luabind/luabind/detail/call.hpp | 858 +++----- libs/luabind/luabind/detail/call_function.hpp | 498 +++-- libs/luabind/luabind/detail/call_member.hpp | 360 +++- .../luabind/detail/call_operator_iterate.hpp | 66 + libs/luabind/luabind/detail/call_traits.hpp | 113 - libs/luabind/luabind/detail/class_cache.hpp | 89 + .../luabind/luabind/detail/class_registry.hpp | 72 +- libs/luabind/luabind/detail/class_rep.hpp | 319 +-- libs/luabind/luabind/detail/compute_score.hpp | 73 + libs/luabind/luabind/detail/constructor.hpp | 132 +- .../conversion_policies/conversion_base.hpp | 81 - .../conversion_policies.hpp | 89 - .../conversion_policies/enum_converter.hpp | 82 - .../function_converter.hpp | 93 - .../lua_proxy_converter.hpp | 73 - .../conversion_policies/native_converter.hpp | 302 --- .../conversion_policies/pointer_converter.hpp | 143 -- .../reference_converter.hpp | 124 -- .../conversion_policies/value_converter.hpp | 79 - .../luabind/detail/conversion_storage.hpp | 48 +- .../luabind/luabind/detail/convert_to_lua.hpp | 92 + libs/luabind/luabind/detail/crtp_iterator.hpp | 58 - libs/luabind/luabind/detail/debug.hpp | 34 +- libs/luabind/luabind/detail/decorate_type.hpp | 230 +- .../luabind/detail/deduce_signature.hpp | 112 +- libs/luabind/luabind/detail/enum_maker.hpp | 20 +- .../luabind/detail/format_signature.hpp | 205 +- .../luabind/detail/garbage_collector.hpp | 37 +- .../luabind/detail/has_get_pointer.hpp | 107 + libs/luabind/luabind/detail/inheritance.hpp | 245 ++- .../luabind/detail/instance_holder.hpp | 228 +- .../luabind/detail/is_indirect_const.hpp | 70 + .../luabind/detail/link_compatibility.hpp | 42 +- libs/luabind/luabind/detail/make_instance.hpp | 208 +- libs/luabind/luabind/detail/meta.hpp | 581 ------ .../most_derived.hpp} | 42 +- libs/luabind/luabind/detail/object.hpp | 386 ---- libs/luabind/luabind/detail/object_call.hpp | 52 + libs/luabind/luabind/detail/object_funs.hpp | 224 ++ libs/luabind/luabind/detail/object_rep.hpp | 180 +- libs/luabind/luabind/detail/operator_id.hpp | 88 +- libs/luabind/luabind/detail/other.hpp | 95 +- libs/luabind/luabind/detail/pcall.hpp | 14 +- .../luabind/luabind/detail/pointee_sizeof.hpp | 54 + .../pointee_typeid.hpp} | 30 +- libs/luabind/luabind/detail/policy.hpp | 1071 +++++++++- libs/luabind/luabind/detail/primitives.hpp | 74 +- libs/luabind/luabind/detail/property.hpp | 38 +- libs/luabind/luabind/detail/push_to_lua.hpp | 74 - libs/luabind/luabind/detail/ref.hpp | 127 +- .../luabind/detail/signature_match.hpp | 32 + libs/luabind/luabind/detail/stack_utils.hpp | 42 +- libs/luabind/luabind/detail/type_traits.hpp | 189 -- libs/luabind/luabind/detail/typetraits.hpp | 190 ++ .../detail/yes_no.hpp} | 18 +- .../luabind/luabind/discard_result_policy.hpp | 57 +- libs/luabind/luabind/error.hpp | 29 +- libs/luabind/luabind/exception_handler.hpp | 125 +- libs/luabind/luabind/from_stack.hpp | 20 +- libs/luabind/luabind/function.hpp | 67 +- .../luabind/function_introspection.hpp | 56 - libs/luabind/luabind/get_main_thread.hpp | 4 +- .../{lua_state_fwd.hpp => get_pointer.hpp} | 25 +- libs/luabind/luabind/handle.hpp | 180 +- libs/luabind/luabind/iterator_policy.hpp | 165 +- libs/luabind/luabind/lua502.hpp | 56 + libs/luabind/luabind/lua_argument_proxy.hpp | 71 - libs/luabind/luabind/lua_include.hpp | 4 +- libs/luabind/luabind/lua_index_proxy.hpp | 137 -- libs/luabind/luabind/lua_iterator_proxy.hpp | 230 -- libs/luabind/luabind/lua_proxy_interface.hpp | 306 --- libs/luabind/luabind/luabind.hpp | 2 - libs/luabind/luabind/make_function.hpp | 172 +- libs/luabind/luabind/nil.hpp | 11 +- libs/luabind/luabind/no_dependency.hpp | 28 - libs/luabind/luabind/object.hpp | 1392 ++++++++++++- libs/luabind/luabind/open.hpp | 2 - libs/luabind/luabind/operator.hpp | 315 +-- libs/luabind/luabind/out_value_policy.hpp | 450 ++-- libs/luabind/luabind/pointer_traits.hpp | 148 -- libs/luabind/luabind/raw_policy.hpp | 78 +- .../luabind/return_reference_to_policy.hpp | 69 +- libs/luabind/luabind/scope.hpp | 102 +- libs/luabind/luabind/set_package_preload.hpp | 54 - libs/luabind/luabind/shared_ptr_converter.hpp | 118 +- libs/luabind/luabind/tag_function.hpp | 111 +- libs/luabind/luabind/typeid.hpp | 75 +- libs/luabind/luabind/value_wrapper.hpp | 168 ++ libs/luabind/luabind/version.hpp | 1 - libs/luabind/luabind/weak_ref.hpp | 32 +- libs/luabind/luabind/wrapper_base.hpp | 153 +- libs/luabind/luabind/yield_policy.hpp | 38 +- libs/luabind/src/CMakeLists.txt | 182 -- libs/luabind/src/class.cpp | 507 ++--- libs/luabind/src/class_info.cpp | 145 +- libs/luabind/src/class_registry.cpp | 190 +- libs/luabind/src/class_rep.cpp | 193 +- libs/luabind/src/create_class.cpp | 204 +- libs/luabind/src/error.cpp | 29 +- libs/luabind/src/exception_handler.cpp | 145 +- libs/luabind/src/function.cpp | 214 +- libs/luabind/src/function_introspection.cpp | 117 -- libs/luabind/src/headertest.cpp | 1 - libs/luabind/src/inheritance.cpp | 361 ++-- libs/luabind/src/link_compatibility.cpp | 15 +- libs/luabind/src/object_rep.cpp | 477 ++--- libs/luabind/src/open.cpp | 230 +- libs/luabind/src/pcall.cpp | 66 +- libs/luabind/src/scope.cpp | 330 +-- libs/luabind/src/set_package_preload.cpp | 60 - libs/luabind/src/stack_content_by_name.cpp | 21 +- libs/luabind/src/weak_ref.cpp | 217 +- libs/luabind/src/wrapper_base.cpp | 42 +- loginserver/CMakeLists.txt | 8 +- loginserver/encryption.cpp | 402 ++-- queryserv/CMakeLists.txt | 2 +- shared_memory/CMakeLists.txt | 2 +- tests/CMakeLists.txt | 2 +- tests/cppunit/CMakeLists.txt | 2 +- ucs/CMakeLists.txt | 2 +- wi/.gitignore | 47 + wi/BUILD.md | 17 + wi/core/jwt_auth.js | 27 + wi/generate_pw_hash.js | 4 + wi/http/common.js | 26 + wi/http/data/account.js | 16 + wi/http/data/endpoint.js | 20 + wi/http/data/index.js | 8 + wi/http/data/item.js | 16 + wi/http/data/sql.js | 319 +++ wi/http/eqw.js | 16 + wi/http/index.js | 9 + wi/http/token.js | 43 + wi/index.js | 56 + wi/key.pem | 27 + wi/network/servertalk_api.js | 148 ++ wi/network/servertalk_client.js | 299 +++ wi/package.json | 24 + wi/settings.json | 21 + wi/test.js | 11 + wi/ws/eqw.js | 18 + wi/ws/index.js | 7 + wi/ws/wi_common.js | 27 + wi/ws/ws_interface.js | 118 ++ world/CMakeLists.txt | 7 +- zone/CMakeLists.txt | 13 +- zone/attack.cpp | 1 + zone/client.cpp | 7 +- zone/embperl.h | 4 - zone/embxs.h | 4 - zone/entity.cpp | 45 +- zone/entity.h | 7 - zone/lua_entity_list.cpp | 14 +- zone/lua_hate_list.cpp | 2 +- zone/lua_mob.cpp | 6 +- zone/lua_mob.h | 2 +- zone/lua_mod.cpp | 4 - zone/lua_parser.cpp | 4 +- zone/lua_stat_bonuses.cpp | 6 +- zone/{main.cpp => net.cpp} | 84 +- zone/net.h | 48 + zone/oldcode.cpp | 1851 +++++++++++++++++ zone/oldcode.h | 22 + zone/queryserv.cpp | 1 + zone/worldserver.cpp | 2 + zone/zone.cpp | 10 +- 193 files changed, 14124 insertions(+), 10507 deletions(-) delete mode 100644 BUILD.md delete mode 100644 cmake/DependencyHelperMSVC.cmake create mode 100644 cmake/FindEQLua51.cmake delete mode 100644 cmake/FindLua51.cmake delete mode 100644 cmake/FindMariaDB.cmake delete mode 100644 cmake/FindmbedTLS.cmake delete mode 100644 libs/luabind/CMakeSettings.json rename libs/luabind/luabind/detail/{call_shared.hpp => calc_arity.hpp} (53%) create mode 100644 libs/luabind/luabind/detail/call_operator_iterate.hpp delete mode 100644 libs/luabind/luabind/detail/call_traits.hpp create mode 100644 libs/luabind/luabind/detail/class_cache.hpp create mode 100644 libs/luabind/luabind/detail/compute_score.hpp delete mode 100644 libs/luabind/luabind/detail/conversion_policies/conversion_base.hpp delete mode 100644 libs/luabind/luabind/detail/conversion_policies/conversion_policies.hpp delete mode 100644 libs/luabind/luabind/detail/conversion_policies/enum_converter.hpp delete mode 100644 libs/luabind/luabind/detail/conversion_policies/function_converter.hpp delete mode 100644 libs/luabind/luabind/detail/conversion_policies/lua_proxy_converter.hpp delete mode 100644 libs/luabind/luabind/detail/conversion_policies/native_converter.hpp delete mode 100644 libs/luabind/luabind/detail/conversion_policies/pointer_converter.hpp delete mode 100644 libs/luabind/luabind/detail/conversion_policies/reference_converter.hpp delete mode 100644 libs/luabind/luabind/detail/conversion_policies/value_converter.hpp create mode 100644 libs/luabind/luabind/detail/convert_to_lua.hpp delete mode 100644 libs/luabind/luabind/detail/crtp_iterator.hpp create mode 100644 libs/luabind/luabind/detail/has_get_pointer.hpp create mode 100644 libs/luabind/luabind/detail/is_indirect_const.hpp delete mode 100644 libs/luabind/luabind/detail/meta.hpp rename libs/luabind/luabind/{lua_proxy.hpp => detail/most_derived.hpp} (64%) delete mode 100644 libs/luabind/luabind/detail/object.hpp create mode 100644 libs/luabind/luabind/detail/object_call.hpp create mode 100644 libs/luabind/luabind/detail/object_funs.hpp create mode 100644 libs/luabind/luabind/detail/pointee_sizeof.hpp rename libs/luabind/luabind/{error_callback_fun.hpp => detail/pointee_typeid.hpp} (63%) delete mode 100644 libs/luabind/luabind/detail/push_to_lua.hpp delete mode 100644 libs/luabind/luabind/detail/type_traits.hpp create mode 100644 libs/luabind/luabind/detail/typetraits.hpp rename libs/luabind/{src/operator.cpp => luabind/detail/yes_no.hpp} (81%) delete mode 100644 libs/luabind/luabind/function_introspection.hpp rename libs/luabind/luabind/{lua_state_fwd.hpp => get_pointer.hpp} (77%) create mode 100644 libs/luabind/luabind/lua502.hpp delete mode 100644 libs/luabind/luabind/lua_argument_proxy.hpp delete mode 100644 libs/luabind/luabind/lua_index_proxy.hpp delete mode 100644 libs/luabind/luabind/lua_iterator_proxy.hpp delete mode 100644 libs/luabind/luabind/lua_proxy_interface.hpp delete mode 100644 libs/luabind/luabind/no_dependency.hpp delete mode 100644 libs/luabind/luabind/pointer_traits.hpp delete mode 100644 libs/luabind/luabind/set_package_preload.hpp create mode 100644 libs/luabind/luabind/value_wrapper.hpp delete mode 100644 libs/luabind/src/CMakeLists.txt delete mode 100644 libs/luabind/src/function_introspection.cpp delete mode 100644 libs/luabind/src/headertest.cpp delete mode 100644 libs/luabind/src/set_package_preload.cpp create mode 100644 wi/.gitignore create mode 100644 wi/BUILD.md create mode 100644 wi/core/jwt_auth.js create mode 100644 wi/generate_pw_hash.js create mode 100644 wi/http/common.js create mode 100644 wi/http/data/account.js create mode 100644 wi/http/data/endpoint.js create mode 100644 wi/http/data/index.js create mode 100644 wi/http/data/item.js create mode 100644 wi/http/data/sql.js create mode 100644 wi/http/eqw.js create mode 100644 wi/http/index.js create mode 100644 wi/http/token.js create mode 100644 wi/index.js create mode 100644 wi/key.pem create mode 100644 wi/network/servertalk_api.js create mode 100644 wi/network/servertalk_client.js create mode 100644 wi/package.json create mode 100644 wi/settings.json create mode 100644 wi/test.js create mode 100644 wi/ws/eqw.js create mode 100644 wi/ws/index.js create mode 100644 wi/ws/wi_common.js create mode 100644 wi/ws/ws_interface.js rename zone/{main.cpp => net.cpp} (92%) create mode 100644 zone/net.h create mode 100644 zone/oldcode.cpp create mode 100644 zone/oldcode.h diff --git a/.gitignore b/.gitignore index daba92762..a21ef251d 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,6 @@ install_manifest.txt log/ logs/ vcpkg/ -perl/ .idea/* *cbp diff --git a/BUILD.md b/BUILD.md deleted file mode 100644 index 1cc3cd99b..000000000 --- a/BUILD.md +++ /dev/null @@ -1,64 +0,0 @@ -# Guide To Building From Source Without Installer - -This guide is far from exhaustive, you should expect to have some experience with building C++ code before considering compiling the code from scratch. You should instead consider using the installer scripts if you don't want to hack on the code directly. - -### CMake - -EQEmu uses CMake as the build system on all platforms. You will need CMake 3.2 or higher to build from source. - -### Dependencies - -The following libraries are required to build from source: -- [boost](https://www.boost.org/ "boost") -- [zlib](https://www.zlib.net/ "zlib") (If not included the source will build [zlib-ng](https://github.com/zlib-ng/zlib-ng "zlib-ng") instead) -- [libmysql](https://dev.mysql.com/downloads/connector/c/ "libmysql") or [libmariadb](https://github.com/MariaDB/mariadb-connector-c "libmariadb") - -The following libraries are not strictly required but in many cased recommended. -- [OpenSSL](https://www.openssl.org/ "OpenSSL") or [mbedTLS](https://tls.mbed.org/ "mbedTLS") (Required for the loginserver and headless client) -- [libsodium](https://github.com/jedisct1/libsodium "libsodium") (Required for strong password hashing on the loginserver) -- [Lua 5.1](https://www.lua.org/ "Lua 5.1") or [LuaJit](http://luajit.org/ "LuaJit") (Required for Lua Quest Scripting) -- [Perl](https://www.perl.org/ "Perl") (Required for Perl Quest Scripting) - -##### Windows -For windows it is suggested you make use of [vcpkg](https://github.com/microsoft/vcpkg "vcpkg") if you wish to build your own dependencies. - -If you wish to use Perl then you should use whichever version of Perl you have installed on the target system. - -You can also download a vcpkg export from our releases section for Visual Studio [x86](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip "x86") or [x64](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip "x64") that includes a toolchain file you can pass to CMake. - -##### Linux -For Linux you simply can install the dependencies from your package manager, below is an example of doing it on Ubuntu using apt-get. - - sudo apt-get install libmysqlclient-dev libperl-dev libboost-dev liblua5.1-0-dev zlib1g-dev uuid-dev libssl-dev - -### Running CMake - -##### Windows -The following is a modified command our automated build server uses to run CMake via the release vcpkg export and its toolchain file. - -Assuming it is starting in c:/projects/eqemu and the x64 dependencies were extracted to c:/projects/eqemu/vcpkg. - - mkdir build - cd build - cmake -G "Visual Studio 15 2017 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON -DEQEMU_ENABLE_BOTS=ON -DCMAKE_TOOLCHAIN_FILE="c:/projects/eqemu/vcpkg/vcpkg-export-20180828-145455/scripts/buildsystems/vcpkg.cmake" .. - -##### Linux -Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator. - - mkdir build - cd build - cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON .. - -### Building - -##### Windows -Inside the build directory a file EQEmu.sln should be produced by a successful run of the CMake command. You can either open this with Visual Studio or build it directly with MSBuild via the command line. - - msbuild EQEmu.sln /p:Configuration=Release - -##### Linux -From the build directory you can simply call make to build. - -For example. - - make -j4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a9e0e241..dedce5c3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,28 +1,120 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) - -SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH}) +#EQEmu CMake +#Variables used: +#EQEMU_DISABLE_CRT_SECURE_WARNINGS +#EQEMU_FAST_FLOATINGPOINT +#EQEMU_ENABLE_CRASH_LOGGING +#EQEMU_DISABLE_SAFESEH +#EQEMU_BUILD_MSVC_MP +#EQEMU_DEBUG_LEVEL +#EQEMU_LOG_LEVEL_DEBUG +#EQEMU_ENABLE_BOTS +#EQEMU_COMMANDS_LOGGING +#EQEMU_BUILD_SERVER +#EQEMU_BUILD_LOGIN +#EQEMU_BUILD_TESTS +#EQEMU_BUILD_PERL +#EQEMU_BUILD_LUA +#EQEMU_SANITIZE_LUA_LIBS +#EQEMU_BUILD_CLIENT_FILES +#EQEMU_USE_MAP_MMFS +#EQEMU_MAP_DIR +#EQEMU_ARCH +#EQEMU_ARCH_ALT +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) IF(POLICY CMP0074) - CMAKE_POLICY(SET CMP0074 NEW) + cmake_policy(SET CMP0074 NEW) ENDIF() +#FindMySQL is located here so lets make it so CMake can find it +SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH}) + +#Our project name is EQEmu PROJECT(EQEmu) +#Default build type is set to RelWithDebInfo for generators that honor that like makefiles IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE) ENDIF(NOT CMAKE_BUILD_TYPE) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) -SET(CMAKE_CXX_EXTENSIONS OFF) +SET(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/dependencies" "${CMAKE_PREFIX_PATH}") + +#Add our various windows definitions +IF(MSVC OR MINGW) + ADD_DEFINITIONS(-D_WINDOWS) + IF(CMAKE_CL_64) + ADD_DEFINITIONS(-DWIN64) + ELSE(CMAKE_CL_64) + ADD_DEFINITIONS(-DWIN32) + ENDIF(CMAKE_CL_64) +ENDIF(MSVC OR MINGW) IF(MSVC) - ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) - ADD_DEFINITIONS(-DNOMINMAX) - ADD_DEFINITIONS(-DCRASH_LOGGING) + IF(CMAKE_CL_64) + SET(EQEMU_ARCH "x64") + SET(EQEMU_ARCH_ALT "x64") + ELSE(CMAKE_CL_64) + SET(EQEMU_ARCH "x86") + SET(EQEMU_ARCH_ALT "Win32") + ENDIF(CMAKE_CL_64) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_${EQEMU_ARCH}") + + IF(VCPKG_TOOLCHAIN) + IF(NOT MSVC_VERSION GREATER 1800) + SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include") + ENDIF() + ELSE(VCPKG_TOOLCHAIN) + SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_${EQEMU_ARCH}") + SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_${EQEMU_ARCH}") + SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_${EQEMU_ARCH}") + + SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include") + ENDIF(VCPKG_TOOLCHAIN) + + IF(SODIUM_INCLUDE_HINTS) + IF(MSVC_VERSION GREATER 1800) + SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/${EQEMU_ARCH_ALT}/Release/v140/dynamic") + ELSEIF(MSVC_VERSION EQUAL 1800) + SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/${EQEMU_ARCH_ALT}/Release/v120/dynamic") + ELSE() + SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/${EQEMU_ARCH_ALT}/Release/v110/dynamic") + ENDIF() + ENDIF(SODIUM_INCLUDE_HINTS) + + #disable CRT warnings on windows cause they're annoying as shit and we use C functions everywhere + OPTION(EQEMU_DISABLE_CRT_SECURE_WARNINGS "Disable Secure CRT Warnings" ON) + IF(EQEMU_DISABLE_CRT_SECURE_WARNINGS) + ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) + ENDIF(EQEMU_DISABLE_CRT_SECURE_WARNINGS) + + #fast FP if you'd like it + OPTION(EQEMU_FAST_FLOATINGPOINT "Use MSVC /fp:fast option" ON) + IF(EQEMU_FAST_FLOATINGPOINT) + ADD_DEFINITIONS(/fp:fast) + ENDIF(EQEMU_FAST_FLOATINGPOINT) + + #crash logging currently only works on windows x86/x64 + OPTION(EQEMU_ENABLE_CRASH_LOGGING "Enable crash logging" ON) + IF(EQEMU_ENABLE_CRASH_LOGGING) + ADD_DEFINITIONS(-DCRASH_LOGGING) + ENDIF(EQEMU_ENABLE_CRASH_LOGGING) + + OPTION(EQEMU_BUILD_MSVC_MP "Enable build with multiple processes." ON) + IF(EQEMU_BUILD_MSVC_MP) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + ENDIF(EQEMU_BUILD_MSVC_MP) + + #We want to compile /MT not /MD so we change that + FOREACH(flag_var CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO) + IF(${flag_var} MATCHES "/MD") + STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + ENDIF(${flag_var} MATCHES "/MD") + ENDFOREACH(flag_var) + + ADD_DEFINITIONS(-DNOMINMAX) ELSE(MSVC) + #Normally set by perl but we don't use the perl flags anymore so we set it. ADD_DEFINITIONS(-DHAS_UNION_SEMUN) ENDIF(MSVC) @@ -39,277 +131,128 @@ IF(UNIX) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin") ENDIF(UNIX) -ADD_DEFINITIONS(-DGLM_FORCE_RADIANS) -ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT) -ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL) +#debug level, 5 is default. Most people wont ever change this but it's there if you want to +SET(EQEMU_DEBUG_LEVEL 5 CACHE STRING "EQEmu debug level: + 0 - Quiet mode Errors to file Status and Normal ignored + 1 - Status and Normal to console, Errors to logfile + 2 - Status, Normal, and Error to console and logfile + 3 - Light debug release errors and status + 4 - Moderate debug release errors and status + 5 - Maximum debug release errors and status + 10 - More errors than you ever wanted to see" +) -#MSVC can fetch dependencies automatically. -IF(MSVC) - INCLUDE("${CMAKE_SOURCE_DIR}/cmake/DependencyHelperMSVC.cmake") -ENDIF() +SET(EQEMU_LOG_LEVEL_DEBUG 3 CACHE STRING "EQEmu logging level for [Debug]: + 0 - Disabled + 1 - Ouput to File Enabled + 2 - Output to stdout Enabled + 3 - Output to File and stdout Enabled + 8 - Output to stderr Enabled + 9 - Output to File and stderr Enabled + 11 - Output to File, stdout and stderr Enabled" +) -#Find everything we need -FIND_PACKAGE(MySQL) -FIND_PACKAGE(MariaDB) -FIND_PACKAGE(ZLIB) -FIND_PACKAGE(OpenSSL) -FIND_PACKAGE(Lua51) -FIND_PACKAGE(PerlLibs) -FIND_PACKAGE(Sodium) -FIND_PACKAGE(mbedTLS) +OPTION(EQEMU_LSPX "" OFF) +MARK_AS_ADVANCED(EQEMU_LSPX) -MESSAGE(STATUS "**************************************************") -MESSAGE(STATUS "* Library Detection *") -MESSAGE(STATUS "**************************************************") +MARK_AS_ADVANCED(EQEMU_LOG_LEVEL_DEBUG) -IF(MYSQL_FOUND) - MESSAGE(STATUS "* MySQL: FOUND *") -ELSE() - MESSAGE(STATUS "* MySQL: MISSING *") -ENDIF() - -IF(MARIADB_FOUND) - MESSAGE(STATUS "* MariaDB: FOUND *") -ELSE() - MESSAGE(STATUS "* MariaDB: MISSING *") -ENDIF() - -IF(ZLIB_FOUND) - MESSAGE(STATUS "* ZLIB: FOUND *") -ELSE() - MESSAGE(STATUS "* ZLIB: MISSING *") -ENDIF() - -IF(Lua51_FOUND) - MESSAGE(STATUS "* Lua: FOUND *") -ELSE() - MESSAGE(STATUS "* Lua: MISSING *") -ENDIF() - -IF(PerlLibs_FOUND) - MESSAGE(STATUS "* Perl: FOUND *") -ELSE() - MESSAGE(STATUS "* Perl: MISSING *") -ENDIF() - -IF(SODIUM_FOUND) - MESSAGE(STATUS "* libsodium: FOUND *") -ELSE() - MESSAGE(STATUS "* libsodium: MISSING *") -ENDIF() - -IF(OpenSSL_FOUND) - MESSAGE(STATUS "* OpenSSL: FOUND *") -ELSE() - MESSAGE(STATUS "* OpenSSL: MISSING *") -ENDIF() - -IF(MBEDTLS_FOUND) - MESSAGE(STATUS "* mbedTLS: FOUND *") -ELSE() - MESSAGE(STATUS "* mbedTLS: MISSING *") -ENDIF() - -MESSAGE(STATUS "**************************************************") - -#options -OPTION(EQEMU_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON) +#Bots are a compile time option so on/off OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF) + +#Enable GM Command log system OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON) -OPTION(EQEMU_BUILD_SERVER "Build the game server." ON) -OPTION(EQEMU_BUILD_LOGIN "Build the login server." ON) -OPTION(EQEMU_BUILD_HC "Build the headless client." OFF) -OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF) -OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON) IF(EQEMU_COMMANDS_LOGGING) ADD_DEFINITIONS(-DCOMMANDS_LOGGING) ENDIF(EQEMU_COMMANDS_LOGGING) +IF(EQEMU_LSPX) + ADD_DEFINITIONS(-DLSPX=ON) +ENDIF(EQEMU_LSPX) + IF(EQEMU_ENABLE_BOTS) ADD_DEFINITIONS(-DBOTS) ENDIF(EQEMU_ENABLE_BOTS) -#database -IF(MySQL_FOUND AND MariaDB_FOUND) - SET(DATABASE_LIBRARY_SELECTION MySQL CACHE STRING "Database library to use: - MySQL - MariaDB" - ) - - IF(DATABASE_LIBRARY_SELECTION STREQUAL "MySQL") - SET(DATABASE_LIBRARY_TYPE " MySQL") - SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES}) - SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR}) - ELSEIF(DATABASE_LIBRARY_SELECTION STREQUAL "MariaDB") - SET(DATABASE_LIBRARY_TYPE "MariaDB") - SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES}) - SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR}) - ELSE() - MESSAGE(FATAL_ERROR "Unknown database library set, should be one of: MySQL, MariaDB") - ENDIF() -ELSEIF(MariaDB_FOUND) - SET(DATABASE_LIBRARY_TYPE "MariaDB") - SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES}) - SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR}) -ELSEIF(MySQL_FOUND) - SET(DATABASE_LIBRARY_TYPE " MySQL") - SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES}) - SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR}) -ELSE() - MESSAGE(FATAL_ERROR "One of MySQL or MariaDB is a required dependency.") -ENDIF() +#What to build +OPTION(EQEMU_BUILD_SERVER "Build the game server." ON) +OPTION(EQEMU_BUILD_LOGIN "Build the login server." OFF) +OPTION(EQEMU_BUILD_HC "Build the headless client." OFF) +OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF) +OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON) +OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON) +OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON) -#security -#prefer openssl to mbedtls (arbitrary) -IF(OpenSSL_FOUND AND MBEDTLS_FOUND) - SET(TLS_LIBRARY_SELECTION OpenSSL CACHE STRING "TLS library to use: - OpenSSL - mbedTLS" - ) - - IF(TLS_LIBRARY_SELECTION STREQUAL "OpenSSL") - SET(TLS_LIBRARY_TYPE " OpenSSL") - SET(TLS_LIBRARY_ENABLED ON) - SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES}) - SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR}) - ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL) - ELSEIF(TLS_LIBRARY_SELECTION STREQUAL "mbedTLS") - SET(TLS_LIBRARY_TYPE " mbedTLS") - SET(TLS_LIBRARY_ENABLED ON) - SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY}) - SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR}) - ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS) - ELSE() - MESSAGE(FATAL_ERROR "Unknown TLS library set, should be one of: OpenSSL, mbedTLS") +#C++11 stuff +IF(NOT MSVC) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") + IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reserved-user-defined-literal") ENDIF() -ELSEIF(OpenSSL_FOUND) - SET(TLS_LIBRARY_TYPE " OpenSSL") - SET(TLS_LIBRARY_ENABLED ON) - SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES}) - SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR}) - ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL) -ELSEIF(MBEDTLS_FOUND) - SET(TLS_LIBRARY_TYPE " mbedTLS") - SET(TLS_LIBRARY_ENABLED ON) - SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY}) - SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR}) - ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS) -ELSE() - SET(TLS_LIBRARY_TYPE "Disabled") - SET(TLS_LIBRARY_ENABLED OFF) -ENDIF() +ENDIF(NOT MSVC) +#Various definitions +IF(EQEMU_BUILD_PERL) + ADD_DEFINITIONS(-DEMBPERL) + ADD_DEFINITIONS(-DEMBPERL_PLUGIN) +ENDIF(EQEMU_BUILD_PERL) +IF(EQEMU_BUILD_LUA) + ADD_DEFINITIONS(-DLUA_EQEMU) +ENDIF(EQEMU_BUILD_LUA) + +#Disabled until reevaluation performed +#OPTION(EQEMU_USE_MAP_MMFS "Create and use Zone Map MMF files." OFF) +#IF(EQEMU_USE_MAP_MMFS) +# ADD_DEFINITIONS(-DUSE_MAP_MMFS) +#ENDIF(EQEMU_USE_MAP_MMFS) + +SET(EQEMU_MAP_DIR "./Maps" CACHE STRING "The dir that maps, water maps, and paths are located in.") + +ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL}) +ADD_DEFINITIONS(-DINVERSEXY) +ADD_DEFINITIONS(-DFIELD_ITEMS) +ADD_DEFINITIONS(-DMAP_DIR="${EQEMU_MAP_DIR}") +ADD_DEFINITIONS(-DLOG_LEVEL_DEBUG=${EQEMU_LOG_LEVEL_DEBUG}) +ADD_DEFINITIONS(-DGLM_FORCE_RADIANS) +ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT) +ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL) + +#Find everything we need +FIND_PACKAGE(ZLIB) +FIND_PACKAGE(MySQL REQUIRED) +IF(EQEMU_BUILD_PERL) + FIND_PACKAGE(PerlLibs REQUIRED) + INCLUDE_DIRECTORIES(SYSTEM "${PERL_INCLUDE_PATH}") +ENDIF(EQEMU_BUILD_PERL) + +SET(SERVER_LIBS common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} uv_a fmt RecastNavigation::Detour) + +FIND_PACKAGE(Sodium REQUIRED) IF(SODIUM_FOUND) - SET(SODIUM_LIBRARY_TYPE "Libsodium") - SET(SODIUM_LIBRARY_ENABLED ON) - SET(SODIUM_LIBRARY_LIBS ${SODIUM_LIBRARIES}) - SET(SODIUM_LIBRARY_INCLUDE ${SODIUM_INCLUDE_DIRS}) - ADD_DEFINITIONS(-DENABLE_SECURITY) -ELSE() - SET(SODIUM_LIBRARY_TYPE " Disabled") - SET(SODIUM_LIBRARY_ENABLED OFF) + OPTION(EQEMU_ENABLE_SECURITY "Use Encryption For TCP Connections" ON) + IF(EQEMU_ENABLE_SECURITY) + INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_INCLUDE_DIRS}") + ADD_DEFINITIONS(-DENABLE_SECURITY) + SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARIES}) + ENDIF() ENDIF() -IF(Lua51_FOUND) - SET(LUA_LIBRARY_TYPE " Lua 5.1") - SET(LUA_LIBRARY_ENABLED ON) - SET(LUA_LIBRARY_LIBS ${LUA_LIBRARY} luabind) - SET(LUA_LIBRARY_INCLUDE ${LUA_INCLUDE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind") -ELSE() - SET(LUA_LIBRARY_TYPE "Disabled") - SET(LUA_LIBRARY_ENABLED OFF) -ENDIF() - -IF(PerlLibs_FOUND) - SET(PERL_LIBRARY_TYPE " Perl") - SET(PERL_LIBRARY_ENABLED ON) - SET(PERL_LIBRARY_LIBS ${PERL_LIBRARY}) - SET(PERL_LIBRARY_INCLUDE ${PERL_INCLUDE_PATH}) -ELSE() - SET(PERL_LIBRARY_TYPE "Disabled") - SET(PERL_LIBRARY_ENABLED OFF) -ENDIF() - -#use zlib if exists IF(ZLIB_FOUND) - OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." ON) + OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." OFF) + IF(EQEMU_BUILD_ZLIB) - SET(ZLIB_LIBRARY_TYPE "zlib-ng") - SET(ZLIB_LIBRARY_LIBS "zlibstatic") - SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng") + INCLUDE_DIRECTORIES(BEFORE SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng" "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng") + SET(SERVER_LIBS ${SERVER_LIBS} "zlibstatic") ELSE() - SET(ZLIB_LIBRARY_TYPE " zlib") - SET(ZLIB_LIBRARY_LIBS ${ZLIB_LIBRARY}) - SET(ZLIB_LIBRARY_INCLUDE ${ZLIB_INCLUDE_DIRS}) + INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}") + SET(SERVER_LIBS ${SERVER_LIBS} ${ZLIB_LIBRARY}) ENDIF() ELSE() - SET(ZLIB_LIBRARY_TYPE "zlib-ng") - SET(ZLIB_LIBRARY_LIBS "zlibstatic") - SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng") -ENDIF() - -MESSAGE(STATUS "") -MESSAGE(STATUS "**************************************************") -MESSAGE(STATUS "* Library Usage *") -MESSAGE(STATUS "**************************************************") -MESSAGE(STATUS "* Database: ${DATABASE_LIBRARY_TYPE} *") -MESSAGE(STATUS "* TLS: ${TLS_LIBRARY_TYPE} *") -MESSAGE(STATUS "* Sodium: ${SODIUM_LIBRARY_TYPE} *") -MESSAGE(STATUS "* Lua: ${LUA_LIBRARY_TYPE} *") -MESSAGE(STATUS "* Perl: ${PERL_LIBRARY_TYPE} *") -MESSAGE(STATUS "* zlib: ${ZLIB_LIBRARY_TYPE} *") -MESSAGE(STATUS "**************************************************") - -#setup server libs and headers -SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} uv_a fmt RecastNavigation::Detour) - -INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}") -INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}") -INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm") -INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include") -INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include") -INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv/include" ) -INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DebugUtils/Include") -INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Detour/Include") -INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourCrowd/Include") -INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourTileCache/Include") -INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include") -INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp") - -IF(TLS_LIBRARY_ENABLED) - SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS}) - INCLUDE_DIRECTORIES(SYSTEM "${TLS_LIBRARY_INCLUDE}") -ENDIF() - -IF(SODIUM_LIBRARY_ENABLED) - SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARY_LIBS}) - INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_LIBRARY_INCLUDE}") -ENDIF() - -IF(LUA_LIBRARY_ENABLED) - OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON) - - IF(EQEMU_BUILD_LUA) - ADD_DEFINITIONS(-DLUA_EQEMU) - SET(SERVER_LIBS ${SERVER_LIBS} ${LUA_LIBRARY_LIBS}) - INCLUDE_DIRECTORIES(SYSTEM "${LUA_LIBRARY_INCLUDE}") - - OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON) - IF(EQEMU_SANITIZE_LUA_LIBS) - ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS) - ENDIF() - ENDIF() -ENDIF() - -IF(PERL_LIBRARY_ENABLED) - OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON) - IF(EQEMU_BUILD_PERL) - SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS}) - INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}") - ADD_DEFINITIONS(-DEMBPERL) - ADD_DEFINITIONS(-DEMBPERL_PLUGIN) - ENDIF() + MESSAGE(STATUS "Could NOT find ZLIB - using ZLIBSTATIC package.") + SET(EQEMU_BUILD_ZLIB ON) + INCLUDE_DIRECTORIES(BEFORE SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng" "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng") + SET(SERVER_LIBS ${SERVER_LIBS} "zlibstatic") ENDIF() IF(WIN32) @@ -324,32 +267,52 @@ IF(UNIX) SET(SERVER_LIBS ${SERVER_LIBS} "uuid") ENDIF() -IF(EQEMU_BUILD_LOGIN AND NOT TLS_LIBRARY_ENABLED) - MESSAGE(FATAL_ERROR "Login server requires a TLS Library to build.") -ENDIF() +IF(EQEMU_BUILD_LUA) + FIND_PACKAGE(EQLua51 REQUIRED) + SET(Boost_USE_STATIC_LIBS OFF) + SET(Boost_USE_MULTITHREADED ON) + SET(Boost_USE_STATIC_RUNTIME OFF) + SET(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/boost") -IF(EQEMU_BUILD_HC AND NOT TLS_LIBRARY_ENABLED) - MESSAGE(FATAL_ERROR "Headless client requires a TLS Library to build.") -ENDIF() + FIND_PACKAGE(Boost REQUIRED) + INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}") + INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind") + + OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON) + IF(EQEMU_SANITIZE_LUA_LIBS) + ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS) + ENDIF(EQEMU_SANITIZE_LUA_LIBS) +ENDIF(EQEMU_BUILD_LUA) + +INCLUDE_DIRECTORIES(SYSTEM "${MySQL_INCLUDE_DIR}") +INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm") +INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include") +INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include") +INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv/include" ) +INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DebugUtils/Include") +INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Detour/Include") +INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourCrowd/Include") +INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourTileCache/Include") +INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include") +INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp") IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC) ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(libs) ADD_SUBDIRECTORY(submodules/fmt) ADD_SUBDIRECTORY(submodules/libuv) + + SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo") + SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests") + SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples") + ADD_SUBDIRECTORY(submodules/recastnavigation) IF(EQEMU_BUILD_ZLIB) SET(ZLIB_COMPAT ON CACHE BOOL "Compile with zlib compatible API") SET(ZLIB_ENABLE_TESTS OFF CACHE BOOL "Build test binaries") ADD_SUBDIRECTORY(libs/zlibng) ENDIF() - - SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo") - SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests") - SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples") - ADD_SUBDIRECTORY(submodules/recastnavigation) ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC) - IF(EQEMU_BUILD_SERVER) ADD_SUBDIRECTORY(shared_memory) ADD_SUBDIRECTORY(world) @@ -358,7 +321,6 @@ IF(EQEMU_BUILD_SERVER) ADD_SUBDIRECTORY(queryserv) ADD_SUBDIRECTORY(eqlaunch) ENDIF(EQEMU_BUILD_SERVER) - IF(EQEMU_BUILD_LOGIN) ADD_SUBDIRECTORY(loginserver) ENDIF(EQEMU_BUILD_LOGIN) diff --git a/client_files/CMakeLists.txt b/client_files/CMakeLists.txt index fe377ec9f..93d748dc6 100644 --- a/client_files/CMakeLists.txt +++ b/client_files/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) add_subdirectory(import) add_subdirectory(export) diff --git a/client_files/export/CMakeLists.txt b/client_files/export/CMakeLists.txt index 08cbbc822..c24a01865 100644 --- a/client_files/export/CMakeLists.txt +++ b/client_files/export/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(export_sources main.cpp diff --git a/client_files/import/CMakeLists.txt b/client_files/import/CMakeLists.txt index a76bab416..0f779497c 100644 --- a/client_files/import/CMakeLists.txt +++ b/client_files/import/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(import_sources main.cpp diff --git a/cmake/DependencyHelperMSVC.cmake b/cmake/DependencyHelperMSVC.cmake deleted file mode 100644 index 48b99c9d9..000000000 --- a/cmake/DependencyHelperMSVC.cmake +++ /dev/null @@ -1,94 +0,0 @@ -OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG "Automatically fetch vcpkg dependencies for MSCV" ON) -OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL "Automatically fetch perl dependencies for MSCV" ON) - -MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG) -MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL) - -SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip") -SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip") -SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-32bit-portable.zip") -SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-64bit-portable.zip") -SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP "vcpkg-export-x86.zip") -SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP "vcpkg-export-x64.zip") -SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR "vcpkg-export-20180828-145854") -SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR "vcpkg-export-20180828-145455") -SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP "strawberry-perl-5.24.4.1-32bit-portable.zip") -SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP "strawberry-perl-5.24.4.1-64bit-portable.zip") -SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR "x86") -SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR "x64") - -IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64}) - SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X64}) - SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP}) - SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR}) - SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP}) - SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR}) -ELSE() - SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86}) - SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X86}) - SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP}) - SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR}) - SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP}) - SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR}) -ENDIF() - -IF(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG) - MESSAGE(STATUS "Resolving vcpkg dependencies...") - - IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}) - EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vcpkg) - - MESSAGE(STATUS "Downloading existing vcpkg dependencies from releases...") - FILE(DOWNLOAD ${EQEMU_VCPKG_URL} ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP} - SHOW_PROGRESS - STATUS DOWNLOAD_STATUS) - - LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE) - IF(NOT STATUS_CODE EQUAL 0) - MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_VCPKG_URL}") - ENDIF() - - MESSAGE(STATUS "Extracting files...") - EXECUTE_PROCESS( - COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vcpkg - ) - ENDIF() - - INCLUDE(${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake) -ENDIF() - -IF(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL) - #Try to find perl first, (so you can use your active install first) - FIND_PACKAGE(PerlLibs) - - IF(NOT PerlLibs_FOUND) - MESSAGE(STATUS "Resolving perl dependencies...") - - IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}) - EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl) - EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}) - - MESSAGE(STATUS "Downloading portable perl...") - FILE(DOWNLOAD ${EQEMU_PERL_URL} ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP} - SHOW_PROGRESS - STATUS DOWNLOAD_STATUS) - - LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE) - IF(NOT STATUS_CODE EQUAL 0) - MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_PERL_URL}") - ENDIF() - - MESSAGE(STATUS "Extracting files...") - EXECUTE_PROCESS( - COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR} - ) - ENDIF() - - SET(PERL_EXECUTABLE ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/bin/perl.exe CACHE FILEPATH "Path to perl program" FORCE) - SET(PERL_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE CACHE PATH "Path to perl include files" FORCE) - SET(PERL_LIBRARY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE/libperl524.a CACHE FILEPATH "Path to perl library" FORCE) - ENDIF() -ENDIF() \ No newline at end of file diff --git a/cmake/FindEQLua51.cmake b/cmake/FindEQLua51.cmake new file mode 100644 index 000000000..9f6663d56 --- /dev/null +++ b/cmake/FindEQLua51.cmake @@ -0,0 +1,124 @@ +#CMake - Cross Platform Makefile Generator +#Copyright 2000-2011 Kitware, Inc., Insight Software Consortium +#All rights reserved. +# +#Redistribution and use in source and binary forms, with or without +#modification, are permitted provided that the following conditions +#are met: +# +#* Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +#* Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +#* Neither the names of Kitware, Inc., the Insight Software Consortium, +# nor the names of their contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +#A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +#HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +#SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +#LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# This module defines +# LUA51_FOUND, if false, do not try to link to Lua +# LUA_LIBRARIES +# LUA_INCLUDE_DIR, where to find lua.h +# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8) + +IF(LUA_ROOT) + FIND_PATH(LUA_INCLUDE_DIR + NAMES lua.h + HINTS + ENV LUA_DIR + PATHS + ${LUA_ROOT} + ~/Library/Frameworks + /Library/Frameworks + /sw + /opt/local + /opt/csw + /opt + PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include src + ) + + FIND_LIBRARY(LUA_LIBRARY + NAMES lua51 lua5.1 lua-5.1 lua + HINTS + ENV LUA_DIR + PATHS + ${LUA_ROOT} + ~/Library/Frameworks + /Library/Frameworks + /sw + /opt/local + /opt/csw + /opt + PATH_SUFFIXES lib bin + ) +ELSE(LUA_ROOT) + FIND_PATH(LUA_INCLUDE_DIR + NAMES lua.h + HINTS + ENV LUA_DIR + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw + /opt/local + /opt/csw + /opt + PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include + ) + + FIND_LIBRARY(LUA_LIBRARY + NAMES lua51 lua5.1 lua-5.1 lua + HINTS + ENV LUA_DIR + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw + /opt/local + /opt/csw + /opt + PATH_SUFFIXES lib bin + ) +ENDIF(LUA_ROOT) + +IF(LUA_LIBRARY) + # include the math library for Unix + IF(UNIX AND NOT APPLE) + FIND_LIBRARY(LUA_MATH_LIBRARY m) + SET(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries") + # For Windows and Mac, don't need to explicitly include the math library + ELSE() + SET( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries") + ENDIF() +ENDIF() + +IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h") + FILE(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"") + + STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}") + UNSET(lua_version_str) +ENDIF() + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51 + REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR + VERSION_VAR LUA_VERSION_STRING) + +MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY) + + diff --git a/cmake/FindLua51.cmake b/cmake/FindLua51.cmake deleted file mode 100644 index 47fa0aaae..000000000 --- a/cmake/FindLua51.cmake +++ /dev/null @@ -1,91 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. -# Modified from the FindLua51 that comes with CMake - -#[=======================================================================[.rst: -FindLua51 ---------- - - - -Locate Lua51 library This module defines - -:: - - LUA51_FOUND, if false, do not try to link to Lua - LUA_LIBRARIES - LUA_INCLUDE_DIR, where to find lua.h - LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8) - - - -Note that the expected include convention is - -:: - - #include "lua.h" - -and not - -:: - - #include - -This is because, the lua location is not standardized and may exist in -locations other than lua/ -#]=======================================================================] - -find_path(LUA_INCLUDE_DIR lua.h - HINTS - ENV LUA_DIR - PATH_SUFFIXES include/lua51 include/lua5.1 include/lua-5.1 include/lua include/luajit include - PATHS - ~/Library/Frameworks - /Library/Frameworks - /sw # Fink - /opt/local # DarwinPorts - /opt/csw # Blastwave - /opt -) - -find_library(LUA_LIBRARY - NAMES lua51 lua5.1 lua-5.1 lua luajit - HINTS - ENV LUA_DIR - PATH_SUFFIXES lib - PATHS - ~/Library/Frameworks - /Library/Frameworks - /sw - /opt/local - /opt/csw - /opt -) - -if(LUA_LIBRARY) - # include the math library for Unix - if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU) - find_library(LUA_MATH_LIBRARY m) - set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries") - # For Windows and Mac, don't need to explicitly include the math library - else() - set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries") - endif() -endif() - -if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h") - file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"") - - string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}") - unset(lua_version_str) -endif() - -include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) -# handle the QUIETLY and REQUIRED arguments and set LUA51_FOUND to TRUE if -# all listed variables are TRUE -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51 - REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR - VERSION_VAR LUA_VERSION_STRING) - -mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY) - diff --git a/cmake/FindMariaDB.cmake b/cmake/FindMariaDB.cmake deleted file mode 100644 index 14f54734d..000000000 --- a/cmake/FindMariaDB.cmake +++ /dev/null @@ -1,87 +0,0 @@ -# - Find mariadbclient -# -# -*- cmake -*- -# -# Find the native MariaDB includes and library -# -# MariaDB_INCLUDE_DIR - where to find mysql.h, etc. -# MariaDB_LIBRARIES - List of libraries when using MariaDB. -# MariaDB_FOUND - True if MariaDB found. -# The following can be used as a hint as to where to search: -# MARIADB_ROOT - -IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES) - # Already in cache, be silent - SET(MariaDB_FIND_QUIETLY TRUE) -ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES) - -# Include dir -IF(MARIADB_ROOT) - FIND_PATH(MariaDB_INCLUDE_DIR - NAMES mariadb_version.h - PATHS ${MARIADB_ROOT}/include - PATH_SUFFIXES mysql mariadb - NO_DEFAULT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - ) - FIND_PATH(MariaDB_INCLUDE_DIR - NAMES mariadb_version.h - PATH_SUFFIXES mysql mariadb - ) -ELSE(MARIADB_ROOT) - FIND_PATH(MariaDB_INCLUDE_DIR - NAMES mariadb_version.h - PATH_SUFFIXES mysql mariadb - ) -ENDIF(MARIADB_ROOT) - -# Library -SET(MariaDB_NAMES libmariadb) -IF(MARIADB_ROOT) - FIND_LIBRARY(MariaDB_LIBRARY - NAMES ${MariaDB_NAMES} - PATHS ${MARIADB_ROOT}/lib - PATH_SUFFIXES mysql mariadb - NO_DEFAULT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - ) - - FIND_LIBRARY(MariaDB_LIBRARY - NAMES ${MariaDB_NAMES} - PATH_SUFFIXES mysql mariadb - ) -ELSE(MARIADB_ROOT) - FIND_LIBRARY(MariaDB_LIBRARY - NAMES ${MariaDB_NAMES} mariadbclient_r mariadbclient - PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64 - PATH_SUFFIXES mysql mariadb - ) -ENDIF(MARIADB_ROOT) - -IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY) - SET(MariaDB_FOUND TRUE) - SET(MariaDB_LIBRARIES ${MariaDB_LIBRARY}) -ELSE (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY) - SET(MariaDB_FOUND FALSE) - SET(MariaDB_LIBRARIES) -ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY) - - -# handle the QUIETLY and REQUIRED arguments and set MariaDB_FOUND to TRUE if -# all listed variables are TRUE -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(MariaDB DEFAULT_MSG MariaDB_LIBRARY MariaDB_INCLUDE_DIR) - -IF(MariaDB_FOUND) - SET( MariaDB_LIBRARY_RELEASE ${MariaDB_LIBRARY} ) - SET( MariaDB_LIBRARY_DEBUG ${MariaDB_LIBRARY} ) - SET( MariaDB_LIBRARIES ${MariaDB_LIBRARY_RELEASE} ${MariaDB_LIBRARY_DEBUG} ) -ELSE(MariaDB_FOUND) - SET( MariaDB_LIBRARIES ) -ENDIF(MariaDB_FOUND) - -MARK_AS_ADVANCED( - MariaDB_LIBRARY_DEBUG - MariaDB_LIBRARY_RELEASE - MariaDB_INCLUDE_DIR - ) diff --git a/cmake/FindmbedTLS.cmake b/cmake/FindmbedTLS.cmake deleted file mode 100644 index d2a3ce3b9..000000000 --- a/cmake/FindmbedTLS.cmake +++ /dev/null @@ -1,93 +0,0 @@ -# - Try to find mbedTLS -# Once done this will define -# -# Read-Only variables -# MBEDTLS_FOUND - system has mbedTLS -# MBEDTLS_INCLUDE_DIR - the mbedTLS include directory -# MBEDTLS_LIBRARY_DIR - the mbedTLS library directory -# MBEDTLS_LIBRARIES - Link these to use mbedTLS -# MBEDTLS_LIBRARY - path to mbedTLS library -# MBEDX509_LIBRARY - path to mbedTLS X.509 library -# MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library -# -# Hint -# MBEDTLS_ROOT_DIR can be pointed to a local mbedTLS installation. - -SET(_MBEDTLS_ROOT_HINTS - ${MBEDTLS_ROOT_DIR} - ENV MBEDTLS_ROOT_DIR -) - -SET(_MBEDTLS_ROOT_HINTS_AND_PATHS - HINTS ${_MBEDTLS_ROOT_HINTS} - PATHS ${_MBEDTLS_ROOT_PATHS} -) - -FIND_PATH(MBEDTLS_INCLUDE_DIR - NAMES mbedtls/version.h - ${_MBEDTLS_ROOT_HINTS_AND_PATHS} - PATH_SUFFIXES include -) - -IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES) - # Already in cache, be silent - SET(MBEDTLS_FIND_QUIETLY TRUE) -ENDIF() - -FIND_LIBRARY(MBEDTLS_LIBRARY - NAMES mbedtls libmbedtls - ${_MBEDTLS_ROOT_HINTS_AND_PATHS} - PATH_SUFFIXES library -) -FIND_LIBRARY(MBEDX509_LIBRARY - NAMES mbedx509 libmbedx509 - ${_MBEDTLS_ROOT_HINTS_AND_PATHS} - PATH_SUFFIXES library -) -FIND_LIBRARY(MBEDCRYPTO_LIBRARY - NAMES mbedcrypto libmbedcrypto - ${_MBEDTLS_ROOT_HINTS_AND_PATHS} - PATH_SUFFIXES library -) - -IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY) - SET(MBEDTLS_FOUND TRUE) -ENDIF() - -IF(MBEDTLS_FOUND) - # split mbedTLS into -L and -l linker options, so we can set them for pkg-config - GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH) - GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE) - GET_FILENAME_COMPONENT(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE) - GET_FILENAME_COMPONENT(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE) - STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE}) - STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE}) - STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE}) - SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}") - - IF(NOT MBEDTLS_FIND_QUIETLY) - MESSAGE(STATUS "Found mbedTLS:") - FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT) - STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT}) - IF (MBEDTLSMATCH) - STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH}) - MESSAGE(STATUS " version ${MBEDTLS_VERSION}") - ENDIF(MBEDTLSMATCH) - MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}") - MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}") - MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}") - ENDIF(NOT MBEDTLS_FIND_QUIETLY) -ELSE(MBEDTLS_FOUND) - IF(MBEDTLS_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find mbedTLS") - ENDIF(MBEDTLS_FIND_REQUIRED) -ENDIF(MBEDTLS_FOUND) - -MARK_AS_ADVANCED( - MBEDTLS_INCLUDE_DIR - MBEDTLS_LIBRARY_DIR - MBEDTLS_LIBRARIES - MBEDTLS_LIBRARY - MBEDX509_LIBRARY - MBEDCRYPTO_LIBRARY -) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index c4dec4074..32c64e7ca 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(common_sources base_packet.cpp diff --git a/common/useperl.h b/common/useperl.h index fb638be57..a6345df5d 100644 --- a/common/useperl.h +++ b/common/useperl.h @@ -13,10 +13,6 @@ #ifndef WIN32 extern "C" { //the perl headers dont do this for us... #endif -#if _MSC_VER -#define __inline__ __inline -#define __builtin_expect -#endif #include #include #ifndef WIN32 diff --git a/eqlaunch/CMakeLists.txt b/eqlaunch/CMakeLists.txt index c5e7bbd03..260a2b5bc 100644 --- a/eqlaunch/CMakeLists.txt +++ b/eqlaunch/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(eqlaunch_sources eqlaunch.cpp diff --git a/hc/CMakeLists.txt b/hc/CMakeLists.txt index 9f2c78298..1aa5805d5 100644 --- a/hc/CMakeLists.txt +++ b/hc/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(hc_sources eq.cpp @@ -13,10 +13,14 @@ SET(hc_headers world.h ) +FIND_PACKAGE(OpenSSL REQUIRED) + +INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR}) + ADD_EXECUTABLE(hc ${hc_sources} ${hc_headers}) INSTALL(TARGETS hc RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) -TARGET_LINK_LIBRARIES(hc ${SERVER_LIBS}) +TARGET_LINK_LIBRARIES(hc ${SERVER_LIBS} ${OPENSSL_LIBRARIES}) SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) diff --git a/libs/luabind/CMakeLists.txt b/libs/luabind/CMakeLists.txt index 48a120400..de3b60c61 100644 --- a/libs/luabind/CMakeLists.txt +++ b/libs/luabind/CMakeLists.txt @@ -1,61 +1,38 @@ -# Build for LuaBind -# Ryan Pavlik -# http://academic.cleardefinition.com/ -# Iowa State University HCI Graduate Program/VRAC +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) -cmake_minimum_required(VERSION 3.0) -project(LuaBind) - -set(CPACK_PACKAGE_VERSION_MAJOR "0") -set(CPACK_PACKAGE_VERSION_MINOR "9") -set(CPACK_PACKAGE_VERSION_PATCH "1") -set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") - -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) - -if(NOT LUA_FOUND AND NOT LUA51_FOUND) - find_package(Lua51 REQUIRED) - set(LUA_INCLUDE_DIRS "${LUA_INCLUDE_DIR}") -endif() - -if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) - # We are the top-level project - include(CTest) - option(LUABIND_INSTALL "Install the LuaBind library and headers" ON) - option(LUABIND_BUILD_DOCS "Build documentation files" OFF) - option(LUABIND_BUILD_SHARED "Build luabind as a shared library?" OFF) -endif() - -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - # Requiring C++11 - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -endif() - -if(MSVC) - # Requiring C++11 -# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++11") -# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /std:c++11") -endif() - -set(BUILD_SHARED_LIBS ${LUABIND_BUILD_SHARED}) -if(BUILD_SHARED_LIBS) - add_definitions(-DLUABIND_DYNAMIC_LINK) -endif() - -include_directories( - "${CMAKE_CURRENT_SOURCE_DIR}" - ${LUA_INCLUDE_DIRS} +SET(lb_sources + src/class.cpp + src/class_info.cpp + src/class_registry.cpp + src/class_rep.cpp + src/create_class.cpp + src/error.cpp + src/exception_handler.cpp + src/function.cpp + src/inheritance.cpp + src/link_compatibility.cpp + src/object_rep.cpp + src/open.cpp + src/pcall.cpp + src/scope.cpp + src/stack_content_by_name.cpp + src/weak_ref.cpp + src/wrapper_base.cpp ) -add_subdirectory(src) +SET(lb_headers -if(BUILD_TESTING) - add_subdirectory(test) -endif() +) -if(LUABIND_BUILD_DOCS) - add_subdirectory(doc) -endif() +ADD_LIBRARY(luabind ${lb_sources} ${lb_headers}) + +IF(UNIX) + set_source_files_properties(${lb_sources} PROPERTY COMPILE_FLAGS -Wno-deprecated-declarations) +ENDIF(UNIX) + +IF(MSVC) + set_source_files_properties(${lb_sources} PROPERTY COMPILE_FLAGS " /W0 " ) +ENDIF(MSVC) + +SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) diff --git a/libs/luabind/CMakeSettings.json b/libs/luabind/CMakeSettings.json deleted file mode 100644 index d85358021..000000000 --- a/libs/luabind/CMakeSettings.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "configurations": [ - { - "name": "x32-debug", - "generator": "Visual Studio 15 2017", - "buildRoot": "${projectDir}/temp/x32-debug", - "cmakeCommandArgs": "", - "configurationType": "Debug", - "variables": [ - { - "name": "LUA_INCLUDE_DIR", - "value": "C:/gitprojects/LuaJIT-2.1.0-beta3/src" - }, - { - "name": "LUA_LIBRARIES", - "value": "C:/gitprojects/LuaJIT-2.1.0-beta3/src/lua51.lib" - }, - { - "name": "LUABIND_INSTALL", - "value": "ON" - }, - { - "name": "CMAKE_INSTALL_PREFIX", - "value": "${projectDir}/build/debug" - } - ] - }, - { - "name": "x32-release", - "generator": "Visual Studio 15 2017", - "buildRoot": "${projectDir}/temp/x32-release", - "cmakeCommandArgs": "", - "configurationType": "Release", - "variables": [ - { - "name": "LUA_INCLUDE_DIR", - "value": "C:/gitprojects/LuaJIT-2.1.0-beta3/src" - }, - { - "name": "LUA_LIBRARIES", - "value": "C:/gitprojects/LuaJIT-2.1.0-beta3/src/lua51.lib" - }, - { - "name": "LUABIND_INSTALL", - "value": "ON" - }, - { - "name": "CMAKE_INSTALL_PREFIX", - "value": "${projectDir}/build/release" - } - ] - } - ] -} diff --git a/libs/luabind/luabind/adopt_policy.hpp b/libs/luabind/luabind/adopt_policy.hpp index 3f4751cc3..5e81b948b 100644 --- a/libs/luabind/luabind/adopt_policy.hpp +++ b/libs/luabind/luabind/adopt_policy.hpp @@ -28,111 +28,114 @@ #include #include #include +#include +#include -namespace luabind { - namespace detail { +namespace luabind { namespace detail +{ + template + void adjust_backref_ownership(T* ptr, mpl::true_) + { + if (wrap_base* p = dynamic_cast(ptr)) + { + wrapped_self_t& wrapper = wrap_access::ref(*p); + wrapper.get(wrapper.state()); + wrapper.m_strong_ref.set(wrapper.state()); + } + } - template - void adjust_backref_ownership(T* ptr, std::true_type) + inline void adjust_backref_ownership(void*, mpl::false_) + {} + + template + struct adopt_pointer : pointer_converter + { + typedef adopt_pointer type; + + int const consumed_args(...) + { + return 1; + } + + template + T* apply(lua_State* L, by_pointer, int index) { - if(wrap_base* p = dynamic_cast(ptr)) - { - wrapped_self_t& wrapper = wrap_access::ref(*p); - wrapper.get(wrapper.state()); - wrapper.m_strong_ref.set(wrapper.state()); - } + T* ptr = pointer_converter::apply( + L, LUABIND_DECORATE_TYPE(T*), index); + + object_rep* obj = static_cast( + lua_touserdata(L, index)); + obj->release(); + + adjust_backref_ownership(ptr, boost::is_polymorphic()); + + return ptr; } - inline void adjust_backref_ownership(void*, std::false_type) - {} - - template - struct adopt_pointer : pointer_converter + template + int match(lua_State* L, by_pointer, int index) { - using type = adopt_pointer; + return pointer_converter::match( + L, LUABIND_DECORATE_TYPE(T*), index); + } - enum { consumed_args = 1 }; + template + void converter_postcall(lua_State*, T, int) {} + }; - template - T* to_cpp(lua_State* L, by_pointer, int index) + template<> + struct adopt_pointer + { + typedef adopt_pointer type; + + template + void apply(lua_State* L, T* ptr) + { + if (ptr == 0) { - T* ptr = pointer_converter::to_cpp(L, decorate_type_t(), index); - - object_rep* obj = static_cast(lua_touserdata(L, index)); - obj->release(); - - adjust_backref_ownership(ptr, std::is_polymorphic()); - - return ptr; + lua_pushnil(L); + return; } - template - int match(lua_State* L, by_pointer, int index) - { - return pointer_converter::match(L, decorate_type_t(), index); - } + // if there is a back_reference, then the + // ownership will be removed from the + // back reference and put on the lua stack. + if (luabind::move_back_reference(L, ptr)) + return; - template - void converter_postcall(lua_State*, T, int) {} - }; + make_instance(L, std::auto_ptr(ptr)); + } + }; - template - struct pointer_or_default + template +// struct adopt_policy : converter_policy_tag + struct adopt_policy : conversion_policy + { +// BOOST_STATIC_CONSTANT(int, index = N); + + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + + struct only_accepts_nonconst_pointers {}; + + template + struct apply { - using type = Pointer; + typedef luabind::detail::is_nonconst_pointer is_nonconst_p; + typedef typename boost::mpl::if_, only_accepts_nonconst_pointers>::type type; }; + }; - template - struct pointer_or_default - { - using type = std::unique_ptr; - }; - - template - struct adopt_pointer - { - using type = adopt_pointer; - - template - void to_lua(lua_State* L, T* ptr) - { - if(ptr == 0) - { - lua_pushnil(L); - return; - } - - // if there is a back_reference, then the - // ownership will be removed from the - // back reference and put on the lua stack. - if(luabind::move_back_reference(L, ptr)) - return; - - using pointer_type = typename pointer_or_default::type; - - make_pointer_instance(L, pointer_type(ptr)); - } - }; - - template - struct adopt_policy_impl - { - template - struct specialize - { - static_assert(detail::is_nonconst_pointer::value, "Adopt policy only accepts non-const pointers"); - using type = adopt_pointer; - }; - }; - - } -} +}} namespace luabind { - // Caution: if we use the aliased type "policy_list" here, MSVC crashes. - template - using adopt_policy = meta::type_list>>; + template + detail::policy_cons, detail::null_type> + adopt(LUABIND_PLACEHOLDER_ARG(N)) + { + return detail::policy_cons, detail::null_type>(); + } } #endif // LUABIND_ADOPT_POLICY_HPP_INCLUDE diff --git a/libs/luabind/luabind/back_reference.hpp b/libs/luabind/luabind/back_reference.hpp index 1635c047f..5027618fb 100644 --- a/libs/luabind/luabind/back_reference.hpp +++ b/libs/luabind/luabind/back_reference.hpp @@ -23,86 +23,88 @@ #ifndef LUABIND_BACK_REFERENCE_040510_HPP #define LUABIND_BACK_REFERENCE_040510_HPP -#include -#include -#include - -#if !defined(LUABIND_NO_RTTI) && !defined(LUABIND_WRAPPER_BASE_HPP_INCLUDED) +#include #include -#endif - -#include +#include +#include +#include +#include +#include namespace luabind { - struct wrap_base; - namespace detail - { - template - wrap_base const* get_back_reference_aux0(T const* p, std::true_type) - { - return dynamic_cast(p); - } +namespace detail +{ + namespace mpl = boost::mpl; + + template + wrap_base const* get_back_reference_aux0(T const* p, mpl::true_) + { + return dynamic_cast(p); + } - template - wrap_base const* get_back_reference_aux0(T const*, std::false_type) - { - return 0; - } + template + wrap_base const* get_back_reference_aux0(T const*, mpl::false_) + { + return 0; + } - template - wrap_base const* get_back_reference_aux1(T const* p) - { - return get_back_reference_aux0(p, std::is_polymorphic()); - } + template + wrap_base const* get_back_reference_aux1(T const* p) + { + return get_back_reference_aux0(p, boost::is_polymorphic()); + } - template - wrap_base const* get_back_reference_aux2(T const& x, std::true_type) - { - return get_back_reference_aux1(get_pointer(x)); - } + template + wrap_base const* get_back_reference_aux2(T const& x, mpl::true_) + { + return get_back_reference_aux1(get_pointer(x)); + } - template - wrap_base const* get_back_reference_aux2(T const& x, std::false_type) - { - return get_back_reference_aux1(&x); - } + template + wrap_base const* get_back_reference_aux2(T const& x, mpl::false_) + { + return get_back_reference_aux1(&x); + } - template - wrap_base const* get_back_reference(T const& x) - { - return detail::get_back_reference_aux2(x, has_get_pointer()); - } + template + wrap_base const* get_back_reference(T const& x) + { + return detail::get_back_reference_aux2( + x + , has_get_pointer() + ); + } + +} // namespace detail - } // namespace detail - - template - bool get_back_reference(lua_State* L, T const& x) - { +template +bool get_back_reference(lua_State* L, T const& x) +{ #ifndef LUABIND_NO_RTTI - if(wrap_base const* w = detail::get_back_reference(x)) - { - detail::wrap_access::ref(*w).get(L); - return true; - } + if (wrap_base const* w = detail::get_back_reference(x)) + { + detail::wrap_access::ref(*w).get(L); + return true; + } #endif - return false; - } + return false; +} - template - bool move_back_reference(lua_State* L, T const& x) - { +template +bool move_back_reference(lua_State* L, T const& x) +{ #ifndef LUABIND_NO_RTTI - if(wrap_base* w = const_cast(detail::get_back_reference(x))) - { - assert(detail::wrap_access::ref(*w).m_strong_ref.is_valid()); - detail::wrap_access::ref(*w).get(L); - detail::wrap_access::ref(*w).m_strong_ref.reset(); - return true; - } + if (wrap_base* w = const_cast(detail::get_back_reference(x))) + { + assert(detail::wrap_access::ref(*w).m_strong_ref.is_valid()); + detail::wrap_access::ref(*w).get(L); + detail::wrap_access::ref(*w).m_strong_ref.reset(); + return true; + } #endif - return false; - } + return false; +} } // namespace luabind diff --git a/libs/luabind/luabind/back_reference_fwd.hpp b/libs/luabind/luabind/back_reference_fwd.hpp index 85cb4478e..ffe141dba 100644 --- a/libs/luabind/luabind/back_reference_fwd.hpp +++ b/libs/luabind/luabind/back_reference_fwd.hpp @@ -23,15 +23,13 @@ #ifndef LUABIND_BACK_REFERENCE_FWD_040510_HPP #define LUABIND_BACK_REFERENCE_FWD_040510_HPP -#include - namespace luabind { - template - bool get_back_reference(lua_State* L, T const& x); +template +bool get_back_reference(lua_State* L, T const& x); - template - bool move_back_reference(lua_State* L, T const& x); +template +bool move_back_reference(lua_State* L, T const& x); } // namespace luabind diff --git a/libs/luabind/luabind/class.hpp b/libs/luabind/luabind/class.hpp index 320c8065f..10fb8e03d 100644 --- a/libs/luabind/luabind/class.hpp +++ b/libs/luabind/luabind/class.hpp @@ -52,7 +52,7 @@ TODO: ------------------------------------------------------ - finish smart pointer support + finish smart pointer support * the adopt policy should not be able to adopt pointers to held_types. This must be prohibited. * name_of_type must recognize holder_types and not return "custom" @@ -64,7 +64,7 @@ support the __concat metamethod. This is a bit tricky, since it cannot be treated as a normal operator. It is a binary operator but we want to use the __tostring implementation for both arguments. - + */ #include @@ -75,27 +75,42 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include -#include // -> object.hpp +#include #include -#include // -> object.hpp +#include +#include +#include +#include #include #include -#include +#include #include -#include #include +#include +#include #include #include #include +#include #include #include -#include -#include #include -#include // to remove the 'this' used in initialization list-warning #ifdef _MSC_VER @@ -103,8 +118,17 @@ #pragma warning(disable: 4355) #endif -namespace luabind { - namespace detail { +namespace boost +{ + + template class shared_ptr; + +} // namespace boost + +namespace luabind +{ + namespace detail + { struct unspecified {}; template struct operator_; @@ -112,86 +136,96 @@ namespace luabind { struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {}; } - template < typename... BaseClasses > - struct bases { }; - - using no_bases = bases< >; - using default_holder = null_type; - - namespace detail { - - template < typename T > - struct make_bases { - using type = bases< T >; - }; - - template< typename... Bases > - struct make_bases< bases< Bases... > > { - using type = bases< Bases... >; - }; - } - - template< typename T > - using make_bases = typename detail::make_bases< T >::type; - - template< typename... Args > - struct constructor - {}; - - // helper for overloaded methods, only need to provide argument types (IntelliSense bug squiggles the code, but it does compile!) - template< typename... Args > - struct meth { - template< typename Class, typename Ret > - static auto use_nonconst(Ret(Class::*fn)(Args...)) -> decltype(fn) - { - return fn; - } - - template< typename Class, typename Ret > - static auto use_const(Ret(Class::*fn)(Args...) const) -> decltype(fn) - { - return fn; - } - - template< typename Class, typename Ret > - static auto use_auto(Ret(Class::*fn)(Args...) const) -> decltype(fn) - { - return fn; - } - - template< typename Class, typename Ret > - static auto use_auto(Ret(Class::*fn)(Args...)) -> decltype(fn) - { - return fn; - } - }; - - // TODO: Could specialize for certain base classes to make the interface "type safe". - template + template struct class_; // TODO: this function will only be invoked if the user hasn't defined a correct overload // maybe we should have a static assert in here? inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr* - get_const_holder(...) + get_const_holder(...) { return 0; } template - std::shared_ptr* get_const_holder(std::shared_ptr*) + boost::shared_ptr* get_const_holder(boost::shared_ptr*) { return 0; } + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + LUABIND_MAX_BASES, class A, detail::null_type) + > + struct bases + {}; + typedef bases no_bases; + + namespace detail + { + template + struct is_bases + : mpl::false_ + {}; + + template + struct is_bases > + : mpl::true_ + {}; + + template + struct is_unspecified + : mpl::apply1 + {}; + + template + struct is_unspecified + : mpl::true_ + {}; + + template + struct is_unspecified_mfn + { + template + struct apply + : is_unspecified + {}; + }; + + template + struct get_predicate + { + typedef mpl::protect > type; + }; + + template + struct result_or_default + { + typedef Result type; + }; + + template + struct result_or_default + { + typedef Default type; + }; + + template + struct extract_parameter + { + typedef typename get_predicate::type pred; + typedef typename boost::mpl::find_if::type iterator; + typedef typename result_or_default< + typename iterator::type, DefaultValue + >::type type; + }; - namespace detail { // prints the types of the values on the stack, in the // range [start_index, lua_gettop()] LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); - + struct LUABIND_API create_class { static int stage1(lua_State* L); @@ -218,7 +252,7 @@ namespace luabind { private: template void operator,(U const&) const; void operator=(static_scope const&); - + T& self; }; @@ -227,7 +261,7 @@ namespace luabind { struct LUABIND_API class_base : scope { public: - class_base(char const* name); + class_base(char const* name); struct base_desc { @@ -236,10 +270,10 @@ namespace luabind { }; void init( - type_id const& type, class_id id - , type_id const& wrapped_type, class_id wrapper_id); + type_id const& type, class_id id + , type_id const& wrapped_type, class_id wrapper_id); - void add_base(type_id const& base, cast_function cast); + void add_base(type_id const& base, cast_function cast); void add_member(registration* member); void add_default_member(registration* member); @@ -249,15 +283,15 @@ namespace luabind { void add_static_constant(const char* name, int val); void add_inner_scope(scope& s); - void add_cast(class_id src, class_id target, cast_function cast); + void add_cast(class_id src, class_id target, cast_function cast); private: class_registration* m_registration; }; - // MSVC complains about member being sensitive to alignment (C4121) - // when F is a pointer to member of a class with virtual bases. -# ifdef _MSC_VER +// MSVC complains about member being sensitive to alignment (C4121) +// when F is a pointer to member of a class with virtual bases. +# ifdef BOOST_MSVC # pragma pack(push) # pragma pack(16) # endif @@ -265,327 +299,574 @@ namespace luabind { template struct memfun_registration : registration { - memfun_registration(char const* name, F f) - : name(name), f(f) + memfun_registration(char const* name, F f, Policies const& policies) + : name(name) + , f(f) + , policies(policies) {} void register_(lua_State* L) const { - // Need to check if the class type of the signature is a base of this class - object fn = make_function(L, f, deduce_signature_t(), Policies()); - add_overload(object(from_stack(L, -1)), name, fn); + object fn = make_function( + L, f, deduce_signature(f, (Class*)0), policies); + + add_overload( + object(from_stack(L, -1)) + , name + , fn + ); } char const* name; F f; + Policies policies; }; -# ifdef _MSC_VER +# ifdef BOOST_MSVC # pragma pack(pop) # endif - template - struct default_pointer - { - using type = P; - }; + template + struct default_pointer + { + typedef P type; + }; - template - struct default_pointer - { - using type = std::unique_ptr; - }; + template + struct default_pointer + { + typedef std::auto_ptr type; + }; - template - struct constructor_registration : registration - { - constructor_registration() - {} + template + struct constructor_registration : registration + { + constructor_registration(Policies const& policies) + : policies(policies) + {} - void register_(lua_State* L) const - { - using pointer = typename default_pointer::type; - object fn = make_function(L, construct(), Signature(), Policies()); - add_overload(object(from_stack(L, -1)), "__init", fn); - } - }; + void register_(lua_State* L) const + { + typedef typename default_pointer::type pointer; - template - struct reference_result - : std::conditional< std::is_pointer::value || is_primitive::value, T, typename std::add_lvalue_reference< T >::type > - {}; + object fn = make_function( + L + , construct(), Signature() + , policies + ); - template - struct reference_argument - : std::conditional< std::is_pointer::value || is_primitive::value, T, typename std::add_lvalue_reference< typename std::add_const::type >::type > - {}; + add_overload( + object(from_stack(L, -1)) + , "__init" + , fn + ); + } - template - struct inject_dependency_policy - { - using type = typename std::conditional < - is_primitive::value || meta::contains >::value, - Policies, - typename meta::push_back< Policies, call_policy_injector< dependency_policy<0, 1> > >::type - >::type; - }; + Policies policies; + }; - template - struct property_registration : registration - { - property_registration(char const* name, Get const& get, Set const& set = null_type()) - : name(name), get(get), set(set) - {} + template + struct reference_result + : mpl::if_< + mpl::or_, is_primitive > + , T + , typename boost::add_reference::type + > + {}; - template - object make_get(lua_State* L, F const& f, std::false_type /*member_ptr*/) const - { - return make_function(L, f, GetPolicies()); - } + template + struct inject_dependency_policy + : mpl::if_< + is_primitive + , Policies + , policy_cons, Policies> + > + {}; - template - object make_get(lua_State* L, D T::* mem_ptr, std::true_type /*member_ptr*/) const - { - using result_type = typename reference_result::type; - using get_signature = meta::type_list; - using injected_list = typename inject_dependency_policy< D, GetPolicies >::type; + template < + class Class + , class Get, class GetPolicies + , class Set = null_type, class SetPolicies = null_type + > + struct property_registration : registration + { + property_registration( + char const* name + , Get const& get + , GetPolicies const& get_policies + , Set const& set = Set() + , SetPolicies const& set_policies = SetPolicies() + ) + : name(name) + , get(get) + , get_policies(get_policies) + , set(set) + , set_policies(set_policies) + {} - return make_function(L, access_member_ptr(mem_ptr), get_signature(), injected_list()); - } + void register_(lua_State* L) const + { + object context(from_stack(L, -1)); + register_aux( + L + , context + , make_get(L, get, boost::is_member_object_pointer()) + , set + ); + } - template - object make_set(lua_State* L, F const& f, std::false_type /*member_ptr*/) const - { - return make_function(L, f, deduce_signature_t(), SetPolicies()); - } + template + object make_get(lua_State* L, F const& f, mpl::false_) const + { + return make_function( + L, f, deduce_signature(f, (Class*)0), get_policies); + } - template - object make_set(lua_State* L, D T::* mem_ptr, std::true_type /*member_ptr*/) const - { - using argument_type = typename reference_argument::type; - using signature_type = meta::type_list; + template + object make_get(lua_State* L, D T::* mem_ptr, mpl::true_) const + { + typedef typename reference_result::type result_type; + typedef typename inject_dependency_policy< + D, GetPolicies>::type policies; - return make_function(L, access_member_ptr(mem_ptr), signature_type(), SetPolicies()); - } + return make_function( + L + , access_member_ptr(mem_ptr) + , mpl::vector2() + , policies() + ); + } - // if a setter was given - template - void register_aux(lua_State* L, object const& context, object const& get_, SetterType const&) const - { - context[name] = property(get_, make_set(L, set, std::is_member_object_pointer())); - } + template + object make_set(lua_State* L, F const& f, mpl::false_) const + { + return make_function( + L, f, deduce_signature(f, (Class*)0), set_policies); + } - // if no setter was given - void register_aux(lua_State*, object const& context, object const& get_, null_type) const - { - context[name] = property(get_); - } + template + object make_set(lua_State* L, D T::* mem_ptr, mpl::true_) const + { + return make_function( + L + , access_member_ptr(mem_ptr) + , mpl::vector3() + , set_policies + ); + } - // register entry - void register_(lua_State* L) const - { - object context(from_stack(L, -1)); - register_aux(L, context, make_get(L, get, std::is_member_object_pointer()), set); - } + template + void register_aux( + lua_State* L, object const& context + , object const& get_, S const&) const + { + context[name] = property( + get_ + , make_set(L, set, boost::is_member_object_pointer()) + ); + } + void register_aux( + lua_State*, object const& context + , object const& get_, null_type) const + { + context[name] = property(get_); + } - char const* name; - Get get; - Set set; - }; + char const* name; + Get get; + GetPolicies get_policies; + Set set; + SetPolicies set_policies; + }; } // namespace detail // registers a class in the lua environment - template - struct class_ - : detail::class_base + template + struct class_: detail::class_base { - using self_t = class_; - using BaseList = make_bases< BaseOrBases >; + typedef class_ self_t; + private: + + template + class_(const class_&); public: - class_(const char* name) : class_base(name), scope(*this) + + typedef boost::mpl::vector4 parameters_type; + + // WrappedType MUST inherit from T + typedef typename detail::extract_parameter< + parameters_type + , boost::is_base_and_derived + , detail::null_type + >::type WrappedType; + + typedef typename detail::extract_parameter< + parameters_type + , boost::mpl::not_< + boost::mpl::or_< + detail::is_bases + , boost::is_base_and_derived + , boost::is_base_and_derived + > + > + , detail::null_type + >::type HeldType; + + template + void add_downcast(Src*, Target*, boost::mpl::true_) + { + add_cast( + detail::registered_class::id + , detail::registered_class::id + , detail::dynamic_cast_::execute + ); + } + + template + void add_downcast(Src*, Target*, boost::mpl::false_) + {} + + // this function generates conversion information + // in the given class_rep structure. It will be able + // to implicitly cast to the given template type + template + void gen_base_info(detail::type_) + { + add_base(typeid(To), detail::static_cast_::execute); + add_cast( + detail::registered_class::id + , detail::registered_class::id + , detail::static_cast_::execute + ); + + add_downcast((To*)0, (T*)0, boost::is_polymorphic()); + } + + void gen_base_info(detail::type_) + {} + +#define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_()); + + template + void generate_baseclass_list(detail::type_ >) + { + BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _) + } + +#undef LUABIND_GEN_BASE_INFO + + class_(const char* name): class_base(name), scope(*this) { #ifndef NDEBUG detail::check_link_compatibility(); #endif - init(); + init(); + } + + template + class_& def(const char* name, F f) + { + return this->virtual_def( + name, f, detail::null_type() + , detail::null_type(), boost::mpl::true_()); } // virtual functions - template - class_& def(char const* name, F fn, policy_list< Injectors... > policies = no_policies()) + template + class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies) { - return this->virtual_def(name, fn, policies, null_type()); + return this->virtual_def( + name, fn, default_or_policies, detail::null_type() + , LUABIND_MSVC_TYPENAME detail::is_policy_cons::type()); } - // IntelliSense bug squiggles the code, but it does compile! - template - class_& def_nonconst(char const* name, Ret(C::*fn)(Args...), policy_list policies = no_policies()) + template + class_& def(char const* name, F fn + , Default default_, Policies const& policies) { - return def(name, fn, policies); + return this->virtual_def( + name, fn, default_ + , policies, boost::mpl::false_()); } - // IntelliSense bug squiggles the code, but it does compile! - template - class_& def_const(char const* name, Ret(C::*fn)(Args...) const, policy_list policies = no_policies()) + template + class_& def(constructor sig) { - return def(name, fn, policies); + return this->def_constructor(&sig, detail::null_type()); } - template - class_& def(char const* name, F fn, Default default_, policy_list< Injectors... > policies = no_policies()) + template + class_& def(constructor sig, const Policies& policies) { - return this->virtual_def(name, fn, policies, default_); + return this->def_constructor(&sig, policies); } - template - class_& def(constructor sig, policy_list< Injectors... > policies = no_policies()) + template + class_& property(const char* name, Getter g) + { + this->add_member( + new detail::property_registration( + name, g, detail::null_type())); + return *this; + } + + template + class_& property(const char* name, Getter g, MaybeSetter s) + { + return property_impl( + name, g, s + , boost::mpl::bool_::value>() + ); + } + + template + class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies) + { + typedef detail::property_registration< + T, Getter, GetPolicies, Setter, detail::null_type + > registration_type; + + this->add_member( + new registration_type(name, g, get_policies, s)); + return *this; + } + + template + class_& property( + const char* name + , Getter g, Setter s + , GetPolicies const& get_policies + , SetPolicies const& set_policies) + { + typedef detail::property_registration< + T, Getter, GetPolicies, Setter, SetPolicies + > registration_type; + + this->add_member( + new registration_type(name, g, get_policies, s, set_policies)); + return *this; + } + + template + class_& def_readonly(const char* name, D C::*mem_ptr) + { + typedef detail::property_registration + registration_type; + + this->add_member( + new registration_type(name, mem_ptr, detail::null_type())); + return *this; + } + + template + class_& def_readonly(const char* name, D C::*mem_ptr, Policies const& policies) + { + typedef detail::property_registration + registration_type; + + this->add_member( + new registration_type(name, mem_ptr, policies)); + return *this; + } + + template + class_& def_readwrite(const char* name, D C::*mem_ptr) + { + typedef detail::property_registration< + T, D C::*, detail::null_type, D C::* + > registration_type; + + this->add_member( + new registration_type( + name, mem_ptr, detail::null_type(), mem_ptr)); + return *this; + } + + template + class_& def_readwrite( + const char* name, D C::*mem_ptr, GetPolicies const& get_policies) + { + typedef detail::property_registration< + T, D C::*, GetPolicies, D C::* + > registration_type; + + this->add_member( + new registration_type( + name, mem_ptr, get_policies, mem_ptr)); + return *this; + } + + template + class_& def_readwrite( + const char* name + , D C::*mem_ptr + , GetPolicies const& get_policies + , SetPolicies const& set_policies + ) + { + typedef detail::property_registration< + T, D C::*, GetPolicies, D C::*, SetPolicies + > registration_type; + + this->add_member( + new registration_type( + name, mem_ptr, get_policies, mem_ptr, set_policies)); + return *this; + } + + template + class_& def(detail::operator_, Policies const& policies) { - return this->def_constructor(sig, policies); + return this->def( + Derived::name() + , &Derived::template apply::execute + , policies + ); } - // ====================== - // Start of reworked property overloads - // ====================== - - template - class_& property(const char* name, Getter g, policy_list< Injectors... > get_injectors = no_policies()) + template + class_& def(detail::operator_) { - return property(name, g, null_type(), get_injectors); - } - - template - class_& property(const char* name, Getter g, Setter s, policy_list = no_policies(), policy_list = no_policies()) - { - using registration_type = detail::property_registration, Setter, policy_list>; - this->add_member(new registration_type(name, g, s)); - return *this; - } - - template - class_& def_readonly(const char* name, D C::*mem_ptr, policy_list policies = no_policies()) - { - return property(name, mem_ptr, policies); - } - - template - class_& def_readwrite(const char* name, D C::*mem_ptr, policy_list get_injectors = no_policies(), policy_list set_injectors = no_policies()) - { - return property(name, mem_ptr, mem_ptr, get_injectors, set_injectors); - } - - // ===================== - // End of reworked property overloads - // ===================== - - template - class_& def(detail::operator_, policy_list policies = no_policies()) - { - using policy_list_type = policy_list; - return this->def(Derived::name(), &Derived::template apply::execute, policies); + return this->def( + Derived::name() + , &Derived::template apply::execute + ); } detail::enum_maker enum_(const char*) { return detail::enum_maker(*this); } - + detail::static_scope scope; - + private: - void init() - { - class_base::init(typeid(T), detail::registered_class::id, typeid(WrapperType), detail::registered_class::id); - add_wrapper_cast((WrapperType*)0); - generate_baseclass_list(); - } - - - template - class_(const class_&); - - template - void add_downcast(Src*, Target*, std::true_type) - { - add_cast(detail::registered_class::id, detail::registered_class::id, detail::dynamic_cast_::execute); - } - - template - void add_downcast(Src*, Target*, std::false_type) - {} - - // this function generates conversion information - // in the given class_rep structure. It will be able - // to implicitly cast to the given template type - template - void gen_base_info(bases) - { - add_base(typeid(Class0), detail::static_cast_::execute); - add_cast(detail::registered_class::id, detail::registered_class::id, detail::static_cast_::execute); - add_downcast((Class0*)0, (T*)0, std::is_polymorphic()); - gen_base_info(bases()); - } - - void gen_base_info(bases<>) - { - } - - void generate_baseclass_list() - { - gen_base_info(BaseList()); - } - void operator=(class_ const&); - void add_wrapper_cast(null_type*) - {} + void add_wrapper_cast(detail::null_type*) + {} - template - void add_wrapper_cast(U*) + template + void add_wrapper_cast(U*) + { + add_cast( + detail::registered_class::id + , detail::registered_class::id + , detail::static_cast_::execute + ); + + add_downcast((T*)0, (U*)0, boost::is_polymorphic()); + } + + void init() { - add_cast(detail::registered_class::id, detail::registered_class::id, detail::static_cast_::execute); - add_downcast((T*)0, (U*)0, std::is_polymorphic()); + typedef typename detail::extract_parameter< + parameters_type + , boost::mpl::or_< + detail::is_bases + , boost::is_base_and_derived + > + , no_bases + >::type bases_t; + + typedef typename + boost::mpl::if_ + , bases_t + , bases + >::type Base; + + class_base::init( + typeid(T) + , detail::registered_class::id + , typeid(WrappedType) + , detail::registered_class::id + ); + + add_wrapper_cast((WrappedType*)0); + + generate_baseclass_list(detail::type_()); + } + + template + class_& property_impl(const char* name, + Getter g, + GetPolicies policies, + boost::mpl::bool_) + { + this->add_member( + new detail::property_registration( + name, g, policies)); + return *this; + } + + template + class_& property_impl(const char* name, + Getter g, + Setter s, + boost::mpl::bool_) + { + typedef detail::property_registration< + T, Getter, detail::null_type, Setter, detail::null_type + > registration_type; + + this->add_member( + new registration_type(name, g, detail::null_type(), s)); + return *this; } // these handle default implementation of virtual functions - template - class_& virtual_def(char const* name, F const& fn, policy_list< Injectors... >, Default default_) + template + class_& virtual_def(char const* name, F const& fn + , Policies const&, detail::null_type, boost::mpl::true_) { - using policy_list_type = policy_list< Injectors... >; - this->add_member(new detail::memfun_registration(name, fn)); - this->add_default_member(new detail::memfun_registration(name, default_)); + this->add_member( + new detail::memfun_registration( + name, fn, Policies())); return *this; } - template - class_& virtual_def(char const* name, F const& fn, policy_list< Injectors... >, null_type) + template + class_& virtual_def(char const* name, F const& fn + , Default const& default_, Policies const&, boost::mpl::false_) { - using policy_list_type = policy_list< Injectors... >; - this->add_member(new detail::memfun_registration(name, fn)); + this->add_member( + new detail::memfun_registration( + name, fn, Policies())); + + this->add_default_member( + new detail::memfun_registration( + name, default_, Policies())); + return *this; } - template - class_& def_constructor(constructor const&, policy_list< Injectors... > const&) - { - using signature_type = meta::type_list; - using policy_list_type = policy_list< Injectors... >; + template + class_& def_constructor(Signature*, Policies const&) + { + typedef typename Signature::signature signature; - using construct_type = typename std::conditional< - is_null_type::value, - T, - WrapperType - >::type; + typedef typename boost::mpl::if_< + boost::is_same + , T + , WrappedType + >::type construct_type; - using registration_type = detail::constructor_registration; - this->add_member(new registration_type()); - this->add_default_member(new registration_type()); + this->add_member( + new detail::constructor_registration< + construct_type, HeldType, signature, Policies>( + Policies())); - return *this; - } + this->add_default_member( + new detail::constructor_registration< + construct_type, HeldType, signature, Policies>( + Policies())); + + return *this; + } }; } diff --git a/libs/luabind/luabind/class_info.hpp b/libs/luabind/luabind/class_info.hpp index d779f250b..a4f18a8cc 100644 --- a/libs/luabind/luabind/class_info.hpp +++ b/libs/luabind/luabind/class_info.hpp @@ -20,6 +20,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. + #ifndef LUABIND_CLASS_INFO_HPP_INCLUDED #define LUABIND_CLASS_INFO_HPP_INCLUDED @@ -31,16 +32,16 @@ namespace luabind { struct LUABIND_API class_info - { + { std::string name; object methods; object attributes; }; - LUABIND_API class_info get_class_info(argument const&); + LUABIND_API class_info get_class_info(argument const&); - // returns a table of bound class names - LUABIND_API object get_class_names(lua_State* L); + // returns a table of bound class names + LUABIND_API object get_class_names(lua_State* L); LUABIND_API void bind_class_info(lua_State*); } diff --git a/libs/luabind/luabind/config.hpp b/libs/luabind/luabind/config.hpp index e91c867de..e8eea875c 100644 --- a/libs/luabind/luabind/config.hpp +++ b/libs/luabind/luabind/config.hpp @@ -20,26 +20,57 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. + #ifndef LUABIND_CONFIG_HPP_INCLUDED #define LUABIND_CONFIG_HPP_INCLUDED +#include + +#ifdef BOOST_MSVC + #define LUABIND_ANONYMOUS_FIX static +#else + #define LUABIND_ANONYMOUS_FIX +#endif + +#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1200) + +#define for if (false) {} else for + +#include + +namespace std +{ + using ::strlen; + using ::strcmp; + using ::type_info; +} + +#endif + + +#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1300) + #define LUABIND_MSVC_TYPENAME +#else + #define LUABIND_MSVC_TYPENAME typename +#endif + // the maximum number of arguments of functions that's // registered. Must at least be 2 #ifndef LUABIND_MAX_ARITY -#define LUABIND_MAX_ARITY 100 + #define LUABIND_MAX_ARITY 10 #elif LUABIND_MAX_ARITY <= 1 -#undef LUABIND_MAX_ARITY -#define LUABIND_MAX_ARITY 2 + #undef LUABIND_MAX_ARITY + #define LUABIND_MAX_ARITY 2 #endif // the maximum number of classes one class // can derive from // max bases must at least be 1 #ifndef LUABIND_MAX_BASES -#define LUABIND_MAX_BASES 100 + #define LUABIND_MAX_BASES 4 #elif LUABIND_MAX_BASES <= 0 -#undef LUABIND_MAX_BASES -#define LUABIND_MAX_BASES 1 + #undef LUABIND_MAX_BASES + #define LUABIND_MAX_BASES 1 #endif // LUABIND_NO_ERROR_CHECKING @@ -70,18 +101,12 @@ // C code has undefined behavior, lua is written in C). #ifdef LUABIND_DYNAMIC_LINK -# if defined (_WIN32) +# ifdef BOOST_WINDOWS # ifdef LUABIND_BUILDING # define LUABIND_API __declspec(dllexport) # else # define LUABIND_API __declspec(dllimport) # endif -# elif defined (__CYGWIN__) -# ifdef LUABIND_BUILDING -# define LUABIND_API __attribute__ ((dllexport)) -# else -# define LUABIND_API __attribute__ ((dllimport)) -# endif # else # if defined(_GNUC_) && _GNUC_ >=4 # define LUABIND_API __attribute__ ((visibility("default"))) @@ -93,19 +118,9 @@ # define LUABIND_API #endif -// This switches between using tag arguments / structure specialization for code size tests -#define LUABIND_NO_INTERNAL_TAG_ARGUMENTS - namespace luabind { - LUABIND_API void disable_super_deprecation(); - - namespace detail { - const int max_argument_count = 100; - const int max_hierarchy_depth = 100; - } - - const int no_match = -(detail::max_argument_count*detail::max_hierarchy_depth + 1); +LUABIND_API void disable_super_deprecation(); } // namespace luabind diff --git a/libs/luabind/luabind/container_policy.hpp b/libs/luabind/luabind/container_policy.hpp index 460096abb..68ad0a90f 100644 --- a/libs/luabind/luabind/container_policy.hpp +++ b/libs/luabind/luabind/container_policy.hpp @@ -20,111 +20,124 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. + #ifndef LUABIND_CONTAINER_POLICY_HPP_INCLUDED #define LUABIND_CONTAINER_POLICY_HPP_INCLUDED #include #include -#include // for decorated_type -#include // for null_type (ptr only), etc +#include -namespace luabind { - namespace detail { +namespace luabind { namespace detail { - template - struct container_converter_lua_to_cpp + namespace mpl = boost::mpl; + + template + struct container_converter_lua_to_cpp + { + int const consumed_args(...) + { + return 1; + } + + template + T apply(lua_State* L, by_const_reference, int index) { - enum { consumed_args = 1 }; + typedef typename T::value_type value_type; - template - T to_cpp(lua_State* L, by_const_reference, int index) + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + + T container; + + lua_pushnil(L); + while (lua_next(L, index)) { - using value_type = typename T::value_type; - specialized_converter_policy_n<1, Policies, value_type, lua_to_cpp> converter; - - T container; - - lua_pushnil(L); - while(lua_next(L, index - 1)) - { - container.push_back(converter.apply(L, decorated_type(), -1)); - lua_pop(L, 1); // pop value - } - - return container; + container.push_back(converter.apply(L, LUABIND_DECORATE_TYPE(value_type), -1)); + lua_pop(L, 1); // pop value } - template - T to_cpp(lua_State* L, by_value, int index) - { - return to_cpp(L, by_const_reference(), index); - } + return container; + } - template - static int match(lua_State* L, by_const_reference, int index) - { - if(lua_istable(L, index)) return 0; else return no_match; - } - - template - static int match(lua_State* L, by_value, int index) - { - return match(L, by_const_reference(), index); - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - template - struct container_converter_cpp_to_lua + template + T apply(lua_State* L, by_value, int index) { - template - void to_lua(lua_State* L, const T& container) - { - using value_type = typename T::value_type; - specialized_converter_policy_n<1, Policies, value_type, lua_to_cpp> converter; + return apply(L, by_const_reference(), index); + } - lua_newtable(L); - - int index = 1; - - for(const auto& element : container) - { - converter.apply(L, element); - lua_rawseti(L, -2, index); - ++index; - } - } - }; - - template - struct container_policy + template + static int match(lua_State* L, by_const_reference, int index) { - struct only_accepts_nonconst_pointers {}; + if (lua_istable(L, index)) return 0; else return -1; + } - template - struct specialize; + template + void converter_postcall(lua_State*, T, int) {} + }; - template - struct specialize { - using type = container_converter_lua_to_cpp; - }; + template + struct container_converter_cpp_to_lua + { + template + void apply(lua_State* L, const T& container) + { + typedef typename T::value_type value_type; - template - struct specialize { - using type = container_converter_cpp_to_lua; - }; + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + + lua_newtable(L); + + int index = 1; + + for (typename T::const_iterator i = container.begin(); i != container.end(); ++i) + { + converter.apply(L, *i); + lua_rawseti(L, -2, index); + ++index; + } + } + }; + + template +// struct container_policy : converter_policy_tag + struct container_policy : conversion_policy + { +// BOOST_STATIC_CONSTANT(int, index = N); + + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + + struct only_accepts_nonconst_pointers {}; + + template + struct apply + { + typedef typename boost::mpl::if_ + , container_converter_lua_to_cpp + , container_converter_cpp_to_lua + >::type type; }; + }; - } -} +}} namespace luabind { - template - using container_policy = meta::type_list>>; + template + detail::policy_cons, detail::null_type> + container(LUABIND_PLACEHOLDER_ARG(N)) + { + return detail::policy_cons, detail::null_type>(); + } + + template + detail::policy_cons, detail::null_type> + container(LUABIND_PLACEHOLDER_ARG(N), const Policies&) + { + return detail::policy_cons, detail::null_type>(); + } } #endif // LUABIND_CONTAINER_POLICY_HPP_INCLUDED - diff --git a/libs/luabind/luabind/copy_policy.hpp b/libs/luabind/luabind/copy_policy.hpp index 7115a4511..1a18b729b 100644 --- a/libs/luabind/luabind/copy_policy.hpp +++ b/libs/luabind/luabind/copy_policy.hpp @@ -8,41 +8,52 @@ # include namespace luabind { - namespace detail { - struct copy_converter - { - template - void to_lua(lua_State* L, T const& x) - { - value_converter().to_lua(L, x); - } +namespace detail +{ - template - void to_lua(lua_State* L, T* x) - { - if(!x) - lua_pushnil(L); - else - to_lua(L, *x); - } - }; + struct copy_converter + { + template + void apply(lua_State* L, T const& x) + { + value_converter().apply(L, x); + } - struct copy_policy - { - template - struct specialize - { - static_assert(std::is_same::value, "Copy policy only supports cpp -> lua"); - using type = copy_converter; - }; - }; + template + void apply(lua_State* L, T* x) + { + if (!x) + lua_pushnil(L); + else + apply(L, *x); + } + }; - } // namespace detail + template + struct copy_policy : conversion_policy + { + static void precall(lua_State*, index_map const&) + {} - // Caution: If we use the aliased type "policy_list" here, MSVC crashes. - template< unsigned int N > - using copy_policy = meta::type_list< converter_policy_injector< N, detail::copy_policy > >; + static void postcall(lua_State*, index_map const&) + {} + + template + struct apply + { + typedef copy_converter type; + }; + }; + +} // namespace detail + +template +detail::policy_cons, detail::null_type> +copy(LUABIND_PLACEHOLDER_ARG(N)) +{ + return detail::policy_cons, detail::null_type>(); +} } // namespace luabind diff --git a/libs/luabind/luabind/dependency_policy.hpp b/libs/luabind/luabind/dependency_policy.hpp index c16db1605..cafa49aa1 100644 --- a/libs/luabind/luabind/dependency_policy.hpp +++ b/libs/luabind/luabind/dependency_policy.hpp @@ -25,75 +25,95 @@ #define LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED #include -#include // for policy_cons, etc -#include // for object_rep -#include // for null_type +#include -namespace luabind { - namespace detail { - - // makes A dependent on B, meaning B will outlive A. - // internally A stores a reference to B - template - struct dependency_policy +namespace luabind { namespace detail +{ + // makes A dependent on B, meaning B will outlive A. + // internally A stores a reference to B + template + struct dependency_policy + { + static void postcall(lua_State* L, const index_map& indices) { - template< unsigned int... StackIndices > - static void postcall(lua_State* L, int results, meta::index_list) - { - object_rep* nurse = static_cast(lua_touserdata(L, meta::get, A>::value)); + int nurse_index = indices[A]; + int patient = indices[B]; - // If the nurse isn't an object_rep, just make this a nop. - if(nurse == 0) - return; + object_rep* nurse = static_cast(lua_touserdata(L, nurse_index)); - nurse->add_dependency(L, meta::get, B>::value); - } - }; + // If the nurse isn't an object_rep, just make this a nop. + if (nurse == 0) + return; - template - struct dependency_policy<0, B> - { - template< unsigned int... StackIndices > - static void postcall(lua_State* L, int results, meta::index_list) - { - object_rep* nurse = static_cast(lua_touserdata(L, meta::get, 0>::value + results)); + nurse->add_dependency(L, patient); + } + }; - // If the nurse isn't an object_rep, just make this a nop. - if(nurse == 0) - return; +}} - nurse->add_dependency(L, meta::get, B>::value); - } - }; - - template - struct dependency_policy - { - template< unsigned int... StackIndices > - static void postcall(lua_State* L, int results, meta::index_list) - { - object_rep* nurse = static_cast(lua_touserdata(L, meta::get, A>::value)); - - // If the nurse isn't an object_rep, just make this a nop. - if(nurse == 0) - return; - - nurse->add_dependency(L, meta::get, 0>::value + results); - } - }; - - } -} +#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1200) namespace luabind { - // Caution: If we use the aliased type "policy_list" here, MSVC crashes. - template - using dependency_policy = meta::type_list>>; + // most absurd workaround of all time? + namespace detail + { + template + struct size_char_array + { + char storage[N + 2]; + }; - template - using return_internal_reference = meta::type_list>>; + template + size_char_array deduce_size(LUABIND_PLACEHOLDER_ARG(N)); + + template + struct get_index_workaround + { + static T t; + BOOST_STATIC_CONSTANT(int, value = sizeof(deduce_size(t)) - 2); + }; + } + + template + detail::policy_cons::value + , detail::get_index_workaround::value>, detail::null_type> dependency(A,B) + { + return detail::policy_cons::value, detail::get_index_workaround::value> + , detail::null_type>(); + } + + template + detail::policy_cons::value>, detail::null_type> + return_internal_reference(A) + { + return detail::policy_cons::value>, detail::null_type>(); + } } +#else + +namespace luabind +{ + template + detail::policy_cons, detail::null_type> + dependency(LUABIND_PLACEHOLDER_ARG(A), LUABIND_PLACEHOLDER_ARG(B)) + { + return detail::policy_cons, detail::null_type>(); + } + + template + detail::policy_cons, detail::null_type> + return_internal_reference(LUABIND_PLACEHOLDER_ARG(A)) + { + return detail::policy_cons, detail::null_type>(); + } +} + +#endif + #endif // LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/call_shared.hpp b/libs/luabind/luabind/detail/calc_arity.hpp similarity index 53% rename from libs/luabind/luabind/detail/call_shared.hpp rename to libs/luabind/luabind/detail/calc_arity.hpp index 9b33973aa..c2e0aad91 100644 --- a/libs/luabind/luabind/detail/call_shared.hpp +++ b/libs/luabind/luabind/detail/calc_arity.hpp @@ -20,46 +20,42 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef LUABIND_CALL_SHARED_HPP_INCLUDED -#define LUABIND_CALL_SHARED_HPP_INCLUDED +#if !BOOST_PP_IS_ITERATING -namespace luabind { - namespace detail { +# include - inline void call_error(lua_State* L) +#ifndef LUABIND_CALC_ARITY_HPP_INCLUDED +#define LUABIND_CALC_ARITY_HPP_INCLUDED + +#define LUABIND_FIND_CONV(z,n,text) typedef typename find_conversion_policy::type p##n; +#define LUABIND_CALC_ARITY(z,n,text) + BOOST_PP_CAT(p,n)::has_arg + +namespace luabind { namespace detail +{ + template struct calc_arity; + + #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) + #include BOOST_PP_ITERATE() +}} + +#undef LUABIND_CALC_ARITY +#undef LUABIND_FIND_CONV + + +#endif // LUABIND_CALC_ARITY_HPP_INCLUDED + +#else // BOOST_PP_ITERATE + + template<> + struct calc_arity + { + template + static int apply(constructor, Policies*) { -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if(e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); -#endif + BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_FIND_CONV, _) + return 0 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_CALC_ARITY, _); } - - template - void cast_error(lua_State* L) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(L, typeid(T)); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if(e) e(L, typeid(T)); - - assert(0 && "the lua function's return value could not be converted." - " If you want to handle the error you can use luabind::set_cast_failed_callback()"); - std::terminate(); -#endif - } - - template< typename... Args > - void expand_hack(Args... /*args*/) - {} - - } -} + }; #endif + diff --git a/libs/luabind/luabind/detail/call.hpp b/libs/luabind/luabind/detail/call.hpp index 94dbb8d4d..cd9402ef3 100644 --- a/libs/luabind/luabind/detail/call.hpp +++ b/libs/luabind/luabind/detail/call.hpp @@ -1,547 +1,323 @@ -// Copyright Daniel Wallin 208.Use, modification and distribution is +// Copyright Daniel Wallin 2008. Use, modification and distribution is // subject to 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) -#ifndef LUABIND_CALL2_080911_HPP -#define LUABIND_CALL2_080911_HPP - -#include -#include -#include -#include -#include -#include -#include - -#ifdef LUABIND_NO_INTERNAL_TAG_ARGUMENTS -#include -#endif - -namespace luabind { - namespace detail { - - struct invoke_context; - - struct LUABIND_API function_object - { - function_object(lua_CFunction entry) - : entry(entry) - , next(0) - {} - - virtual ~function_object() - {} - - virtual int call(lua_State* L, invoke_context& ctx) /* const */ = 0; - virtual void format_signature(lua_State* L, char const* function) const = 0; - - lua_CFunction entry; - std::string name; - function_object* next; - object keepalive; - }; - - struct LUABIND_API invoke_context - { - invoke_context() - : best_score((std::numeric_limits::max)()) - //This need to avoid static analyzer's treats - , candidates{ nullptr,nullptr,nullptr,nullptr,nullptr, - nullptr,nullptr,nullptr,nullptr,nullptr } - , candidate_index(0) - {} - - operator bool() const - { - return candidate_index == 1; - } - - void format_error(lua_State* L, function_object const* overloads) const; - - int best_score; - function_object const* candidates[10]; // This looks like it could crash if you provide too many overloads? - int candidate_index; - }; - - namespace call_detail_new { - - /* - Compute Stack Indices - Given the list of argument converter arities, computes the stack indices that each converter addresses. - */ - - template< typename ConsumedList, unsigned int CurrentSum, unsigned int... StackIndices > - struct compute_stack_indices; - - template< unsigned int Consumed0, unsigned int... Consumeds, unsigned int CurrentSum, unsigned int... StackIndices > - struct compute_stack_indices< meta::index_list< Consumed0, Consumeds... >, CurrentSum, StackIndices... > - { - using type = typename compute_stack_indices< meta::index_list< Consumeds... >, CurrentSum + Consumed0, StackIndices..., CurrentSum >::type; - }; - - template< unsigned int CurrentSum, unsigned int... StackIndices > - struct compute_stack_indices< meta::index_list< >, CurrentSum, StackIndices... > - { - using type = meta::index_list< StackIndices... >; - }; - - template< typename Foo > - struct FooFoo { // Foo! - enum { consumed_args = Foo::consumed_args }; - }; - - - template< typename PolicyList, typename StackIndexList > - struct policy_list_postcall; - - template< typename Policy0, typename... Policies, typename StackIndexList > - struct policy_list_postcall< meta::type_list< call_policy_injector, Policies... >, StackIndexList > { - static void postcall(lua_State* L, int results) { - Policy0::postcall(L, results, StackIndexList()); - policy_list_postcall< meta::type_list< Policies... >, StackIndexList >::postcall(L, results); - } - }; - - template< typename ConverterPolicy, typename StackIndexList, bool has_postcall > - struct converter_policy_postcall { - static void postcall(lua_State* L, int results) { - ConverterPolicy::postcall(L, results, StackIndexList()); - } - }; - - template< typename ConverterPolicy, typename StackIndexList > - struct converter_policy_postcall< ConverterPolicy, StackIndexList, false > { - static void postcall(lua_State* /*L*/, int /*results*/) { - } - }; - - template< unsigned int Index, typename Policy, typename... Policies, typename StackIndexList > - struct policy_list_postcall< meta::type_list< converter_policy_injector< Index, Policy >, Policies... >, StackIndexList > { - static void postcall(lua_State* L, int results) { - converter_policy_postcall < Policy, StackIndexList, converter_policy_injector< Index, Policy >::has_postcall >::postcall(L, results); - policy_list_postcall< meta::type_list< Policies... >, StackIndexList >::postcall(L, results); - } - }; - - template< typename StackIndexList > - struct policy_list_postcall< meta::type_list< >, StackIndexList > { - static void postcall(lua_State* /*L*/, int /*results*/) {} - }; - -#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS - template< typename... ArgumentConverters > - struct compute_invoke_values { - using consumed_list = meta::index_list< FooFoo::consumed_args... >; - using stack_index_list = typename compute_stack_indices< consumed_list, 1 >::type; - enum { arity = meta::sum::value }; - }; -#endif - - - } - -#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS - inline int match_deferred(lua_State* L, meta::index_list<>, meta::type_list<>) - { - return 0; - } - - template< unsigned int StackIndex0, unsigned int... StackIndices, - typename ArgumentType0, typename... ArgumentTypes, - typename ArgumentConverter0, typename... ArgumentConverters > - int match_deferred(lua_State* L, - meta::index_list< StackIndex0, StackIndices... >, - meta::type_list< ArgumentType0, ArgumentTypes... >, - ArgumentConverter0& converter0, ArgumentConverters&... converters - ) - { - const int this_match = converter0.match(L, decorated_type(), StackIndex0); - const int other_match = match_deferred(L, meta::index_list(), meta::type_list(), converters...); - return (this_match >= 0) ? // could also sum them all up unconditionally - this_match + match_deferred(L, meta::index_list(), meta::type_list(), converters...) - : no_match; - } - - template< typename T, bool isvoid, bool memfun = std::is_member_function_pointer::value > struct do_call_struct; - - template< typename T > - struct do_call_struct< T, true, true /*memfun*/> { - template< typename F, typename ArgumentType0, typename... ArgumentTypes, unsigned int StackIndex0, unsigned int... StackIndices, typename ReturnConverter, typename Argument0Converter, typename... ArgumentConverters > - static void do_call(lua_State* L, F& f, - meta::index_list, meta::type_list, - ReturnConverter& result_converter, Argument0Converter& arg0_converter, ArgumentConverters&... arg_converters - ) - { - ((arg0_converter.to_cpp(L, decorated_type(), StackIndex0)).*f)( - arg_converters.to_cpp(L, decorated_type(), StackIndices)... - ); - } - }; - - template< typename T > - struct do_call_struct< T, false, true /*memfun*/> { - template< typename F, typename ArgumentType0, typename... ArgumentTypes, unsigned int StackIndex0, unsigned int... StackIndices, typename ReturnConverter, typename Argument0Converter, typename... ArgumentConverters > - static void do_call(lua_State* L, F& f, - meta::index_list, meta::type_list, - ReturnConverter& result_converter, Argument0Converter& arg0_converter, ArgumentConverters&... arg_converters - ) - { - result_converter.to_lua(L, - ((arg0_converter.to_cpp(L, decorated_type(), StackIndex0)).*f)( - arg_converters.to_cpp(L, decorated_type(), StackIndices)... - ) - ); - } - }; - - - template< typename T > - struct do_call_struct< T, true, false > { - template< - typename F, - typename... ArgumentTypes, unsigned int... StackIndices, - typename ReturnConverter, typename... ArgumentConverters - > - static void do_call(lua_State* L, F& f, - meta::index_list, meta::type_list, - ReturnConverter& result_converter, ArgumentConverters&... arg_converters) - { - f(arg_converters.to_cpp(L, decorated_type(), StackIndices)...); - } - }; - - template< typename T > - struct do_call_struct< T, false, false > { - template< - typename F, - typename... ArgumentTypes, unsigned int... StackIndices, - typename ReturnConverter, typename... ArgumentConverters - > - static void do_call(lua_State* L, F& f, - meta::index_list, meta::type_list, - ReturnConverter& result_converter, ArgumentConverters&... arg_converters) - { - result_converter.to_lua(L, - f(arg_converters.to_cpp(L, decorated_type(), StackIndices)...) - ); - } - }; - - template< typename F, typename ReturnType, typename... Arguments, - typename ReturnConverter, typename... ArgumentConverters, - unsigned int Index0, unsigned int... Indices, typename PolicyList - > - int invoke3(lua_State* L, function_object const& self, invoke_context& ctx, F& f, - PolicyList, meta::index_list< Index0, Indices... > index_list, meta::type_list signature_list, - ReturnConverter return_converter, ArgumentConverters... argument_converters) - { - using invoke_values = typename call_detail_new::compute_invoke_values< ArgumentConverters... >; - using argument_list_type = meta::type_list; - using argument_index_list = meta::index_list; - - int const arguments = lua_gettop(L); - int score = no_match; - - if(invoke_values::arity == arguments) { - score = match_deferred(L, typename invoke_values::stack_index_list(), argument_list_type(), argument_converters...); - } - - if(score >= 0 && score < ctx.best_score) { - ctx.best_score = score; - ctx.candidates[0] = &self; - ctx.candidate_index = 1; - } else if(score == ctx.best_score) { - ctx.candidates[ctx.candidate_index++] = &self; - } - - int results = 0; - - if(self.next) - { - results = self.next->call(L, ctx); - } - - if(score == ctx.best_score && ctx.candidate_index == 1) - { - do_call_struct::value>::do_call(L, f, typename invoke_values::stack_index_list(), argument_list_type(), return_converter, argument_converters...); - meta::init_order{ (argument_converters.converter_postcall(L, decorated_type(), meta::get< typename invoke_values::stack_index_list, Indices - 1 >::value), 0)... }; - - results = lua_gettop(L) - invoke_values::arity; - if(has_call_policy::value) { - results = lua_yield(L, results); - } - - // call policiy list postcall - call_detail_new::policy_list_postcall < PolicyList, typename meta::push_front< typename invoke_values::stack_index_list, meta::index >::type >::postcall(L, results); - } - - return results; - } - - template< typename F, typename ReturnType, typename... Arguments, unsigned int Index0, unsigned int... Indices, typename PolicyList > - int invoke2(lua_State* L, function_object const& self, invoke_context& ctx, F& f, - meta::type_list signature, meta::index_list, PolicyList) - { - using signature_type = meta::type_list; - using return_converter = specialized_converter_policy_n<0, PolicyList, ReturnType, cpp_to_lua>; - return invoke3(L, self, ctx, f, - PolicyList(), meta::index_list(), signature, - return_converter(), specialized_converter_policy_n()... - ); - } - - - template - // boost::bind's operator() is const, std::bind's is not - inline int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f, Signature, - meta::type_list< PolicyInjectors... > const& injectors) - { - return invoke2(L, self, ctx, f, Signature(), typename meta::make_index_range<0, meta::size::value>::type(), injectors); - } -#endif - -#ifdef LUABIND_NO_INTERNAL_TAG_ARGUMENTS - - // VC2013RC doesn't support expanding a template and its member template in one expression, that's why we have to to incrementally build - // the converter list instead of a single combined expansion. - template< typename ArgumentList, typename PolicyList, typename CurrentList = meta::type_list<>, unsigned int Counter = 1 > - struct compute_argument_converter_list; - - template< typename Argument0, typename... Arguments, typename PolicyList, typename... CurrentConverters, unsigned int Counter > - struct compute_argument_converter_list< meta::type_list, PolicyList, meta::type_list, Counter > - { - using converter_type = typename policy_detail::get_converter_policy::type; - using this_specialized = typename converter_type::template specialize::type; - using type = typename compute_argument_converter_list, PolicyList, meta::type_list, Counter + 1>::type; - }; - - template - struct compute_argument_converter_list< meta::type_list<>, PolicyList, meta::type_list, Counter > - { - using type = meta::type_list; - }; - - template< typename ConverterList > - struct build_consumed_list; - - template< typename... Converters > - struct build_consumed_list< meta::type_list< Converters... > > { - using consumed_list = meta::index_list< call_detail_new::FooFoo::consumed_args... >; - }; - - template< typename SignatureList, typename PolicyList > - struct invoke_traits; - - // Specialization for free functions - template< typename ResultType, typename... Arguments, typename PolicyList > - struct invoke_traits< meta::type_list, PolicyList > - { - using signature_list = meta::type_list; - using policy_list = PolicyList; - using result_type = ResultType; - using result_converter = specialized_converter_policy_n<0, PolicyList, result_type, cpp_to_lua >; - using argument_list = meta::type_list; - - using decorated_argument_list = meta::type_list< decorate_type_t... >; - // note that this is 0-based, so whenever you want to fetch from the converter list, you need to add 1 - using argument_index_list = typename meta::make_index_range< 0, sizeof...(Arguments) >::type; - using argument_converter_list = typename compute_argument_converter_list::type; - using argument_converter_tuple_type = typename meta::make_tuple::type; - using consumed_list = typename build_consumed_list::consumed_list; - using stack_index_list = typename call_detail_new::compute_stack_indices< consumed_list, 1 >::type; - enum { arity = meta::sum::value }; - }; - - template< typename StackIndexList, typename SignatureList, unsigned int End = meta::size::value, unsigned int Index = 1 > - struct match_struct { - template< typename TupleType > - static int match(lua_State* L, TupleType& tuple) - { - const int this_match = std::get(tuple).match(L, decorate_type_t>(), meta::get::value); - return this_match >= 0 ? // could also sum them up unconditionally - this_match + match_struct::match(L, tuple) - : no_match; - } - }; - - template< typename StackIndexList, typename SignatureList, unsigned int Index > - struct match_struct< StackIndexList, SignatureList, Index, Index > - { - template< typename TupleType > - static int match(lua_State* /*L*/, TupleType&) { - return 0; - } - }; - - template< typename PolicyList, typename Signature, typename F > - struct invoke_struct - { - using traits = invoke_traits< Signature, PolicyList >; - - template< bool IsMember, bool IsVoid, typename IndexList > - struct call_struct; - - template< unsigned int... ArgumentIndices > - struct call_struct< false /*member*/, false /*void*/, meta::index_list > - { - static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple) - { - using decorated_list = typename traits::decorated_argument_list; - using stack_indices = typename traits::stack_index_list; - using result_converter = typename traits::result_converter; - - result_converter().to_lua(L, - f((std::get(argument_tuple).to_cpp(L, - typename meta::get::type(), - meta::get::value))... - ) - ); - - meta::init_order{ - (std::get(argument_tuple).converter_postcall(L, - typename meta::get::type(), - meta::get::value), 0)... - }; - } - }; - - template< unsigned int... ArgumentIndices > - struct call_struct< false /*member*/, true /*void*/, meta::index_list > - { - static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple) - { - using decorated_list = typename traits::decorated_argument_list; - using stack_indices = typename traits::stack_index_list; - - // This prevents unused warnings with empty parameter lists - (void)L; - - f(std::get(argument_tuple).to_cpp(L, - typename meta::get::type(), - meta::get::value)... - - ); - - meta::init_order{ - (std::get(argument_tuple).converter_postcall(L, - typename meta::get::type(), - meta::get::value), 0)... - }; - } - }; - - template< unsigned int ClassIndex, unsigned int... ArgumentIndices > - struct call_struct< true /*member*/, false /*void*/, meta::index_list > - { - static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple) - { - using decorated_list = typename traits::decorated_argument_list; - using stack_indices = typename traits::stack_index_list; - using result_converter = typename traits::result_converter; - - auto& object = std::get<0>(argument_tuple).to_cpp(L, - typename meta::get::type(), 1); - - result_converter().to_lua(L, - (object.*f)(std::get(argument_tuple).to_cpp(L, - typename meta::get::type(), - meta::get::value)... - ) - ); - - meta::init_order{ - (std::get(argument_tuple).converter_postcall(L, - typename meta::get::type(), - meta::get::value), 0)... - }; - } - }; - - template< unsigned int ClassIndex, unsigned int... ArgumentIndices > - struct call_struct< true /*member*/, true /*void*/, meta::index_list > - { - static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple) - { - using decorated_list = typename traits::decorated_argument_list; - using stack_indices = typename traits::stack_index_list; - - auto& object = std::get<0>(argument_tuple).to_cpp(L, typename meta::get::type(), 1); - - (object.*f)(std::get(argument_tuple).to_cpp(L, - typename meta::get::type(), - meta::get::value)... - ); - - meta::init_order{ - (std::get(argument_tuple).converter_postcall(L, - typename meta::get::type(), - meta::get::value), 0)... - }; - } - }; - - static int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f) { - int const arguments = lua_gettop(L); - int score = no_match; - - // Even match needs the tuple, since pointer_converters buffer the cast result - typename traits::argument_converter_tuple_type converter_tuple; - - if(traits::arity == arguments) { - // Things to remember: - // 0 is the perfect match. match > 0 means that objects had to be casted, where the value - // is the total distance of all arguments to their given types (graph distance). - // This is why we can say MaxArguments = 100, MaxDerivationDepth = 100, so no match will be > 100*100=10k and -10k1 absorbs every match. - // This gets rid of the awkward checks during converter match traversal. - using struct_type = match_struct< typename traits::stack_index_list, typename traits::signature_list >; - score = struct_type::match(L, converter_tuple); - } - - if(score >= 0 && score < ctx.best_score) { - ctx.best_score = score; - ctx.candidates[0] = &self; - ctx.candidate_index = 1; - } else if(score == ctx.best_score) { - ctx.candidates[ctx.candidate_index++] = &self; - } - - int results = 0; - - if(self.next) - { - results = self.next->call(L, ctx); - } - - if(score == ctx.best_score && ctx.candidate_index == 1) - { - call_struct< - std::is_member_function_pointer::value, - std::is_void::value, - typename traits::argument_index_list - >::call(L, f, converter_tuple); - - results = lua_gettop(L) - traits::arity; - if(has_call_policy::value) { - results = lua_yield(L, results); - } - - call_detail_new::policy_list_postcall < PolicyList, typename meta::push_front< typename traits::stack_index_list, meta::index >::type >::postcall(L, results); - } - - return results; - } - - }; - - template< typename PolicyList, typename Signature, typename F> - inline int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f) - { - return invoke_struct::invoke(L, self, ctx, f); - } -#endif - - } -} // namespace luabind::detail +#if !BOOST_PP_IS_ITERATING + +# ifndef LUABIND_CALL2_080911_HPP +# define LUABIND_CALL2_080911_HPP + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include +# include +# include + +namespace luabind { namespace detail { + +struct invoke_context; + +struct LUABIND_API function_object +{ + function_object(lua_CFunction entry) + : entry(entry) + , next(0) + {} + + virtual ~function_object() + {} + + virtual int call( + lua_State* L, invoke_context& ctx) const = 0; + virtual void format_signature(lua_State* L, char const* function) const = 0; + + lua_CFunction entry; + std::string name; + function_object* next; + object keepalive; +}; + +struct LUABIND_API invoke_context +{ + invoke_context() + : best_score((std::numeric_limits::max)()) + , candidate_index(0) + {} + + operator bool() const + { + return candidate_index == 1; + } + + void format_error(lua_State* L, function_object const* overloads) const; + + int best_score; + function_object const* candidates[10]; + int candidate_index; +}; + +template +inline int invoke0( + lua_State* L, function_object const& self, invoke_context& ctx + , F const& f, Signature, Policies const& policies, IsVoid, mpl::true_) +{ + return invoke_member( + L, self, ctx, f, Signature(), policies + , mpl::long_::value - 1>(), IsVoid() + ); +} + +template +inline int invoke0( + lua_State* L, function_object const& self, invoke_context& ctx, + F const& f, Signature, Policies const& policies, IsVoid, mpl::false_) +{ + return invoke_normal( + L, self, ctx, f, Signature(), policies + , mpl::long_::value - 1>(), IsVoid() + ); +} + +template +inline int invoke( + lua_State* L, function_object const& self, invoke_context& ctx + , F const& f, Signature, Policies const& policies) +{ + return invoke0( + L, self, ctx, f, Signature(), policies + , boost::is_void::type>() + , boost::is_member_function_pointer() + ); +} + +inline int maybe_yield_aux(lua_State*, int results, mpl::false_) +{ + return results; +} + +inline int maybe_yield_aux(lua_State* L, int results, mpl::true_) +{ + return lua_yield(L, results); +} + +template +int maybe_yield(lua_State* L, int results, Policies*) +{ + return maybe_yield_aux( + L, results, mpl::bool_::value>()); +} + +inline int sum_scores(int const* first, int const* last) +{ + int result = 0; + + for (; first != last; ++first) + { + if (*first < 0) + return *first; + result += *first; + } + + return result; +} + +# define LUABIND_INVOKE_NEXT_ITER(n) \ + typename mpl::next< \ + BOOST_PP_IF( \ + n, BOOST_PP_CAT(iter,BOOST_PP_DEC(n)), first) \ + >::type + +# define LUABIND_INVOKE_NEXT_INDEX(n) \ + BOOST_PP_IF( \ + n \ + , BOOST_PP_CAT(index,BOOST_PP_DEC(n)) + \ + BOOST_PP_CAT(c,BOOST_PP_DEC(n)).consumed_args() \ + , 1 \ + ) + +# define LUABIND_INVOKE_COMPUTE_ARITY(n) + BOOST_PP_CAT(c,n).consumed_args() + +# define LUABIND_INVOKE_DECLARE_CONVERTER(n) \ + typedef LUABIND_INVOKE_NEXT_ITER(n) BOOST_PP_CAT(iter,n); \ + typedef typename mpl::deref::type \ + BOOST_PP_CAT(a,n); \ + typedef typename find_conversion_policy::type \ + BOOST_PP_CAT(p,n); \ + typename mpl::apply_wrap2< \ + BOOST_PP_CAT(p,n), BOOST_PP_CAT(a,n), lua_to_cpp>::type BOOST_PP_CAT(c,n); \ + int const BOOST_PP_CAT(index,n) = LUABIND_INVOKE_NEXT_INDEX(n); + +# define LUABIND_INVOKE_COMPUTE_SCORE(n) \ + , BOOST_PP_CAT(c,n).match( \ + L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n)) + +# define LUABIND_INVOKE_ARG(z, n, base) \ + BOOST_PP_CAT(c,base(n)).apply( \ + L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,base(n))), BOOST_PP_CAT(index,base(n))) + +# define LUABIND_INVOKE_CONVERTER_POSTCALL(n) \ + BOOST_PP_CAT(c,n).converter_postcall( \ + L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n)); + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +# define LUABIND_INVOKE_VOID +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +# undef LUABIND_INVOKE_VOID +# define LUABIND_INVOKE_MEMBER +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +# define LUABIND_INVOKE_VOID +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +}} // namespace luabind::detail # endif // LUABIND_CALL2_080911_HPP +#else // BOOST_PP_IS_ITERATING + +# ifdef LUABIND_INVOKE_MEMBER +# define N BOOST_PP_INC(BOOST_PP_ITERATION()) +# else +# define N BOOST_PP_ITERATION() +# endif + +template +inline int +# ifdef LUABIND_INVOKE_MEMBER +invoke_member +# else +invoke_normal +# endif +( + lua_State* L, function_object const& self, invoke_context& ctx + , F const& f, Signature, Policies const&, mpl::long_ +# ifdef LUABIND_INVOKE_VOID + , mpl::true_ +# else + , mpl::false_ +# endif +) +{ + typedef typename mpl::begin::type first; +# ifndef LUABIND_INVOKE_VOID + typedef typename mpl::deref::type result_type; + typedef typename find_conversion_policy<0, Policies>::type result_policy; + typename mpl::apply_wrap2< + result_policy, result_type, cpp_to_lua>::type result_converter; +# endif + +# if N > 0 +# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_DECLARE_CONVERTER(n) +# define BOOST_PP_LOCAL_LIMITS (0,N-1) +# include BOOST_PP_LOCAL_ITERATE() +# endif + + int const arity = 0 +# if N > 0 +# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_COMPUTE_ARITY(n) +# define BOOST_PP_LOCAL_LIMITS (0,N-1) +# include BOOST_PP_LOCAL_ITERATE() +# endif + ; + + int const arguments = lua_gettop(L); + + int score = -1; + + if (arity == arguments) + { + int const scores[] = { + 0 +# if N > 0 +# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_COMPUTE_SCORE(n) +# define BOOST_PP_LOCAL_LIMITS (0,N-1) +# include BOOST_PP_LOCAL_ITERATE() +# endif + }; + + score = sum_scores(scores + 1, scores + 1 + N); + } + + if (score >= 0 && score < ctx.best_score) + { + ctx.best_score = score; + ctx.candidates[0] = &self; + ctx.candidate_index = 1; + } + else if (score == ctx.best_score) + { + ctx.candidates[ctx.candidate_index++] = &self; + } + + int results = 0; + + if (self.next) + { + results = self.next->call(L, ctx); + } + + if (score == ctx.best_score && ctx.candidate_index == 1) + { +# ifndef LUABIND_INVOKE_VOID + result_converter.apply( + L, +# endif +# ifdef LUABIND_INVOKE_MEMBER + (c0.apply(L, LUABIND_DECORATE_TYPE(a0), index0).*f)( + BOOST_PP_ENUM(BOOST_PP_DEC(N), LUABIND_INVOKE_ARG, BOOST_PP_INC) + ) +# else +# define LUABIND_INVOKE_IDENTITY(x) x + f( + BOOST_PP_ENUM(N, LUABIND_INVOKE_ARG, LUABIND_INVOKE_IDENTITY) + ) +# undef LUABIND_INVOKE_IDENTITY +# endif +# ifndef LUABIND_INVOKE_VOID + ) +# endif + ; + +# if N > 0 +# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_CONVERTER_POSTCALL(n) +# define BOOST_PP_LOCAL_LIMITS (0,N-1) +# include BOOST_PP_LOCAL_ITERATE() +# endif + + results = maybe_yield(L, lua_gettop(L) - arguments, (Policies*)0); + + int const indices[] = { + arguments + results BOOST_PP_ENUM_TRAILING_PARAMS(N, index) + }; + + policy_list_postcall::apply(L, indices); + } + + return results; +} + +# undef N + +#endif + diff --git a/libs/luabind/luabind/detail/call_function.hpp b/libs/luabind/luabind/detail/call_function.hpp index 90a6a4e1b..e3ac2b761 100644 --- a/libs/luabind/luabind/detail/call_function.hpp +++ b/libs/luabind/luabind/detail/call_function.hpp @@ -20,175 +20,423 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. + +#if !BOOST_PP_IS_ITERATING + #ifndef LUABIND_CALL_FUNCTION_HPP_INCLUDED #define LUABIND_CALL_FUNCTION_HPP_INCLUDED #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include -#include +#include #include -#include -#include namespace luabind { - namespace adl { - class object; - } + namespace detail + { - using adl::object; + // if the proxy_function_caller returns non-void + template + class proxy_function_caller + { +// friend class luabind::object; + public: - namespace detail { + typedef int(*function_t)(lua_State*, int, int); - template< typename PolicyList, unsigned int pos > - void push_arguments(lua_State* /*L*/) {} + proxy_function_caller( + lua_State* L + , int params + , function_t fun + , const Tuple args) + : m_state(L) + , m_params(params) + , m_fun(fun) + , m_args(args) + , m_called(false) + { + } - template< typename PolicyList, unsigned int Pos, typename Arg0, typename... Args > - void push_arguments(lua_State* L, Arg0&& arg0, Args&&... args) - { - using converter_type = specialized_converter_policy< fetched_converter_policy, Arg0, cpp_to_lua >; - converter_type().to_lua(L, unwrapped::get(std::forward(arg0))); - push_arguments(L, std::forward(args)...); - } + proxy_function_caller(const proxy_function_caller& rhs) + : m_state(rhs.m_state) + , m_params(rhs.m_params) + , m_fun(rhs.m_fun) + , m_args(rhs.m_args) + , m_called(rhs.m_called) + { + rhs.m_called = true; + } -#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS - template - void call_function_impl(lua_State* L, int m_params, Fn fn, std::true_type /* void */, meta::index_list, Args&&... args) - { - int top = lua_gettop(L); + ~proxy_function_caller() + { + if (m_called) return; - push_arguments(L, std::forward(args)...); + m_called = true; + lua_State* L = m_state; - if(fn(L, sizeof...(Args), 0)) { - assert(lua_gettop(L) == top - m_params + 1); - call_error(L); - } - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - } + int top = lua_gettop(L); - template - Ret call_function_impl(lua_State* L, int m_params, Fn fn, std::false_type /* void */, meta::index_list, Args&&... args) - { - int top = lua_gettop(L); - - push_arguments(L, std::forward(args)...); - - if(fn(L, sizeof...(Args), 1)) { - assert(lua_gettop(L) == top - m_params + 1); - call_error(L); - } - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - - specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter; - if(converter.match(L, decorate_type_t(), -1) < 0) { - cast_error(L); - } - - return converter.to_cpp(L, decorate_type_t(), -1); - } + push_args_from_tuple<1>::apply(L, m_args); + if (m_fun(L, boost::tuples::length::value, 0)) + { + assert(lua_gettop(L) == top - m_params + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); #else - template::value> - struct call_function_struct; + error_callback_fun e = get_error_callback(); + if (e) e(L); - template - struct call_function_struct< Ret, PolicyList, meta::index_list, NumParams, Function, true /* void */ > - { - template< typename... Args > - static void call(lua_State* L, Args&&... args) { - int top = lua_gettop(L); + assert(0 && "the lua function threw an error and exceptions are disabled." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); - push_arguments(L, std::forward(args)...); - - if(Function(L, sizeof...(Args), 0)) { - if(Function == &detail::pcall) { - assert(lua_gettop(L) == static_cast(top - NumParams + 1)); +#endif } - call_error(L); + + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); } - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + NumParams); - } - }; - template - struct call_function_struct< Ret, PolicyList, meta::index_list, NumParams, Function, false /* void */ > - { - template< typename... Args > - static Ret call(lua_State* L, Args&&... args) { - int top = lua_gettop(L); + operator Ret() + { + typename mpl::apply_wrap2::type converter; - push_arguments(L, std::forward(args)...); + m_called = true; + lua_State* L = m_state; - if(Function(L, sizeof...(Args), 1)) { - if(Function == &detail::pcall) { - assert(lua_gettop(L) == static_cast(top - NumParams + 1)); + int top = lua_gettop(L); + + push_args_from_tuple<1>::apply(L, m_args); + if (m_fun(L, boost::tuples::length::value, 1)) + { + assert(lua_gettop(L) == top - m_params + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); +#endif } - call_error(L); - } - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + NumParams); - specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter; - if(converter.match(L, decorate_type_t(), -1) < 0) { - cast_error(L); + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(L, typeid(Ret)); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(L, typeid(Ret)); + + assert(0 && "the lua function's return value could not be converted." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); + +#endif + } +#endif + return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); } - return converter.to_cpp(L, decorate_type_t(), -1); - } - }; -#endif - } + template + Ret operator[](const Policies& p) + { + typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; - template - R call_pushed_function(lua_State* L, Args&&... args) - { -#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS - return detail::call_function_impl(L, 1, &detail::pcall, std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); + m_called = true; + lua_State* L = m_state; + + int top = lua_gettop(L); + + detail::push_args_from_tuple<1>::apply(L, m_args, p); + if (m_fun(L, boost::tuples::length::value, 1)) + { + assert(lua_gettop(L) == top - m_params + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw error(L); #else - return detail::call_function_struct, 1, &detail::pcall >::call(L, std::forward(args)...); + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); #endif - } + } - template - R call_function(lua_State* L, const char* name, Args&&... args) - { - assert(name && "luabind::call_function() expects a function name"); - lua_getglobal(L, name); - return call_pushed_function(L, std::forward(args)...); - } + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); - template - R resume_pushed_function(lua_State* L, Args&&... args) - { -#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS - return detail::call_function_impl(L, 1, &detail::resume_impl, std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); +#ifndef LUABIND_NO_ERROR_CHECKING + + if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(L, typeid(Ret)); #else - return detail::call_function_struct, 1, &detail::resume_impl >::call(L, std::forward(args)...); + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(L, typeid(Ret)); + + assert(0 && "the lua function's return value could not be converted." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); + #endif - } + } +#endif + return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); + } - template - R resume_function(lua_State* L, const char* name, Args&&... args) - { - assert(name && "luabind::resume_function() expects a function name"); - lua_getglobal(L, name); - return resume_pushed_function(L, std::forward(args)...); - } + private: - template - R resume(lua_State* L, Args&&... args) - { -#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS - return detail::call_function_impl(L, 0, &detail::resume_impl, std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); + lua_State* m_state; + int m_params; + function_t m_fun; + Tuple m_args; + mutable bool m_called; + + }; + + // if the proxy_member_caller returns void + template + class proxy_function_void_caller + { + friend class luabind::object; + public: + + typedef int(*function_t)(lua_State*, int, int); + + proxy_function_void_caller( + lua_State* L + , int params + , function_t fun + , const Tuple args) + : m_state(L) + , m_params(params) + , m_fun(fun) + , m_args(args) + , m_called(false) + { + } + + proxy_function_void_caller(const proxy_function_void_caller& rhs) + : m_state(rhs.m_state) + , m_params(rhs.m_params) + , m_fun(rhs.m_fun) + , m_args(rhs.m_args) + , m_called(rhs.m_called) + { + rhs.m_called = true; + } + + ~proxy_function_void_caller() + { + if (m_called) return; + + m_called = true; + lua_State* L = m_state; + + int top = lua_gettop(L); + + push_args_from_tuple<1>::apply(L, m_args); + if (m_fun(L, boost::tuples::length::value, 0)) + { + assert(lua_gettop(L) == top - m_params + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); #else - return detail::call_function_struct, 0, &detail::resume_impl >::call(L, std::forward(args)...); + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); #endif + } + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); + } + + template + void operator[](const Policies& p) + { + m_called = true; + lua_State* L = m_state; + + int top = lua_gettop(L); + + detail::push_args_from_tuple<1>::apply(L, m_args, p); + if (m_fun(L, boost::tuples::length::value, 0)) + { + assert(lua_gettop(L) == top - m_params + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); +#endif + } + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); + } + + private: + + lua_State* m_state; + int m_params; + function_t m_fun; + Tuple m_args; + mutable bool m_called; + + }; + } + #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) + #include BOOST_PP_ITERATE() + } #endif // LUABIND_CALL_FUNCTION_HPP_INCLUDED +#else +#if BOOST_PP_ITERATION_FLAGS() == 1 + +#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * +#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n + + + template + typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type + call_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) + { + assert(name && "luabind::call_function() expects a function name"); + typedef boost::tuples::tuple tuple_t; +#if BOOST_PP_ITERATION() == 0 + tuple_t args; +#else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); +#endif + typedef typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type proxy_type; + + lua_getglobal(L, name); + + return proxy_type(L, 1, &detail::pcall, args); + } + + template + typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type + call_function(luabind::object const& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) + { + typedef boost::tuples::tuple tuple_t; +#if BOOST_PP_ITERATION() == 0 + tuple_t args; +#else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); +#endif + typedef typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type proxy_type; + + obj.push(obj.interpreter()); + return proxy_type(obj.interpreter(), 1, &detail::pcall, args); + } + + template + typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type + resume_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) + { + assert(name && "luabind::resume_function() expects a function name"); + typedef boost::tuples::tuple tuple_t; +#if BOOST_PP_ITERATION() == 0 + tuple_t args; +#else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); +#endif + typedef typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type proxy_type; + + lua_getglobal(L, name); + + return proxy_type(L, 1, &detail::resume_impl, args); + } + + template + typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type + resume_function(luabind::object const& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) + { + typedef boost::tuples::tuple tuple_t; +#if BOOST_PP_ITERATION() == 0 + tuple_t args; +#else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); +#endif + typedef typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type proxy_type; + + obj.push(obj.interpreter()); + return proxy_type(obj.interpreter(), 1, &detail::resume_impl, args); + } + + template + typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type + resume(lua_State* L BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) + { + typedef boost::tuples::tuple tuple_t; +#if BOOST_PP_ITERATION() == 0 + tuple_t args; +#else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); +#endif + typedef typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type proxy_type; + + return proxy_type(L, 0, &detail::resume_impl, args); + } + + +#undef LUABIND_OPERATOR_PARAMS +#undef LUABIND_TUPLE_PARAMS + +#endif +#endif + diff --git a/libs/luabind/luabind/detail/call_member.hpp b/libs/luabind/luabind/detail/call_member.hpp index 23b1bd496..e63555bc6 100644 --- a/libs/luabind/luabind/detail/call_member.hpp +++ b/libs/luabind/luabind/detail/call_member.hpp @@ -20,82 +20,325 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. + +#if !BOOST_PP_IS_ITERATING + #ifndef LUABIND_CALL_MEMBER_HPP_INCLUDED #define LUABIND_CALL_MEMBER_HPP_INCLUDED #include -#include +#include #include #include #include -#include -#include +#include // TODO: REMOVE DEPENDENCY + +#include + +#include +#include +#include + +#include namespace luabind { - using adl::object; + namespace detail + { - namespace detail { + namespace mpl = boost::mpl; - template - R call_member_impl(lua_State* L, std::true_type /*void*/, meta::index_list, Args&&... args) - { - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; + // if the proxy_member_caller returns non-void + template + class proxy_member_caller + { +// friend class luabind::object; + public: - // pcall will pop the function and self reference - // and all the parameters + proxy_member_caller(lua_State* L_, const Tuple args) + : L(L_) + , m_args(args) + , m_called(false) + { + } + + proxy_member_caller(const proxy_member_caller& rhs) + : L(rhs.L) + , m_args(rhs.m_args) + , m_called(rhs.m_called) + { + rhs.m_called = true; + } + + ~proxy_member_caller() + { + if (m_called) return; + + m_called = true; + + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; + + // pcall will pop the function and self reference + // and all the parameters + + push_args_from_tuple<1>::apply(L, m_args); + if (pcall(L, boost::tuples::length::value + 1, 0)) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + } + + operator Ret() + { + typename mpl::apply_wrap2::type converter; + + m_called = true; + + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; + + // pcall will pop the function and self reference + // and all the parameters + push_args_from_tuple<1>::apply(L, m_args); + if (pcall(L, boost::tuples::length::value + 1, 1)) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(L, typeid(Ret)); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(L, typeid(Ret)); + + assert(0 && "the lua function's return value could not be converted." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } +#endif + return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); + } + + template + Ret operator[](const Policies& p) + { + typedef typename find_conversion_policy<0, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + + m_called = true; + + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; + + // pcall will pop the function and self reference + // and all the parameters + + detail::push_args_from_tuple<1>::apply(L, m_args, p); + if (pcall(L, boost::tuples::length::value + 1, 1)) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(L, typeid(Ret)); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(L, typeid(Ret)); + + assert(0 && "the lua function's return value could not be converted." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } +#endif + return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); + } + + private: + + lua_State* L; + Tuple m_args; + mutable bool m_called; - meta::init_order{ ( - specialized_converter_policy_n::type, cpp_to_lua>().to_lua(L, unwrapped::get(std::forward(args))), 0)... }; - if(pcall(L, sizeof...(Args)+1, 0)) + // if the proxy_member_caller returns void + template + class proxy_member_void_caller { - assert(lua_gettop(L) == top + 1); - call_error(L); - } - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - } + friend class luabind::object; + public: - template - R call_member_impl(lua_State* L, std::false_type /*void*/, meta::index_list, Args&&... args) - { - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; + proxy_member_void_caller(lua_State* L_, const Tuple args) + : L(L_) + , m_args(args) + , m_called(false) + { + } - // pcall will pop the function and self reference - // and all the parameters + proxy_member_void_caller(const proxy_member_void_caller& rhs) + : L(rhs.L) + , m_args(rhs.m_args) + , m_called(rhs.m_called) + { + rhs.m_called = true; + } + + ~proxy_member_void_caller() + { + if (m_called) return; + + m_called = true; + + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; + + // pcall will pop the function and self reference + // and all the parameters + + push_args_from_tuple<1>::apply(L, m_args); + if (pcall(L, boost::tuples::length::value + 1, 0)) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + } + + template + void operator[](const Policies& p) + { + m_called = true; + + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; + + // pcall will pop the function and self reference + // and all the parameters + + detail::push_args_from_tuple<1>::apply(L, m_args, p); + if (pcall(L, boost::tuples::length::value + 1, 0)) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + } + + private: + lua_State* L; + Tuple m_args; + mutable bool m_called; - meta::init_order{ ( - specialized_converter_policy_n::type, cpp_to_lua>().to_lua(L, unwrapped::get(std::forward(args))), 0)... }; - if(pcall(L, sizeof...(Args)+1, 1)) - { - assert(lua_gettop(L) == top + 1); - call_error(L); - } - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - - specialized_converter_policy_n<0, PolicyList, R, lua_to_cpp> converter; - if(converter.match(L, decorate_type_t(), -1) < 0) { - cast_error(L); - } - - return converter.to_cpp(L, decorate_type_t(), -1); - } - - } // detail - template - R call_member(object const& obj, const char* name, Args&&... args) + #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) + #include BOOST_PP_ITERATE() + +} + +#endif // LUABIND_CALL_MEMBER_HPP_INCLUDED + +#else +#if BOOST_PP_ITERATION_FLAGS() == 1 + +#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * +#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n + + template + typename boost::mpl::if_ + , luabind::detail::proxy_member_void_caller > + , luabind::detail::proxy_member_caller > >::type + call_member(object const& obj, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) { + typedef boost::tuples::tuple tuple_t; +#if BOOST_PP_ITERATION() == 0 + tuple_t args; +#else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); +#endif + + typedef typename boost::mpl::if_ + , luabind::detail::proxy_member_void_caller > + , luabind::detail::proxy_member_caller > >::type proxy_type; + // this will be cleaned up by the proxy object // once the call has been made @@ -111,17 +354,12 @@ namespace luabind // now the function and self objects // are on the stack. These will both // be popped by pcall - - return detail::call_member_impl(obj.interpreter(), std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); + return proxy_type(obj.interpreter(), args); } - template - R call_member(wrap_base const* self, char const* fn, Args&&... args) - { - return self->call(fn, std::forward(args)...); - } +#undef LUABIND_OPERATOR_PARAMS +#undef LUABIND_TUPLE_PARAMS -} - -#endif // LUABIND_CALL_MEMBER_HPP_INCLUDED +#endif +#endif diff --git a/libs/luabind/luabind/detail/call_operator_iterate.hpp b/libs/luabind/luabind/detail/call_operator_iterate.hpp new file mode 100644 index 000000000..c6f95a10c --- /dev/null +++ b/libs/luabind/luabind/detail/call_operator_iterate.hpp @@ -0,0 +1,66 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// 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. + +#define N BOOST_PP_ITERATION() + +#define LUABIND_UNWRAP_PARAMETER(z, n, _) \ + typename detail::unwrap_parameter_type::type \ + BOOST_PP_CAT(_, n) + +template +struct BOOST_PP_CAT(call_operator, N) + : detail::operator_< + BOOST_PP_CAT(call_operator, N)< + Self BOOST_PP_ENUM_TRAILING_PARAMS(N, A) + > + > +{ + BOOST_PP_CAT(call_operator, N)(int) {} + + template + struct apply + { + static void execute( + lua_State* L + , typename detail::unwrap_parameter_type::type self + BOOST_PP_ENUM_TRAILING(N, LUABIND_UNWRAP_PARAMETER, _) + ) + { + using namespace detail; + operator_result( + L +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + , self(BOOST_PP_ENUM_PARAMS(N, _)) +#else + , (self(BOOST_PP_ENUM_PARAMS(N, _)), detail::operator_void_return()) +#endif + , (Policies*)0 + ); + } + }; + + static char const* name() { return "__call"; } +}; + +#undef LUABIND_UNWRAP_PARAMETER +#undef N + diff --git a/libs/luabind/luabind/detail/call_traits.hpp b/libs/luabind/luabind/detail/call_traits.hpp deleted file mode 100644 index 227e3662e..000000000 --- a/libs/luabind/luabind/detail/call_traits.hpp +++ /dev/null @@ -1,113 +0,0 @@ -// This has been stripped from boost minus the compatibility for borland etc. -// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. -// Use, modification and distribution are subject to 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). -// -// See http://www.boost.org/libs/utility for most recent version including documentation. - -// call_traits: defines typedefs for function usage -// (see libs/utility/call_traits.htm) - -/* Release notes: -23rd July 2000: -Fixed array specialization. (JM) -Added Borland specific fixes for reference types -(issue raised by Steve Cleary). -*/ - -#ifndef LUABIND_CALL_TRAITS_HPP_INCLUDED -#define LUABIND_CALL_TRAITS_HPP_INCLUDED - -namespace luabind { - namespace detail { - - template - struct ct_imp2 - { - using param_type = const T&; - }; - - template - struct ct_imp2 - { - using param_type = const T; - }; - - template - struct ct_imp - { - using param_type = const T&; - }; - - template - struct ct_imp - { - using param_type = typename ct_imp2::param_type; - }; - - template - struct ct_imp - { - using param_type = typename ct_imp2::param_type; - }; - - template - struct ct_imp - { - using param_type = const T; - }; - - template - struct call_traits - { - public: - using value_type = T; - using reference = T&; - using const_reference = const T&; - - using param_type = typename ct_imp< - T, - std::is_pointer::value, - std::is_integral::value || std::is_floating_point::value, - std::is_enum::value - >::param_type; - }; - - template - struct call_traits - { - using value_type = T&; - using reference = T&; - using const_reference = const T&; - using param_type = T&; - }; - - template - struct call_traits - { - private: - using array_type = T[N]; - public: - using value_type = const T*; - using reference = array_type&; - using const_reference = const array_type&; - using param_type = const T* const; - }; - - template - struct call_traits - { - private: - using array_type = const T[N]; - public: - using value_type = const T*; - using reference = array_type&; - using const_reference = const array_type&; - using param_type = const T* const; - }; - } -} - -#endif - diff --git a/libs/luabind/luabind/detail/class_cache.hpp b/libs/luabind/luabind/detail/class_cache.hpp new file mode 100644 index 000000000..f49687c30 --- /dev/null +++ b/libs/luabind/luabind/detail/class_cache.hpp @@ -0,0 +1,89 @@ +// Copyright (c) 2004 Daniel Wallin + +// 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 CLASS_CACHE_040218_HPP +#define CLASS_CACHE_040218_HPP + +#include +#include +#include + +namespace luabind { namespace detail { + +#ifdef LUABIND_NOT_THREADSAFE + + class class_rep; + + template + struct class_cache_impl + { + static lua_State* state; + static class_rep* class_; + }; + + template + lua_State* class_cache_impl::state = 0; + + template + class_rep* class_cache_impl::class_ = 0; + + template + struct class_cache + : class_cache_impl< + typename boost::add_reference< + typename boost::add_const< + T + >::type + >::type + > + { + }; + + template + class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0) + { + if (class_cache::state != L) + { + class_cache::state = L; + + class_registry* registry = class_registry::get_registry(L); + class_cache::class_ = registry->find_class(typeid(T)); + } + + return class_cache::class_; + } + +#else + + template + class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0) + { + class_registry* registry = class_registry::get_registry(L); + return registry->find_class(typeid(T)); + } + +#endif + +}} // namespace luabind::detail + +#endif // CLASS_CACHE_040218_HPP + diff --git a/libs/luabind/luabind/detail/class_registry.hpp b/libs/luabind/luabind/detail/class_registry.hpp index da0a47080..12ed03cfe 100644 --- a/libs/luabind/luabind/detail/class_registry.hpp +++ b/libs/luabind/luabind/detail/class_registry.hpp @@ -30,58 +30,56 @@ #include #include -namespace luabind { - namespace detail { +namespace luabind { namespace detail +{ + class class_rep; - class class_rep; + struct LUABIND_API class_registry + { + class_registry(lua_State* L); - struct LUABIND_API class_registry - { - class_registry(lua_State* L); + static class_registry* get_registry(lua_State* L); - static class_registry* get_registry(lua_State* L); + int cpp_instance() const { return m_instance_metatable; } + int cpp_class() const { return m_cpp_class_metatable; } - int cpp_instance() const { return m_instance_metatable; } - int cpp_class() const { return m_cpp_class_metatable; } + int lua_instance() const { return m_instance_metatable; } + int lua_class() const { return m_lua_class_metatable; } + int lua_function() const { return m_lua_function_metatable; } - int lua_instance() const { return m_instance_metatable; } - int lua_class() const { return m_lua_class_metatable; } - int lua_function() const { return m_lua_function_metatable; } + void add_class(type_id const& info, class_rep* crep); - void add_class(type_id const& info, class_rep* crep); + class_rep* find_class(type_id const& info) const; - class_rep* find_class(type_id const& info) const; + std::map const& get_classes() const + { + return m_classes; + } - std::map const& get_classes() const - { - return m_classes; - } + private: - private: + std::map m_classes; - std::map m_classes; + // this is a lua reference that points to the lua table + // that is to be used as meta table for all C++ class + // instances. It is a kind of v-table. + int m_instance_metatable; - // this is a lua reference that points to the lua table - // that is to be used as meta table for all C++ class - // instances. It is a kind of v-table. - int m_instance_metatable; + // this is a lua reference to the metatable to be used + // for all classes defined in C++. + int m_cpp_class_metatable; - // this is a lua reference to the metatable to be used - // for all classes defined in C++. - int m_cpp_class_metatable; + // this is a lua reference to the metatable to be used + // for all classes defined in lua + int m_lua_class_metatable; - // this is a lua reference to the metatable to be used - // for all classes defined in lua - int m_lua_class_metatable; + // this metatable only contains a destructor + // for luabind::Detail::free_functions::function_rep + int m_lua_function_metatable; - // this metatable only contains a destructor - // for luabind::Detail::free_functions::function_rep - int m_lua_function_metatable; + }; - }; - - } -} +}} #endif // LUABIND_CLASS_REGISTRY_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/class_rep.hpp b/libs/luabind/luabind/detail/class_rep.hpp index 119e15888..aa5e866d3 100644 --- a/libs/luabind/luabind/detail/class_rep.hpp +++ b/libs/luabind/luabind/detail/class_rep.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -24,12 +24,16 @@ #ifndef LUABIND_CLASS_REP_HPP_INCLUDED #define LUABIND_CLASS_REP_HPP_INCLUDED +#include +#include + #include #include #include #include #include +#include #include #include #include @@ -39,174 +43,171 @@ #include #include -namespace luabind { - namespace detail { +namespace luabind { namespace detail +{ - LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); + LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); - struct class_registration; + struct class_registration; - struct conversion_storage; + struct conversion_storage; - // This function is used as a tag to identify "properties". - LUABIND_API int property_tag(lua_State*); + // This function is used as a tag to identify "properties". + LUABIND_API int property_tag(lua_State*); - // this is class-specific information, poor man's vtable - // this is allocated statically (removed by the compiler) - // a pointer to this structure is stored in the lua tables' - // metatable with the name __classrep - // it is used when matching parameters to function calls - // to determine possible implicit casts - // it is also used when finding the best match for overloaded - // methods + // this is class-specific information, poor man's vtable + // this is allocated statically (removed by the compiler) + // a pointer to this structure is stored in the lua tables' + // metatable with the name __classrep + // it is used when matching parameters to function calls + // to determine possible implicit casts + // it is also used when finding the best match for overloaded + // methods - class cast_graph; - class class_id_map; + class cast_graph; + class class_id_map; - class LUABIND_API class_rep + class LUABIND_API class_rep + { + friend struct class_registration; + friend int super_callback(lua_State*); +//TODO: avoid the lua-prefix + friend int lua_class_gettable(lua_State*); + friend int lua_class_settable(lua_State*); + friend int static_class_gettable(lua_State*); + public: + + enum class_type { - friend struct class_registration; - friend int super_callback(lua_State*); - //TODO: avoid the lua-prefix - friend int lua_class_gettable(lua_State*); - friend int lua_class_settable(lua_State*); - friend int static_class_gettable(lua_State*); - public: - - enum class_type - { - cpp_class = 0, - lua_class = 1 - }; - - // EXPECTS THE TOP VALUE ON THE LUA STACK TO - // BE THE USER DATA WHERE THIS CLASS IS BEING - // INSTANTIATED! - class_rep(type_id const& type - , const char* name - , lua_State* L - ); - - // used when creating a lua class - // EXPECTS THE TOP VALUE ON THE LUA STACK TO - // BE THE USER DATA WHERE THIS CLASS IS BEING - // INSTANTIATED! - class_rep(lua_State* L, const char* name); - - ~class_rep(); - - std::pair allocate(lua_State* L) const; - - // this is called as metamethod __call on the class_rep. - static int constructor_dispatcher(lua_State* L); - - struct base_info - { - int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance) - class_rep* base; - }; - - void add_base_class(const base_info& binfo); - - const std::vector& bases() const throw() { return m_bases; } - - void set_type(type_id const& t) { m_type = t; } - type_id const& type() const throw() { return m_type; } - - const char* name() const throw() { return m_name; } - - // the lua reference to the metatable for this class' instances - int metatable_ref() const throw() { return m_instance_metatable; } - - void get_table(lua_State* L) const { m_table.push(L); } - void get_default_table(lua_State* L) const { m_default_table.push(L); } - - class_type get_class_type() const { return m_class_type; } - - void add_static_constant(const char* name, int val); - - static int super_callback(lua_State* L); - - static int lua_settable_dispatcher(lua_State* L); - - // called from the metamethod for __index - // obj is the object pointer - static int static_class_gettable(lua_State* L); - - bool has_operator_in_lua(lua_State*, int id); - - cast_graph const& casts() const - { - return *m_casts; - } - - class_id_map const& classes() const - { - return *m_classes; - } - - private: - - // Code common to both constructors - void shared_init(lua_State * L); - - void cache_operators(lua_State*); - - // this is a pointer to the type_info structure for - // this type - // warning: this may be a problem when using dll:s, since - // typeid() may actually return different pointers for the same - // type. - type_id m_type; - - // a list of info for every class this class derives from - // the information stored here is sufficient to do - // type casts to the base classes - std::vector m_bases; - - // the class' name (as given when registered to lua with class_) - const char* m_name; - - // a reference to this structure itself. Since this struct - // is kept inside lua (to let lua collect it when lua_close() - // is called) we need to lock it to prevent collection. - // the actual reference is not currently used. - detail::lua_reference m_self_ref; - - // this should always be used when accessing - // members in instances of a class. - // this table contains c closures for all - // member functions in this class, they - // may point to both static and virtual functions - handle m_table; - - // this table contains default implementations of the - // virtual functions in m_table. - handle m_default_table; - - // the type of this class.. determines if it's written in c++ or lua - class_type m_class_type; - - // this is a lua reference that points to the lua table - // that is to be used as meta table for all instances - // of this class. - int m_instance_metatable; - - std::map m_static_constants; - - // the first time an operator is invoked - // we check the associated lua table - // and cache the result - int m_operator_cache; - - cast_graph* m_casts; - class_id_map* m_classes; + cpp_class = 0, + lua_class = 1 }; - LUABIND_API bool is_class_rep(lua_State* L, int index); + // EXPECTS THE TOP VALUE ON THE LUA STACK TO + // BE THE USER DATA WHERE THIS CLASS IS BEING + // INSTANTIATED! + class_rep(type_id const& type + , const char* name + , lua_State* L + ); - } -} + // used when creating a lua class + // EXPECTS THE TOP VALUE ON THE LUA STACK TO + // BE THE USER DATA WHERE THIS CLASS IS BEING + // INSTANTIATED! + class_rep(lua_State* L, const char* name); + + ~class_rep(); + + std::pair allocate(lua_State* L) const; + + // this is called as metamethod __call on the class_rep. + static int constructor_dispatcher(lua_State* L); + + struct base_info + { + int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance) + class_rep* base; + }; + + void add_base_class(const base_info& binfo); + + const std::vector& bases() const throw() { return m_bases; } + + void set_type(type_id const& t) { m_type = t; } + type_id const& type() const throw() { return m_type; } + + const char* name() const throw() { return m_name; } + + // the lua reference to the metatable for this class' instances + int metatable_ref() const throw() { return m_instance_metatable; } + + void get_table(lua_State* L) const { m_table.push(L); } + void get_default_table(lua_State* L) const { m_default_table.push(L); } + + class_type get_class_type() const { return m_class_type; } + + void add_static_constant(const char* name, int val); + + static int super_callback(lua_State* L); + + static int lua_settable_dispatcher(lua_State* L); + + // called from the metamethod for __index + // obj is the object pointer + static int static_class_gettable(lua_State* L); + + bool has_operator_in_lua(lua_State*, int id); + + cast_graph const& casts() const + { + return *m_casts; + } + + class_id_map const& classes() const + { + return *m_classes; + } + + private: + + void cache_operators(lua_State*); + + // this is a pointer to the type_info structure for + // this type + // warning: this may be a problem when using dll:s, since + // typeid() may actually return different pointers for the same + // type. + type_id m_type; + + // a list of info for every class this class derives from + // the information stored here is sufficient to do + // type casts to the base classes + std::vector m_bases; + + // the class' name (as given when registered to lua with class_) + const char* m_name; + + // a reference to this structure itself. Since this struct + // is kept inside lua (to let lua collect it when lua_close() + // is called) we need to lock it to prevent collection. + // the actual reference is not currently used. + detail::lua_reference m_self_ref; + + // this should always be used when accessing + // members in instances of a class. + // this table contains c closures for all + // member functions in this class, they + // may point to both static and virtual functions + handle m_table; + + // this table contains default implementations of the + // virtual functions in m_table. + handle m_default_table; + + // the type of this class.. determines if it's written in c++ or lua + class_type m_class_type; + + // this is a lua reference that points to the lua table + // that is to be used as meta table for all instances + // of this class. + int m_instance_metatable; + + std::map m_static_constants; + + // the first time an operator is invoked + // we check the associated lua table + // and cache the result + int m_operator_cache; + + cast_graph* m_casts; + class_id_map* m_classes; + }; + + bool is_class_rep(lua_State* L, int index); + +}} + +//#include #endif // LUABIND_CLASS_REP_HPP_INCLUDED - diff --git a/libs/luabind/luabind/detail/compute_score.hpp b/libs/luabind/luabind/detail/compute_score.hpp new file mode 100644 index 000000000..c9a7e9ea1 --- /dev/null +++ b/libs/luabind/luabind/detail/compute_score.hpp @@ -0,0 +1,73 @@ +// Copyright Daniel Wallin 2008. Use, modification and distribution is +// subject to 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) + +#ifndef LUABIND_COMPUTE_RANK_081006_HPP +# define LUABIND_COMPUTE_RANK_081006_HPP + +# include +# include +# include +# include +# include +# include + +namespace luabind { namespace detail { + +namespace mpl = boost::mpl; + +template +int compute_score_aux( + lua_State*L, int index, Idx, Iter, End end, Policies const& policies) +{ + typedef typename Iter::type arg_type; + typedef typename find_conversion_policy::type + conversion_policy; + typedef typename mpl::apply_wrap2< + conversion_policy, arg_type, lua_to_cpp>::type converter; + + int score = converter::match(L, LUABIND_DECORATE_TYPE(arg_type), index); + + if (score < 0) + return score; + + if (conversion_policy::has_arg) + ++index; + + int next = compute_score_aux( + L + , index + , typename mpl::next::type() + , typename mpl::next::type() + , end + , policies + ); + + if (next < 0) + return next; + + return score + next; +} + +template +int compute_score_aux(lua_State*, int, Idx, End, End, Policies const&) +{ + return 0; +} + +template +int compute_score(lua_State* L, Signature, Policies const& policies) +{ + return compute_score_aux( + L + , 1 + , mpl::int_<1>() + , typename mpl::next::type>::type() + , typename mpl::end::type() + , policies + ); +} + +}} // namespace luabind::detail + +#endif // LUABIND_COMPUTE_RANK_081006_HPP diff --git a/libs/luabind/luabind/detail/constructor.hpp b/libs/luabind/luabind/detail/constructor.hpp index 964d07695..1cbceb789 100644 --- a/libs/luabind/luabind/detail/constructor.hpp +++ b/libs/luabind/luabind/detail/constructor.hpp @@ -2,64 +2,110 @@ // subject to 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) -#ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP -#define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP +#if !BOOST_PP_IS_ITERATING -#include -#include -#include -#include +# ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP +# define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP -namespace luabind { - namespace detail { +# include +# include +# include +# include - inline void inject_backref(lua_State*, void*, void*) - {} +# include +# include +# include +# include - template - void inject_backref(lua_State* L, T* p, wrap_base*) - { - weak_ref(get_main_thread(L), L, 1).swap(wrap_access::ref(*p)); - } +namespace luabind { namespace detail { - template< class T, class Pointer, class Signature, class Arguments, class ArgumentIndices > - struct construct_aux_helper; +inline void inject_backref(lua_State*, void*, void*) +{} - template< class T, class Pointer, class Signature, typename... Arguments, unsigned int... ArgumentIndices > - struct construct_aux_helper< T, Pointer, Signature, meta::type_list< Arguments... >, meta::index_list< ArgumentIndices... > > - { - using holder_type = pointer_holder; +template +void inject_backref(lua_State* L, T* p, wrap_base*) +{ + weak_ref(get_main_thread(L), L, 1).swap(wrap_access::ref(*p)); +} - void operator()(argument const& self_, Arguments... args) const - { - object_rep* self = touserdata(self_); +template +struct construct_aux; - std::unique_ptr instance(new T(args...)); - inject_backref(self_.interpreter(), instance.get(), instance.get()); +template +struct construct + : construct_aux::value - 2, T, Pointer, Signature> +{}; - void* naked_ptr = instance.get(); - Pointer ptr(instance.release()); +template +struct construct_aux<0, T, Pointer, Signature> +{ + typedef pointer_holder holder_type; - void* storage = self->allocate(sizeof(holder_type)); + void operator()(argument const& self_) const + { + object_rep* self = touserdata(self_); + class_rep* cls = self->crep(); - self->set_instance(new (storage) holder_type(std::move(ptr), registered_class::id, naked_ptr)); - } - }; + std::auto_ptr instance(new T); + inject_backref(self_.interpreter(), instance.get(), instance.get()); + void* naked_ptr = instance.get(); + Pointer ptr(instance.release()); - template< class T, class Pointer, class Signature > - struct construct : - public construct_aux_helper < - T, - Pointer, - Signature, typename meta::sub_range< Signature, 2, meta::size::value >::type, - typename meta::make_index_range<0, meta::size::value - 2>::type > - { - }; + void* storage = self->allocate(sizeof(holder_type)); - } // namespace detail + self->set_instance(new (storage) holder_type( + ptr, registered_class::id, naked_ptr, cls)); + } +}; -} // namespace luabind +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (1, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +}} // namespace luabind::detail # endif // LUABIND_DETAIL_CONSTRUCTOR_081018_HPP +#else // !BOOST_PP_IS_ITERATING + +# define N BOOST_PP_ITERATION() + +template +struct construct_aux +{ + typedef typename mpl::begin::type first; + typedef typename mpl::next::type iter0; + +# define BOOST_PP_LOCAL_MACRO(n) \ + typedef typename mpl::next< \ + BOOST_PP_CAT(iter,BOOST_PP_DEC(n))>::type BOOST_PP_CAT(iter,n); \ + typedef typename BOOST_PP_CAT(iter,n)::type BOOST_PP_CAT(a,BOOST_PP_DEC(n)); + +# define BOOST_PP_LOCAL_LIMITS (1,N) +# include BOOST_PP_LOCAL_ITERATE() + + typedef pointer_holder holder_type; + + void operator()(argument const& self_, BOOST_PP_ENUM_BINARY_PARAMS(N,a,_)) const + { + object_rep* self = touserdata(self_); + class_rep* cls = self->crep(); + + std::auto_ptr instance(new T(BOOST_PP_ENUM_PARAMS(N,_))); + inject_backref(self_.interpreter(), instance.get(), instance.get()); + + void* naked_ptr = instance.get(); + Pointer ptr(instance.release()); + + void* storage = self->allocate(sizeof(holder_type)); + + self->set_instance(new (storage) holder_type( + ptr, registered_class::id, naked_ptr, cls)); + } +}; + +# undef N + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/conversion_base.hpp b/libs/luabind/luabind/detail/conversion_policies/conversion_base.hpp deleted file mode 100644 index 6eb7ba4b8..000000000 --- a/libs/luabind/luabind/detail/conversion_policies/conversion_base.hpp +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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 LUABIND_CONVERSION_BASE_HPP_INCLUDED -#define LUABIND_CONVERSION_BASE_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include - - -namespace luabind { - namespace detail { - - // Something's strange with the references here... need to know when to copy :( - template - void make_pointee_instance(lua_State* L, T&& x, std::true_type, Clone) - { - if(get_pointer(x)) - { - make_pointer_instance(L, std::forward(x)); - } - else - { - lua_pushnil(L); - } - } - - template - void make_pointee_instance(lua_State* L, T&& x, std::false_type, std::true_type) - { - using value_type = typename std::remove_reference::type; - - std::unique_ptr ptr(new value_type(std::move(x))); - make_pointer_instance(L, std::move(ptr)); - } - - template - void make_pointee_instance(lua_State* L, T&& x, std::false_type, std::false_type) - { - // need a second make_instance that moves x into place - make_pointer_instance(L, &x); - } - - template - void make_pointee_instance(lua_State* L, T&& x, Clone) - { - make_pointee_instance(L, std::forward(x), has_get_pointer(), Clone()); - } - - } - - template - struct default_converter; - -} - -#endif - diff --git a/libs/luabind/luabind/detail/conversion_policies/conversion_policies.hpp b/libs/luabind/luabind/detail/conversion_policies/conversion_policies.hpp deleted file mode 100644 index 936982eb3..000000000 --- a/libs/luabind/luabind/detail/conversion_policies/conversion_policies.hpp +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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 LUABIND_CONVERSION_POLICIES_HPP_INCLUDED -#define LUABIND_CONVERSION_POLICIES_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace luabind { - - template <> - struct default_converter - { - enum { consumed_args = 0 }; - - template - lua_State* to_cpp(lua_State* L, U, int /*index*/) - { - return L; - } - - template - static int match(lua_State*, U, int /*index*/) - { - return 0; - } - - template - void converter_postcall(lua_State*, U, int) {} - }; - - namespace detail { - - // This is the one that gets hit, if default_policy doesn't hit one of the specializations defined all over the place - template< class T > - struct default_converter_generator - : public meta::select_ < - meta::case_< is_lua_proxy_arg, lua_proxy_converter >, - meta::case_< std::is_enum::type>, enum_converter >, - meta::case_< is_nonconst_pointer, pointer_converter >, - meta::case_< is_const_pointer, const_pointer_converter >, - meta::case_< is_nonconst_reference, ref_converter >, - meta::case_< is_const_reference, const_ref_converter >, - meta::default_< value_converter > - > ::type - { - }; - - } - - template - struct default_converter - : detail::default_converter_generator::type - {}; - -} - -#endif - diff --git a/libs/luabind/luabind/detail/conversion_policies/enum_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/enum_converter.hpp deleted file mode 100644 index dcdd82dd7..000000000 --- a/libs/luabind/luabind/detail/conversion_policies/enum_converter.hpp +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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 LUABIND_ENUM_CONVERTER_HPP_INCLUDED -#define LUABIND_ENUM_CONVERTER_HPP_INCLUDED - -#include -#include -#include - -namespace luabind { - namespace detail { - - struct enum_converter - { - using type = enum_converter; - using is_native = std::false_type; - - enum { consumed_args = 1 }; - - void to_lua(lua_State* L, int val) - { - lua_pushnumber(L, val); - } - - template - T to_cpp(lua_State* L, by_value, int index) - { - return static_cast(static_cast(lua_tonumber(L, index))); - } - - template - static int match(lua_State* L, by_value, int index) - { - if(lua_isnumber(L, index)) { - return 0; - } else { - return no_match; - } - } - - template - T to_cpp(lua_State* L, by_const_reference, int index) - { - return static_cast(static_cast(lua_tonumber(L, index))); - } - - template - static int match(lua_State* L, by_const_reference, int index) - { - if(lua_isnumber(L, index)) return 0; else return no_match; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - } - -} - -#endif - diff --git a/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp deleted file mode 100644 index 905784730..000000000 --- a/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright Christian Neumüller 2013. Use, modification and distribution is -// subject to 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) - -#ifndef LUABIND_FUNCTION_CONVERTER_HPP_INCLUDED -#define LUABIND_FUNCTION_CONVERTER_HPP_INCLUDED -#include -#include -#include -#include -#include - -namespace luabind { - - template - struct function - { - using result_type = R; - - function(luabind::object const& obj) - : m_func(obj) - { - } - - template< typename... Args> - R operator() (Args&&... args) - { - return call_function(m_func, std::forward(args)...); - } - - private: - object m_func; - }; - - namespace detail { - - template< typename T > - struct is_function : public std::false_type {}; - - template< typename T > - struct is_function< std::function< T > > : public std::true_type {}; - } - - template< typename R, typename... Args, typename WrappedType > - struct deduce_signature , WrappedType > - { - using type = meta::type_list< R, Args... >; - }; - - template - struct default_converter>::value>::type> - { - using is_native = std::true_type; - - enum { consumed_args = 1 }; - - template - void converter_postcall(lua_State*, U const&, int) - {} - - template - static int match(lua_State* L, U, int index) - { - if(lua_type(L, index) == LUA_TFUNCTION) - return 0; - if(luaL_getmetafield(L, index, "__call")) { - lua_pop(L, 1); - return 1; - } - return no_match; - } - - template - F to_cpp(lua_State* L, U, int index) - { - // If you get a compiler error here, you are probably trying to - // get a function pointer from Lua. This is not supported: - // you must use a type which is constructible from a - // luabind::function, e.g. std::function or boost::function. - return function(object(from_stack(L, index))); - } - - void to_lua(lua_State* L, F value) - { - make_function(L, value).push(L); - } - }; - -} // namespace luabind - - -#endif // LUABIND_FUNCTION_CONVERTER_HPP_INCLUDED - diff --git a/libs/luabind/luabind/detail/conversion_policies/lua_proxy_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/lua_proxy_converter.hpp deleted file mode 100644 index 302a0bffa..000000000 --- a/libs/luabind/luabind/detail/conversion_policies/lua_proxy_converter.hpp +++ /dev/null @@ -1,73 +0,0 @@ -// 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 LUABIND_VALUE_WRAPPER_CONVERTER_HPP_INCLUDED -#define LUABIND_VALUE_WRAPPER_CONVERTER_HPP_INCLUDED - -#include -#include - -namespace luabind { - namespace detail { - - template - struct lua_proxy_converter - { - using type = lua_proxy_converter; - using is_native = std::true_type; - - enum { consumed_args = 1 }; - - template - T to_cpp(lua_State* L, by_const_reference, int index) - { - return T(from_stack(L, index)); - } - - template - T to_cpp(lua_State* L, by_value, int index) - { - return to_cpp(L, by_const_reference(), index); - } - - template - static int match(lua_State* L, by_const_reference, int index) - { - return lua_proxy_traits::check(L, index) - ? max_hierarchy_depth - : no_match; - } - - template - static int match(lua_State* L, by_value, int index) - { - return match(L, by_const_reference(), index); - } - - void converter_postcall(...) {} - - template - void to_lua(lua_State* interpreter, T const& value_wrapper) - { - lua_proxy_traits::unwrap(interpreter, value_wrapper); - } - }; - - } -} - -#endif - diff --git a/libs/luabind/luabind/detail/conversion_policies/native_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/native_converter.hpp deleted file mode 100644 index 35e2130e4..000000000 --- a/libs/luabind/luabind/detail/conversion_policies/native_converter.hpp +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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 LUABIND_NATIVE_CONVERTER_HPP_INCLUDED -#define LUABIND_NATIVE_CONVERTER_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include -#include - -#if LUA_VERSION_NUM < 502 -# define lua_rawlen lua_objlen -#endif - -namespace luabind { - - template > - struct native_converter_base - { - using is_native = std::true_type; - using value_type = typename detail::call_traits::value_type; - using param_type = typename detail::call_traits::param_type; - - enum { consumed_args = 1 }; - - template - void converter_postcall(lua_State*, U const&, int) - {} - - int match(lua_State* L, by_value, int index) - { - return Derived::compute_score(L, index); - } - - int match(lua_State* L, by_value, int index) - { - return Derived::compute_score(L, index); - } - - - int match(lua_State* L, by_const_reference, int index) - { - return Derived::compute_score(L, index); - } - - value_type to_cpp(lua_State* L, by_value, int index) - { - return derived().to_cpp_deferred(L, index); - } - - value_type to_cpp(lua_State* L, by_const_reference, int index) - { - return derived().to_cpp_deferred(L, index); - } - - void to_lua(lua_State* L, param_type value) - { - derived().to_lua_deferred(L, value); - } - - Derived& derived() - { - return static_cast(*this); - } - }; - - template - struct integer_converter - : native_converter_base> - { - using T = remove_const_reference_t; - using value_type = typename native_converter_base::value_type; - using param_type = typename native_converter_base::param_type; - - static int compute_score(lua_State* L, int index) - { - return lua_type(L, index) == LUA_TNUMBER ? 0 : no_match; - } - - static value_type to_cpp_deferred(lua_State* L, int index) - { - if((std::is_unsigned::value && sizeof(value_type) >= sizeof(lua_Integer)) || (sizeof(value_type) > sizeof(lua_Integer))) { - return static_cast(lua_tonumber(L, index)); - } else { - return static_cast(lua_tointeger(L, index)); - } - } - - void to_lua_deferred(lua_State* L, param_type value) - { - if((std::is_unsigned::value && sizeof(value_type) >= sizeof(lua_Integer)) || (sizeof(value_type) > sizeof(lua_Integer))) - { - lua_pushnumber(L, (lua_Number)value); - } else { - lua_pushinteger(L, static_cast(value)); - } - } - }; - - template - struct number_converter - : native_converter_base> - { - using T = remove_const_reference_t; - using value_type = typename native_converter_base::value_type; - using param_type = typename native_converter_base::param_type; - - static int compute_score(lua_State* L, int index) - { - return lua_type(L, index) == LUA_TNUMBER ? 0 : no_match; - } - - static value_type to_cpp_deferred(lua_State* L, int index) - { - return static_cast(lua_tonumber(L, index)); - } - - static void to_lua_deferred(lua_State* L, param_type value) - { - lua_pushnumber(L, static_cast(value)); - } - }; - - template <> - struct default_converter - : native_converter_base - { - static int compute_score(lua_State* L, int index) - { - return lua_type(L, index) == LUA_TBOOLEAN ? 0 : no_match; - } - - static bool to_cpp_deferred(lua_State* L, int index) - { - return lua_toboolean(L, index) == 1; - } - - static void to_lua_deferred(lua_State* L, bool value) - { - lua_pushboolean(L, value); - } - }; - - - template <> - struct default_converter - : default_converter - {}; - - template <> - struct default_converter - : default_converter - {}; - - template <> - struct default_converter - : native_converter_base - { - static int compute_score(lua_State* L, int index) - { - return lua_type(L, index) == LUA_TSTRING ? 0 : no_match; - } - - static std::string to_cpp_deferred(lua_State* L, int index) - { - return std::string(lua_tostring(L, index), lua_rawlen(L, index)); - } - - static void to_lua_deferred(lua_State* L, std::string const& value) - { - lua_pushlstring(L, value.data(), value.size()); - } - }; - - template <> - struct default_converter - : default_converter - {}; - - template <> - struct default_converter - : default_converter - {}; - - template <> - struct default_converter - : default_converter - {}; - - template <> - struct default_converter - { - using is_native = std::true_type; - - enum { consumed_args = 1 }; - - template - static int match(lua_State* L, U, int index) - { - int type = lua_type(L, index); - return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : no_match; - } - - template - static char const* to_cpp(lua_State* L, U, int index) - { - return lua_tostring(L, index); - } - - static void to_lua(lua_State* L, char const* str) - { - lua_pushstring(L, str); - } - - template - void converter_postcall(lua_State*, U, int) - {} - }; - - template <> - struct default_converter - : default_converter - {}; - - template <> - struct default_converter - : default_converter - {}; - - template <> - struct default_converter - : default_converter - {}; - - template <> - struct default_converter - : default_converter - {}; - - template - struct default_converter - : default_converter - {}; - - template - struct default_converter - : default_converter - {}; - - template - struct default_converter - : default_converter - {}; - - template - struct default_converter - : default_converter - {}; - - template - struct default_converter < T, typename std::enable_if< std::is_integral>::value >::type > - : integer_converter - { - }; - - template - struct default_converter < T, typename std::enable_if< std::is_floating_point>::value >::type > - : number_converter - { - }; - -} - -#if LUA_VERSION_NUM < 502 -# undef lua_rawlen -#endif - -#endif - diff --git a/libs/luabind/luabind/detail/conversion_policies/pointer_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/pointer_converter.hpp deleted file mode 100644 index 95289811d..000000000 --- a/libs/luabind/luabind/detail/conversion_policies/pointer_converter.hpp +++ /dev/null @@ -1,143 +0,0 @@ -// 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 LUABIND_POINTER_CONVERTER_HPP_INCLUDED -#define LUABIND_POINTER_CONVERTER_HPP_INCLUDED - -#include -#include -#include -#include - -namespace luabind { - - /* - Todo: Remove code duplication - */ - - namespace detail { - - struct pointer_converter - { - using type = pointer_converter; - using is_native = std::false_type; - - pointer_converter() - : result(0) - {} - - void* result; - - enum { consumed_args = 1 }; - - template - static void to_lua(lua_State* L, T* ptr) - { - if(ptr == 0) - { - lua_pushnil(L); - return; - } - - if(luabind::get_back_reference(L, ptr)) - return; - - make_pointer_instance(L, ptr); - } - - template - T* to_cpp(lua_State*, by_pointer, int /*index*/) - { - return static_cast(result); - } - - template - int match(lua_State* L, by_pointer, int index) - { - if(lua_isnil(L, index)) return 0; - object_rep* obj = get_instance(L, index); - if(obj == 0) return no_match; - - if(obj->is_const()) - return no_match; - - std::pair s = obj->get_instance(registered_class::id); - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, by_pointer, int /*index*/) - {} - }; - - struct const_pointer_converter - { - using type = const_pointer_converter; - using is_native = std::false_type; - - enum { consumed_args = 1 }; - - const_pointer_converter() - : result(0) - {} - - void* result; - - template - void to_lua(lua_State* L, const T* ptr) - { - if(ptr == 0) - { - lua_pushnil(L); - return; - } - - if(luabind::get_back_reference(L, ptr)) - return; - - make_pointer_instance(L, ptr); - } - - template - T const* to_cpp(lua_State*, by_const_pointer, int) - { - return static_cast(result); - } - - template - int match(lua_State* L, by_const_pointer, int index) - { - if(lua_isnil(L, index)) return 0; - object_rep* obj = get_instance(L, index); - if(obj == 0) return no_match; // if the type is not one of our own registered types, classify it as a non-match - std::pair s = obj->get_instance(registered_class::id); - if(s.second >= 0 && !obj->is_const()) - s.second += 10; - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - } - -} - -#endif - diff --git a/libs/luabind/luabind/detail/conversion_policies/reference_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/reference_converter.hpp deleted file mode 100644 index 679c63692..000000000 --- a/libs/luabind/luabind/detail/conversion_policies/reference_converter.hpp +++ /dev/null @@ -1,124 +0,0 @@ -// 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 LUABIND_REFERENCE_CONVERTER_HPP_INCLUDED -#define LUABIND_REFERENCE_CONVERTER_HPP_INCLUDED - -#include -#include -#include -#include - -namespace luabind { - - /* - TODO: Remove code duplication - */ - namespace detail { - - struct ref_converter : pointer_converter - { - using type = ref_converter; - using is_native = std::false_type; - - enum { consumed_args = 1 }; - - template - void to_lua(lua_State* L, T& ref) - { - if(luabind::get_back_reference(L, ref)) - return; - - make_pointee_instance(L, ref, std::false_type()); - } - - template - T& to_cpp(lua_State* L, by_reference, int index) - { - assert(!lua_isnil(L, index)); - return *pointer_converter::to_cpp(L, by_pointer(), index); - } - - template - int match(lua_State* L, by_reference, int index) - { - object_rep* obj = get_instance(L, index); - if(obj == 0) return no_match; - - if(obj->is_const()) - return no_match; - - std::pair s = obj->get_instance(registered_class::id); - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - struct const_ref_converter - { - using type = const_ref_converter; - using is_native = std::false_type; - - enum { consumed_args = 1 }; - - const_ref_converter() - : result(0) - {} - - void* result; - - template - void to_lua(lua_State* L, T const& ref) - { - if(luabind::get_back_reference(L, ref)) - return; - - make_pointee_instance(L, ref, std::false_type()); - } - - template - T const& to_cpp(lua_State*, by_const_reference, int) - { - return *static_cast(result); - } - - template - int match(lua_State* L, by_const_reference, int index) - { - object_rep* obj = get_instance(L, index); - if(obj == 0) return no_match; // if the type is not one of our own registered types, classify it as a non-match - - std::pair s = obj->get_instance(registered_class::id); - if(s.second >= 0 && !obj->is_const()) - s.second += 10; - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, by_const_reference, int) - { - } - }; - - } -} - -#endif - diff --git a/libs/luabind/luabind/detail/conversion_policies/value_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/value_converter.hpp deleted file mode 100644 index fa91e6712..000000000 --- a/libs/luabind/luabind/detail/conversion_policies/value_converter.hpp +++ /dev/null @@ -1,79 +0,0 @@ -// 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 LUABIND_VALUE_CONVERTER_HPP_INCLUDED -#define LUABIND_VALUE_CONVERTER_HPP_INCLUDED - -#include -#include -#include -#include - -namespace luabind { - namespace detail { - - struct value_converter - { - using type = value_converter; - using is_native = std::false_type; - - enum { consumed_args = 1 }; - - value_converter() - : result(0) - {} - - void* result; - - template - void to_lua(lua_State* L, T&& x) - { - if(luabind::get_back_reference(L, x)) - return; - - make_value_instance(L, std::forward(x)); - } - - template - T to_cpp(lua_State*, by_value, int) - { - return *static_cast(result); - } - - template - int match(lua_State* L, by_value, int index) - { - // special case if we get nil in, try to match the holder type - if(lua_isnil(L, index)) - return no_match; - - object_rep* obj = get_instance(L, index); - if(obj == 0) return no_match; - - std::pair s = obj->get_instance(registered_class::id); - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - } -} - -#endif - diff --git a/libs/luabind/luabind/detail/conversion_storage.hpp b/libs/luabind/luabind/detail/conversion_storage.hpp index 9fc443163..153112d62 100644 --- a/libs/luabind/luabind/detail/conversion_storage.hpp +++ b/libs/luabind/luabind/detail/conversion_storage.hpp @@ -6,38 +6,36 @@ # define LUABIND_CONVERSION_STORAGE_080930_HPP # include -# include +# include -namespace luabind { - namespace detail { +namespace luabind { namespace detail { - using destruction_function = void(*)(void*); +typedef void(*destruction_function)(void*); - // This is used by the converters in policy.hpp, and - // class_rep::convert_to as temporary storage when constructing - // holders. +// This is used by the converters in policy.hpp, and +// class_rep::convert_to as temporary storage when constructing +// holders. - struct conversion_storage - { - conversion_storage() - : destructor(0) - {} +struct conversion_storage +{ + conversion_storage() + : destructor(0) + {} - ~conversion_storage() - { - if(destructor) - destructor(&data); - } + ~conversion_storage() + { + if (destructor) + destructor(&data); + } - // Unfortunately the converters currently doesn't have access to - // the actual type being converted when this is instantiated, so - // we have to guess a max size. - std::aligned_storage<128> data; - destruction_function destructor; - }; + // Unfortunately the converters currently doesn't have access to + // the actual type being converted when this is instantiated, so + // we have to guess a max size. + boost::aligned_storage<128> data; + destruction_function destructor; +}; - } -} // namespace luabind::detail +}} // namespace luabind::detail #endif // LUABIND_CONVERSION_STORAGE_080930_HPP diff --git a/libs/luabind/luabind/detail/convert_to_lua.hpp b/libs/luabind/luabind/detail/convert_to_lua.hpp new file mode 100644 index 000000000..f5aa89aea --- /dev/null +++ b/libs/luabind/luabind/detail/convert_to_lua.hpp @@ -0,0 +1,92 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_CONVERT_TO_LUA_HPP_INCLUDED +#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED + +#include +#include +#include + +#include + +namespace luabind { namespace detail +{ + template + struct unwrap_ref + { + template + static const T& get(const T& r) { return r; } + + template + struct apply + { + typedef T type; + }; + }; + + template<> + struct unwrap_ref + { + template + static T& get(const boost::reference_wrapper& r) { return r.get(); } + + template + struct apply + { + typedef typename T::type& type; + }; + }; + + namespace mpl = boost::mpl; + + template + void convert_to_lua(lua_State* L, const T& v) + { + typedef typename mpl::apply_wrap1< + unwrap_ref::value> + , T + >::type value_type; + + typename mpl::apply_wrap2::type converter; + + converter.apply(L, unwrap_ref::value>::get(v)); + } + + template + void convert_to_lua_p(lua_State* L, const T& v, const Policies&) + { + typedef typename mpl::apply_wrap1< + unwrap_ref::value> + , T + >::type value_type; + + typedef typename find_conversion_policy::type converter_policy; + typename mpl::apply_wrap2::type converter; + + converter.apply(L, unwrap_ref::value>::get(v)); + } +}} + +#endif + diff --git a/libs/luabind/luabind/detail/crtp_iterator.hpp b/libs/luabind/luabind/detail/crtp_iterator.hpp deleted file mode 100644 index 7973ba5fd..000000000 --- a/libs/luabind/luabind/detail/crtp_iterator.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef LUABIND_CRTP_ITERATOR_HPP_INCLUDED -#define LUABIND_CRTP_ITERATOR_HPP_INCLUDED - -#include - -namespace luabind { - namespace detail { - - template< typename CRTP, typename Category, typename ValueType, typename ReferenceType = ValueType&, typename DifferenceType = ptrdiff_t > - class crtp_iterator : - public std::iterator - { - public: - using base_type = std::iterator; - - - CRTP& operator++() - { - upcast().increment(); - return upcast(); - } - - CRTP operator++(int) - { - CRTP tmp(upcast()); - upcast().increment(); - return tmp; - } - - bool operator==(const CRTP& rhs) - { - return upcast().equal(rhs); - } - - bool operator!=(const CRTP& rhs) - { - return !upcast().equal(rhs); - } - - typename base_type::reference operator*() - { - return upcast().dereference(); - } - - typename base_type::reference operator->() - { - return upcast().dereference(); - } - - private: - CRTP& upcast() { return static_cast(*this); } - const CRTP& upcast() const { return static_cast(*this); } - }; - - } -} - -#endif diff --git a/libs/luabind/luabind/detail/debug.hpp b/libs/luabind/luabind/detail/debug.hpp index e3e1c1f14..ef13bc886 100644 --- a/libs/luabind/luabind/detail/debug.hpp +++ b/libs/luabind/luabind/detail/debug.hpp @@ -28,32 +28,28 @@ #include #include -namespace luabind { - namespace detail { +namespace luabind { namespace detail +{ + struct stack_checker_type + { + stack_checker_type(lua_State* L) + : m_L(L) + , m_stack(lua_gettop(m_L)) + {} - struct stack_checker_type + ~stack_checker_type() { - stack_checker_type(lua_State* L) - : m_L(L) - , m_stack(lua_gettop(m_L)) - {} + assert(m_stack == lua_gettop(m_L)); + } - ~stack_checker_type() - { - assert(m_stack == lua_gettop(m_L)); - } - - lua_State* m_L; - int m_stack; - }; - - } -} + lua_State* m_L; + int m_stack; + }; +}} #define LUABIND_CHECK_STACK(L) luabind::detail::stack_checker_type stack_checker_object(L) #else #define LUABIND_CHECK_STACK(L) do {} while (0) #endif #endif // LUABIND_DEBUG_HPP_INCLUDED - diff --git a/libs/luabind/luabind/detail/decorate_type.hpp b/libs/luabind/luabind/detail/decorate_type.hpp index 7752bfd4d..bb144c463 100644 --- a/libs/luabind/luabind/detail/decorate_type.hpp +++ b/libs/luabind/luabind/detail/decorate_type.hpp @@ -25,62 +25,242 @@ #define LUABIND_DECORATE_TYPE_HPP_INCLUDED #include +#include -namespace luabind { +namespace luabind { namespace detail +{ - template struct by_value {}; - template struct by_const_reference {}; - template struct by_reference {}; - template struct by_rvalue_reference {}; - template struct by_pointer {}; - template struct by_const_pointer {}; +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template - struct decorate_type + struct decorated_type { - using type = by_value; + static by_value t; + static inline by_value& get() { return /*by_value()*/t; } }; template - struct decorate_type + by_value decorated_type::t; + + template + struct decorated_type { - using type = by_pointer; + static by_pointer t; + static inline by_pointer& get() { return /*by_pointer()*/t; } }; template - struct decorate_type + by_pointer decorated_type::t; + + template + struct decorated_type { - using type = by_const_pointer; + static by_const_pointer t; + static inline by_const_pointer get() { return /*by_const_pointer()*/t; } }; template - struct decorate_type + by_const_pointer decorated_type::t; + + template + struct decorated_type { - using type = by_const_pointer; + static by_const_pointer t; + static inline by_const_pointer& get() { return /*by_const_pointer()*/t; } }; template - struct decorate_type + by_const_pointer decorated_type::t; + + template + struct decorated_type { - using type = by_reference; + static by_reference t; + static inline by_reference& get() { return /*by_reference()*/t; } }; template - struct decorate_type + by_reference decorated_type::t; + + template + struct decorated_type { - using type = by_const_reference; + static by_const_reference t; + static inline by_const_reference& get() { return /*by_const_reference()*/t; } }; template - struct decorate_type + by_const_reference decorated_type::t; + + #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get() + +#else + +#include + + namespace { - using type = by_rvalue_reference; + LUABIND_ANONYMOUS_FIX char decorated_type_array[64]; + } + + template + struct decorated_type_cref_impl + { +#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 + template + static by_const_reference get(const U&) + { + return by_const_reference(); + } + static T data() { return reinterpret_cast(decorated_type_array); } +#else + + static void(*data())(T) + { return (void(*)(T))0; } + + template + static by_const_reference get(void(*f)(const U&)) + { return by_const_reference(); } +#endif }; - template< typename T > - using decorate_type_t = typename decorate_type::type; + template + struct decorated_type_ref_impl + { +#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 + template + static by_reference get(U&) + { + return by_reference(); + } + static T data() { return reinterpret_cast(decorated_type_array); } +#else + static void(*data())(T) + { return (void(*)(T))0; } -} + template + static by_reference get(void(*)(U&)) + { return by_reference(); } +#endif + }; + + template + struct decorated_type_cptr_impl + { +#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 + template + static by_const_pointer get(const U*) + { + return by_const_pointer(); + } + static T& data() { return reinterpret_cast(decorated_type_array); } +#else + static void(*data())(T) + { return (void(*)(T))0; } + + template + static by_const_pointer get(void(*)(const U*)) + { return by_const_pointer(); } +#endif + }; + + template + struct decorated_type_ptr_impl + { +#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 + template + static by_pointer get(U*) + { + return by_pointer(); + } + static T& data() { return reinterpret_cast(decorated_type_array); } +#else + static void(*data())(T) + { return (void(*)(T))0; } + + template + static by_pointer get(void(*)(U*)) + { return by_pointer(); } +#endif + }; + + template + struct decorated_type_value_impl + { +#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 + template + static by_value get(U&) + { + return by_value(); + } + static T& data() { return reinterpret_cast(decorated_type_array); } +#else + static void(*data())(T&) + { return (void(*)(T&))0; } + + template + static by_value get(void(*)(U&)) + { return by_value(); } +#endif + }; + + template<> + struct decorated_type_value_impl + { + static by_value get(int) + { + return by_value(); + } + static int data() { return 0; } + }; + + template + struct decorated_type_array_impl + { + template + static by_pointer get(U*) + { + return by_pointer(); + } + + template + static by_pointer get(void(*)(U)) + { return by_pointer(); } + + static T& data() { return reinterpret_cast(decorated_type_array); } + }; + + template + struct decorated_type +// : boost::mpl::if_ +// , decorated_type_array_impl + : boost::mpl::if_ + , decorated_type_cref_impl + , typename boost::mpl::if_ + , decorated_type_ref_impl + , typename boost::mpl::if_ + , decorated_type_ptr_impl + , typename boost::mpl::if_ + , decorated_type_cptr_impl + , decorated_type_value_impl + >::type + >::type + >::type + >::type +// >::type + { + }; + +#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 + #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(luabind::detail::decorated_type::data()) +#else +// #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get((void(*)(type))0) + #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(luabind::detail::decorated_type::data()) + //#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(type()) +#endif + +#endif + +}} #endif // LUABIND_DECORATE_TYPE_HPP_INCLUDED - diff --git a/libs/luabind/luabind/detail/deduce_signature.hpp b/libs/luabind/luabind/detail/deduce_signature.hpp index 012d052d5..e47e22f4e 100644 --- a/libs/luabind/luabind/detail/deduce_signature.hpp +++ b/libs/luabind/luabind/detail/deduce_signature.hpp @@ -2,19 +2,117 @@ // subject to 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) +#if !BOOST_PP_IS_ITERATING + # ifndef LUABIND_DEDUCE_SIGNATURE_080911_HPP -# define LUABIND_DEDUCE_SIGNATURE_080911_HPP +# define LUABIND_DEDUCE_SIGNATURE_080911_HPP -#include -#include +# include -namespace luabind { - namespace detail { +# if LUABIND_MAX_ARITY <= 8 +# include +# else +# include +# endif +# include +# include +# include +namespace luabind { namespace detail { - } // namespace detail +namespace mpl = boost::mpl; -} // namespace luabind +template +mpl::vector1 deduce_signature(R(*)(), ...) +{ + return mpl::vector1(); +} + +template +mpl::vector2 deduce_signature(R(T::*)()) +{ + return mpl::vector2(); +} + +template +mpl::vector2::type&> +deduce_signature(R(T::*)(), Wrapped*) +{ + return mpl::vector2::type&>(); +} + +template +mpl::vector2 deduce_signature(R(T::*)() const) +{ + return mpl::vector2(); +} + +template +mpl::vector2::type const&> +deduce_signature(R(T::*)() const, Wrapped*) +{ + return mpl::vector2::type const&>(); +} + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (1, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +}} // namespace luabind::detail # endif // LUABIND_DEDUCE_SIGNATURE_080911_HPP +#else // BOOST_PP_IS_ITERATING + +# define N BOOST_PP_ITERATION() +# define NPLUS1 BOOST_PP_INC(N) + +template +BOOST_PP_CAT(mpl::vector,NPLUS1) +deduce_signature(R(*)(BOOST_PP_ENUM_PARAMS(N,A)), ...) +{ + return BOOST_PP_CAT(mpl::vector,NPLUS1)(); +} + +# define NPLUS2 BOOST_PP_INC(NPLUS1) + +template +BOOST_PP_CAT(mpl::vector,NPLUS2) +deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A))) +{ + return BOOST_PP_CAT(mpl::vector,NPLUS2)(); +} + +template +BOOST_PP_CAT(mpl::vector,NPLUS2)< + R, typename most_derived::type&, BOOST_PP_ENUM_PARAMS(N,A) +> +deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)), Wrapped*) +{ + return BOOST_PP_CAT(mpl::vector,NPLUS2)< + R,typename most_derived::type&,BOOST_PP_ENUM_PARAMS(N,A)>(); +} + +template +BOOST_PP_CAT(mpl::vector,NPLUS2) +deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const) +{ + return BOOST_PP_CAT(mpl::vector,NPLUS2)(); +} + +template +BOOST_PP_CAT(mpl::vector,NPLUS2)< + R, typename most_derived::type const&, BOOST_PP_ENUM_PARAMS(N,A) +> +deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const, Wrapped*) +{ + return BOOST_PP_CAT(mpl::vector,NPLUS2)< + R,typename most_derived::type const&,BOOST_PP_ENUM_PARAMS(N,A)>(); +} + +# undef NPLUS2 +# undef NPLUS1 +# undef N + +#endif // BOOST_PP_IS_ITERATING + diff --git a/libs/luabind/luabind/detail/enum_maker.hpp b/libs/luabind/luabind/detail/enum_maker.hpp index 20161ec3f..fadbe3e52 100644 --- a/libs/luabind/luabind/detail/enum_maker.hpp +++ b/libs/luabind/luabind/detail/enum_maker.hpp @@ -30,8 +30,8 @@ #include #include -namespace luabind { - +namespace luabind +{ struct value; struct value_vector : public std::vector @@ -45,7 +45,7 @@ namespace luabind { struct value { - friend class std::vector; + friend class std::vector; template value(const char* name, T v) : name_(name) @@ -65,7 +65,7 @@ namespace luabind { return v; } - private: + private: value() {} }; @@ -93,18 +93,19 @@ namespace luabind { template struct enum_maker { - explicit enum_maker(From& from) : from_(from) {} + explicit enum_maker(From& from): from_(from) {} From& operator[](const value& val) { from_.add_static_constant(val.name_, val.val_); return from_; } - + From& operator[](const value_vector& values) { - for(const auto& val : values) { - from_.add_static_constant(val.name_, val.val_); + for (value_vector::const_iterator i = values.begin(); i != values.end(); ++i) + { + from_.add_static_constant(i->name_, i->val_); } return from_; @@ -113,11 +114,10 @@ namespace luabind { From& from_; private: - void operator=(enum_maker const&); // C4512, assignment operator could not be generated + void operator=(enum_maker const&); // C4512, assignment operator could not be generated template void operator,(T const&) const; }; } } #endif // LUABIND_ENUM_MAKER_HPP_INCLUDED - diff --git a/libs/luabind/luabind/detail/format_signature.hpp b/libs/luabind/luabind/detail/format_signature.hpp index bb6679dba..ec56b6196 100644 --- a/libs/luabind/luabind/detail/format_signature.hpp +++ b/libs/luabind/luabind/detail/format_signature.hpp @@ -5,70 +5,73 @@ #ifndef LUABIND_FORMAT_SIGNATURE_081014_HPP # define LUABIND_FORMAT_SIGNATURE_081014_HPP -#include -#include -#include -#include +# include +# include +# include -namespace luabind { - namespace adl { +# include +# include +# include - class object; - class argument; - template - struct table; +namespace luabind { namespace adl { - } // namespace adl + class object; + class argument; + template + struct table; +} // namespace adl - using adl::object; - using adl::argument; - using adl::table; +using adl::object; +using adl::argument; +using adl::table; - namespace detail { +} // namespace luabind - LUABIND_API std::string get_class_name(lua_State* L, type_id const& i); +namespace luabind { namespace detail { - template - struct type_to_string - { - static void get(lua_State* L) - { - lua_pushstring(L, get_class_name(L, typeid(T)).c_str()); - } - }; +LUABIND_API std::string get_class_name(lua_State* L, type_id const& i); - template - struct type_to_string - { - static void get(lua_State* L) - { - type_to_string::get(L); - lua_pushstring(L, "*"); - lua_concat(L, 2); - } - }; +template +struct type_to_string +{ + static void get(lua_State* L) + { + lua_pushstring(L, get_class_name(L, typeid(T)).c_str()); + } +}; - template - struct type_to_string - { - static void get(lua_State* L) - { - type_to_string::get(L); - lua_pushstring(L, "&"); - lua_concat(L, 2); - } - }; +template +struct type_to_string +{ + static void get(lua_State* L) + { + type_to_string::get(L); + lua_pushstring(L, "*"); + lua_concat(L, 2); + } +}; - template - struct type_to_string - { - static void get(lua_State* L) - { - type_to_string::get(L); - lua_pushstring(L, " const"); - lua_concat(L, 2); - } - }; +template +struct type_to_string +{ + static void get(lua_State* L) + { + type_to_string::get(L); + lua_pushstring(L, "&"); + lua_concat(L, 2); + } +}; + +template +struct type_to_string +{ + static void get(lua_State* L) + { + type_to_string::get(L); + lua_pushstring(L, " const"); + lua_concat(L, 2); + } +}; # define LUABIND_TYPE_TO_STRING(x) \ template <> \ @@ -84,67 +87,67 @@ namespace luabind { LUABIND_TYPE_TO_STRING(x) \ LUABIND_TYPE_TO_STRING(unsigned x) - LUABIND_INTEGRAL_TYPE_TO_STRING(char) - LUABIND_INTEGRAL_TYPE_TO_STRING(short) - LUABIND_INTEGRAL_TYPE_TO_STRING(int) - LUABIND_INTEGRAL_TYPE_TO_STRING(long) +LUABIND_INTEGRAL_TYPE_TO_STRING(char) +LUABIND_INTEGRAL_TYPE_TO_STRING(short) +LUABIND_INTEGRAL_TYPE_TO_STRING(int) +LUABIND_INTEGRAL_TYPE_TO_STRING(long) - LUABIND_TYPE_TO_STRING(void) - LUABIND_TYPE_TO_STRING(bool) - LUABIND_TYPE_TO_STRING(std::string) - LUABIND_TYPE_TO_STRING(lua_State) +LUABIND_TYPE_TO_STRING(void) +LUABIND_TYPE_TO_STRING(bool) +LUABIND_TYPE_TO_STRING(std::string) +LUABIND_TYPE_TO_STRING(lua_State) - LUABIND_TYPE_TO_STRING(luabind::object) - LUABIND_TYPE_TO_STRING(luabind::argument) +LUABIND_TYPE_TO_STRING(luabind::object) +LUABIND_TYPE_TO_STRING(luabind::argument) # undef LUABIND_INTEGRAL_TYPE_TO_STRING # undef LUABIND_TYPE_TO_STRING - template - struct type_to_string > - { - static void get(lua_State* L) - { - lua_pushstring(L, "table"); - } - }; +template +struct type_to_string > +{ + static void get(lua_State* L) + { + lua_pushstring(L, "table"); + } +}; - inline void format_signature_aux(lua_State*, bool, meta::type_list< >) - {} +template +void format_signature_aux(lua_State*, bool, End, End) +{} - template - void format_signature_aux(lua_State* L, bool first, Signature) - { - if(!first) - lua_pushstring(L, ","); - type_to_string::type>::get(L); - format_signature_aux(L, false, typename meta::pop_front::type()); - } +template +void format_signature_aux(lua_State* L, bool first, Iter, End end) +{ + if (!first) + lua_pushstring(L, ","); + type_to_string::get(L); + format_signature_aux(L, false, typename mpl::next::type(), end); +} - template - void format_signature(lua_State* L, char const* function, Signature) - { - using first = typename meta::front::type; +template +void format_signature(lua_State* L, char const* function, Signature) +{ + typedef typename mpl::begin::type first; - type_to_string::get(L); + type_to_string::get(L); - lua_pushstring(L, " "); - lua_pushstring(L, function); + lua_pushstring(L, " "); + lua_pushstring(L, function); - lua_pushstring(L, "("); - format_signature_aux( - L - , true - , typename meta::pop_front::type() - ); - lua_pushstring(L, ")"); - constexpr size_t ncat = meta::size::value * 2 + 2 + (meta::size::value == 1 ? 1 : 0); - lua_concat(L, static_cast(ncat)); - } + lua_pushstring(L, "("); + format_signature_aux( + L + , true + , typename mpl::next::type() + , typename mpl::end::type() + ); + lua_pushstring(L, ")"); - } // namespace detail + lua_concat(L, static_cast(mpl::size()) * 2 + 2); +} -} // namespace luabind +}} // namespace luabind::detail #endif // LUABIND_FORMAT_SIGNATURE_081014_HPP diff --git a/libs/luabind/luabind/detail/garbage_collector.hpp b/libs/luabind/luabind/detail/garbage_collector.hpp index 9e55d2b4a..c0d68aa36 100644 --- a/libs/luabind/luabind/detail/garbage_collector.hpp +++ b/libs/luabind/luabind/detail/garbage_collector.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -26,31 +26,28 @@ #include -namespace luabind { - namespace detail { +namespace luabind { namespace detail +{ + // function that is used as __gc metafunction on several objects + template + inline int garbage_collector(lua_State* L) + { + T* obj = static_cast(lua_touserdata(L, -1)); + obj->~T(); + return 0; + } - // function that is used as __gc metafunction on several objects - template - inline int garbage_collector(lua_State* L) + template + struct garbage_collector_s + { + static int apply(lua_State* L) { T* obj = static_cast(lua_touserdata(L, -1)); obj->~T(); return 0; } + }; - template - struct garbage_collector_s - { - static int apply(lua_State* L) - { - T* obj = static_cast(lua_touserdata(L, -1)); - obj->~T(); - return 0; - } - }; - - } -} +}} #endif // LUABIND_GARBAGE_COLLECTOR_HPP_INCLUDED - diff --git a/libs/luabind/luabind/detail/has_get_pointer.hpp b/libs/luabind/luabind/detail/has_get_pointer.hpp new file mode 100644 index 000000000..8a001ddda --- /dev/null +++ b/libs/luabind/luabind/detail/has_get_pointer.hpp @@ -0,0 +1,107 @@ +// Copyright (c) 2005 Daniel Wallin + +// 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 LUABIND_HAS_GET_POINTER_051022_HPP +# define LUABIND_HAS_GET_POINTER_051022_HPP + +# include + +# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# include +# endif + +namespace luabind { namespace detail { + +namespace has_get_pointer_ +{ + + struct any + { + template any(T const&); + }; + + struct no_overload_tag + {}; + + typedef char (&yes)[1]; + typedef char (&no)[2]; + + no_overload_tag operator,(no_overload_tag, int); + +// +// On compilers with ADL, we need these generic overloads in this +// namespace as well as in luabind::. Otherwise get_pointer(any) +// will be found before them. +// +# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + + template + T* get_pointer(T const volatile*); + + template + T* get_pointer(std::auto_ptr const&); + +# endif + +// +// On compilers that doesn't support ADL, the overload below has to +// live in luabind::. +// +# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +}} // namespace detail::has_get_pointer_ +# endif + +detail::has_get_pointer_::no_overload_tag + get_pointer(detail::has_get_pointer_::any); + +# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +namespace detail { namespace has_get_pointer_ +{ +# endif + + template + yes check(T const&); + no check(no_overload_tag); + + template + struct impl + { + static typename boost::add_reference::type x; + + BOOST_STATIC_CONSTANT(bool, + value = sizeof(has_get_pointer_::check( (get_pointer(x),0) )) == 1 + ); + + typedef boost::mpl::bool_ type; + }; + +} // namespace has_get_pointer_ + +template +struct has_get_pointer + : has_get_pointer_::impl::type +{}; + +}} // namespace luabind::detail + +#endif // LUABIND_HAS_GET_POINTER_051022_HPP + diff --git a/libs/luabind/luabind/detail/inheritance.hpp b/libs/luabind/luabind/detail/inheritance.hpp index 26bde136a..a7afe0156 100644 --- a/libs/luabind/luabind/detail/inheritance.hpp +++ b/libs/luabind/luabind/detail/inheritance.hpp @@ -1,169 +1,168 @@ // Copyright Daniel Wallin 2009. Use, modification and distribution is // subject to 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) + #ifndef LUABIND_INHERITANCE_090217_HPP # define LUABIND_INHERITANCE_090217_HPP -# include # include # include # include # include # include # include +# include -namespace luabind { +namespace luabind { namespace detail { - namespace detail { +typedef void*(*cast_function)(void*); +typedef std::size_t class_id; - using cast_function = void*(*)(void*); - using class_id = std::size_t; +class_id const unknown_class = (std::numeric_limits::max)(); - constexpr class_id unknown_class = std::numeric_limits::max(); +class class_rep; - class class_rep; +class LUABIND_API cast_graph +{ +public: + cast_graph(); + ~cast_graph(); - class LUABIND_API cast_graph - { - public: - cast_graph(); - ~cast_graph(); + // `src` and `p` here describe the *most derived* object. This means that + // for a polymorphic type, the pointer must be cast with + // dynamic_cast before being passed in here, and `src` has to + // match typeid(*p). + std::pair cast( + void* p, class_id src, class_id target + , class_id dynamic_id, void const* dynamic_ptr) const; + void insert(class_id src, class_id target, cast_function cast); - // `src` and `p` here describe the *most derived* object. This means that - // for a polymorphic type, the pointer must be cast with - // dynamic_cast before being passed in here, and `src` has to - // match typeid(*p). - std::pair cast(void* p, class_id src, class_id target, class_id dynamic_id, void const* dynamic_ptr) const; - void insert(class_id src, class_id target, cast_function cast); +private: + class impl; + boost::scoped_ptr m_impl; +}; - private: - class impl; - std::unique_ptr m_impl; - }; +// Maps a type_id to a class_id. Note that this actually partitions the +// id-space into two, using one half for "local" ids; ids that are used only as +// keys into the conversion cache. This is needed because we need a unique key +// even for types that hasn't been registered explicitly. +class LUABIND_API class_id_map +{ +public: + class_id_map(); - // Maps a type_id to a class_id. Note that this actually partitions the - // id-space into two, using one half for "local" ids; ids that are used only as - // keys into the conversion cache. This is needed because we need a unique key - // even for types that hasn't been registered explicitly. - class LUABIND_API class_id_map - { - public: - class_id_map(); + class_id get(type_id const& type) const; + class_id get_local(type_id const& type); + void put(class_id id, type_id const& type); - class_id get(type_id const& type) const; - class_id get_local(type_id const& type); - void put(class_id id, type_id const& type); +private: + typedef std::map map_type; + map_type m_classes; + class_id m_local_id; - private: - using map_type = std::map; - map_type m_classes; - class_id m_local_id; + static class_id const local_id_base; +}; - static class_id const local_id_base; - }; +inline class_id_map::class_id_map() + : m_local_id(local_id_base) +{} - inline class_id_map::class_id_map() - : m_local_id(local_id_base) - {} +inline class_id class_id_map::get(type_id const& type) const +{ + map_type::const_iterator i = m_classes.find(type); + if (i == m_classes.end() || i->second >= local_id_base) + return unknown_class; + return i->second; +} - inline class_id class_id_map::get(type_id const& type) const - { - map_type::const_iterator i = m_classes.find(type); - if(i == m_classes.end() || i->second >= local_id_base) { - return unknown_class; - } - else { - return i->second; - } - } +inline class_id class_id_map::get_local(type_id const& type) +{ + std::pair result = m_classes.insert( + std::make_pair(type, 0)); - inline class_id class_id_map::get_local(type_id const& type) - { - std::pair result = m_classes.insert(std::make_pair(type, 0)); + if (result.second) + result.first->second = m_local_id++; - if(result.second) result.first->second = m_local_id++; - assert(m_local_id >= local_id_base); - return result.first->second; - } + assert(m_local_id >= local_id_base); - inline void class_id_map::put(class_id id, type_id const& type) - { - assert(id < local_id_base); + return result.first->second; +} - std::pair result = m_classes.insert( - std::make_pair(type, 0)); +inline void class_id_map::put(class_id id, type_id const& type) +{ + assert(id < local_id_base); - assert( - result.second - || result.first->second == id - || result.first->second >= local_id_base - ); + std::pair result = m_classes.insert( + std::make_pair(type, 0)); - result.first->second = id; - } + assert( + result.second + || result.first->second == id + || result.first->second >= local_id_base + ); - class class_map - { - public: - class_rep* get(class_id id) const; - void put(class_id id, class_rep* cls); + result.first->second = id; +} - private: - std::vector m_classes; - }; +class class_map +{ +public: + class_rep* get(class_id id) const; + void put(class_id id, class_rep* cls); - inline class_rep* class_map::get(class_id id) const - { - if(id >= m_classes.size()) - return 0; - return m_classes[id]; - } +private: + std::vector m_classes; +}; - inline void class_map::put(class_id id, class_rep* cls) - { - if(id >= m_classes.size()) - m_classes.resize(id + 1); - m_classes[id] = cls; - } +inline class_rep* class_map::get(class_id id) const +{ + if (id >= m_classes.size()) + return 0; + return m_classes[id]; +} - template - struct static_cast_ - { - static void* execute(void* p) - { - return static_cast(static_cast(p)); - } - }; +inline void class_map::put(class_id id, class_rep* cls) +{ + if (id >= m_classes.size()) + m_classes.resize(id + 1); + m_classes[id] = cls; +} - template - struct dynamic_cast_ - { - static void* execute(void* p) - { - return dynamic_cast(static_cast(p)); - } - }; +template +struct static_cast_ +{ + static void* execute(void* p) + { + return static_cast(static_cast(p)); + } +}; - // Thread safe class_id allocation. - LUABIND_API class_id allocate_class_id(type_id const& cls); +template +struct dynamic_cast_ +{ + static void* execute(void* p) + { + return dynamic_cast(static_cast(p)); + } +}; - template - struct registered_class - { - static class_id const id; - }; +// Thread safe class_id allocation. +LUABIND_API class_id allocate_class_id(type_id const& cls); - template - class_id const registered_class::id = allocate_class_id(typeid(T)); +template +struct registered_class +{ + static class_id const id; +}; - template - struct registered_class - : registered_class - {}; +template +class_id const registered_class::id = allocate_class_id(typeid(T)); - } // namespace detail +template +struct registered_class + : registered_class +{}; -} // namespace luabind +}} // namespace luabind::detail #endif // LUABIND_INHERITANCE_090217_HPP - diff --git a/libs/luabind/luabind/detail/instance_holder.hpp b/libs/luabind/luabind/detail/instance_holder.hpp index bf51ebb06..456e13e6b 100644 --- a/libs/luabind/luabind/detail/instance_holder.hpp +++ b/libs/luabind/luabind/detail/instance_holder.hpp @@ -6,160 +6,126 @@ # define LUABIND_INSTANCE_HOLDER_081024_HPP # include -# include +# include // TODO +# include # include +# include # include -namespace luabind { - namespace detail { +namespace luabind { namespace detail { - class instance_holder - { - public: - instance_holder(bool pointee_const) - : m_pointee_const(pointee_const) - {} +class instance_holder +{ +public: + instance_holder(class_rep* cls, bool pointee_const) + : m_cls(cls) + , m_pointee_const(pointee_const) + {} - virtual ~instance_holder() - {} + virtual ~instance_holder() + {} - virtual std::pair get(cast_graph const& casts, class_id target) const = 0; - virtual void release() = 0; + virtual std::pair get(class_id target) const = 0; - bool pointee_const() const - { - return m_pointee_const; - } + virtual void release() = 0; - private: - bool m_pointee_const; - }; + class_rep* get_class() const + { + return m_cls; + } - template - class pointer_holder : public instance_holder - { - public: - pointer_holder(P p, class_id dynamic_id, void* dynamic_ptr) : - instance_holder(detail::is_pointer_to_const

()), - p(std::move(p)), weak(0), dynamic_id(dynamic_id), dynamic_ptr(dynamic_ptr) - { - } + bool pointee_const() const + { + return m_pointee_const; + } - std::pair get(cast_graph const& casts, class_id target) const override - { - // if somebody wants the smart-ptr, he can get a reference to it - if(target == registered_class

::id) return std::pair(&this->p, 0); +private: + class_rep* m_cls; + bool m_pointee_const; +}; - void* naked_ptr = const_cast(static_cast(weak ? weak : get_pointer(p))); - if(!naked_ptr) return std::pair(nullptr, 0); +namespace mpl = boost::mpl; - using pointee_type = typename std::remove_cv::type>::type; +inline mpl::false_ check_const_pointer(void*) +{ + return mpl::false_(); +} - return casts.cast(naked_ptr, - registered_class< pointee_type >::id, - target, dynamic_id, dynamic_ptr); - } +inline mpl::true_ check_const_pointer(void const*) +{ + return mpl::true_(); +} - explicit operator bool() const - { - return p ? true : false; - } +template +void release_ownership(std::auto_ptr& p) +{ + p.release(); +} - void release() override - { - weak = const_cast(static_cast(get_pointer(p))); - release_ownership(p); - } +template +void release_ownership(P const&) +{ + throw std::runtime_error( + "luabind: smart pointer does not allow ownership transfer"); +} - private: - mutable P p; - // weak will hold a possibly stale pointer to the object owned - // by p once p has released it's owership. This is a workaround - // to make adopt() work with virtual function wrapper classes. - void* weak; - class_id dynamic_id; - void* dynamic_ptr; - }; +template +class_id static_class_id(T*) +{ + return registered_class::id; +} - template - class value_holder : - public instance_holder - { - public: - // No need for dynamic_id / dynamic_ptr, since we always get the most derived type - value_holder(lua_State* /*L*/, ValueType val) - : instance_holder(false), val_(std::move(val)) - {} +template +class pointer_holder : public instance_holder +{ +public: + pointer_holder( + P p, class_id dynamic_id, void* dynamic_ptr, class_rep* cls + ) + : instance_holder(cls, check_const_pointer(false ? get_pointer(p) : 0)) + , p(p) + , weak(0) + , dynamic_id(dynamic_id) + , dynamic_ptr(dynamic_ptr) + {} - explicit operator bool() const - { - return true; - } + std::pair get(class_id target) const + { + if (target == registered_class

::id) + return std::pair(&this->p, 0); - std::pair get(cast_graph const& casts, class_id target) const override - { - const auto this_id = registered_class::id; - void* const naked_ptr = const_cast((const void*)&val_); - if(target == this_id) return std::pair(naked_ptr, 0); - return casts.cast(naked_ptr, this_id, target, this_id, naked_ptr); - } + void* naked_ptr = const_cast(static_cast( + weak ? weak : get_pointer(p))); - void release() override - {} + if (!naked_ptr) + return std::pair((void*)0, 0); - private: - ValueType val_; - }; + return get_class()->casts().cast( + naked_ptr + , static_class_id(false ? get_pointer(p) : 0) + , target + , dynamic_id + , dynamic_ptr + ); + } - /* - Pointer types should automatically convert to reference types - */ - template - class pointer_like_holder : - public instance_holder - { - public: - // No need for dynamic_id / dynamic_ptr, since we always get the most derived type - pointer_like_holder(lua_State* /*L*/, ValueType val, class_id dynamic_id, void* dynamic_ptr) - : - instance_holder(std::is_const< decltype(*get_pointer(val)) >::value), - val_(std::move(val)), - dynamic_id_(dynamic_id), - dynamic_ptr_(dynamic_ptr) - { - } + void release() + { + weak = const_cast(static_cast( + get_pointer(p))); + release_ownership(p); + } - explicit operator bool() const - { - return val_ ? true : false; - } +private: + mutable P p; + // weak will hold a possibly stale pointer to the object owned + // by p once p has released it's owership. This is a workaround + // to make adopt() work with virtual function wrapper classes. + void* weak; + class_id dynamic_id; + void* dynamic_ptr; +}; - std::pair get(cast_graph const& casts, class_id target) const override - { - const auto value_id = registered_class::id; - void* const naked_value_ptr = const_cast((const void*)&val_); - if(target == value_id) return std::pair(naked_value_ptr, 0); - // If we were to support automatic pointer conversion, this would be the place - - using pointee_type = typename std::remove_cv::type >::type; - const auto pointee_id = registered_class< pointee_type >::id; - void* const naked_pointee_ptr = const_cast((const void*)get_pointer(val_)); - return casts.cast(naked_pointee_ptr, pointee_id, target, dynamic_id_, dynamic_ptr_); - } - - void release() override - {} - - private: - ValueType val_; - class_id dynamic_id_; - void* dynamic_ptr_; - // weak? must understand what the comment up there really means - }; - - } - -} // namespace luabind::detail +}} // namespace luabind::detail #endif // LUABIND_INSTANCE_HOLDER_081024_HPP - diff --git a/libs/luabind/luabind/detail/is_indirect_const.hpp b/libs/luabind/luabind/detail/is_indirect_const.hpp new file mode 100644 index 000000000..b6c1282fb --- /dev/null +++ b/libs/luabind/luabind/detail/is_indirect_const.hpp @@ -0,0 +1,70 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// 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 IS_INDIRECT_CONST_040211_HPP +#define IS_INDIRECT_CONST_040211_HPP + +#include +#include +#include + +namespace luabind { + + namespace detail { + + template + typename boost::is_const::type + is_indirect_const_check(T(*)(), int); + + template + typename boost::is_const::type + is_indirect_const_check(T*(*)(), long); + + template + typename boost::is_const::type + is_indirect_const_check(T&(*)(), long); + + yes_t to_yes_no(boost::mpl::true_); + no_t to_yes_no(boost::mpl::false_); + + } // namespace detail + + // returns true for: + // T = U* is_const + // T = U& is_const + // T = U is_const + template + struct is_indirect_const + { + BOOST_STATIC_CONSTANT(int, value = ( + sizeof( + detail::to_yes_no( + detail::is_indirect_const_check((T(*)())0, 0L) + )) + == sizeof(detail::yes_t) + )); + }; + +} // namespace luabind + +#endif // IS_INDIRECT_CONST_040211_HPP + diff --git a/libs/luabind/luabind/detail/link_compatibility.hpp b/libs/luabind/luabind/detail/link_compatibility.hpp index 33cb9a985..6f0006afa 100644 --- a/libs/luabind/luabind/detail/link_compatibility.hpp +++ b/libs/luabind/luabind/detail/link_compatibility.hpp @@ -25,38 +25,36 @@ #include -namespace luabind { - namespace detail { +namespace luabind { namespace detail +{ #ifdef LUABIND_NOT_THREADSAFE - LUABIND_API void not_threadsafe_defined_conflict(); + LUABIND_API void not_threadsafe_defined_conflict(); #else - LUABIND_API void not_threadsafe_not_defined_conflict(); + LUABIND_API void not_threadsafe_not_defined_conflict(); #endif #ifdef LUABIND_NO_ERROR_CHECKING - LUABIND_API void no_error_checking_defined_conflict(); + LUABIND_API void no_error_checking_defined_conflict(); #else - LUABIND_API void no_error_checking_not_defined_conflict(); + LUABIND_API void no_error_checking_not_defined_conflict(); #endif - inline void check_link_compatibility() - { -#ifdef LUABIND_NOT_THREADSAFE - not_threadsafe_defined_conflict(); -#else - not_threadsafe_not_defined_conflict(); -#endif - -#ifdef LUABIND_NO_ERROR_CHECKING - no_error_checking_defined_conflict(); -#else - no_error_checking_not_defined_conflict(); -#endif - } + inline void check_link_compatibility() + { + #ifdef LUABIND_NOT_THREADSAFE + not_threadsafe_defined_conflict(); + #else + not_threadsafe_not_defined_conflict(); + #endif + #ifdef LUABIND_NO_ERROR_CHECKING + no_error_checking_defined_conflict(); + #else + no_error_checking_not_defined_conflict(); + #endif } -} + +}} #endif - diff --git a/libs/luabind/luabind/detail/make_instance.hpp b/libs/luabind/luabind/detail/make_instance.hpp index 94c89330c..3150cf048 100644 --- a/libs/luabind/luabind/detail/make_instance.hpp +++ b/libs/luabind/luabind/detail/make_instance.hpp @@ -5,167 +5,101 @@ #ifndef LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP # define LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP +# include # include # include -namespace luabind { - namespace detail { +namespace luabind { namespace detail { - template - std::pair get_dynamic_class_aux(lua_State* L, T const* p, std::true_type) - { - lua_pushliteral(L, "__luabind_class_id_map"); - lua_rawget(L, LUA_REGISTRYINDEX); - class_id_map& class_ids = *static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); +template +std::pair get_dynamic_class_aux( + lua_State* L, T const* p, mpl::true_) +{ + lua_pushliteral(L, "__luabind_class_id_map"); + lua_rawget(L, LUA_REGISTRYINDEX); - return std::make_pair(class_ids.get_local(typeid(*p)), dynamic_cast(const_cast(p))); - } + class_id_map& class_ids = *static_cast( + lua_touserdata(L, -1)); - template - std::pair get_dynamic_class_aux(lua_State*, T const* p, std::false_type) - { - return std::make_pair(registered_class::id, (void*)p); - } + lua_pop(L, 1); - template - std::pair get_dynamic_class(lua_State* L, T* p) - { - return get_dynamic_class_aux(L, p, std::is_polymorphic()); - } + return std::make_pair( + class_ids.get_local(typeid(*p)) + , dynamic_cast(const_cast(p)) + ); +} - template - class_rep* get_pointee_class(class_map const& classes, T*) - { - return classes.get(registered_class::id); - } +template +std::pair get_dynamic_class_aux( + lua_State*, T const* p, mpl::false_) +{ + return std::make_pair(registered_class::id, (void*)p); +} - template - class_rep* get_pointee_class(lua_State* L, P const& p, class_id dynamic_id) - { - lua_pushliteral(L, "__luabind_class_map"); - lua_rawget(L, LUA_REGISTRYINDEX); +template +std::pair get_dynamic_class(lua_State* L, T* p) +{ + return get_dynamic_class_aux(L, p, boost::is_polymorphic()); +} - class_map const& classes = *static_cast(lua_touserdata(L, -1)); +template +class_rep* get_pointee_class(class_map const& classes, T*) +{ + return classes.get(registered_class::id); +} - lua_pop(L, 1); +template +class_rep* get_pointee_class(lua_State* L, P const& p, class_id dynamic_id) +{ + lua_pushliteral(L, "__luabind_class_map"); + lua_rawget(L, LUA_REGISTRYINDEX); - class_rep* cls = classes.get(dynamic_id); + class_map const& classes = *static_cast( + lua_touserdata(L, -1)); - if(!cls) { - cls = get_pointee_class(classes, get_pointer(p)); - } + lua_pop(L, 1); - return cls; - } + class_rep* cls = classes.get(dynamic_id); - // Create an appropriate instance holder for the given pointer like object. - template - void make_pointer_instance(lua_State* L, P p) - { - std::pair dynamic = get_dynamic_class(L, get_pointer(p)); + if (!cls) + cls = get_pointee_class(classes, get_pointer(p)); - class_rep* cls = get_pointee_class(L, p, dynamic.first); + return cls; +} - if(!cls) - { - throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(P).name())); - } +// Create an appropriate instance holder for the given pointer like object. +template +void make_instance(lua_State* L, P p) +{ + std::pair dynamic = get_dynamic_class(L, get_pointer(p)); - object_rep* instance = push_new_instance(L, cls); + class_rep* cls = get_pointee_class(L, p, dynamic.first); - using value_type = typename std::remove_reference

::type; - using holder_type = pointer_holder; + if (!cls) + { + throw std::runtime_error("Trying to use unregistered class"); + } - void* storage = instance->allocate(sizeof(holder_type)); + object_rep* instance = push_new_instance(L, cls); - try - { - new (storage) holder_type(std::move(p), dynamic.first, dynamic.second); - } - catch(...) - { - instance->deallocate(storage); - lua_pop(L, 1); - throw; - } + typedef pointer_holder

holder_type; - instance->set_instance(static_cast(storage)); - } + void* storage = instance->allocate(sizeof(holder_type)); + try + { + new (storage) holder_type(p, dynamic.first, dynamic.second, cls); + } + catch (...) + { + instance->deallocate(storage); + lua_pop(L, 1); + throw; + } - template< typename ValueType > - void make_value_instance(lua_State* L, ValueType&& val, std::true_type /* is smart ptr */) - { - if(get_pointer(val)) { - std::pair dynamic = get_dynamic_class(L, get_pointer(val)); - class_rep* cls = get_pointee_class(L, val, dynamic.first); + instance->set_instance(static_cast(storage)); +} - using pointee_type = decltype(*get_pointer(val)); - - if(!cls) { - throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(pointee_type).name())); - } - - object_rep* instance = push_new_instance(L, cls); - - using value_type = typename std::remove_reference::type; - using holder_type = pointer_like_holder; - - void* storage = instance->allocate(sizeof(holder_type)); - - try { - new (storage) holder_type(L, std::forward(val), dynamic.first, dynamic.second); - } - catch(...) { - instance->deallocate(storage); - lua_pop(L, 1); - throw; - } - - instance->set_instance(static_cast(storage)); - } else { - lua_pushnil(L); - } - } - - template< typename ValueType > - void make_value_instance(lua_State* L, ValueType&& val, std::false_type /* smart ptr */) - { - const auto value_type_id = detail::registered_class::id; - class_rep* cls = get_pointee_class(L, &val, value_type_id); - - if(!cls) { - throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(ValueType).name())); - } - - object_rep* instance = push_new_instance(L, cls); - - using value_type = typename std::remove_reference::type; - using holder_type = value_holder; - - void* storage = instance->allocate(sizeof(holder_type)); - - try { - new (storage) holder_type(L, std::forward(val)); - } - catch(...) { - instance->deallocate(storage); - lua_pop(L, 1); - throw; - } - - instance->set_instance(static_cast(storage)); - } - - template< typename ValueType > - void make_value_instance(lua_State* L, ValueType&& val) - { - make_value_instance(L, std::forward(val), has_get_pointer()); - } - - } // namespace detail -} // namespace luabind +}} // namespace luabind::detail #endif // LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP - diff --git a/libs/luabind/luabind/detail/meta.hpp b/libs/luabind/luabind/detail/meta.hpp deleted file mode 100644 index 8b6acc303..000000000 --- a/libs/luabind/luabind/detail/meta.hpp +++ /dev/null @@ -1,581 +0,0 @@ -// Copyright Michael Steinberg 2013. Use, modification and distribution is -// subject to 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) - -#ifndef LUABIND_META_HPP_INCLUDED -#define LUABIND_META_HPP_INCLUDED - -#include - -namespace luabind { - namespace meta { - - struct type_list_tag {}; - struct index_list_tag {}; - - /* - Index list and type list share pretty common patterns... is there a way to unify them? - */ - - template< unsigned int > - struct count - {}; - - template< unsigned int > - struct index - {}; - - template< typename Type > - struct type - {}; - - // Use this to unpack a parameter pack into a list of T's - template< typename T, typename DontCare > - struct unpack_helper - { - using type = T; - }; - - struct init_order { - init_order(std::initializer_list) {} - }; - - // common operators - template< typename T > - struct size; - - template< typename T, unsigned int Index > // Specializations so index lists can use the same syntax - struct get; - - template< typename... Lists > - struct join; - - template< typename List1, typename List2, typename... Lists > - struct join< List1, List2, Lists... > { - // Could try to join on both sides - using type = typename join< typename join< List1, List2 >::type, Lists... >::type; - }; - - // convenience - template< typename T > - struct front : public get< T, 0 > - { - }; - - template< typename List, typename T > - struct push_front; - - template< typename List, typename T > - struct push_back; - - template< typename T > - struct pop_front; - - template< typename T > - struct pop_back; - - template< typename List, unsigned int Index, typename T > - struct replace; - - template< typename List, unsigned int Index, template< typename > class T > - struct enwrap; - - template< typename List, template< typename > class T > - struct enwrap_all; - - template< typename List, unsigned int Index, template< typename > class T > - struct transform; - - template< typename List, unsigned int Index, template< typename > class Function > - using transform_t = typename transform< List, Index, Function >::type; - - template< typename List, template< typename > class Function > - struct transform_all; - - template< typename List, template< typename > class Function > - using transform_all_t = typename transform_all< List, Function >::type; - - - template< typename T, unsigned int start, unsigned int end > - struct sub_range; - - /* - aliases - */ - template< typename T > - using pop_front_t = typename pop_front::type; - - template< typename T1, typename... Types > - using join_t = typename join< T1, Types... >::type; - - template< typename T, unsigned int start, unsigned int end > - using sub_range_t = typename sub_range< T, start, end >::type; - - template< typename T, unsigned int index > - using get_t = typename get< T, index >::type; - - - // Used as terminator on type and index lists - struct null_type {}; - - template< typename... Types > - struct type_list : public type_list_tag - { - template< unsigned int Index > - using at = typename get::type; - }; - - template< typename... Types1, typename... Types2 > - type_list operator|(const type_list&, const type_list&) { - return type_list(); - } - - template< typename T > - struct is_typelist : public std::false_type - { - static const bool value = false; - }; - - template< typename... Types > - struct is_typelist< type_list< Types... > > : public std::true_type - { - static const bool value = true; - }; - - /* - Find type - */ - - template< typename TypeList, typename Type > - struct contains; - - template< typename Type0, typename... Types, typename Type > - struct contains< type_list, Type > - : std::conditional< std::is_same::value, std::true_type, contains< type_list, Type > >::type - { - }; - - template< typename Type > - struct contains< type_list< >, Type > - : std::false_type - { - }; - - /* - size - */ - - template< > - struct size< type_list< > > { - enum { value = 0 }; - }; - - template< typename Type0, typename... Types > - struct size< type_list< Type0, Types... > > { - enum { value = 1 + size< type_list >::value }; - }; - - - template< typename... Types, typename Type > - struct push_front< type_list, Type > - { - using type = type_list< Type, Types... >; - }; - - template< typename... Types, typename Type > - struct push_back< type_list, Type > - { - using type = type_list< Types..., Type >; - }; - - /* - pop_front - */ - - template< typename Type0, typename... Types > - struct pop_front< type_list< Type0, Types... > > - { - using type = type_list< Types... >; - }; - - template< > - struct pop_front< type_list< > > - { - using type = type_list< >; - }; - - /* - Index access to type list - */ - template< typename Element0, typename... Elements, unsigned int Index > - struct get< type_list, Index > { - using type = typename get< type_list, Index - 1 >::type; - }; - - template< typename Element0, typename... Elements > - struct get< type_list, 0 > - { - using type = Element0; - }; - - template< unsigned int Index > - struct get< type_list< >, Index > - { - static_assert(size< type_list< int > >::value == 1, "Bad Index"); - }; - - /* - Join Type Lists - */ - template< typename... Types1, typename... Types2 > - struct join< type_list< Types1... >, type_list< Types2... > > - { - using type = type_list< Types1..., Types2... >; - }; - - namespace detail { - template< typename HeadList, typename TailList, typename Type, unsigned int Index > - struct replace_helper; - - template< typename... HeadTypes, typename CurrentType, typename... TailTypes, typename Type, unsigned int Index > - struct replace_helper< type_list< HeadTypes... >, type_list< CurrentType, TailTypes... >, Type, Index> { - using type = typename replace_helper< type_list< HeadTypes..., CurrentType >, type_list, Type, Index - 1 >::type; - }; - - template< typename... HeadTypes, typename CurrentType, typename... TailTypes, typename Type > - struct replace_helper< type_list< HeadTypes... >, type_list< CurrentType, TailTypes... >, Type, 0 > { - using type = type_list< HeadTypes..., Type, TailTypes... >; - }; - } - - template< typename... Types, unsigned int Index, typename Type > - struct replace< type_list< Types... >, Index, Type > - { - using TypeList = type_list< Types... >; - - using type = join_t< - sub_range_t< TypeList, 0, Index >, - meta::type_list, - sub_range_t< TypeList, Index + 1, sizeof...(Types) > - >; - }; - - /* - Enwrap all elements of a type list in an template - */ - template< typename... Types, unsigned int Index, template< typename > class Enwrapper > - struct enwrap< type_list< Types... >, Index, Enwrapper > { - using type = join_t< - sub_range_t< type_list, 0, Index >, - Enwrapper< get_t< type_list, Index> >, - sub_range_t< type_list, Index + 1, sizeof...(Types) > - >; - }; - - template< typename... Types, template< typename > class Enwrapper > - struct enwrap_all< type_list< Types... >, Enwrapper > - { - using type = type_list< Enwrapper< Types >... >; - }; - - /* - Transform a certain element of a type list - */ - template< typename T, unsigned int Index, template< typename > class Function > - struct transform; - - template< typename... Types, unsigned int Index, template< typename > class Function > - struct transform< type_list< Types... >, Index, Function > { - using type = join_t< - sub_range_t< type_list, 0, Index >, - typename Function< get_t< type_list, Index> >::type, - sub_range_t< type_list, Index + 1, sizeof...(Types) > - >; - }; - - /* - Transform all elements of a type list - */ - template< typename... Types, template< typename > class Function > - struct transform_all< type_list< Types... >, Function > { - using type = type_list< typename Function::type... >; - }; - - /* - Tuple from type list - */ - template< class TypeList > - struct make_tuple; - - template< typename... Types > - struct make_tuple< type_list< Types... > > - { - using type = std::tuple< Types... >; - }; - - - /* - Type selection - */ - - template< typename ConvertibleToTrueFalse, typename Result > - struct case_ : public ConvertibleToTrueFalse { - using type = Result; - }; - - template< typename Result > - struct default_ { - using type = Result; - }; - - - template< typename Case, typename... CaseList > - struct select_ - { - using type = typename std::conditional< - std::is_convertible::value, - typename Case::type, - typename select_::type - >::type; - }; - - template< typename Case > - struct select_< Case > - { - using type = typename std::conditional< - std::is_convertible::value, - typename Case::type, - null_type - >::type; - }; - - template< typename T > - struct select_< default_ > { - using type = typename default_::type; - }; - - /* - Create index lists to expand on type_lists - */ - - template< unsigned int... Indices > - struct index_list : public index_list_tag - { - }; - - /* - Index index list - */ - - namespace detail { - - template< unsigned int Index, unsigned int Value0, unsigned int... Values > - struct get_iterate { - static const unsigned int value = get_iterate< Index - 1, Values... >::value; - }; - - template< unsigned int Value0, unsigned int... Values > - struct get_iterate< 0, Value0, Values... > { - static const unsigned int value = Value0; - }; - - } - - template< unsigned int... Values, unsigned int Index > - struct get< index_list< Values... >, Index > - { - static_assert(sizeof...(Values) > Index, "Bad Index"); - static const unsigned int value = detail::get_iterate< Index, Values... >::value; - }; - - /* - Index list size - */ - - template< unsigned int... Values > - struct size< index_list< Values... > > { - static const unsigned int value = sizeof...(Values); - }; - - - /* - Index list push front - */ - template< unsigned int... Indices, unsigned int Index > - struct push_front< index_list< Indices... >, index > - { - using type = index_list< Index, Indices... >; - }; - - /* - Index list push back - */ - template< unsigned int... Indices, unsigned int Index > - struct push_back< index_list< Indices... >, index > - { - using type = index_list< Indices..., Index >; - }; - - /* - Index list pop_front - */ - template< unsigned int Index0, unsigned int... Indices > - struct pop_front< index_list< Index0, Indices... > > { - using type = index_list< Indices... >; - }; - - template< > - struct pop_front< index_list< > > { - using type = index_list< >; - }; - - /* - Index list range creation - */ - namespace detail { - - template< unsigned int curr, unsigned int end, unsigned int... Indices > - struct make_index_range : - public make_index_range< curr + 1, end, Indices..., curr > - { - }; - - template< unsigned int end, unsigned int... Indices > - struct make_index_range< end, end, Indices... > - { - using type = index_list< Indices... >; - }; - - } - - /* - make_index_range< start, end > - Creates the index list list of range [start, end) - */ - template< unsigned int start, unsigned int end > - struct make_index_range { - static_assert(end >= start, "end must be greater than or equal to start"); - using type = typename detail::make_index_range< start, end >::type; - }; - - template< unsigned int start, unsigned int end > - using index_range = typename make_index_range::type; - - namespace detail { - // These implementation are not really efficient... - template< typename SourceList, typename IndexList > - struct sub_range_index; - - template< typename SourceList, unsigned int... Indices > - struct sub_range_index< SourceList, index_list< Indices... > > { - using type = index_list< get< SourceList, Indices >::value... >; - }; - - template< typename SourceList, typename IndexList > - struct sub_range_type; - - template< typename SourceList, unsigned int... Indices > - struct sub_range_type< SourceList, index_list< Indices... > > { - using type = type_list< typename get< SourceList, Indices >::type... >; - }; - - } - - /* - Index list sub_range [start, end) - */ - template< unsigned int start, unsigned int end, unsigned int... Indices > - struct sub_range< index_list, start, end > - { - static_assert(end >= start, "end must be greater or equal to start"); - using type = typename detail::sub_range_index< index_list, typename make_index_range::type >::type; - }; - - /* - Type list sub_range [start, end) - */ - template< unsigned int start, unsigned int end, typename... Types > - struct sub_range< type_list, start, end > - { - static_assert(end >= start, "end must be greater or equal to start"); - using type = typename detail::sub_range_type< type_list, typename make_index_range::type >::type; - }; - - /* - Index list sum - */ - - namespace detail { - - template< typename T, T... Values > - struct sum_values; - - template< typename T, T Value0, T... Values > - struct sum_values< T, Value0, Values... > { - static const T value = Value0 + sum_values< T, Values... >::value; - }; - - template< typename T > - struct sum_values< T > - { - static const T value = 0; - }; - - } - - template< typename T > - struct sum; - - template< unsigned int... Args > - struct sum< index_list > - { - static const unsigned int value = detail::sum_values::value; - }; - - /* - and_ or_ - */ - - template< typename... ConvertiblesToTrueFalse > - struct and_; - - template< typename Convertible0, typename... Convertibles > - struct and_< Convertible0, Convertibles... > - : std::conditional < - std::is_convertible< Convertible0, std::true_type >::value, - and_< Convertibles... >, - std::false_type > ::type - { - }; - - template< > - struct and_< > - : std::true_type - { - }; - - - template< typename... ConvertiblesToTrueFalse > - struct or_; - - template< typename Convertible0, typename... Convertibles > - struct or_< Convertible0, Convertibles... > - : std::conditional < - std::is_convertible< Convertible0, std::true_type >::value, - std::true_type, - or_< Convertibles... > - > ::type - { - }; - - template< > - struct or_< > - : std::true_type - { - }; - - } -} - -#endif - diff --git a/libs/luabind/luabind/lua_proxy.hpp b/libs/luabind/luabind/detail/most_derived.hpp similarity index 64% rename from libs/luabind/luabind/lua_proxy.hpp rename to libs/luabind/luabind/detail/most_derived.hpp index 6ecdf82fc..4dd9d9159 100644 --- a/libs/luabind/luabind/lua_proxy.hpp +++ b/libs/luabind/luabind/detail/most_derived.hpp @@ -20,35 +20,25 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef LUABIND_VALUE_WRAPPER_050419_HPP -#define LUABIND_VALUE_WRAPPER_050419_HPP +#ifndef MOST_DERIVED_051018_HPP +# define MOST_DERIVED_051018_HPP -#include -#include +# include +# include -namespace luabind { +namespace luabind { namespace detail { - // - // Concept "lua_proxy" - // +template +struct most_derived +{ + typedef typename boost::mpl::if_< + boost::is_base_and_derived + , WrappedClass + , Class + >::type type; +}; - template - struct lua_proxy_traits - { - using is_specialized = std::false_type; - }; +}} // namespace luabind::detail - template - struct is_lua_proxy_type - : lua_proxy_traits::is_specialized - {}; - - template< class T > - struct is_lua_proxy_arg - : std::conditional>::value, std::true_type, std::false_type >::type - {}; - -} // namespace luabind - -#endif // LUABIND_VALUE_WRAPPER_050419_HPP +#endif // MOST_DERIVED_051018_HPP diff --git a/libs/luabind/luabind/detail/object.hpp b/libs/luabind/luabind/detail/object.hpp deleted file mode 100644 index a6fea5928..000000000 --- a/libs/luabind/luabind/detail/object.hpp +++ /dev/null @@ -1,386 +0,0 @@ -// Copyright (c) 2005 Daniel Wallin and Arvid Norberg - -// 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 LUABIND_OBJECT_050419_HPP -#define LUABIND_OBJECT_050419_HPP - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if LUA_VERSION_NUM < 502 -# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) -#endif - -namespace luabind { - namespace adl { - - // An object holds a reference to a Lua value residing - // in the registry. - class object : - public lua_proxy_interface - { - public: - object() - {} - - explicit object(handle const& other) - : m_handle(other) - {} - - explicit object(from_stack const& stack_reference) - : m_handle(stack_reference.interpreter, stack_reference.index) - { - } - - template - object(lua_State* interpreter, T&& value) - { - detail::push_to_lua(interpreter, std::forward(value)); - detail::stack_pop pop(interpreter, 1); - handle(interpreter, -1).swap(m_handle); - } - - template - object(lua_State* interpreter, T&& value, Policies const&) - { - detail::push_to_lua<1, Policies>(interpreter, std::forward(value)); - detail::stack_pop pop(interpreter, 1); - handle(interpreter, -1).swap(m_handle); - } - - void push(lua_State* interpreter) const; - lua_State* interpreter() const; - bool is_valid() const; - - template - index_proxy operator[](T const& key) const - { - return index_proxy( - *this, m_handle.interpreter(), key - ); - } - - void swap(object& other) - { - m_handle.swap(other.m_handle); - } - - private: - handle m_handle; - }; - - inline void object::push(lua_State* interpreter) const - { - m_handle.push(interpreter); - } - - inline lua_State* object::interpreter() const - { - return m_handle.interpreter(); - } - - inline bool object::is_valid() const - { - return m_handle.interpreter() != 0; - } - - } // namespace adl - - using adl::object; - - template<> - struct lua_proxy_traits - { - using is_specialized = std::true_type; - - static lua_State* interpreter(object const& value) - { - return value.interpreter(); - } - - static void unwrap(lua_State* interpreter, object const& value) - { - value.push(interpreter); - } - - static bool check(...) - { - return true; - } - }; - - template - R call_function(luabind::object const& obj, Args&&... args) - { - obj.push(obj.interpreter()); - return call_pushed_function(obj.interpreter(), std::forward(args)...); - } - - template - R resume_function(luabind::object const& obj, Args&&... args) - { - obj.push(obj.interpreter()); - return resume_pushed_function(obj.interpreter(), std::forward(args)...); - } - - // declared in luabind/lua_index_proxy.hpp - template - adl::index_proxy::operator object() - { - detail::stack_pop pop(m_interpreter, 1); - push(m_interpreter); - return object(from_stack(m_interpreter, -1)); - } - - // declared in luabind/lua_proxy_interface.hpp - template - template - object adl::lua_proxy_interface::call(Args&&... args) - { - return call_function(derived(), std::forward(args)...); - } - - // declared in luabind/lua_proxy_interface.hpp - template - template - object adl::lua_proxy_interface::operator()(Args&&... args) - { - return call(std::forward(args)...); - } - - // declared in luabind/lua_iterator_proxy.hpp - template - adl::iterator_proxy::operator object() - { - lua_pushvalue(m_interpreter, m_key_index); - AccessPolicy::get(m_interpreter, m_table_index); - detail::stack_pop pop(m_interpreter, 1); - return object(from_stack(m_interpreter, -1)); - } - - // declared in luabind/lua_iterator_proxy.hpp - template - object detail::basic_iterator::key() const - { - return object(m_key); - } - - namespace adl { - // Simple value_wrapper adaptor with the sole purpose of helping with - // overload resolution. Use this as a function parameter type instead - // of "object" or "argument" to restrict the parameter to Lua tables. - template - struct table : Base - { - table(from_stack const& stack_reference) - : Base(stack_reference) - {} - }; - - } // namespace adl - - using adl::table; - - template - struct lua_proxy_traits > - : lua_proxy_traits - { - static bool check(lua_State* L, int idx) - { - return lua_proxy_traits::check(L, idx) && - lua_istable(L, idx); - } - }; - - inline object newtable(lua_State* interpreter) - { - lua_newtable(interpreter); - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); - } - - // this could be optimized by returning a proxy - inline object globals(lua_State* interpreter) - { - lua_pushglobaltable(interpreter); - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); - } - - // this could be optimized by returning a proxy - inline object registry(lua_State* interpreter) - { - lua_pushvalue(interpreter, LUA_REGISTRYINDEX); - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); - } - - template - inline object gettable(ValueWrapper const& table, K&& key) - { - lua_State* interpreter = lua_proxy_traits::interpreter(table); - - lua_proxy_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 2); - detail::push_to_lua(interpreter, std::forward(key)); - lua_gettable(interpreter, -2); - return object(from_stack(interpreter, -1)); - } - - template - inline void settable(ValueWrapper const& table, K&& key, T&& value) - { - lua_State* interpreter = lua_proxy_traits::interpreter(table); - - // TODO: Exception safe? - - lua_proxy_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 1); - detail::push_to_lua(interpreter, std::forward(key)); - detail::push_to_lua(interpreter, std::forward(value)); - lua_settable(interpreter, -3); - } - - template - inline object rawget(ValueWrapper const& table, K&& key) - { - lua_State* interpreter = lua_proxy_traits::interpreter( - table - ); - - lua_proxy_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 2); - detail::push_to_lua(interpreter, std::forward(key)); - lua_rawget(interpreter, -2); - return object(from_stack(interpreter, -1)); - } - - template - inline void rawset(ValueWrapper const& table, K&& key, T&& value) - { - lua_State* interpreter = lua_proxy_traits::interpreter( - table - ); - - // TODO: Exception safe? - - lua_proxy_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 1); - detail::push_to_lua(interpreter, std::forward(key)); - detail::push_to_lua(interpreter, std::forward(value)); - lua_rawset(interpreter, -3); - } - - template - inline int type(ValueWrapper const& value) - { - lua_State* interpreter = lua_proxy_traits::interpreter(value); - - lua_proxy_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 1); - return lua_type(interpreter, -1); - } - - template - inline object getmetatable(ValueWrapper const& obj) - { - lua_State* interpreter = lua_proxy_traits::interpreter(obj); - lua_proxy_traits::unwrap(interpreter, obj); - detail::stack_pop pop(interpreter, 2); - lua_getmetatable(interpreter, -1); - return object(from_stack(interpreter, -1)); - } - - template - inline void setmetatable(ValueWrapper1 const& obj, ValueWrapper2 const& metatable) - { - lua_State* interpreter = lua_proxy_traits::interpreter(obj); - lua_proxy_traits::unwrap(interpreter, obj); - detail::stack_pop pop(interpreter, 1); - lua_proxy_traits::unwrap(interpreter, metatable); - lua_setmetatable(interpreter, -2); - } - - template - inline std::tuple getupvalue(ValueWrapper const& value, int index) - { - lua_State* interpreter = lua_proxy_traits::interpreter(value); - lua_proxy_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 2); - const char* name = lua_getupvalue(interpreter, -1, index); - return std::make_tuple(name, object(from_stack(interpreter, -1))); - } - - template - inline void setupvalue(ValueWrapper1 const& function, int index, ValueWrapper2 const& value) - { - lua_State* interpreter = lua_proxy_traits::interpreter(function); - - lua_proxy_traits::unwrap(interpreter, function); - detail::stack_pop pop(interpreter, 1); - lua_proxy_traits::unwrap(interpreter, value); - lua_setupvalue(interpreter, -2, index); - } - - template - object property(GetValueWrapper const& get) - { - lua_State* interpreter = lua_proxy_traits::interpreter(get); - lua_proxy_traits::unwrap(interpreter, get); - lua_pushnil(interpreter); - lua_pushcclosure(interpreter, &detail::property_tag, 2); - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); - } - - template - object property(GetValueWrapper const& get, SetValueWrapper const& set) - { - lua_State* interpreter = lua_proxy_traits::interpreter(get); - lua_proxy_traits::unwrap(interpreter, get); - lua_proxy_traits::unwrap(interpreter, set); - lua_pushcclosure(interpreter, &detail::property_tag, 2); - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); - } - -} // namespace luabind - -#if LUA_VERSION_NUM < 502 -#undef lua_pushglobaltable -#endif - -#include - -#endif // LUABIND_OBJECT_050419_HPP - diff --git a/libs/luabind/luabind/detail/object_call.hpp b/libs/luabind/luabind/detail/object_call.hpp new file mode 100644 index 000000000..46ab0d958 --- /dev/null +++ b/libs/luabind/luabind/detail/object_call.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2005 Daniel Wallin and Arvid Norberg + +// 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. + +#if !BOOST_PP_IS_ITERATING +# error Do not include object_call.hpp directly! +#endif + +#include +#include +#include + +#define N BOOST_PP_ITERATION() + +template +call_proxy< + Derived + , boost::tuples::tuple< + BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT) + > +> operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a)) +{ + typedef boost::tuples::tuple< + BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT) + > arguments; + + return call_proxy( + derived() + , arguments(BOOST_PP_ENUM_PARAMS(N, &a)) + ); +} + +#undef N + diff --git a/libs/luabind/luabind/detail/object_funs.hpp b/libs/luabind/luabind/detail/object_funs.hpp new file mode 100644 index 000000000..2600238d9 --- /dev/null +++ b/libs/luabind/luabind/detail/object_funs.hpp @@ -0,0 +1,224 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_OBJECT_PROXY_HPP_INCLUDED +#define LUABIND_OBJECT_PROXY_HPP_INCLUDED + +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace luabind +{ + + namespace detail + { + + namespace mpl = boost::mpl; + + template + inline T object_cast_impl(const Obj& obj, const Policies&) + { + if (obj.lua_state() == 0) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(0, typeid(T)); +#else + lua_State* L = obj.lua_state(); + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(L, typeid(T)); + + assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + + LUABIND_CHECK_STACK(obj.lua_state()); + + typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + + obj.pushvalue(); + + lua_State* L = obj.lua_state(); + detail::stack_pop p(L, 1); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(L, typeid(T)); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(L, typeid(T)); + + assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } +#endif + + return converter.apply(L, LUABIND_DECORATE_TYPE(T), -1); + } + + template + boost::optional object_cast_nothrow_impl(const Obj& obj, const Policies&) + { + typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + + if (obj.lua_state() == 0) return boost::optional(); + LUABIND_CHECK_STACK(obj.lua_state()); + + obj.pushvalue(); + + lua_State* L = obj.lua_state(); + detail::stack_pop p(L, 1); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0) + return boost::optional(); +#endif + + return boost::optional(converter.apply(L, LUABIND_DECORATE_TYPE(T), -1)); + } + } + + template + T object_cast(const object& obj) + { return detail::object_cast_impl(obj, detail::null_type()); } + + template + T object_cast(const object& obj, const Policies& p) + { return detail::object_cast_impl(obj, p); } + + template + boost::optional object_cast_nothrow(const object& obj) + { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } + + template + boost::optional object_cast_nothrow(const object& obj, const Policies& p) + { return detail::object_cast_nothrow_impl(obj, p); } + + + template + T object_cast(const detail::proxy_object& obj) + { return detail::object_cast_impl(obj, detail::null_type()); } + + template + T object_cast(const detail::proxy_object& obj, const Policies& p) + { return detail::object_cast_impl(obj, p); } + + template + boost::optional object_cast_nothrow(const detail::proxy_object& obj) + { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } + + template + boost::optional object_cast_nothrow(const detail::proxy_object& obj, const Policies& p) + { return detail::object_cast_nothrow_impl(obj, p); } + + + template + T object_cast(const detail::proxy_raw_object& obj) + { return detail::object_cast_impl(obj, detail::null_type()); } + + template + T object_cast(const detail::proxy_raw_object& obj, const Policies& p) + { return detail::object_cast_impl(obj, p); } + + template + boost::optional object_cast_nothrow(const detail::proxy_raw_object& obj) + { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } + + template + boost::optional object_cast_nothrow(const detail::proxy_raw_object& obj, const Policies& p) + { return detail::object_cast_nothrow_impl(obj, p); } + + + template + T object_cast(const detail::proxy_array_object& obj) + { return detail::object_cast_impl(obj, detail::null_type()); } + + template + T object_cast(const detail::proxy_array_object& obj, const Policies& p) + { return detail::object_cast_impl(obj, p); } + + template + boost::optional object_cast_nothrow(const detail::proxy_array_object& obj) + { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } + + template + boost::optional object_cast_nothrow(const detail::proxy_array_object& obj, const Policies& p) + { return detail::object_cast_nothrow_impl(obj, p); } + + + + + inline object get_globals(lua_State* L) + { + lua_pushvalue(L, LUA_GLOBALSINDEX); + detail::lua_reference ref; + ref.set(L); + return object(L, ref, true/*object::reference()*/); + } + + inline object get_registry(lua_State* L) + { + lua_pushvalue(L, LUA_REGISTRYINDEX); + detail::lua_reference ref; + ref.set(L); + return object(L, ref, true/*object::reference()*/); + } + + inline object newtable(lua_State* L) + { + lua_newtable(L); + detail::lua_reference ref; + ref.set(L); + return object(L, ref, true/*object::reference()*/); + } +} + +/* + +struct A +{ +}; + +object f = class_(); + +A* ptr = object_cast(f(), adopt(_1)); + +delete ptr; + +*/ + +#endif // LUABIND_OBJECT_PROXY_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/object_rep.hpp b/libs/luabind/luabind/detail/object_rep.hpp index 139a1f64c..93b3e39d6 100644 --- a/libs/luabind/luabind/detail/object_rep.hpp +++ b/libs/luabind/luabind/detail/object_rep.hpp @@ -24,114 +24,110 @@ #ifndef LUABIND_OBJECT_REP_HPP_INCLUDED #define LUABIND_OBJECT_REP_HPP_INCLUDED +#include #include -#include #include #include -#include // std::aligned_storage #include -namespace luabind { - namespace detail { +namespace luabind { namespace detail +{ + class class_rep; - void finalize(lua_State* L, class_rep* crep); + void finalize(lua_State* L, class_rep* crep); - // this class is allocated inside lua for each pointer. - // it contains the actual c++ object-pointer. - // it also tells if it is const or not. - class LUABIND_API object_rep + // this class is allocated inside lua for each pointer. + // it contains the actual c++ object-pointer. + // it also tells if it is const or not. + class LUABIND_API object_rep + { + public: + object_rep(instance_holder* instance, class_rep* crep); + ~object_rep(); + + const class_rep* crep() const { return m_classrep; } + class_rep* crep() { return m_classrep; } + + void set_instance(instance_holder* instance) { m_instance = instance; } + + void add_dependency(lua_State* L, int index); + void release_dependency_refs(lua_State* L); + + std::pair get_instance(class_id target) const { - public: - object_rep(instance_holder* instance, class_rep* crep); - ~object_rep(); + if (m_instance == 0) + return std::pair((void*)0, -1); + return m_instance->get(target); + } - const class_rep* crep() const { return m_classrep; } - class_rep* crep() { return m_classrep; } - - void set_instance(instance_holder* instance) { m_instance = instance; } - - void add_dependency(lua_State* L, int index); - - std::pair get_instance(class_id target) const - { - if(m_instance == 0) - return std::pair(nullptr, -1); - return m_instance->get(m_classrep->casts(), target); - } - - bool is_const() const - { - return m_instance && m_instance->pointee_const(); - } - - void release() - { - if(m_instance) - m_instance->release(); - } - - void* allocate(std::size_t size) - { - if(size <= 32) { - return &m_instance_buffer; - } - else { - return std::malloc(size); - } - - } - - void deallocate(void* storage) - { - if(storage == &m_instance_buffer) { - return; - } - else { - std::free(storage); - } - } - - private: - object_rep(object_rep const&) = delete; - void operator=(object_rep const&) = delete; - - instance_holder* m_instance; - std::aligned_storage<32>::type m_instance_buffer; - class_rep* m_classrep; // the class information about this object's type - detail::lua_reference m_dependency_ref; // reference to lua table holding dependency references - }; - - template - struct delete_s + bool is_const() const { - static void apply(void* ptr) - { - delete static_cast(ptr); - } - }; + return m_instance && m_instance->pointee_const(); + } - template - struct destruct_only_s + void release() + { + if (m_instance) + m_instance->release(); + } + + void* allocate(std::size_t size) { - static void apply(void* ptr) - { - // Removes unreferenced formal parameter warning on VC7. - (void)ptr; + if (size <= 32) + return &m_instance_buffer; + return std::malloc(size); + } + + void deallocate(void* storage) + { + if (storage == &m_instance_buffer) + return; + std::free(storage); + } + + private: + + object_rep(object_rep const&) + {} + + void operator=(object_rep const&) + {} + + instance_holder* m_instance; + boost::aligned_storage<32> m_instance_buffer; + class_rep* m_classrep; // the class information about this object's type + std::size_t m_dependency_cnt; // counts dependencies + }; + + template + struct delete_s + { + static void apply(void* ptr) + { + delete static_cast(ptr); + } + }; + + template + struct destruct_only_s + { + static void apply(void* ptr) + { + // Removes unreferenced formal parameter warning on VC7. + (void)ptr; #ifndef NDEBUG - int completeness_check[sizeof(T)]; - (void)completeness_check; + int completeness_check[sizeof(T)]; + (void)completeness_check; #endif - static_cast(ptr)->~T(); - } - }; + static_cast(ptr)->~T(); + } + }; - LUABIND_API object_rep* get_instance(lua_State* L, int index); - LUABIND_API void push_instance_metatable(lua_State* L); - LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls); + LUABIND_API object_rep* get_instance(lua_State* L, int index); + LUABIND_API void push_instance_metatable(lua_State* L); + LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls); - } // namespace detail - -} // namespace luabind +}} #endif // LUABIND_OBJECT_REP_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/operator_id.hpp b/libs/luabind/luabind/detail/operator_id.hpp index 3b6564ac6..ed64ba6d5 100644 --- a/libs/luabind/luabind/detail/operator_id.hpp +++ b/libs/luabind/luabind/detail/operator_id.hpp @@ -26,58 +26,54 @@ #include -namespace luabind { - namespace detail { +namespace luabind { namespace detail { - enum operator_id - { - op_add = 0, - op_sub, - op_mul, - op_div, - op_mod, - op_pow, - op_lt, - op_le, - op_eq, - op_call, - op_unm, - op_tostring, - op_concat, - op_len, + enum operator_id + { + op_add = 0, + op_sub, + op_mul, + op_div, + op_pow, + op_lt, + op_le, + op_eq, + op_call, + op_unm, + op_tostring, + op_concat, + op_len, - number_of_operators - }; + number_of_operators + }; - inline const char* get_operator_name(int i) - { - static const char* a[number_of_operators] = { - "__add", "__sub", "__mul", "__div", "__mod", "__pow", - "__lt", "__le", "__eq", "__call", "__unm", - "__tostring", "__concat", "__len" }; - return a[i]; - } + inline const char* get_operator_name(int i) + { + static const char* a[number_of_operators] = { + "__add", "__sub", "__mul", "__div", "__pow", + "__lt", "__le", "__eq", "__call", "__unm", + "__tostring", "__concat", "__len" }; + return a[i]; + } - inline const char* get_operator_symbol(int i) - { - static const char* a[number_of_operators] = { - "+", "-", "*", "/", "%", "^", "<", - "<=", "==", "()", "- (unary)", - "tostring", "..", "#" }; - return a[i]; - } + inline const char* get_operator_symbol(int i) + { + static const char* a[number_of_operators] = { + "+", "-", "*", "/", "^", "<", + "<=", "==", "()", "- (unary)", + "tostring", "..", "#" }; + return a[i]; + } - inline bool is_unary(int i) - { - // the reason why unary minus is not considered a unary operator here is - // that it always is given two parameters, where the second parameter always - // is nil. - return i == op_tostring; - } + inline bool is_unary(int i) + { + // the reason why unary minus is not considered a unary operator here is + // that it always is given two parameters, where the second parameter always + // is nil. + return i == op_tostring; + } - } // namespace detail -} // namespace luabind +}} #endif // LUABIND_OPERATOR_ID_HPP_INCLUDED - diff --git a/libs/luabind/luabind/detail/other.hpp b/libs/luabind/luabind/detail/other.hpp index d2f48c93d..679058c9e 100644 --- a/libs/luabind/luabind/detail/other.hpp +++ b/libs/luabind/luabind/detail/other.hpp @@ -33,34 +33,87 @@ // to its suitability for any purpose. #include +#include -namespace luabind { - +namespace luabind +{ template struct other { - using type = T; + typedef T type; + }; +} + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +namespace luabind { namespace detail +{ + template + class unwrap_other + { + public: + typedef T type; }; -} // namespace luabind + template + class unwrap_other > + { + public: + typedef T type; + }; +}} // namespace luabind::detail -namespace luabind { - namespace detail { - template - class unwrap_other - { - public: - using type = T; - }; +# else // no partial specialization - template - class unwrap_other > - { - public: - using type = T; - }; - } -} // namespace luabind::detail +#include + +namespace luabind { namespace detail +{ + typedef char (&yes_other_t)[1]; + typedef char (&no_other_t)[2]; + + no_other_t is_other_test(...); + + template + yes_other_t is_other_test(type_< other >); + + template + struct other_unwrapper + { + template + struct apply + { + typedef T type; + }; + }; + + template<> + struct other_unwrapper + { + template + struct apply + { + typedef typename T::type type; + }; + }; + + template + class is_other + { + public: + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof(detail::is_other_test(type_())) + == sizeof(detail::yes_other_t))); + }; + + template + class unwrap_other + : public detail::other_unwrapper< + is_other::value + >::template apply + {}; + +}} // namespace luabind::detail +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #endif // LUABIND_OTHER_HPP_INCLUDED - diff --git a/libs/luabind/luabind/detail/pcall.hpp b/libs/luabind/luabind/detail/pcall.hpp index ab9f63c02..f0d72b162 100644 --- a/libs/luabind/luabind/detail/pcall.hpp +++ b/libs/luabind/luabind/detail/pcall.hpp @@ -25,14 +25,12 @@ #include -#include +struct lua_State; -namespace luabind { - namespace detail { - LUABIND_API int pcall(lua_State *L, int nargs, int nresults); - LUABIND_API int resume_impl(lua_State *L, int nargs, int nresults); - } -} +namespace luabind { namespace detail +{ + LUABIND_API int pcall(lua_State *L, int nargs, int nresults); + LUABIND_API int resume_impl(lua_State *L, int nargs, int nresults); +}} #endif - diff --git a/libs/luabind/luabind/detail/pointee_sizeof.hpp b/libs/luabind/luabind/detail/pointee_sizeof.hpp new file mode 100644 index 000000000..3875c09dd --- /dev/null +++ b/libs/luabind/luabind/detail/pointee_sizeof.hpp @@ -0,0 +1,54 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// 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 POINTEE_SIZEOF_040211_HPP +#define POINTEE_SIZEOF_040211_HPP + +#include + +namespace luabind { + + namespace detail { + + template T& deref_type(T(*)(), int); + template T& deref_type(T*(*)(), long); + + } // namespace detail + + // returns the indirect sizeof U, as in + // sizeof(T*) = sizeof(T) + // sizeof(T&) = sizeof(T) + // sizeof(T) = sizeof(T) + template + struct pointee_sizeof + { + BOOST_STATIC_CONSTANT(int, value = ( + sizeof(detail::deref_type((T(*)())0), 0L) + )); + + typedef boost::mpl::int_ type; + }; + +} // namespace luabind + +#endif // POINTEE_SIZEOF_040211_HPP + diff --git a/libs/luabind/luabind/error_callback_fun.hpp b/libs/luabind/luabind/detail/pointee_typeid.hpp similarity index 63% rename from libs/luabind/luabind/error_callback_fun.hpp rename to libs/luabind/luabind/detail/pointee_typeid.hpp index f25e67d17..ab4113711 100644 --- a/libs/luabind/luabind/error_callback_fun.hpp +++ b/libs/luabind/luabind/detail/pointee_typeid.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg +// Copyright (c) 2004 Daniel Wallin // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -20,27 +20,21 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8 -#define INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8 +#ifndef POINTEE_TYPEID_040211_HPP +#define POINTEE_TYPEID_040211_HPP -// Internal Includes #include -#include +#include -// Library/third-party includes -// - none +namespace luabind { namespace detail { -// Standard includes -// - none + template + type_id pointee_typeid(T*) + { + return typeid(T); + } -namespace luabind -{ - class type_id; +}} // namespace luabind::detail - using error_callback_fun = void(*)(lua_State*); - using cast_failed_callback_fun = void(*)(lua_State*, type_id const&); - using pcall_callback_fun = void(*)(lua_State*); -} - -#endif // INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8 +#endif // POINTEE_TYPEID_040211_HPP diff --git a/libs/luabind/luabind/detail/policy.hpp b/libs/luabind/luabind/detail/policy.hpp index 195b369f5..79577c9a4 100644 --- a/libs/luabind/luabind/detail/policy.hpp +++ b/libs/luabind/luabind/detail/policy.hpp @@ -25,131 +25,998 @@ #define LUABIND_POLICY_HPP_INCLUDED #include -#include -#include #include -#include #include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#if LUA_VERSION_NUM < 502 -# define lua_rawlen lua_objlen -#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include namespace luabind { - template< typename... T > - using policy_list = meta::type_list< T... >; - using no_policies = policy_list< >; - - namespace detail { - - struct converter_policy_has_postcall_tag {}; - - } - - // A converter policy injector instructs the call mechanism to use a certain converter policy for - // an element of a function call signature that is denoted by the parameter Index - // 0 stands for the return value, while 1 might denote an implicit "this" argument or the first - // actual argument of the function call. - template< unsigned int Index, typename T > - struct converter_policy_injector - { - static constexpr bool has_postcall = std::is_convertible::value; - }; - - // A call policy injector instructs the call mechanism to call certain static function "postcall" on type T - // after having executed a call. - template< typename T > - struct call_policy_injector - {}; - - template< typename T, typename Enable = void > - struct default_converter; - namespace detail { - struct lua_to_cpp {}; - struct cpp_to_lua {}; + struct conversion_policy_base {}; + } - struct default_policy + template + struct conversion_policy : detail::conversion_policy_base + { + BOOST_STATIC_CONSTANT(int, index = N); + BOOST_STATIC_CONSTANT(bool, has_arg = HasArg); + }; + + class index_map + { + public: + index_map(const int* m): m_map(m) {} + + int operator[](int index) const { - template - struct specialize - { - using type = default_converter; - }; - }; - - template - struct is_primitive - : default_converter::is_native - {}; - - namespace policy_detail { - template< unsigned int Index, typename PoliciesList > - struct get_converter_policy; - - template< unsigned int Index, typename Injector0, typename... Injectors > - struct get_converter_policy< Index, meta::type_list< Injector0, Injectors... > > - { - using type = typename get_converter_policy< Index, meta::type_list< Injectors... > >::type; - }; - - template< unsigned int Index, typename ConverterPolicy, typename... Injectors > - struct get_converter_policy< Index, meta::type_list< converter_policy_injector< Index, ConverterPolicy >, Injectors... > > - { - using type = ConverterPolicy; - }; - - template< unsigned int Index > - struct get_converter_policy< Index, meta::type_list< > > - { - using type = default_policy; - }; + return m_map[index]; } - // Fetches converter policy for Signature element [Index] from policy list [PolicyList] - template - using fetched_converter_policy = typename policy_detail::get_converter_policy::type; + private: + const int* m_map; + }; - // Specializes converter policy [ConverterPolicy] for type [Type] in direction [Direction] - template - using specialized_converter_policy = typename ConverterPolicy::template specialize::type; +// template class functor; + class weak_ref; +} - // Fetches the converter policy for Signature element [Index] from the policy list [PolicyList] and specializes it - // for the concrete type [T] with [Direction] being either "lua_to_cpp" or "cpp_to_lua". - template - using specialized_converter_policy_n = typename policy_detail::get_converter_policy::type::template specialize::type; +namespace luabind { namespace detail +{ + template + struct policy_cons + { + typedef H head; + typedef T tail; - /* - call_policies - */ + template + policy_cons > operator,(policy_cons) + { + return policy_cons >(); + } - template< typename List, class Sought > - struct has_call_policy : public meta::contains< List, call_policy_injector< Sought > > + template + policy_cons > operator+(policy_cons) + { + return policy_cons >(); + } + + template + policy_cons > operator|(policy_cons) + { + return policy_cons >(); + } + }; + + struct indirection_layer + { + template + indirection_layer(const T&); + }; + + yes_t is_policy_cons_test(const null_type&); + template + yes_t is_policy_cons_test(const policy_cons&); + no_t is_policy_cons_test(...); + + template + struct is_policy_cons + { + static const T& t; + + BOOST_STATIC_CONSTANT(bool, value = + sizeof(is_policy_cons_test(t)) == sizeof(yes_t)); + + typedef boost::mpl::bool_ type; + }; + + template + struct is_string_literal + { + static no_t helper(indirection_layer); + static yes_t helper(const char*); + }; + + template<> + struct is_string_literal + { + static no_t helper(indirection_layer); + }; + + + namespace mpl = boost::mpl; + + template + void make_pointee_instance(lua_State* L, T& x, mpl::true_, Clone) + { + if (get_pointer(x)) + { + make_instance(L, x); + } + else + { + lua_pushnil(L); + } + } + + template + void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::true_) + { + std::auto_ptr ptr(new T(x)); + make_instance(L, ptr); + } + + template + void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::false_) + { + make_instance(L, &x); + } + + template + void make_pointee_instance(lua_State* L, T& x, Clone) + { + make_pointee_instance(L, x, has_get_pointer(), Clone()); + } + +// ********** pointer converter *********** + + struct pointer_converter + { + typedef pointer_converter type; + typedef mpl::false_ is_native; + + pointer_converter() + : result(0) + {} + + void* result; + + int const consumed_args(...) + { + return 1; + } + + template + void apply(lua_State* L, T* ptr) + { + if (ptr == 0) + { + lua_pushnil(L); + return; + } + + if (luabind::get_back_reference(L, ptr)) + return; + + make_instance(L, ptr); + } + + template + T* apply(lua_State*, by_pointer, int) + { + return static_cast(result); + } + + template + int match(lua_State* L, by_pointer, int index) + { + if (lua_isnil(L, index)) return 0; + object_rep* obj = get_instance(L, index); + if (obj == 0) return -1; + + if (obj->is_const()) + return -1; + + std::pair s = obj->get_instance(registered_class::id); + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, by_pointer, int) + {} + }; + +// ******* value converter ******* + + struct value_converter + { + typedef value_converter type; + typedef mpl::false_ is_native; + + int const consumed_args(...) + { + return 1; + } + + value_converter() + : result(0) + {} + + void* result; + + template + void apply(lua_State* L, T x) + { + if (luabind::get_back_reference(L, x)) + return; + + make_pointee_instance(L, x, mpl::true_()); + } + + template + T apply(lua_State*, by_value, int) + { + return *static_cast(result); + } + + template + int match(lua_State* L, by_value, int index) + { + // special case if we get nil in, try to match the holder type + if (lua_isnil(L, index)) + return -1; + + object_rep* obj = get_instance(L, index); + if (obj == 0) return -1; + + std::pair s = obj->get_instance(registered_class::id); + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + +// ******* const pointer converter ******* + + struct const_pointer_converter + { + typedef const_pointer_converter type; + typedef mpl::false_ is_native; + + int const consumed_args(...) + { + return 1; + } + + const_pointer_converter() + : result(0) + {} + + void* result; + + template + void apply(lua_State* L, const T* ptr) + { + if (ptr == 0) + { + lua_pushnil(L); + return; + } + + if (luabind::get_back_reference(L, ptr)) + return; + + make_instance(L, ptr); + } + + template + T const* apply(lua_State*, by_const_pointer, int) + { + return static_cast(result); + } + + template + int match(lua_State* L, by_const_pointer, int index) + { + if (lua_isnil(L, index)) return 0; + object_rep* obj = get_instance(L, index); + if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match + std::pair s = obj->get_instance(registered_class::id); + if (s.second >= 0 && !obj->is_const()) + s.second += 10; + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + +// ******* reference converter ******* + + struct ref_converter : pointer_converter + { + typedef ref_converter type; + typedef mpl::false_ is_native; + + int const consumed_args(...) + { + return 1; + } + + template + void apply(lua_State* L, T& ref) + { + if (luabind::get_back_reference(L, ref)) + return; + + make_pointee_instance(L, ref, mpl::false_()); + } + + template + T& apply(lua_State* L, by_reference, int index) + { + assert(!lua_isnil(L, index)); + return *pointer_converter::apply(L, by_pointer(), index); + } + + template + int match(lua_State* L, by_reference, int index) + { + object_rep* obj = get_instance(L, index); + if (obj == 0) return -1; + + if (obj->is_const()) + return -1; + + std::pair s = obj->get_instance(registered_class::id); + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + +// ******** const reference converter ********* + + struct const_ref_converter + { + typedef const_ref_converter type; + typedef mpl::false_ is_native; + + int const consumed_args(...) + { + return 1; + } + + const_ref_converter() + : result(0) + {} + + void* result; + + template + void apply(lua_State* L, T const& ref) + { + if (luabind::get_back_reference(L, ref)) + return; + + make_pointee_instance(L, ref, mpl::false_()); + } + + template + T const& apply(lua_State*, by_const_reference, int) + { + return *static_cast(result); + } + + template + int match(lua_State* L, by_const_reference, int index) + { + object_rep* obj = get_instance(L, index); + if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match + + std::pair s = obj->get_instance(registered_class::id); + if (s.second >= 0 && !obj->is_const()) + s.second += 10; + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, by_const_reference, int) + { + } + }; + + // ****** enum converter ******** + + struct enum_converter + { + typedef enum_converter type; + typedef mpl::true_ is_native; + + int const consumed_args(...) + { + return 1; + } + + void apply(lua_State* L, int val) + { + lua_pushnumber(L, val); + } + + template + T apply(lua_State* L, by_value, int index) + { + return static_cast(static_cast(lua_tonumber(L, index))); + } + + template + static int match(lua_State* L, by_value, int index) + { + if (lua_isnumber(L, index)) return 0; else return -1; + } + + template + T apply(lua_State* L, by_const_reference, int index) + { + return static_cast(static_cast(lua_tonumber(L, index))); + } + + template + static int match(lua_State* L, by_const_reference, int index) + { + if (lua_isnumber(L, index)) return 0; else return -1; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + + template + struct value_wrapper_converter + { + typedef value_wrapper_converter type; + typedef mpl::true_ is_native; + + int const consumed_args(...) + { + return 1; + } + + template + T apply(lua_State* L, by_const_reference, int index) + { + return T(from_stack(L, index)); + } + + template + T apply(lua_State* L, by_value, int index) + { + return apply(L, by_const_reference(), index); + } + + template + static int match(lua_State* L, by_const_reference, int index) + { + return value_wrapper_traits::check(L, index) + ? (std::numeric_limits::max)() / LUABIND_MAX_ARITY + : -1; + } + + template + static int match(lua_State* L, by_value, int index) + { + return match(L, by_const_reference(), index); + } + + void converter_postcall(...) {} + + template + void apply(lua_State* interpreter, T const& value_wrapper) + { + value_wrapper_traits::unwrap(interpreter, value_wrapper); + } + }; + + template + struct default_converter_generator + : mpl::eval_if< + is_value_wrapper_arg + , value_wrapper_converter + , mpl::eval_if< + boost::is_enum::type> + , enum_converter + , mpl::eval_if< + is_nonconst_pointer + , pointer_converter + , mpl::eval_if< + is_const_pointer + , const_pointer_converter + , mpl::eval_if< + is_nonconst_reference + , ref_converter + , mpl::eval_if< + is_const_reference + , const_ref_converter + , value_converter + > + > + > + > + > + > + {}; + +} // namespace detail + +// *********** default_policy ***************** + +template +struct default_converter + : detail::default_converter_generator::type +{}; + +template > +struct native_converter_base +{ + typedef boost::mpl::true_ is_native; + + int const consumed_args(...) + { + return 1; + } + + template + void converter_postcall(lua_State*, U const&, int) + {} + + int match(lua_State* L, detail::by_value, int index) + { + return derived().compute_score(L, index); + } + + int match(lua_State* L, detail::by_value, int index) + { + return derived().compute_score(L, index); + } + + int match(lua_State* L, detail::by_const_reference, int index) + { + return derived().compute_score(L, index); + } + + T apply(lua_State* L, detail::by_value, int index) + { + return derived().from(L, index); + } + + T apply(lua_State* L, detail::by_value, int index) + { + return derived().from(L, index); + } + + T apply(lua_State* L, detail::by_const_reference, int index) + { + return derived().from(L, index); + } + + void apply(lua_State* L, T const& value) + { + derived().to(L, value); + } + + Derived& derived() + { + return static_cast(*this); + } +}; + +template +lua_Integer as_lua_integer(T v) +{ + return static_cast(v); +} + +template +lua_Number as_lua_number(T v) +{ + return static_cast(v); +} + +# define LUABIND_NUMBER_CONVERTER(type, kind) \ + template <> \ +struct default_converter \ + : native_converter_base \ +{ \ + int compute_score(lua_State* L, int index) \ + { \ + return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; \ + }; \ + \ + type from(lua_State* L, int index) \ + { \ + return static_cast(BOOST_PP_CAT(lua_to, kind)(L, index)); \ + } \ + \ + void to(lua_State* L, type const& value) \ + { \ + BOOST_PP_CAT(lua_push, kind)(L, BOOST_PP_CAT(as_lua_, kind)(value)); \ + } \ +}; \ +\ +template <> \ +struct default_converter \ + : default_converter \ +{}; \ +\ +template <> \ +struct default_converter \ + : default_converter \ +{}; + +LUABIND_NUMBER_CONVERTER(char, integer) +LUABIND_NUMBER_CONVERTER(signed char, integer) +LUABIND_NUMBER_CONVERTER(unsigned char, integer) +LUABIND_NUMBER_CONVERTER(signed short, integer) +LUABIND_NUMBER_CONVERTER(unsigned short, integer) +LUABIND_NUMBER_CONVERTER(signed int, integer) + +LUABIND_NUMBER_CONVERTER(unsigned int, number) +LUABIND_NUMBER_CONVERTER(unsigned long, number) + +LUABIND_NUMBER_CONVERTER(signed long, integer) +LUABIND_NUMBER_CONVERTER(float, number) +LUABIND_NUMBER_CONVERTER(double, number) +LUABIND_NUMBER_CONVERTER(long double, number) + +# undef LUABIND_NUMBER_CONVERTER + +template <> +struct default_converter + : native_converter_base +{ + static int compute_score(lua_State* L, int index) + { + return lua_type(L, index) == LUA_TBOOLEAN ? 0 : -1; + } + + bool from(lua_State* L, int index) + { + return lua_toboolean(L, index) == 1; + } + + void to(lua_State* L, bool value) + { + lua_pushboolean(L, value); + } +}; + +template <> +struct default_converter + : default_converter +{}; + +template <> +struct default_converter + : default_converter +{}; + +template <> +struct default_converter + : native_converter_base +{ + static int compute_score(lua_State* L, int index) + { + return lua_type(L, index) == LUA_TSTRING ? 0 : -1; + } + + std::string from(lua_State* L, int index) + { + return std::string(lua_tostring(L, index), lua_strlen(L, index)); + } + + void to(lua_State* L, std::string const& value) + { + lua_pushlstring(L, value.data(), value.size()); + } +}; + +template <> +struct default_converter + : default_converter +{}; + +template <> +struct default_converter + : default_converter +{}; + +template <> +struct default_converter +{ + typedef boost::mpl::true_ is_native; + + int const consumed_args(...) + { + return 1; + } + + template + static int match(lua_State* L, U, int index) + { + int type = lua_type(L, index); + return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : -1; + } + + template + char const* apply(lua_State* L, U, int index) + { + return lua_tostring(L, index); + } + + void apply(lua_State* L, char const* str) + { + lua_pushstring(L, str); + } + + template + void converter_postcall(lua_State*, U, int) + {} +}; + +template <> +struct default_converter + : default_converter +{}; + +template <> +struct default_converter + : default_converter +{}; + +template +struct default_converter + : default_converter +{}; + +template +struct default_converter + : default_converter +{}; + +template <> +struct default_converter +{ + int const consumed_args(...) + { + return 0; + } + + template + lua_State* apply(lua_State* L, U, int) + { + return L; + } + + template + static int match(lua_State*, U, int) + { + return 0; + } + + template + void converter_postcall(lua_State*, U, int) {} +}; + +namespace detail +{ + + struct default_policy : converter_policy_tag + { + BOOST_STATIC_CONSTANT(bool, has_arg = true); + + template + static void precall(lua_State*, T, int) {} + + template + struct apply + { + typedef default_converter type; + }; + }; + + template + struct is_primitive + : default_converter::is_native + {}; + +// ============== new policy system ================= + + template struct find_conversion_policy; + + template + struct find_conversion_impl + { + template + struct apply + { + typedef typename find_conversion_policy::type type; + }; + }; + + template<> + struct find_conversion_impl + { + template + struct apply + { + typedef typename Policies::head head; + typedef typename Policies::tail tail; + + BOOST_STATIC_CONSTANT(bool, found = (N == head::index)); + + typedef typename + boost::mpl::if_c::type + >::type type; + }; + }; + + template + struct find_conversion_impl2 + { + template + struct apply + : find_conversion_impl< + boost::is_base_and_derived::value + >::template apply { }; + }; - } -} // namespace luabind::detail + template<> + struct find_conversion_impl2 + { + template + struct apply + { + typedef default_policy type; + }; + }; -namespace luabind { - constexpr meta::index<0> return_value; - constexpr meta::index<0> result; - constexpr meta::index<1> _1; - constexpr meta::index<2> _2; - constexpr meta::index<3> _3; - constexpr meta::index<4> _4; - constexpr meta::index<5> _5; - constexpr meta::index<6> _6; - constexpr meta::index<7> _7; - constexpr meta::index<8> _8; - constexpr meta::index<9> _9; -} + template + struct find_conversion_policy : find_conversion_impl2::template apply + { + }; + + template + struct policy_list_postcall + { + typedef typename List::head head; + typedef typename List::tail tail; + + static void apply(lua_State* L, const index_map& i) + { + head::postcall(L, i); + policy_list_postcall::apply(L, i); + } + }; + + template<> + struct policy_list_postcall + { + static void apply(lua_State*, const index_map&) {} + }; + +// ================================================== + +// ************** precall and postcall on policy_cons ********************* + + + template + struct policy_precall + { + typedef typename List::head head; + typedef typename List::tail tail; + + static void apply(lua_State* L, int index) + { + head::precall(L, index); + policy_precall::apply(L, index); + } + }; + + template<> + struct policy_precall + { + static void apply(lua_State*, int) {} + }; + + template + struct policy_postcall + { + typedef typename List::head head; + typedef typename List::tail tail; + + static void apply(lua_State* L, int index) + { + head::postcall(L, index); + policy_postcall::apply(L, index); + } + }; + + template<> + struct policy_postcall + { + static void apply(lua_State*, int) {} + }; + +}} // namespace luabind::detail + + +namespace luabind { namespace +{ +#if defined(__GNUC__) && ( \ + (BOOST_VERSION < 103500) \ + || (BOOST_VERSION < 103900 && (__GNUC__ * 100 + __GNUC_MINOR__ <= 400)) \ + || (__GNUC__ * 100 + __GNUC_MINOR__ < 400)) + static inline boost::arg<0> return_value() + { + return boost::arg<0>(); + } + + static inline boost::arg<0> result() + { + return boost::arg<0>(); + } +# define LUABIND_PLACEHOLDER_ARG(N) boost::arg(*)() +#elif defined(BOOST_MSVC) || defined(__MWERKS__) \ + || (BOOST_VERSION >= 103900 && defined(__GNUC__) \ + && (__GNUC__ * 100 + __GNUC_MINOR__ == 400)) + static boost::arg<0> return_value; + static boost::arg<0> result; +# define LUABIND_PLACEHOLDER_ARG(N) boost::arg +#else + boost::arg<0> return_value; + boost::arg<0> result; +# define LUABIND_PLACEHOLDER_ARG(N) boost::arg +#endif +}} #endif // LUABIND_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/primitives.hpp b/libs/luabind/luabind/detail/primitives.hpp index a5fe734d8..04ce17b87 100644 --- a/libs/luabind/luabind/detail/primitives.hpp +++ b/libs/luabind/luabind/detail/primitives.hpp @@ -24,40 +24,62 @@ #ifndef LUABIND_PRIMITIVES_HPP_INCLUDED #define LUABIND_PRIMITIVES_HPP_INCLUDED - // std::reference_wrapper... -#include // std::true_type... +#include #include -namespace luabind { - namespace detail { +#include +#include - template - struct type_ {}; +namespace luabind { namespace detail +{ + template + struct identity + { + typedef T type; + }; - struct ltstr - { - bool operator()(const char* s1, const char* s2) const { return std::strcmp(s1, s2) < 0; } - }; + template + struct type_ {}; - template - struct aligned - { - char storage[N]; - }; + struct null_type {}; - // returns the offset added to a Derived* when cast to a Base* - template - ptrdiff_t ptr_offset(type_, type_) - { - aligned obj; - Derived* ptr = reinterpret_cast(&obj); +/* typedef char yes_t; + typedef double no_t;*/ - return ptrdiff_t(static_cast(static_cast(static_cast(ptr))) - - static_cast(static_cast(ptr))); - } + struct lua_to_cpp {}; + struct cpp_to_lua {}; + template struct by_value {}; + template struct by_reference {}; + template struct by_const_reference {}; + template struct by_pointer {}; + template struct by_const_pointer {}; + + struct converter_policy_tag {}; + + struct ltstr + { + bool operator()(const char* s1, const char* s2) const { return std::strcmp(s1, s2) < 0; } + }; + + template + struct aligned + { + char storage[N]; + }; + + // returns the offset added to a Derived* when cast to a Base* + // TODO: return ptrdiff + template + int ptr_offset(type_, type_) + { + aligned obj; + Derived* ptr = reinterpret_cast(&obj); + + return int(static_cast(static_cast(static_cast(ptr))) + - static_cast(static_cast(ptr))); } -} + +}} #endif // LUABIND_PRIMITIVES_HPP_INCLUDED - diff --git a/libs/luabind/luabind/detail/property.hpp b/libs/luabind/luabind/detail/property.hpp index e177df209..2c30ce000 100644 --- a/libs/luabind/luabind/detail/property.hpp +++ b/libs/luabind/luabind/detail/property.hpp @@ -5,31 +5,29 @@ #ifndef LUABIND_PROPERTY_081020_HPP # define LUABIND_PROPERTY_081020_HPP -namespace luabind { - namespace detail { +namespace luabind { namespace detail { - template - struct access_member_ptr - { - access_member_ptr(T Class::* mem_ptr) - : mem_ptr(mem_ptr) - {} +template +struct access_member_ptr +{ + access_member_ptr(T Class::* mem_ptr) + : mem_ptr(mem_ptr) + {} - Result operator()(Class const& x) const - { - return const_cast(x).*mem_ptr; - } + Result operator()(Class const& x) const + { + return const_cast(x).*mem_ptr; + } - void operator()(Class& x, T const& value) const - { - x.*mem_ptr = value; - } + void operator()(Class& x, T const& value) const + { + x.*mem_ptr = value; + } - T Class::* mem_ptr; - }; + T Class::* mem_ptr; +}; - } // namespace detail -} // namespace luabind +}} // namespace luabind::detail #endif // LUABIND_PROPERTY_081020_HPP diff --git a/libs/luabind/luabind/detail/push_to_lua.hpp b/libs/luabind/luabind/detail/push_to_lua.hpp deleted file mode 100644 index 8bb2e646a..000000000 --- a/libs/luabind/luabind/detail/push_to_lua.hpp +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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 LUABIND_CONVERT_TO_LUA_HPP_INCLUDED -#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED - -#include -#include -#include - -namespace luabind { - - namespace detail { - - template< typename T > - struct unwrapped { - static const bool is_wrapped_ref = false; - using type = T; - - static const T& get(const T& t) { - return t; - } - }; - - template< typename T > - struct unwrapped< std::reference_wrapper< T > > - { - static const bool is_wrapped_ref = true; - using type = T&; - - static T& get(const std::reference_wrapper& refwrap) - { - return refwrap.get(); - } - }; - - template - using unwrapped_t = typename unwrapped< T >::type; - - template - void push_to_lua(lua_State* L, T&& v) - { - using value_type = unwrapped_t>; - - specialized_converter_policy_n() - .to_lua(L, unwrapped::get(v)); - } - - } - -} - -#endif - diff --git a/libs/luabind/luabind/detail/ref.hpp b/libs/luabind/luabind/detail/ref.hpp index 73d7b6328..3edbfebfb 100644 --- a/libs/luabind/luabind/detail/ref.hpp +++ b/libs/luabind/luabind/detail/ref.hpp @@ -33,83 +33,80 @@ namespace luabind { - namespace detail +namespace detail +{ + + struct lua_reference { - - struct lua_reference + lua_reference(lua_State* L_ = 0) + : L(L_) + , m_ref(LUA_NOREF) + {} + lua_reference(lua_reference const& r) + : L(r.L) + , m_ref(LUA_NOREF) { - lua_reference(lua_State* L_ = 0) - : L(L_) - , m_ref(LUA_NOREF) - {} - lua_reference(lua_reference const& r) - : L(r.L) - , m_ref(LUA_NOREF) - { - if(!r.is_valid()) return; - r.get(L); - set(L); - } - ~lua_reference() { reset(); } + if (!r.is_valid()) return; + r.get(L); + set(L); + } + ~lua_reference() { reset(); } - lua_State* state() const { return L; } + lua_State* state() const { return L; } - void operator=(lua_reference const& r) - { - // TODO: self assignment problems - reset(); - if(!r.is_valid()) return; - r.get(r.state()); - set(r.state()); - } + void operator=(lua_reference const& r) + { + // TODO: self assignment problems + reset(); + if (!r.is_valid()) return; + r.get(r.state()); + set(r.state()); + } - bool is_valid() const - { - return m_ref != LUA_NOREF; - } + bool is_valid() const + { return m_ref != LUA_NOREF; } - void set(lua_State* L_) - { - reset(); - L = L_; - m_ref = luaL_ref(L, LUA_REGISTRYINDEX); - } + void set(lua_State* L_) + { + reset(); + L = L_; + m_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } - void replace(lua_State* L_) - { - lua_rawseti(L_, LUA_REGISTRYINDEX, m_ref); - } + void replace(lua_State* L_) + { + lua_rawseti(L_, LUA_REGISTRYINDEX, m_ref); + } - // L may not be the same pointer as - // was used when creating this reference - // since it may be a thread that shares - // the same globals table. - void get(lua_State* L_) const - { - assert(m_ref != LUA_NOREF); - assert(L_); - lua_rawgeti(L_, LUA_REGISTRYINDEX, m_ref); - } + // L may not be the same pointer as + // was used when creating this reference + // since it may be a thread that shares + // the same globals table. + void get(lua_State* L_) const + { + assert(m_ref != LUA_NOREF); + assert(L_); + lua_rawgeti(L_, LUA_REGISTRYINDEX, m_ref); + } - void reset() - { - if(L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref); - m_ref = LUA_NOREF; - } + void reset() + { + if (L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref); + m_ref = LUA_NOREF; + } - void swap(lua_reference& r) - { - assert(r.L == L); - std::swap(r.m_ref, m_ref); - } + void swap(lua_reference& r) + { + assert(r.L == L); + std::swap(r.m_ref, m_ref); + } - private: - lua_State* L; - int m_ref; - }; + private: + lua_State* L; + int m_ref; + }; - } -} +}} #endif // LUABIND_REF_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/signature_match.hpp b/libs/luabind/luabind/detail/signature_match.hpp index f0f32f18e..d76ed6627 100644 --- a/libs/luabind/luabind/detail/signature_match.hpp +++ b/libs/luabind/luabind/detail/signature_match.hpp @@ -25,5 +25,37 @@ #include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace luabind +{ + + namespace adl + { + class argument; + } + + template + struct constructor + { + typedef BOOST_PP_CAT( + boost::mpl::vector, BOOST_PP_INC(BOOST_PP_INC(LUABIND_MAX_ARITY)))< + void, argument const&, BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A) + > signature0; + + typedef typename boost::mpl::remove< + signature0, detail::null_type>::type signature; + }; + +} + #endif // LUABIND_SIGNATURE_MATCH_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/stack_utils.hpp b/libs/luabind/luabind/detail/stack_utils.hpp index 624d58975..15f3a7fce 100644 --- a/libs/luabind/luabind/detail/stack_utils.hpp +++ b/libs/luabind/luabind/detail/stack_utils.hpp @@ -23,36 +23,30 @@ #ifndef LUABIND_STACK_UTILS_HPP_INCLUDED #define LUABIND_STACK_UTILS_HPP_INCLUDED -#ifndef LUA_INCLUDE_HPP_INCLUDED -#include -#endif - #include -namespace luabind { - namespace detail { +namespace luabind { namespace detail +{ - struct stack_pop + struct stack_pop + { + stack_pop(lua_State* L, int n) + : m_state(L) + , m_n(n) + { + } + + ~stack_pop() { - stack_pop(lua_State* L, int n) - : m_state(L) - , m_n(n) - { - } + lua_pop(m_state, m_n); + } - ~stack_pop() - { - lua_pop(m_state, m_n); - } + private: - private: - - lua_State* m_state; - int m_n; - }; - - } // namespace detail -} // namespace luabind + lua_State* m_state; + int m_n; + }; +}} #endif // LUABIND_STACK_UTILS_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/type_traits.hpp b/libs/luabind/luabind/detail/type_traits.hpp deleted file mode 100644 index d1a0e7cb9..000000000 --- a/libs/luabind/luabind/detail/type_traits.hpp +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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 LUABIND_TYPETRAITS_HPP_INCLUDED -#define LUABIND_TYPETRAITS_HPP_INCLUDED - -#include -#include // reference_wrapper -#include - -namespace luabind { - - namespace detail { - - template< typename T > - struct is_const_reference - : public std::conditional< std::is_reference::value && std::is_const::type>::value, std::true_type, std::false_type >::type - { - }; - - template - struct is_nonconst_reference - : public std::conditional< std::is_reference::value && !std::is_const::type>::value, std::true_type, std::false_type >::type - { - }; - - template - struct is_const_pointer - : public std::conditional< std::is_const::type>::value && std::is_pointer::value, std::true_type, std::false_type >::type - { - }; - - template - struct is_nonconst_pointer : - public std::conditional < std::is_pointer::value && !std::is_const::type>::value, std::true_type, std::false_type >::type - { - }; - - template - struct max_c - { - enum { value = (v1 > v2) ? v1 : v2 }; - }; - - } // namespace detail - - template< typename T > - struct remove_const_reference { - using type = typename std::remove_const::type>::type; - }; - - template< typename T > - using remove_const_reference_t = typename remove_const_reference::type; - - // - // most_derived - // - - template - struct most_derived - { - using type = typename std::conditional< - std::is_base_of::value - , B - , A - >::type; - }; - - template< typename A, typename B > - using most_derived_t = typename most_derived::type; - - // - // null_type - // - - struct null_type {}; - - template< typename T > - struct is_null_type : public std::false_type {}; - - template< > - struct is_null_type< null_type > : public std::true_type {}; - - // - // deduce_signature - // - - template< typename, typename > struct tagged_function; - - template< typename T, typename WrappedType = null_type > - struct deduce_signature; - - template< typename R, typename... Args, typename WrappedType > - struct deduce_signature < R(Args...), WrappedType > - { - using type = meta::type_list< R, Args... >; - }; - - template< typename R, typename... Args, typename WrappedType > - struct deduce_signature < R(*)(Args...), WrappedType > - { - using type = meta::type_list< R, Args... >; - }; - - template< typename R, typename Class, typename... Args > - struct deduce_signature < R(Class::*)(Args...), null_type > - { - using type = meta::type_list< R, Class&, Args... >; - }; - - template< typename R, typename Class, typename... Args > - struct deduce_signature < R(Class::*)(Args...) const, null_type > - { - using type = meta::type_list< R, Class const&, Args... >; - }; - - template< typename R, typename Class, typename... Args, class WrappedType > - struct deduce_signature < R(Class::*)(Args...), WrappedType > - { - using type = meta::type_list< R, typename most_derived::type&, Args... >; - }; - - template< typename R, typename Class, typename... Args, class WrappedType > - struct deduce_signature < R(Class::*)(Args...) const, WrappedType > - { - using type = meta::type_list< R, typename most_derived::type const&, Args... >; - }; - - template< typename Signature, typename F, class WrappedType > - struct deduce_signature< tagged_function< Signature, F >, WrappedType > - { - using type = Signature; - }; - - template< typename T, typename WrappedType = null_type > - using deduce_signature_t = typename deduce_signature::type; - - // - // is_reference_wrapper - // - - template< typename T > struct is_reference_wrapper : public std::false_type { }; - template< typename T > struct is_reference_wrapper< std::reference_wrapper > : public std::true_type { }; - - // - // apply_reference_wrapper - // - - template< typename T > struct apply_reference_wrapper { using type = T; }; - template< typename T > struct apply_reference_wrapper< std::reference_wrapper > { using type = T&; }; - - template< typename T > - using apply_reference_wrapper_t = typename apply_reference_wrapper::type; - - // - // identity - // - - template< typename T > struct identity { using type = T; }; - - template< typename T > - using identity_t = typename identity::type; - - template< typename Dst > Dst implicit_cast(typename identity::type t) { return t; } - -} // namespace luabind - -#endif // LUABIND_TYPETRAITS_HPP_INCLUDED - diff --git a/libs/luabind/luabind/detail/typetraits.hpp b/libs/luabind/luabind/detail/typetraits.hpp new file mode 100644 index 000000000..f27934e98 --- /dev/null +++ b/libs/luabind/luabind/detail/typetraits.hpp @@ -0,0 +1,190 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_TYPETRAITS_HPP_INCLUDED +#define LUABIND_TYPETRAITS_HPP_INCLUDED + +#include +#include +#include +#include +#include + +namespace luabind { namespace detail +{ + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + template + struct is_const_type + { + typedef typename boost::mpl::if_ + , yes_t + , no_t + >::type type; + }; + + template + struct is_const_reference_helper + { + template + struct apply + { + enum + { + value = false + }; + }; + }; + + template + typename is_const_type::type is_const_reference_tester(T&); + no_t is_const_reference_tester(...); + + template<> + struct is_const_reference_helper + { + template + struct apply + { + static T getT(); + + enum + { + value = sizeof(is_const_reference_tester(getT())) == sizeof(yes_t) + }; + }; + }; + + template + struct is_const_reference + : is_const_reference_helper::value>::template apply + { + typedef boost::mpl::bool_ type; + }; + +#else + + template + struct is_const_reference + { + enum { value = false }; + typedef boost::mpl::bool_ type; + }; + + template + struct is_const_reference + { + enum { value = true }; + typedef boost::mpl::bool_ type; + }; + +#endif + + + template + struct is_nonconst_reference + { + enum + { + value = boost::is_reference::value && !is_const_reference::value + }; + typedef boost::mpl::bool_ type; + }; + + template + yes_t is_const_pointer_helper(void(*)(const A*)); + no_t is_const_pointer_helper(...); + + template + struct is_const_pointer + { + enum { value = sizeof(is_const_pointer_helper((void(*)(T))0)) == sizeof(yes_t) }; + typedef boost::mpl::bool_ type; + }; + + template + yes_t is_nonconst_pointer_helper(void(*)(A*)); + no_t is_nonconst_pointer_helper(...); + + template + struct is_nonconst_pointer + { + enum { value = sizeof(is_nonconst_pointer_helper((void(*)(T))0)) == sizeof(yes_t) && !is_const_pointer::value }; + typedef boost::mpl::bool_ type; + }; +/* + template + struct is_constructable_from_helper + { + static yes_t check(const T&); + static no_t check(...); + }; + + template + struct is_constructable_from + { + static From getFrom(); + + enum + { + value = sizeof(is_constructable_from_helper::check(getFrom())) == sizeof(yes_t) + }; + }; + + template + struct is_const_member_function_helper + { + static no_t test(...); + template + static yes_t test(R(T::*)() const); + template + static yes_t test(R(T::*)(A1) const); + template + static yes_t test(R(T::*)(A1,A2) const); + template + static yes_t test(R(T::*)(A1,A2,A3) const); + }; + + template + struct is_const_member_function + { + static U getU(); + + enum + { + value = sizeof(is_const_member_function_helper::test(getU())) == sizeof(yes_t) + }; + }; +*/ + + template + struct max_c + { + enum { value = (v1>v2)?v1:v2 }; + }; + +}} + +#endif // LUABIND_TYPETRAITS_HPP_INCLUDED + diff --git a/libs/luabind/src/operator.cpp b/libs/luabind/luabind/detail/yes_no.hpp similarity index 81% rename from libs/luabind/src/operator.cpp rename to libs/luabind/luabind/detail/yes_no.hpp index db64ce862..931847c60 100644 --- a/libs/luabind/src/operator.cpp +++ b/libs/luabind/luabind/detail/yes_no.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg +// Copyright (c) 2004 Daniel Wallin // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -20,13 +20,15 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#define LUABIND_BUILDING +#ifndef YES_NO_040211_HPP +#define YES_NO_040211_HPP -#include +namespace luabind { namespace detail { -namespace luabind -{ - LUABIND_API self_type self; - LUABIND_API const_self_type const_self; -} + typedef char(&yes_t)[1]; + typedef char(&no_t)[2]; + +}} // namespace luabind::detail + +#endif // YES_NO_040211_HPP diff --git a/libs/luabind/luabind/discard_result_policy.hpp b/libs/luabind/luabind/discard_result_policy.hpp index 277d88137..149a7b1bc 100644 --- a/libs/luabind/luabind/discard_result_policy.hpp +++ b/libs/luabind/luabind/discard_result_policy.hpp @@ -20,41 +20,52 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. + #ifndef LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED #define LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED #include -#include // for index_map, etc -#include // for null_type, etc -#include +#include -namespace luabind { - namespace detail { +namespace luabind { namespace detail +{ + struct discard_converter + { + template + void apply(lua_State*, T) {} + }; - struct discard_converter + struct discard_result_policy : conversion_policy<0> + { + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + + struct can_only_convert_from_cpp_to_lua {}; + + template + struct apply { - template - void to_lua(lua_State*, T) {} + typedef typename boost::mpl::if_ + , discard_converter + , can_only_convert_from_cpp_to_lua + >::type type; }; + }; - struct discard_result_policy - { - struct can_only_convert_from_cpp_to_lua {}; - - template - struct specialize - { - static_assert(std::is_same< Direction, cpp_to_lua >::value, "Can only convert from cpp to lua"); - using type = discard_converter; - }; - }; - - } -} +}} namespace luabind { - using discard_result = meta::type_list>; + detail::policy_cons< + detail::discard_result_policy, detail::null_type> const discard_result = {}; + + namespace detail + { + inline void ignore_unused_discard_result() + { + (void)discard_result; + } + } } #endif // LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/error.hpp b/libs/luabind/luabind/error.hpp index cf42091aa..b282a411a 100644 --- a/libs/luabind/luabind/error.hpp +++ b/libs/luabind/luabind/error.hpp @@ -26,13 +26,9 @@ #include #include #include -#include -#include -#include - -#ifndef LUABIND_NO_EXCEPTIONS #include -#endif + +struct lua_State; namespace luabind { @@ -42,19 +38,22 @@ namespace luabind // this exception usually means that the lua function you called // from C++ failed with an error code. You will have to // read the error code from the top of the lua stack - // note that std::string's copy constructor + // the reason why this exception class doesn't contain + // the message itself is that std::string's copy constructor // may throw, if the copy constructor of an exception that is // being thrown throws another exception, terminate will be called // and the entire application is killed. class LUABIND_API error : public std::exception { public: - explicit error(lua_State* L); - - virtual const char* what() const throw(); - + explicit error(lua_State* L): m_L(L) {} + lua_State* state() const throw() { return m_L; } + virtual const char* what() const throw() + { + return "lua runtime error"; + } private: - std::string m_message; + lua_State* m_L; }; // if an object_cast<>() fails, this is thrown @@ -63,7 +62,7 @@ namespace luabind class LUABIND_API cast_failed : public std::exception { public: - cast_failed(lua_State* L, type_id const& i) : m_L(L), m_info(i) {} + cast_failed(lua_State* L, type_id const& i): m_L(L), m_info(i) {} lua_State* state() const throw() { return m_L; } type_id info() const throw() { return m_info; } virtual const char* what() const throw() { return "unable to make cast"; } @@ -74,6 +73,9 @@ namespace luabind #else + typedef void(*error_callback_fun)(lua_State*); + typedef void(*cast_failed_callback_fun)(lua_State*, type_id const&); + LUABIND_API void set_error_callback(error_callback_fun e); LUABIND_API void set_cast_failed_callback(cast_failed_callback_fun c); LUABIND_API error_callback_fun get_error_callback(); @@ -81,6 +83,7 @@ namespace luabind #endif + typedef int(*pcall_callback_fun)(lua_State*); LUABIND_API void set_pcall_callback(pcall_callback_fun e); LUABIND_API pcall_callback_fun get_pcall_callback(); diff --git a/libs/luabind/luabind/exception_handler.hpp b/libs/luabind/luabind/exception_handler.hpp index 71d3fd20f..0048563af 100644 --- a/libs/luabind/luabind/exception_handler.hpp +++ b/libs/luabind/luabind/exception_handler.hpp @@ -3,73 +3,106 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef LUABIND_EXCEPTION_HANDLER_050601_HPP -#define LUABIND_EXCEPTION_HANDLER_050601_HPP +# define LUABIND_EXCEPTION_HANDLER_050601_HPP -#include // for LUABIND_API -#include -#include -#include +# include +# include +# include +# include + +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +# include +# include +# endif namespace luabind { # ifndef LUABIND_NO_EXCEPTIONS - namespace detail { +namespace detail +{ - struct LUABIND_API exception_handler_base - { - exception_handler_base() - : next(0) - {} + struct LUABIND_API exception_handler_base + { + exception_handler_base() + : next(0) + {} - virtual ~exception_handler_base() {} - virtual void handle(lua_State*) const = 0; + virtual ~exception_handler_base() {} + virtual void handle(lua_State*) const = 0; - void try_next(lua_State*) const; + void try_next(lua_State*) const; - exception_handler_base* next; - }; + exception_handler_base* next; + }; - template - struct exception_handler : exception_handler_base - { - using argument = E const&; + namespace mpl = boost::mpl; - exception_handler(Handler handler) - : handler(handler) - {} + template + struct exception_handler : exception_handler_base + { +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + typedef typename mpl::if_< + boost::is_pointer, E, E const& + >::type argument; +# else + typedef E const& argument; +# endif - void handle(lua_State* L) const - { - try - { - try_next(L); - } - catch(argument e) - { - handler(L, e); - } - } + exception_handler(Handler handler) + : handler(handler) + {} - Handler handler; - }; + void handle(lua_State* L) const + { + try + { + try_next(L); + } + catch (argument e) + { + handler(L, e); + } + } - LUABIND_API void handle_exception_aux(lua_State* L); - LUABIND_API void register_exception_handler(exception_handler_base*); + Handler handler; + }; - } // namespace detail + LUABIND_API void handle_exception_aux(lua_State* L); + LUABIND_API void register_exception_handler(exception_handler_base*); + +} // namespace detail # endif - template - void register_exception_handler(Handler handler, meta::type* = 0) - { +template +void register_exception_handler(Handler handler, boost::type* = 0) +{ # ifndef LUABIND_NO_EXCEPTIONS - detail::register_exception_handler( - new detail::exception_handler(handler) - ); + detail::register_exception_handler( + new detail::exception_handler(handler) + ); # endif - } +} + +template +boost::optional handle_exceptions(lua_State* L, F fn, boost::type* = 0) +{ +# ifndef LUABIND_NO_EXCEPTIONS + try + { + return fn(); + } + catch (...) + { + detail::handle_exception_aux(L); + } + + return boost::optional(); +# else + return fn(); +# endif +} } // namespace luabind diff --git a/libs/luabind/luabind/from_stack.hpp b/libs/luabind/luabind/from_stack.hpp index cde5644a1..56bc268d8 100644 --- a/libs/luabind/luabind/from_stack.hpp +++ b/libs/luabind/luabind/from_stack.hpp @@ -23,20 +23,18 @@ #ifndef LUABIND_FROM_STACK_050715_HPP #define LUABIND_FROM_STACK_050715_HPP -#include - namespace luabind { - struct from_stack - { - from_stack(lua_State* interpreter, int index) - : interpreter(interpreter) - , index(index) - {} +struct from_stack +{ + from_stack(lua_State* interpreter, int index) + : interpreter(interpreter) + , index(index) + {} - lua_State* interpreter; - int index; - }; + lua_State* interpreter; + int index; +}; } // namespace luabind diff --git a/libs/luabind/luabind/function.hpp b/libs/luabind/luabind/function.hpp index 815108a98..e156fbfcb 100644 --- a/libs/luabind/luabind/function.hpp +++ b/libs/luabind/luabind/function.hpp @@ -11,43 +11,50 @@ namespace luabind { - namespace detail - { +namespace detail +{ - template - struct function_registration : registration - { - function_registration(char const* name, F f) - : name(name) - , f(f) - {} + template + struct function_registration : registration + { + function_registration(char const* name, F f, Policies const& policies) + : name(name) + , f(f) + , policies(policies) + {} - void register_(lua_State* L) const - { - object fn = make_function(L, f, PolicyInjectors()); - add_overload(object(from_stack(L, -1)), name, fn); - } + void register_(lua_State* L) const + { + object fn = make_function(L, f, deduce_signature(f), policies); - char const* name; - F f; - }; + add_overload( + object(from_stack(L, -1)) + , name + , fn + ); + } - LUABIND_API bool is_luabind_function(lua_State* L, int index); + char const* name; + F f; + Policies policies; + }; - } // namespace detail + LUABIND_API bool is_luabind_function(lua_State* L, int index); - template - scope def(char const* name, F f, policy_list const&) - { - return scope(std::unique_ptr( - new detail::function_registration>(name, f))); - } +} // namespace detail - template - scope def(char const* name, F f) - { - return def(name, f, no_policies()); - } +template +scope def(char const* name, F f, Policies const& policies) +{ + return scope(std::auto_ptr( + new detail::function_registration(name, f, policies))); +} + +template +scope def(char const* name, F f) +{ + return def(name, f, detail::null_type()); +} } // namespace luabind diff --git a/libs/luabind/luabind/function_introspection.hpp b/libs/luabind/luabind/function_introspection.hpp deleted file mode 100644 index c18dab7df..000000000 --- a/libs/luabind/luabind/function_introspection.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/** @file - @brief Header - - @date 2012 - - @author - Ryan Pavlik - and - http://academic.cleardefinition.com/ - Iowa State University Virtual Reality Applications Center - Human-Computer Interaction Graduate Program -*/ - -// Copyright Iowa State University 2012. -// 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 INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065 -#define INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065 - -// Internal Includes -#include -#include - -// Library/third-party includes -// - none - -// Standard includes -// - none - - -namespace luabind { - - LUABIND_API int bind_function_introspection(lua_State * L); - -} // end of namespace luabind - -#endif // INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065 - diff --git a/libs/luabind/luabind/get_main_thread.hpp b/libs/luabind/luabind/get_main_thread.hpp index 80b44ef10..f94d6e4bc 100644 --- a/libs/luabind/luabind/get_main_thread.hpp +++ b/libs/luabind/luabind/get_main_thread.hpp @@ -6,13 +6,11 @@ # define LUABIND_GET_MAIN_THREAD_090321_HPP # include -# include namespace luabind { - LUABIND_API lua_State* get_main_thread(lua_State* L); +LUABIND_API lua_State* get_main_thread(lua_State* L); } // namespace luabind #endif // LUABIND_GET_MAIN_THREAD_090321_HPP - diff --git a/libs/luabind/luabind/lua_state_fwd.hpp b/libs/luabind/luabind/get_pointer.hpp similarity index 77% rename from libs/luabind/luabind/lua_state_fwd.hpp rename to libs/luabind/luabind/get_pointer.hpp index 215574a13..b9aae48a7 100644 --- a/libs/luabind/luabind/lua_state_fwd.hpp +++ b/libs/luabind/luabind/get_pointer.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2005 Daniel Wallin and Arvid Norberg +// Copyright (c) 2005 Daniel Wallin // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -20,19 +20,20 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef LUABIND_LUA_STATE_FWD_HPP -#define LUABIND_LUA_STATE_FWD_HPP +#ifndef LUABIND_GET_POINTER_051023_HPP +# define LUABIND_GET_POINTER_051023_HPP -#ifndef LUABIND_CPLUSPLUS_LUA -extern "C" -{ -#endif +// +// We need these overloads in the luabind namespace. +// - struct lua_State; +# include -#ifndef LUABIND_CPLUSPLUS_LUA -} -#endif +namespace luabind { -#endif // LUABIND_BACK_REFERENCE_FWD_040510_HPP +using boost::get_pointer; + +} // namespace luabind + +#endif // LUABIND_GET_POINTER_051023_HPP diff --git a/libs/luabind/luabind/handle.hpp b/libs/luabind/luabind/handle.hpp index 5aa98aa14..14adacbae 100644 --- a/libs/luabind/luabind/handle.hpp +++ b/libs/luabind/luabind/handle.hpp @@ -24,115 +24,119 @@ #define LUABIND_HANDLE_050420_HPP #include -#include -#include +#include namespace luabind { - // A reference to a Lua value. Represents an entry in the - // registry table. - class handle - { - public: - handle(); - handle(lua_State* interpreter, int stack_index); - handle(lua_State* main, lua_State* interpreter, int stack_index); - handle(handle const& other); - ~handle(); +// A reference to a Lua value. Represents an entry in the +// registry table. +class handle +{ +public: + handle(); + handle(lua_State* interpreter, int stack_index); + handle(lua_State* main, lua_State* interpreter, int stack_index); + handle(handle const& other); + ~handle(); - handle& operator=(handle const& other); - void swap(handle& other); + handle& operator=(handle const& other); + void swap(handle& other); - void push(lua_State* interpreter) const; + void push(lua_State* interpreter) const; - lua_State* interpreter() const; + lua_State* interpreter() const; - void replace(lua_State* interpreter, int stack_index); + void replace(lua_State* interpreter, int stack_index); - private: - lua_State* m_interpreter; - int m_index; - }; +private: + lua_State* m_interpreter; + int m_index; +}; - inline handle::handle() - : m_interpreter(0), m_index(LUA_NOREF) - {} +inline handle::handle() + : m_interpreter(0) + , m_index(LUA_NOREF) +{} - inline handle::handle(handle const& other) - : m_interpreter(other.m_interpreter), m_index(LUA_NOREF) - { - if(m_interpreter == 0) return; - lua_rawgeti(m_interpreter, LUA_REGISTRYINDEX, other.m_index); - m_index = luaL_ref(m_interpreter, LUA_REGISTRYINDEX); - } +inline handle::handle(handle const& other) + : m_interpreter(other.m_interpreter) + , m_index(LUA_NOREF) +{ + if (m_interpreter == 0) return; + lua_rawgeti(m_interpreter, LUA_REGISTRYINDEX, other.m_index); + m_index = luaL_ref(m_interpreter, LUA_REGISTRYINDEX); +} - inline handle::handle(lua_State* interpreter, int stack_index) - : m_interpreter(interpreter), m_index(LUA_NOREF) - { - lua_pushvalue(interpreter, stack_index); - m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); - } +inline handle::handle(lua_State* interpreter, int stack_index) + : m_interpreter(interpreter) + , m_index(LUA_NOREF) +{ + lua_pushvalue(interpreter, stack_index); + m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); +} - inline handle::handle(lua_State* main, lua_State* interpreter, int stack_index) - : m_interpreter(main), m_index(LUA_NOREF) - { - lua_pushvalue(interpreter, stack_index); - m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); - } +inline handle::handle(lua_State* main, lua_State* interpreter, int stack_index) + : m_interpreter(main) + , m_index(LUA_NOREF) +{ + lua_pushvalue(interpreter, stack_index); + m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); +} - inline handle::~handle() - { - if(m_interpreter && m_index != LUA_NOREF) luaL_unref(m_interpreter, LUA_REGISTRYINDEX, m_index); - } +inline handle::~handle() +{ + if (m_interpreter && m_index != LUA_NOREF) + luaL_unref(m_interpreter, LUA_REGISTRYINDEX, m_index); +} - inline handle& handle::operator=(handle const& other) - { - handle(other).swap(*this); - return *this; - } +inline handle& handle::operator=(handle const& other) +{ + handle(other).swap(*this); + return *this; +} - inline void handle::swap(handle& other) - { - std::swap(m_interpreter, other.m_interpreter); - std::swap(m_index, other.m_index); - } +inline void handle::swap(handle& other) +{ + std::swap(m_interpreter, other.m_interpreter); + std::swap(m_index, other.m_index); +} - inline void handle::push(lua_State* interpreter) const - { - lua_rawgeti(interpreter, LUA_REGISTRYINDEX, m_index); - } +inline void handle::push(lua_State* interpreter) const +{ + lua_rawgeti(interpreter, LUA_REGISTRYINDEX, m_index); +} - inline lua_State* handle::interpreter() const - { - return m_interpreter; - } +inline lua_State* handle::interpreter() const +{ + return m_interpreter; +} - inline void handle::replace(lua_State* interpreter, int stack_index) - { - lua_pushvalue(interpreter, stack_index); - lua_rawseti(interpreter, LUA_REGISTRYINDEX, m_index); - } +inline void handle::replace(lua_State* interpreter, int stack_index) +{ + lua_pushvalue(interpreter, stack_index); + lua_rawseti(interpreter, LUA_REGISTRYINDEX, m_index); +} - template<> - struct lua_proxy_traits - { - using is_specialized = std::true_type; +template<> +struct value_wrapper_traits +{ + typedef boost::mpl::true_ is_specialized; - static lua_State* interpreter(handle const& value) - { - return value.interpreter(); - } + static lua_State* interpreter(handle const& value) + { + return value.interpreter(); + } + + static void unwrap(lua_State* interpreter, handle const& value) + { + value.push(interpreter); + } - static void unwrap(lua_State* interpreter, handle const& value) - { - value.push(interpreter); - } - - static bool check(...) - { - return true; - } - }; + static bool check(...) + { + return true; + } +}; } // namespace luabind diff --git a/libs/luabind/luabind/iterator_policy.hpp b/libs/luabind/luabind/iterator_policy.hpp index 03840a968..b1f827fe3 100644 --- a/libs/luabind/luabind/iterator_policy.hpp +++ b/libs/luabind/luabind/iterator_policy.hpp @@ -5,105 +5,108 @@ #ifndef LUABIND_ITERATOR_POLICY__071111_HPP # define LUABIND_ITERATOR_POLICY__071111_HPP -# include // for LUABIND_ANONYMOUS_FIX -# include // for convert_to_lua -# include // for index_map, etc +# include +# include +# include -# include // for operator new +namespace luabind { namespace detail { -namespace luabind { - namespace detail { +template +struct iterator +{ + static int next(lua_State* L) + { + iterator* self = static_cast( + lua_touserdata(L, lua_upvalueindex(1))); - template - struct iterator - { - static int next(lua_State* L) - { - iterator* self = static_cast( - lua_touserdata(L, lua_upvalueindex(1))); + if (self->first != self->last) + { + convert_to_lua(L, *self->first); + ++self->first; + } + else + { + lua_pushnil(L); + } - if(self->first != self->last) - { - push_to_lua(L, *self->first); - ++self->first; - } else - { - lua_pushnil(L); - } + return 1; + } - return 1; - } + static int destroy(lua_State* L) + { + iterator* self = static_cast(lua_touserdata(L, 1)); + self->~iterator(); + return 0; + } - static int destroy(lua_State* L) - { - iterator* self = static_cast(lua_touserdata(L, 1)); - self->~iterator(); - return 0; - } + iterator(Iterator first, Iterator last) + : first(first) + , last(last) + {} - iterator(Iterator first, Iterator last) - : first(first) - , last(last) - {} + Iterator first; + Iterator last; +}; - Iterator first; - Iterator last; - }; +template +int make_range(lua_State* L, Iterator first, Iterator last) +{ + void* storage = lua_newuserdata(L, sizeof(iterator)); + lua_newtable(L); + lua_pushcclosure(L, iterator::destroy, 0); + lua_setfield(L, -2, "__gc"); + lua_setmetatable(L, -2); + lua_pushcclosure(L, iterator::next, 1); + new (storage) iterator(first, last); + return 1; +} - template - int make_range(lua_State* L, Iterator first, Iterator last) - { - void* storage = lua_newuserdata(L, sizeof(iterator)); - lua_newtable(L); - lua_pushcclosure(L, iterator::destroy, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); - lua_pushcclosure(L, iterator::next, 1); - new (storage) iterator(first, last); - return 1; - } +template +int make_range(lua_State* L, Container& container) +{ + return make_range(L, container.begin(), container.end()); +} - template - int make_range(lua_State* L, Container& container) - { - return make_range(L, container.begin(), container.end()); - } +struct iterator_converter +{ + typedef iterator_converter type; - struct iterator_converter - { - using type = iterator_converter; + template + void apply(lua_State* L, Container& container) + { + make_range(L, container); + } - template - void to_lua(lua_State* L, Container& container) - { - make_range(L, container); - } + template + void apply(lua_State* L, Container const& container) + { + make_range(L, container); + } +}; - template - void tu_lua(lua_State* L, Container const& container) - { - make_range(L, container); - } - }; +struct iterator_policy : conversion_policy<0> +{ + static void precall(lua_State*, index_map const&) + {} - struct iterator_policy - { - template - struct specialize - { - static_assert(std::is_same::value, "Iterator policy can only convert from cpp to lua."); - using type = iterator_converter; - }; - }; + static void postcall(lua_State*, index_map const&) + {} - } // namespace detail -} // namespace luabind + template + struct apply + { + typedef iterator_converter type; + }; +}; -namespace luabind { +}} // namespace luabind::detail - using return_stl_iterator = policy_list>; +namespace luabind { namespace { -} // namespace luabind +LUABIND_ANONYMOUS_FIX detail::policy_cons< + detail::iterator_policy, detail::null_type> return_stl_iterator; + +}} // namespace luabind::unnamed #endif // LUABIND_ITERATOR_POLICY__071111_HPP diff --git a/libs/luabind/luabind/lua502.hpp b/libs/luabind/luabind/lua502.hpp new file mode 100644 index 000000000..5006128ec --- /dev/null +++ b/libs/luabind/luabind/lua502.hpp @@ -0,0 +1,56 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// 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 LUA_502_HPP +#define LUA_502_HPP + +#if LUA_VERSION_NUM >= 502 + +inline LUA_API int lua_equal(lua_State *L, int idx1, int idx2) +{ + return lua_compare(L, idx1, idx2, LUA_OPEQ); +} + +inline LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2) +{ + return lua_compare(L, idx1, idx2, LUA_OPLT); +} + +#undef lua_strlen +#define lua_strlen lua_rawlen + +#undef lua_getfenv +#define lua_getfenv lua_getuservalue + +#undef lua_setfenv +#define lua_setfenv lua_setuservalue + +#undef lua_open +#define lua_open luaL_newstate + +#else // LUA_VERSION_NUM >= 502 + +#define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) + +#endif // LUA_VERSION_NUM >= 502 + +#endif \ No newline at end of file diff --git a/libs/luabind/luabind/lua_argument_proxy.hpp b/libs/luabind/luabind/lua_argument_proxy.hpp deleted file mode 100644 index ed5997961..000000000 --- a/libs/luabind/luabind/lua_argument_proxy.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef LUA_ARGUMENT_PROXY_HPP_INCLUDED -#define LUA_ARGUMENT_PROXY_HPP_INCLUDED - -#include -#include -#include -#include - -namespace luabind { - - namespace adl { - - class argument : public lua_proxy_interface - { - public: - argument(from_stack const& stack_reference) - : m_interpreter(stack_reference.interpreter), m_index(stack_reference.index) - { - if(m_index < 0) m_index = lua_gettop(m_interpreter) - m_index + 1; - } - - template - index_proxy operator[](T const& key) const - { - return index_proxy(*this, m_interpreter, key); - } - - void push(lua_State* L) const - { - lua_pushvalue(L, m_index); - } - - lua_State* interpreter() const - { - return m_interpreter; - } - - private: - lua_State* m_interpreter; - int m_index; - }; - - } - - using adl::argument; - - template<> - struct lua_proxy_traits - { - using is_specialized = std::true_type; - - static lua_State* interpreter(argument const& value) - { - return value.interpreter(); - } - - static void unwrap(lua_State* interpreter, argument const& value) - { - value.push(interpreter); - } - - static bool check(...) - { - return true; - } - }; - -} - -#endif - diff --git a/libs/luabind/luabind/lua_include.hpp b/libs/luabind/luabind/lua_include.hpp index 64c595bf3..7327b533e 100644 --- a/libs/luabind/luabind/lua_include.hpp +++ b/libs/luabind/luabind/lua_include.hpp @@ -28,8 +28,8 @@ extern "C" { #endif -#include "lua.h" -#include "lauxlib.h" + #include "lua.h" + #include "lauxlib.h" #ifndef LUABIND_CPLUSPLUS_LUA } diff --git a/libs/luabind/luabind/lua_index_proxy.hpp b/libs/luabind/luabind/lua_index_proxy.hpp deleted file mode 100644 index c62314f91..000000000 --- a/libs/luabind/luabind/lua_index_proxy.hpp +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef LUA_INDEX_PROXY_HPP_INCLUDED -#define LUA_INDEX_PROXY_HPP_INCLUDED - -#include -#include -#include -#include - -namespace luabind { - - namespace adl { - - class object; - - template - class index_proxy - : public lua_proxy_interface > - { - public: - using this_type = index_proxy; - - template - index_proxy(Next const& next, lua_State* interpreter, Key const& key) - : m_interpreter(interpreter), m_key_index(lua_gettop(interpreter) + 1), m_next(next) - { - detail::push_to_lua(m_interpreter, key); - } - - index_proxy(index_proxy const& other) - : m_interpreter(other.m_interpreter), m_key_index(other.m_key_index), m_next(other.m_next) - { - other.m_interpreter = 0; - } - - ~index_proxy() - { - if(m_interpreter) - lua_pop(m_interpreter, 1); - } - - // This is non-const to prevent conversion on lvalues. - // defined in luabind/detail/object.hpp - operator object(); - - // this will set the value to nil - this_type& operator=(luabind::detail::nil_type) - { - lua_proxy_traits::unwrap(m_interpreter, m_next); - detail::stack_pop pop(m_interpreter, 1); - - lua_pushvalue(m_interpreter, m_key_index); - lua_pushnil(m_interpreter); - lua_settable(m_interpreter, -3); - return *this; - } - - template - this_type& operator=(T&& value) - { - lua_proxy_traits::unwrap(m_interpreter, m_next); - detail::stack_pop pop(m_interpreter, 1); - - lua_pushvalue(m_interpreter, m_key_index); - detail::push_to_lua(m_interpreter, std::forward(value)); - lua_settable(m_interpreter, -3); - return *this; - } - - this_type& operator=(this_type const& value) - { - lua_proxy_traits::unwrap(m_interpreter, m_next); - detail::stack_pop pop(m_interpreter, 1); - - lua_pushvalue(m_interpreter, m_key_index); - detail::push_to_lua(m_interpreter, value); - lua_settable(m_interpreter, -3); - return *this; - } - - template - index_proxy operator[](T const& key) - { - return index_proxy(*this, m_interpreter, key); - } - - void push(lua_State* interpreter); - - lua_State* interpreter() const - { - return m_interpreter; - } - - private: - struct hidden_type {}; - mutable lua_State* m_interpreter; - int m_key_index; - - Next const& m_next; - }; - - template - inline void index_proxy::push(lua_State* interpreter) - { - assert(interpreter == m_interpreter); - - lua_proxy_traits::unwrap(m_interpreter, m_next); - - lua_pushvalue(m_interpreter, m_key_index); - lua_gettable(m_interpreter, -2); - lua_remove(m_interpreter, -2); - } - - } // namespace adl - - template - struct lua_proxy_traits > - { - using is_specialized = std::true_type; - - template - static lua_State* interpreter(adl::index_proxy const& proxy) - { - return proxy.interpreter(); - } - - template - static void unwrap(lua_State* interpreter, adl::index_proxy const& proxy) - { - const_cast&>(proxy).push(interpreter); - } - }; - - -} // namespace luabind - -#endif - diff --git a/libs/luabind/luabind/lua_iterator_proxy.hpp b/libs/luabind/luabind/lua_iterator_proxy.hpp deleted file mode 100644 index 155c67ef2..000000000 --- a/libs/luabind/luabind/lua_iterator_proxy.hpp +++ /dev/null @@ -1,230 +0,0 @@ -#ifndef LUA_ITERATOR_PROXY_HPP_INCLUDED -#define LUA_ITERATOR_PROXY_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include - -#if LUA_VERSION_NUM < 502 -# define lua_compare(L, index1, index2, fn) fn(L, index1, index2) -# define LUA_OPEQ lua_equal -#endif - -namespace luabind { - - namespace adl { - - template - class iterator_proxy : - public lua_proxy_interface > - { - public: - iterator_proxy(lua_State* interpreter, handle const& table, handle const& key) - : m_interpreter(interpreter), m_table_index(lua_gettop(interpreter) + 1), m_key_index(m_table_index + 1) - { - table.push(m_interpreter); - key.push(m_interpreter); - } - - iterator_proxy(iterator_proxy const& other) - : m_interpreter(other.m_interpreter), m_table_index(other.m_table_index), m_key_index(other.m_key_index) - { - other.m_interpreter = 0; - } - - ~iterator_proxy() - { - if(m_interpreter) lua_pop(m_interpreter, 2); - } - - // this will set the value to nil - iterator_proxy & operator=(luabind::detail::nil_type) - { - lua_pushvalue(m_interpreter, m_key_index); - lua_pushnil(m_interpreter); - AccessPolicy::set(m_interpreter, m_table_index); - return *this; - } - - template - iterator_proxy& operator=(T&& value) - { - lua_pushvalue(m_interpreter, m_key_index); - detail::push_to_lua(m_interpreter, std::forward(value)); - AccessPolicy::set(m_interpreter, m_table_index); - return *this; - } - - template - index_proxy > operator[](Key const& key) - { - return index_proxy >( - *this, m_interpreter, key - ); - } - - // This is non-const to prevent conversion on lvalues. - // defined in luabind/object.hpp - operator object(); - - lua_State* interpreter() const - { - return m_interpreter; - } - - // TODO: Why is it non-const? - void push(lua_State* interpreter) - { - assert(interpreter == m_interpreter); - lua_pushvalue(m_interpreter, m_key_index); - AccessPolicy::get(m_interpreter, m_table_index); - } - - private: - mutable lua_State* m_interpreter; - int m_table_index; - int m_key_index; - }; - - } - - template - struct lua_proxy_traits > - { - using is_specialized = std::true_type; - - template - static lua_State* interpreter(Proxy const& p) - { - return p.interpreter(); - } - - template - static void unwrap(lua_State* interpreter, Proxy const& p) - { - // TODO: Why const_cast? - const_cast(p).push(interpreter); - } - }; - - namespace detail - { - struct basic_access - { - static void set(lua_State* interpreter, int table) - { - lua_settable(interpreter, table); - } - - static void get(lua_State* interpreter, int table) - { - lua_gettable(interpreter, table); - } - }; - - struct raw_access - { - static void set(lua_State* interpreter, int table) - { - lua_rawset(interpreter, table); - } - - static void get(lua_State* interpreter, int table) - { - lua_rawget(interpreter, table); - } - }; - - template - class basic_iterator : - public detail::crtp_iterator< basic_iterator, adl::iterator_proxy, std::forward_iterator_tag, adl::iterator_proxy > - { - public: - basic_iterator() - : m_interpreter(0) - {} - - template - explicit basic_iterator(ValueWrapper const& value_wrapper) - : m_interpreter(lua_proxy_traits::interpreter(value_wrapper)) - { - detail::stack_pop pop(m_interpreter, 1); - lua_proxy_traits::unwrap(m_interpreter, value_wrapper); - - lua_pushnil(m_interpreter); - if(lua_next(m_interpreter, -2) != 0) { - detail::stack_pop pop(m_interpreter, 2); - handle(m_interpreter, -2).swap(m_key); - } else { - m_interpreter = 0; - return; - } - - handle(m_interpreter, -1).swap(m_table); - } - - // defined in luabind/detail/object.hpp - adl::object key() const; - - private: - template< typename, typename, typename, typename, typename > - friend class detail::crtp_iterator; - - void increment() - { - m_table.push(m_interpreter); - m_key.push(m_interpreter); - - detail::stack_pop pop(m_interpreter, 1); - - if(lua_next(m_interpreter, -2) != 0) { - m_key.replace(m_interpreter, -2); - lua_pop(m_interpreter, 2); - } else { - m_interpreter = 0; - handle().swap(m_table); - handle().swap(m_key); - } - } - - bool equal(basic_iterator const& other) const - { - if(m_interpreter == 0 && other.m_interpreter == 0) - return true; - - if(m_interpreter != other.m_interpreter) - return false; - - detail::stack_pop pop(m_interpreter, 2); - m_key.push(m_interpreter); - other.m_key.push(m_interpreter); - return lua_compare(m_interpreter, -2, -1, LUA_OPEQ) != 0; - } - - adl::iterator_proxy dereference() const - { - return adl::iterator_proxy(m_interpreter, m_table, m_key); - } - - lua_State* m_interpreter; - handle m_table; - handle m_key; - }; - - } // namespace detail - - using iterator = detail::basic_iterator; - using raw_iterator = detail::basic_iterator; - -} - -#if LUA_VERSION_NUM < 502 -#undef LUA_OPEQ -#undef lua_compare -#endif - -#endif - diff --git a/libs/luabind/luabind/lua_proxy_interface.hpp b/libs/luabind/luabind/lua_proxy_interface.hpp deleted file mode 100644 index 80f2de354..000000000 --- a/libs/luabind/luabind/lua_proxy_interface.hpp +++ /dev/null @@ -1,306 +0,0 @@ -#ifndef LUA_PROXY_INTERFACE_HPP_INCLUDED -#define LUA_PROXY_INTERFACE_HPP_INCLUDED - -#include -#include -#include -#include - -#if LUA_VERSION_NUM < 502 -# define lua_compare(L, index1, index2, fn) fn(L, index1, index2) -# define LUA_OPEQ lua_equal -# define LUA_OPLT lua_lessthan -# define lua_rawlen lua_objlen -# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) -#endif - -namespace luabind { - - namespace adl { - - template - class lua_proxy_interface; - - namespace check_object_interface - { - template - std::true_type check(lua_proxy_interface*); - std::false_type check(void*); - } // namespace is_object_interface_aux - - template - struct is_object_interface : public decltype(check_object_interface::check((remove_const_reference_t*)nullptr)) - {}; - - template - struct enable_binary - : std::enable_if< is_object_interface::value || is_object_interface::value, R > - {}; - - template - int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs, std::true_type, std::true_type) - { - L = lua_proxy_traits::interpreter(lhs); - lua_State* L2 = lua_proxy_traits::interpreter(rhs); - - // you are comparing objects with different interpreters - // that's not allowed. - assert(L == L2 || L == 0 || L2 == 0); - - // if the two objects we compare have different interpreters - // then they - - if(L != L2) return -1; - if(L == 0) return 1; - return 0; - } - - template - int binary_interpreter(lua_State*& L, T const& x, U const&, std::true_type, std::false_type) - { - L = lua_proxy_traits::interpreter(x); - return 0; - } - - template - int binary_interpreter(lua_State*& L, T const&, U const& x, std::false_type, std::true_type) - { - L = lua_proxy_traits::interpreter(x); - return 0; - } - - template - int binary_interpreter(lua_State*& L, T const& x, U const& y) - { - return binary_interpreter(L, x, y, is_lua_proxy_type(), is_lua_proxy_type()); - } - - template - typename enable_binary::type - operator==(LHS&& lhs, RHS&& rhs) - { - lua_State* L = 0; - switch(binary_interpreter(L, lhs, rhs)) { - case 1: return true; - case-1: return false; - } - assert(L); - detail::stack_pop pop1(L, 1); - detail::push_to_lua(L, std::forward(lhs)); - detail::stack_pop pop2(L, 1); - detail::push_to_lua(L, std::forward(rhs)); - return lua_compare(L, -1, -2, LUA_OPEQ) != 0; - } - - template - typename enable_binary::type - operator<(LHS&& lhs, RHS&& rhs) - { - lua_State* L = 0; - switch(binary_interpreter(L, lhs, rhs)) { - case 1: return true; - case-1: return false; - } - assert(L); - detail::stack_pop pop1(L, 1); - detail::push_to_lua(L, std::forward(lhs)); - detail::stack_pop pop2(L, 1); - detail::push_to_lua(L, std::forward(rhs)); - return lua_compare(L, -1, -2, LUA_OPLT) != 0; - } - - template - std::ostream& operator<<(std::ostream& os, lua_proxy_interface const& v) - { - using namespace luabind; - lua_State* interpreter = lua_proxy_traits::interpreter( - static_cast(v)); - detail::stack_pop pop(interpreter, 1); - lua_proxy_traits::unwrap(interpreter, static_cast(v)); - char const* p = lua_tostring(interpreter, -1); - std::size_t len = lua_rawlen(interpreter, -1); - os.write(p, len); - //std::copy(p, p+len, std::ostream_iterator(os)); - return os; - } - - - template - typename enable_binary::type - operator>(LHS const& lhs, RHS const& rhs) - { - return !(lhs < rhs || lhs == rhs); - } - - template - typename enable_binary::type - operator<=(LHS const& lhs, RHS const& rhs) - { - return lhs < rhs || lhs == rhs; - } - - template - typename enable_binary::type - operator>=(LHS const& lhs, RHS const& rhs) - { - return !(lhs < rhs); - } - - template - typename enable_binary::type - operator!=(LHS const& lhs, RHS const& rhs) - { - return !(lhs == rhs); - } - - template - class lua_proxy_interface - { - public: - ~lua_proxy_interface() {} - - // defined in luabind/detail/object.hpp - template - object operator()(Args&&... args); - - // defined in luabind/detail/object.hpp - template - object call(Args&&... args); - - explicit operator bool() const - { - lua_State* L = lua_proxy_traits::interpreter(derived()); - if(!L) return 0; - lua_proxy_traits::unwrap(L, derived()); - detail::stack_pop pop(L, 1); - return lua_toboolean(L, -1) == 1; - } - - private: - Derived& derived() { return *static_cast(this); } - Derived const& derived() const { return *static_cast(this); } - }; - - } - - template - std::string to_string(adl::lua_proxy_interface const& v) - { - using namespace luabind; - lua_State* interpreter = lua_proxy_traits::interpreter(static_cast(v)); - detail::stack_pop pop(interpreter, 1); - lua_proxy_traits::unwrap(interpreter, static_cast(v)); - char const* p = lua_tostring(interpreter, -1); - std::size_t len = lua_rawlen(interpreter, -1); - return std::string(p, len); - } - - namespace detail - { - template - ReturnType object_cast_aux(ValueWrapper const& value_wrapper, T*, Policies*, ErrorPolicy error_policy, ReturnType*) - { - lua_State* interpreter = lua_proxy_traits::interpreter(value_wrapper); - -#ifndef LUABIND_NO_ERROR_CHECKING - if(!interpreter) - return error_policy.handle_error(interpreter, typeid(void)); -#endif - lua_proxy_traits::unwrap(interpreter, value_wrapper); - detail::stack_pop pop(interpreter, 1); - specialized_converter_policy_n<0, Policies, T, lua_to_cpp> cv; - - if(cv.match(interpreter, decorate_type_t(), -1) < 0) { - return error_policy.handle_error(interpreter, typeid(T)); - } - return cv.to_cpp(interpreter, decorate_type_t(), -1); - } - - template - struct throw_error_policy - { - T handle_error(lua_State* interpreter, type_id const& type_info) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(interpreter, type_info); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if(e) e(interpreter, type_info); - - assert(0 && "object_cast failed. If you want to handle this error use " - "luabind::set_error_callback()"); - std::terminate(); -#endif - //return *(typename std::remove_reference::type*)0; //DEAD CODE! - } - }; - - template - struct nothrow_error_policy - { - nothrow_error_policy(T rhs) : value(rhs) {} - - T handle_error(lua_State*, type_id const&) - { - return value; - } - private: - T value; - }; - } // namespace detail - - template inline - T object_cast(ValueWrapper const& value_wrapper) - { - return detail::object_cast_aux(value_wrapper, (T*)0, (no_policies*)0, detail::throw_error_policy(), (T*)0); - } - - template inline - T object_cast(ValueWrapper const& value_wrapper, Policies const&) - { - return detail::object_cast_aux(value_wrapper, (T*)0, (Policies*)0, detail::throw_error_policy(), (T*)0); - } - - template inline - ReturnValue object_cast_nothrow(ValueWrapper const& value_wrapper, ReturnValue default_value) - { - return detail::object_cast_aux(value_wrapper, (T*)0, (no_policies*)0, detail::nothrow_error_policy(default_value), (ReturnValue*)0); - } - - template inline - ReturnValue object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&, ReturnValue default_value) - { - return detail::object_cast_aux(value_wrapper, (T*)0, (Policies*)0, detail::nothrow_error_policy(default_value), (ReturnValue*)0); - } - - template - inline lua_CFunction tocfunction(ValueWrapper const& value) - { - lua_State* interpreter = lua_proxy_traits::interpreter(value); - lua_proxy_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 1); - return lua_tocfunction(interpreter, -1); - } - - template - inline T* touserdata(ValueWrapper const& value) - { - lua_State* interpreter = lua_proxy_traits::interpreter(value); - - lua_proxy_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 1); - return static_cast(lua_touserdata(interpreter, -1)); - } - -} - -#if LUA_VERSION_NUM < 502 -# undef lua_compare -# undef LUA_OPEQ -# undef LUA_OPLT -# undef lua_rawlen -# undef lua_pushglobaltable -#endif - -#endif - diff --git a/libs/luabind/luabind/luabind.hpp b/libs/luabind/luabind/luabind.hpp index 9b47f01e2..82298484c 100644 --- a/libs/luabind/luabind/luabind.hpp +++ b/libs/luabind/luabind/luabind.hpp @@ -28,7 +28,5 @@ #include #include #include -#include #endif // LUABIND_BIND_HPP_INCLUDED - diff --git a/libs/luabind/luabind/make_function.hpp b/libs/luabind/luabind/make_function.hpp index 81bbe8f8f..a1ac8716b 100644 --- a/libs/luabind/luabind/make_function.hpp +++ b/libs/luabind/luabind/make_function.hpp @@ -3,125 +3,119 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef LUABIND_MAKE_FUNCTION_081014_HPP -#define LUABIND_MAKE_FUNCTION_081014_HPP +# define LUABIND_MAKE_FUNCTION_081014_HPP -#include -#include -#include -#include -#include +# include +# include +# include +# include +# include +# include namespace luabind { - namespace detail - { +namespace detail +{ # ifndef LUABIND_NO_EXCEPTIONS - LUABIND_API void handle_exception_aux(lua_State* L); + LUABIND_API void handle_exception_aux(lua_State* L); # endif - // MSVC complains about member being sensitive to alignment (C4121) - // when F is a pointer to member of a class with virtual bases. -# ifdef _MSC_VER +// MSVC complains about member being sensitive to alignment (C4121) +// when F is a pointer to member of a class with virtual bases. +# ifdef BOOST_MSVC # pragma pack(push) # pragma pack(16) # endif - template - struct function_object_impl : function_object - { - function_object_impl(F f) - : function_object(&entry_point), f(f) - {} + template + struct function_object_impl : function_object + { + function_object_impl(F f, Policies const& policies) + : function_object(&entry_point) + , f(f) + , policies(policies) + {} - int call(lua_State* L, invoke_context& ctx) /*const*/ - { -#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS - return invoke(L, *this, ctx, f, Signature(), InjectorList()); -#else - return invoke(L, *this, ctx, f); -#endif - } + int call(lua_State* L, invoke_context& ctx) const + { + return invoke(L, *this, ctx, f, Signature(), policies); + } - void format_signature(lua_State* L, char const* function) const - { - detail::format_signature(L, function, Signature()); - } + void format_signature(lua_State* L, char const* function) const + { + detail::format_signature(L, function, Signature()); + } - static bool invoke_defer(lua_State* L, function_object_impl* impl, invoke_context& ctx, int& results) - { - bool exception_caught = false; + static int entry_point(lua_State* L) + { + function_object_impl const* impl = + *(function_object_impl const**)lua_touserdata(L, lua_upvalueindex(1)); - try { -#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS - results = invoke(L, *impl, ctx, impl->f, Signature(), InjectorList()); -#else - results = invoke(L, *impl, ctx, impl->f); -#endif - } - catch(...) { - exception_caught = true; - handle_exception_aux(L); - } + invoke_context ctx; - return exception_caught; - } - - static int entry_point(lua_State* L) - { - function_object_impl const* impl_const = *(function_object_impl const**)lua_touserdata(L, lua_upvalueindex(1)); - - // TODO: Can this be done differently? - function_object_impl* impl = const_cast(impl_const); - invoke_context ctx; - int results = 0; + int results = 0; # ifndef LUABIND_NO_EXCEPTIONS - bool exception_caught = invoke_defer(L, impl, ctx, results); - if(exception_caught) lua_error(L); + bool exception_caught = false; + + try + { + results = invoke( + L, *impl, ctx, impl->f, Signature(), impl->policies); + } + catch (...) + { + exception_caught = true; + handle_exception_aux(L); + } + + if (exception_caught) + lua_error(L); # else -#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS - results = invoke(L, *impl, ctx, impl->f, Signature(), InjectorList()); -#else - results = invoke(L, *impl, ctx, impl->f); -#endif + results = invoke(L, *impl, ctx, impl->f, Signature(), impl->policies); # endif - if(!ctx) { - ctx.format_error(L, impl); - lua_error(L); - } - return results; - } + if (!ctx) + { + ctx.format_error(L, impl); + lua_error(L); + } - F f; - }; + return results; + } -# ifdef _MSC_VER + F f; + Policies policies; + }; + +# ifdef BOOST_MSVC # pragma pack(pop) # endif - LUABIND_API object make_function_aux(lua_State* L, function_object* impl); - LUABIND_API void add_overload(object const&, char const*, object const&); + LUABIND_API object make_function_aux( + lua_State* L, function_object* impl + ); - } // namespace detail + LUABIND_API void add_overload(object const&, char const*, object const&); - template - object make_function(lua_State* L, F f, meta::type_list< SignatureElements... >, meta::type_list< PolicyInjectors... >) - { - return detail::make_function_aux(L, new detail::function_object_impl, meta::type_list< PolicyInjectors...> >(f)); - } +} // namespace detail - template - object make_function(lua_State* L, F f, meta::type_list< PolicyInjectors... >) - { - return make_function(L, f, deduce_signature_t(), meta::type_list< PolicyInjectors... >()); - } +template +object make_function(lua_State* L, F f, Signature, Policies) +{ + return detail::make_function_aux( + L + , new detail::function_object_impl( + f, Policies() + ) + ); +} - template - object make_function(lua_State* L, F f) - { - return make_function(L, f, deduce_signature_t(), no_policies()); - } +template +object make_function(lua_State* L, F f) +{ + return make_function(L, detail::deduce_signature(f), detail::null_type()); +} } // namespace luabind diff --git a/libs/luabind/luabind/nil.hpp b/libs/luabind/luabind/nil.hpp index 9955cdb21..5f9ba4db1 100644 --- a/libs/luabind/luabind/nil.hpp +++ b/libs/luabind/luabind/nil.hpp @@ -27,12 +27,13 @@ namespace luabind { - namespace detail - { - struct nil_type {}; - } + namespace detail + { + struct nil_type {}; + } - constexpr detail::nil_type nil; + // defined in class.cpp + extern LUABIND_API detail::nil_type nil; } #endif diff --git a/libs/luabind/luabind/no_dependency.hpp b/libs/luabind/luabind/no_dependency.hpp deleted file mode 100644 index 89f996bee..000000000 --- a/libs/luabind/luabind/no_dependency.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright Daniel Wallin 2010. Use, modification and distribution is -// subject to 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) - -#ifndef LUABIND_NO_DEPENDENCY_100324_HPP -# define LUABIND_NO_DEPENDENCY_100324_HPP - -# include - -namespace luabind { - - namespace detail - { - - struct no_dependency_policy - { - static void postcall(lua_State*, int /*results*/, meta::index_list_tag) - {} - }; - - } // namespace detail - - using no_dependency = policy_list>; - -} // namespace luabind - -#endif // LUABIND_NO_DEPENDENCY_100324_HPP - diff --git a/libs/luabind/luabind/object.hpp b/libs/luabind/luabind/object.hpp index 5659486e5..0feb7bd48 100644 --- a/libs/luabind/luabind/object.hpp +++ b/libs/luabind/luabind/object.hpp @@ -20,11 +20,1393 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef LUABIND_OBJECT_HPP -#define LUABIND_OBJECT_HPP +#ifndef LUABIND_OBJECT_050419_HPP +#define LUABIND_OBJECT_050419_HPP -#include -#include +#include // detail::push() +#include // detail::push() +#include // value_wrapper_traits specializations +#include +#include +#include -#endif // LUABIND_OBJECT_HPP +#include +#include +#include +#include +#include +#include +#include +#include // REFACTOR +#include + +#include // iterator + +#include +#include + +namespace luabind { + +namespace detail +{ + namespace mpl = boost::mpl; + + template + void push_aux(lua_State* interpreter, T& value, ConverterGenerator*) + { + typedef typename boost::mpl::if_< + boost::is_reference_wrapper + , BOOST_DEDUCED_TYPENAME boost::unwrap_reference::type& + , T + >::type unwrapped_type; + + typename mpl::apply_wrap2< + ConverterGenerator,unwrapped_type,cpp_to_lua + >::type cv; + + cv.apply( + interpreter + , boost::implicit_cast< + BOOST_DEDUCED_TYPENAME boost::unwrap_reference::type& + >(value) + ); + } + + template + void push(lua_State* interpreter, T& value, Policies const&) + { + typedef typename find_conversion_policy< + 0 + , Policies + >::type converter_policy; + + push_aux(interpreter, value, (converter_policy*)0); + } + + template + void push(lua_State* interpreter, T& value) + { + push(interpreter, value, null_type()); + } + +} // namespace detail + +namespace adl +{ + namespace mpl = boost::mpl; + + template + class object_interface; + + namespace is_object_interface_aux + { + typedef char (&yes)[1]; + typedef char (&no)[2]; + + template + yes check(object_interface*); + no check(void*); + + template + struct impl + { + BOOST_STATIC_CONSTANT(bool, value = + sizeof(is_object_interface_aux::check((T*)0)) == sizeof(yes) + ); + + typedef mpl::bool_ type; + }; + + } // namespace detail + + template + struct is_object_interface + : is_object_interface_aux::impl::type + {}; + + template + struct enable_binary +# ifndef BOOST_NO_SFINAE + : boost::enable_if< + mpl::or_< + is_object_interface + , is_object_interface + > + , R + > + {}; +# else + { + typedef R type; + }; +# endif + + template + int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs + , boost::mpl::true_, boost::mpl::true_) + { + L = value_wrapper_traits::interpreter(lhs); + lua_State* L2 = value_wrapper_traits::interpreter(rhs); + + // you are comparing objects with different interpreters + // that's not allowed. + assert(L == L2 || L == 0 || L2 == 0); + + // if the two objects we compare have different interpreters + // then they + + if (L != L2) return -1; + if (L == 0) return 1; + return 0; + } + + template + int binary_interpreter(lua_State*& L, T const& x, U const& + , boost::mpl::true_, boost::mpl::false_) + { + L = value_wrapper_traits::interpreter(x); + return 0; + } + + template + int binary_interpreter(lua_State*& L, T const&, U const& x, boost::mpl::false_, boost::mpl::true_) + { + L = value_wrapper_traits::interpreter(x); + return 0; + } + + template + int binary_interpreter(lua_State*& L, T const& x, U const& y) + { + return binary_interpreter( + L + , x + , y + , is_value_wrapper() + , is_value_wrapper() + ); + } + +#define LUABIND_BINARY_OP_DEF(op, fn) \ + template \ + typename enable_binary::type \ + operator op(LHS const& lhs, RHS const& rhs) \ + { \ + lua_State* L = 0; \ + switch (binary_interpreter(L, lhs, rhs)) \ + { \ + case 1: \ + return true; \ + case -1: \ + return false; \ + } \ +\ + assert(L); \ +\ + detail::stack_pop pop1(L, 1); \ + detail::push(L, lhs); \ + detail::stack_pop pop2(L, 1); \ + detail::push(L, rhs); \ +\ + return fn(L, -1, -2) != 0; \ + } + +LUABIND_BINARY_OP_DEF(==, lua_equal) +LUABIND_BINARY_OP_DEF(<, lua_lessthan) + + template + std::ostream& operator<<(std::ostream& os + , object_interface const& v) + { + using namespace luabind; + lua_State* interpreter = value_wrapper_traits::interpreter( + static_cast(v)); + detail::stack_pop pop(interpreter, 1); + value_wrapper_traits::unwrap(interpreter + , static_cast(v)); + char const* p = lua_tostring(interpreter, -1); + std::size_t len = lua_strlen(interpreter, -1); + std::copy(p, p + len, std::ostream_iterator(os)); + return os; + } + +#undef LUABIND_BINARY_OP_DEF + + template + typename enable_binary::type + operator>(LHS const& lhs, RHS const& rhs) + { + return !(lhs < rhs || lhs == rhs); + } + + template + typename enable_binary::type + operator<=(LHS const& lhs, RHS const& rhs) + { + return lhs < rhs || lhs == rhs; + } + + template + typename enable_binary::type + operator>=(LHS const& lhs, RHS const& rhs) + { + return !(lhs < rhs); + } + + template + typename enable_binary::type + operator!=(LHS const& lhs, RHS const& rhs) + { + return !(lhs == rhs); + } + + template + struct call_proxy; + + template + class index_proxy; + + class object; + + template + class object_interface + { + struct safe_bool_type {}; + public: + ~object_interface() {} + + call_proxy > operator()(); + + template + call_proxy< + Derived + , boost::tuples::tuple + > operator()(A0 const& a0) + { + typedef boost::tuples::tuple arguments; + + return call_proxy( + derived() + , arguments(&a0) + ); + } + + template + call_proxy< + Derived + , boost::tuples::tuple + > operator()(A0 const& a0, A1 const& a1) + { + typedef boost::tuples::tuple arguments; + + return call_proxy( + derived() + , arguments(&a0, &a1) + ); + } + + // The rest of the overloads are PP-generated. + #define BOOST_PP_ITERATION_PARAMS_1 (3, \ + (3, LUABIND_MAX_ARITY, )) + #include BOOST_PP_ITERATE() + + operator safe_bool_type*() const + { + lua_State* L = value_wrapper_traits::interpreter(derived()); + + if (!L) + return 0; + + value_wrapper_traits::unwrap(L, derived()); + detail::stack_pop pop(L, 1); + + return lua_toboolean(L, -1) == 1 ? (safe_bool_type*)1 : 0; + } + + private: + Derived& derived() + { + return *static_cast(this); + } + + Derived const& derived() const + { + return *static_cast(this); + } + }; + +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG + struct iterator_proxy_tag; +#endif + + template + class iterator_proxy + : public object_interface > + { + public: +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG + typedef iterator_proxy_tag value_wrapper_tag; +#endif + + iterator_proxy(lua_State* interpreter, handle const& table, handle const& key) + : m_interpreter(interpreter) + , m_table_index(lua_gettop(interpreter) + 1) + , m_key_index(m_table_index + 1) + { + table.push(m_interpreter); + key.push(m_interpreter); + } + + iterator_proxy(iterator_proxy const& other) + : m_interpreter(other.m_interpreter) + , m_table_index(other.m_table_index) + , m_key_index(other.m_key_index) + { + other.m_interpreter = 0; + } + + ~iterator_proxy() + { + if (m_interpreter) + lua_pop(m_interpreter, 2); + } + + // this will set the value to nil + iterator_proxy & operator=(luabind::detail::nil_type) + { + lua_pushvalue(m_interpreter, m_key_index); + lua_pushnil(m_interpreter); + AccessPolicy::set(m_interpreter, m_table_index); + return *this; + } + + template + iterator_proxy& operator=(T const& value) + { + lua_pushvalue(m_interpreter, m_key_index); + detail::push(m_interpreter, value); + AccessPolicy::set(m_interpreter, m_table_index); + return *this; + } + + template + index_proxy > operator[](Key const& key) + { + return index_proxy >( + *this, m_interpreter, key + ); + } + + // This is non-const to prevent conversion on lvalues. + operator object(); + + lua_State* interpreter() const + { + return m_interpreter; + } + + // TODO: Why is it non-const? + void push(lua_State* interpreter) + { + assert(interpreter == m_interpreter); + lua_pushvalue(m_interpreter, m_key_index); + AccessPolicy::get(m_interpreter, m_table_index); + } + + private: + mutable lua_State* m_interpreter; + int m_table_index; + int m_key_index; + }; + +} // namespace adl + +namespace detail +{ + struct basic_access + { + static void set(lua_State* interpreter, int table) + { + lua_settable(interpreter, table); + } + + static void get(lua_State* interpreter, int table) + { + lua_gettable(interpreter, table); + } + }; + + struct raw_access + { + static void set(lua_State* interpreter, int table) + { + lua_rawset(interpreter, table); + } + + static void get(lua_State* interpreter, int table) + { + lua_rawget(interpreter, table); + } + }; + + template + class basic_iterator + : public boost::iterator_facade< + basic_iterator + , adl::iterator_proxy + , boost::single_pass_traversal_tag + , adl::iterator_proxy + > + { + public: + basic_iterator() + : m_interpreter(0) + {} + + template + explicit basic_iterator(ValueWrapper const& value_wrapper) + : m_interpreter( + value_wrapper_traits::interpreter(value_wrapper) + ) + { + detail::stack_pop pop(m_interpreter, 1); + value_wrapper_traits::unwrap(m_interpreter, value_wrapper); + + lua_pushnil(m_interpreter); + if (lua_next(m_interpreter, -2) != 0) + { + detail::stack_pop pop(m_interpreter, 2); + handle(m_interpreter, -2).swap(m_key); + } + else + { + m_interpreter = 0; + return; + } + + handle(m_interpreter, -1).swap(m_table); + } + + adl::object key() const; + + private: + friend class boost::iterator_core_access; + + void increment() + { + m_table.push(m_interpreter); + m_key.push(m_interpreter); + + detail::stack_pop pop(m_interpreter, 1); + + if (lua_next(m_interpreter, -2) != 0) + { + m_key.replace(m_interpreter, -2); + lua_pop(m_interpreter, 2); + } + else + { + m_interpreter = 0; + handle().swap(m_table); + handle().swap(m_key); + } + } + + bool equal(basic_iterator const& other) const + { + if (m_interpreter == 0 && other.m_interpreter == 0) + return true; + + if (m_interpreter != other.m_interpreter) + return false; + + detail::stack_pop pop(m_interpreter, 2); + m_key.push(m_interpreter); + other.m_key.push(m_interpreter); + return lua_equal(m_interpreter, -2, -1) != 0; + } + + adl::iterator_proxy dereference() const + { + return adl::iterator_proxy(m_interpreter, m_table, m_key); + } + + lua_State* m_interpreter; + handle m_table; + handle m_key; + }; + +// Needed because of some strange ADL issues. +#if BOOST_VERSION < 105700 + +#define LUABIND_OPERATOR_ADL_WKND(op) \ + inline bool operator op( \ + basic_iterator const& x \ + , basic_iterator const& y) \ + { \ + return boost::operator op(x, y); \ + } \ + \ + inline bool operator op( \ + basic_iterator const& x \ + , basic_iterator const& y) \ + { \ + return boost::operator op(x, y); \ + } + + LUABIND_OPERATOR_ADL_WKND(==) + LUABIND_OPERATOR_ADL_WKND(!=) + +#undef LUABIND_OPERATOR_ADL_WKND +#endif + +} // namespace detail + +namespace adl +{ + +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG + struct index_proxy_tag; +#endif + + template + class index_proxy + : public object_interface > + { + public: +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG + typedef index_proxy_tag value_wrapper_tag; +#endif + + typedef index_proxy this_type; + + template + index_proxy(Next const& next, lua_State* interpreter, Key const& key) + : m_interpreter(interpreter) + , m_key_index(lua_gettop(interpreter) + 1) + , m_next(next) + { + detail::push(m_interpreter, key); + } + + index_proxy(index_proxy const& other) + : m_interpreter(other.m_interpreter) + , m_key_index(other.m_key_index) + , m_next(other.m_next) + { + other.m_interpreter = 0; + } + + ~index_proxy() + { + if (m_interpreter) + lua_pop(m_interpreter, 1); + } + + // This is non-const to prevent conversion on lvalues. + operator object(); + + // this will set the value to nil + this_type& operator=(luabind::detail::nil_type) + { + value_wrapper_traits::unwrap(m_interpreter, m_next); + detail::stack_pop pop(m_interpreter, 1); + + lua_pushvalue(m_interpreter, m_key_index); + lua_pushnil(m_interpreter); + lua_settable(m_interpreter, -3); + return *this; + } + + template + this_type& operator=(T const& value) + { + value_wrapper_traits::unwrap(m_interpreter, m_next); + detail::stack_pop pop(m_interpreter, 1); + + lua_pushvalue(m_interpreter, m_key_index); + detail::push(m_interpreter, value); + lua_settable(m_interpreter, -3); + return *this; + } + + this_type& operator=(this_type const& value) + { + value_wrapper_traits::unwrap(m_interpreter, m_next); + detail::stack_pop pop(m_interpreter, 1); + + lua_pushvalue(m_interpreter, m_key_index); + detail::push(m_interpreter, value); + lua_settable(m_interpreter, -3); + return *this; + } + + template + index_proxy operator[](T const& key) + { + return index_proxy(*this, m_interpreter, key); + } + + void push(lua_State* interpreter); + + lua_State* interpreter() const + { + return m_interpreter; + } + + private: + struct hidden_type {}; + +// this_type& operator=(index_proxy const&); + + mutable lua_State* m_interpreter; + int m_key_index; + + Next const& m_next; + }; + +} // namespace adl + +typedef detail::basic_iterator iterator; +typedef detail::basic_iterator raw_iterator; + +#ifndef LUABIND_USE_VALUE_WRAPPER_TAG +template +struct value_wrapper_traits > +#else +template<> +struct value_wrapper_traits +#endif +{ + typedef boost::mpl::true_ is_specialized; + + template + static lua_State* interpreter(adl::index_proxy const& proxy) + { + return proxy.interpreter(); + } + + template + static void unwrap(lua_State* interpreter, adl::index_proxy const& proxy) + { + const_cast&>(proxy).push(interpreter); + } +}; + +#ifndef LUABIND_USE_VALUE_WRAPPER_TAG +template +struct value_wrapper_traits > +#else +template<> +struct value_wrapper_traits +#endif +{ + typedef boost::mpl::true_ is_specialized; + + template + static lua_State* interpreter(Proxy const& p) + { + return p.interpreter(); + } + + template + static void unwrap(lua_State* interpreter, Proxy const& p) + { + // TODO: Why const_cast? + const_cast(p).push(interpreter); + } +}; + +namespace adl +{ + + // An object holds a reference to a Lua value residing + // in the registry. + class object : public object_interface + { + public: + object() + {} + + explicit object(handle const& other) + : m_handle(other) + {} + + explicit object(from_stack const& stack_reference) + : m_handle(stack_reference.interpreter, stack_reference.index) + { + } + + template + object(lua_State* interpreter, T const& value) + { + detail::push(interpreter, value); + detail::stack_pop pop(interpreter, 1); + handle(interpreter, -1).swap(m_handle); + } + + template + object(lua_State* interpreter, T const& value, Policies const&) + { + detail::push(interpreter, value, Policies()); + detail::stack_pop pop(interpreter, 1); + handle(interpreter, -1).swap(m_handle); + } + + void push(lua_State* interpreter) const; + lua_State* interpreter() const; + bool is_valid() const; + + template + index_proxy operator[](T const& key) const + { + return index_proxy( + *this, m_handle.interpreter(), key + ); + } + + void swap(object& other) + { + m_handle.swap(other.m_handle); + } + + private: + handle m_handle; + }; + + inline void object::push(lua_State* interpreter) const + { + m_handle.push(interpreter); + } + + inline lua_State* object::interpreter() const + { + return m_handle.interpreter(); + } + + inline bool object::is_valid() const + { + return m_handle.interpreter() != 0; + } + + class argument : public object_interface + { + public: + argument(from_stack const& stack_reference) + : m_interpreter(stack_reference.interpreter) + , m_index(stack_reference.index) + { + if (m_index < 0) + m_index = lua_gettop(m_interpreter) - m_index + 1; + } + + template + index_proxy operator[](T const& key) const + { + return index_proxy(*this, m_interpreter, key); + } + + void push(lua_State* L) const + { + lua_pushvalue(L, m_index); + } + + lua_State* interpreter() const + { + return m_interpreter; + } + + private: + lua_State* m_interpreter; + int m_index; + }; + +} // namespace adl + +using adl::object; +using adl::argument; + +#ifndef LUABIND_USE_VALUE_WRAPPER_TAG +template +struct value_wrapper_traits > +#else +template<> +struct value_wrapper_traits +#endif +{ + typedef boost::mpl::true_ is_specialized; + + template + static lua_State* interpreter(adl::call_proxy const& proxy) + { + return value_wrapper_traits::interpreter(*proxy.value_wrapper); + } + + template + static void unwrap(lua_State*, adl::call_proxy const& proxy) + { + object result = const_cast&>(proxy); + result.push(result.interpreter()); + } +}; + +template<> +struct value_wrapper_traits +{ + typedef boost::mpl::true_ is_specialized; + + static lua_State* interpreter(object const& value) + { + return value.interpreter(); + } + + static void unwrap(lua_State* interpreter, object const& value) + { + value.push(interpreter); + } + + static bool check(...) + { + return true; + } +}; + +template<> +struct value_wrapper_traits +{ + typedef boost::mpl::true_ is_specialized; + + static lua_State* interpreter(argument const& value) + { + return value.interpreter(); + } + + static void unwrap(lua_State* interpreter, argument const& value) + { + value.push(interpreter); + } + + static bool check(...) + { + return true; + } +}; + +template +inline void adl::index_proxy::push(lua_State* interpreter) +{ + assert(interpreter == m_interpreter); + + value_wrapper_traits::unwrap(m_interpreter, m_next); + + lua_pushvalue(m_interpreter, m_key_index); + lua_gettable(m_interpreter, -2); + lua_remove(m_interpreter, -2); +} + +template +inline adl::index_proxy::operator object() +{ + detail::stack_pop pop(m_interpreter, 1); + push(m_interpreter); + return object(from_stack(m_interpreter, -1)); +} + +template +adl::iterator_proxy::operator object() +{ + lua_pushvalue(m_interpreter, m_key_index); + AccessPolicy::get(m_interpreter, m_table_index); + detail::stack_pop pop(m_interpreter, 1); + return object(from_stack(m_interpreter, -1)); +} + +template +object detail::basic_iterator::key() const +{ + return object(m_key); +} + +namespace detail +{ + + template< + class T + , class ValueWrapper + , class Policies + , class ErrorPolicy + , class ReturnType + > + ReturnType object_cast_aux( + ValueWrapper const& value_wrapper + , T* + , Policies* + , ErrorPolicy* + , ReturnType* + ) + { + lua_State* interpreter = value_wrapper_traits::interpreter( + value_wrapper + ); + +#ifndef LUABIND_NO_ERROR_CHECKING + if (!interpreter) + return ErrorPolicy::handle_error(interpreter, typeid(void)); +#endif + + value_wrapper_traits::unwrap(interpreter, value_wrapper); + + detail::stack_pop pop(interpreter, 1); + + typedef typename detail::find_conversion_policy< + 0 + , Policies + >::type converter_generator; + + typename mpl::apply_wrap2::type cv; + +#ifndef LUABIND_NO_ERROR_CHECKING + if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0) + { + return ErrorPolicy::handle_error(interpreter, typeid(T)); + } +#endif + + return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1); + } + +# ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:4702) // unreachable code +# endif + + template + struct throw_error_policy + { + static T handle_error(lua_State* interpreter, type_id const& type_info) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(interpreter, type_info); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(interpreter, type_info); + + assert(0 && "object_cast failed. If you want to handle this error use " + "luabind::set_error_callback()"); + std::terminate(); +#endif + return *(typename boost::remove_reference::type*)0; + } + }; + +# ifdef BOOST_MSVC +# pragma warning(pop) +# endif + + template + struct nothrow_error_policy + { + static boost::optional handle_error(lua_State*, type_id const&) + { + return boost::optional(); + } + }; + +} // namespace detail + +template +T object_cast(ValueWrapper const& value_wrapper) +{ + return detail::object_cast_aux( + value_wrapper + , (T*)0 + , (detail::null_type*)0 + , (detail::throw_error_policy*)0 + , (T*)0 + ); +} + +template +T object_cast(ValueWrapper const& value_wrapper, Policies const&) +{ + return detail::object_cast_aux( + value_wrapper + , (T*)0 + , (Policies*)0 + , (detail::throw_error_policy*)0 + , (T*)0 + ); +} + +template +boost::optional object_cast_nothrow(ValueWrapper const& value_wrapper) +{ + return detail::object_cast_aux( + value_wrapper + , (T*)0 + , (detail::null_type*)0 + , (detail::nothrow_error_policy*)0 + , (boost::optional*)0 + ); +} + +template +boost::optional object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&) +{ + return detail::object_cast_aux( + value_wrapper + , (T*)0 + , (Policies*)0 + , (detail::nothrow_error_policy*)0 + , (boost::optional*)0 + ); +} + +namespace detail +{ + + template + struct push_args_from_tuple + { + template + inline static void apply(lua_State* L, const boost::tuples::cons& x, const Policies& p) + { + convert_to_lua_p(L, *x.get_head(), p); + push_args_from_tuple::apply(L, x.get_tail(), p); + } + + template + inline static void apply(lua_State* L, const boost::tuples::cons& x) + { + convert_to_lua(L, *x.get_head()); + push_args_from_tuple::apply(L, x.get_tail()); + } + + template + inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {} + + inline static void apply(lua_State*, const boost::tuples::null_type&) {} + }; + +} // namespace detail + +namespace adl +{ + + template + struct call_proxy + { + call_proxy(ValueWrapper& value_wrapper, Arguments arguments) + : value_wrapper(&value_wrapper) + , arguments(arguments) + {} + + call_proxy(call_proxy const& other) + : value_wrapper(other.value_wrapper) + , arguments(other.arguments) + { + other.value_wrapper = 0; + } + + ~call_proxy() + { + if (value_wrapper) + call((detail::null_type*)0); + } + + operator object() + { + return call((detail::null_type*)0); + } + + template + object operator[](Policies const&) + { + return call((Policies*)0); + } + + template + object call(Policies*) + { + lua_State* interpreter = value_wrapper_traits::interpreter( + *value_wrapper + ); + + value_wrapper_traits::unwrap( + interpreter + , *value_wrapper + ); + + value_wrapper = 0; + + detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies()); + + if (detail::pcall(interpreter, boost::tuples::length::value, 1)) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(interpreter); +#else + error_callback_fun e = get_error_callback(); + if (e) e(interpreter); + + assert(0 && "the lua function threw an error and exceptions are disabled." + "if you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); + } + + mutable ValueWrapper* value_wrapper; + Arguments arguments; + }; + + template + call_proxy > + object_interface::operator()() + { + return call_proxy >( + derived() + , boost::tuples::tuple<>() + ); + } + + // Simple value_wrapper adaptor with the sole purpose of helping with + // overload resolution. Use this as a function parameter type instead + // of "object" or "argument" to restrict the parameter to Lua tables. + template + struct table : Base + { + table(from_stack const& stack_reference) + : Base(stack_reference) + {} + }; + +} // namespace adl + +using adl::table; + +template +struct value_wrapper_traits > + : value_wrapper_traits +{ + static bool check(lua_State* L, int idx) + { + return value_wrapper_traits::check(L, idx) && + lua_istable(L, idx); + } +}; + +inline object newtable(lua_State* interpreter) +{ + lua_newtable(interpreter); + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); +} + +// this could be optimized by returning a proxy +inline object globals(lua_State* interpreter) +{ + lua_pushglobaltable(interpreter); + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); +} + +// this could be optimized by returning a proxy +inline object registry(lua_State* interpreter) +{ + lua_pushvalue(interpreter, LUA_REGISTRYINDEX); + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); +} + +template +inline object gettable(ValueWrapper const& table, K const& key) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + table + ); + + value_wrapper_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 2); + detail::push(interpreter, key); + lua_gettable(interpreter, -2); + return object(from_stack(interpreter, -1)); +} + +template +inline void settable(ValueWrapper const& table, K const& key, T const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + table + ); + + // TODO: Exception safe? + + value_wrapper_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 1); + detail::push(interpreter, key); + detail::push(interpreter, value); + lua_settable(interpreter, -3); +} + +template +inline object rawget(ValueWrapper const& table, K const& key) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + table + ); + + value_wrapper_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 2); + detail::push(interpreter, key); + lua_rawget(interpreter, -2); + return object(from_stack(interpreter, -1)); +} + +template +inline void rawset(ValueWrapper const& table, K const& key, T const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + table + ); + + // TODO: Exception safe? + + value_wrapper_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 1); + detail::push(interpreter, key); + detail::push(interpreter, value); + lua_rawset(interpreter, -3); +} + +template +inline int type(ValueWrapper const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + value + ); + + value_wrapper_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return lua_type(interpreter, -1); +} + +template +inline object getmetatable(ValueWrapper const& obj) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + obj + ); + + value_wrapper_traits::unwrap(interpreter, obj); + detail::stack_pop pop(interpreter, 2); + lua_getmetatable(interpreter, -1); + return object(from_stack(interpreter, -1)); +} + +template +inline void setmetatable( + ValueWrapper1 const& obj, ValueWrapper2 const& metatable) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + obj + ); + + value_wrapper_traits::unwrap(interpreter, obj); + detail::stack_pop pop(interpreter, 1); + value_wrapper_traits::unwrap(interpreter, metatable); + lua_setmetatable(interpreter, -2); +} + +template +inline lua_CFunction tocfunction(ValueWrapper const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + value + ); + + value_wrapper_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return lua_tocfunction(interpreter, -1); +} + +template +inline T* touserdata(ValueWrapper const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + value + ); + + value_wrapper_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return static_cast(lua_touserdata(interpreter, -1)); +} + +template +inline object getupvalue(ValueWrapper const& value, int index) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + value + ); + + value_wrapper_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 2); + lua_getupvalue(interpreter, -1, index); + return object(from_stack(interpreter, -1)); +} + +template +inline void setupvalue( + ValueWrapper1 const& function, int index, ValueWrapper2 const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + function + ); + + value_wrapper_traits::unwrap(interpreter, function); + detail::stack_pop pop(interpreter, 1); + value_wrapper_traits::unwrap(interpreter, value); + lua_setupvalue(interpreter, -2, index); +} + +template +object property(GetValueWrapper const& get) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + get + ); + + value_wrapper_traits::unwrap(interpreter, get); + lua_pushnil(interpreter); + + lua_pushcclosure(interpreter, &detail::property_tag, 2); + detail::stack_pop pop(interpreter, 1); + + return object(from_stack(interpreter, -1)); +} + +template +object property(GetValueWrapper const& get, SetValueWrapper const& set) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + get + ); + + value_wrapper_traits::unwrap(interpreter, get); + value_wrapper_traits::unwrap(interpreter, set); + + lua_pushcclosure(interpreter, &detail::property_tag, 2); + detail::stack_pop pop(interpreter, 1); + + return object(from_stack(interpreter, -1)); + +} + + +} // namespace luabind + +#endif // LUABIND_OBJECT_050419_HPP diff --git a/libs/luabind/luabind/open.hpp b/libs/luabind/luabind/open.hpp index 5fe28f409..cca4c7a52 100644 --- a/libs/luabind/luabind/open.hpp +++ b/libs/luabind/luabind/open.hpp @@ -26,8 +26,6 @@ #include -#include - namespace luabind { LUABIND_API void open(lua_State* L); diff --git a/libs/luabind/luabind/operator.hpp b/libs/luabind/luabind/operator.hpp index bde759290..aeb651c03 100644 --- a/libs/luabind/luabind/operator.hpp +++ b/libs/luabind/luabind/operator.hpp @@ -23,6 +23,15 @@ #ifndef OPERATOR_040729_HPP #define OPERATOR_040729_HPP +#include +#include +#include +#include +#include +#include +#include +#include + #if defined(__GNUC__) && __GNUC__ < 3 # define LUABIND_NO_STRINGSTREAM #else @@ -37,155 +46,154 @@ #include #endif -#include -#include -#include -#include +namespace luabind { namespace detail { -namespace luabind { - namespace detail { + template struct unwrap_parameter_type; + template struct operator_ {}; - template struct unwrap_parameter_type; - template struct operator_ {}; + struct operator_void_return {}; - struct operator_void_return {}; +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + template + inline T const& operator,(T const& x, operator_void_return) + { + return x; + } +#endif + +}} // namespace luabind - template - inline T const& operator,(T const& x, operator_void_return) - { - return x; - } +namespace luabind { namespace operators { - template - inline void operator_result(lua_State*, operator_void_return, Policies*) - { - } + #define BOOST_PP_ITERATION_PARAMS_1 (3, \ + (0, LUABIND_MAX_ARITY, )) + #include BOOST_PP_ITERATE() + +}} // namespace luabind::operators - template - inline void operator_result(lua_State* L, T const& x, Policies*) - { - specialized_converter_policy_n<0, Policies, T, cpp_to_lua >().to_lua(L, x); - } - - } -} // namespace luabind - - -namespace luabind { - namespace operators { - - template - struct call_operator - : detail::operator_ < call_operator< Self, Args... > > - { - call_operator(int) {} - - template - struct apply - { - static void execute( - lua_State* L - , typename detail::unwrap_parameter_type::type self - , typename detail::unwrap_parameter_type::type... args - ) - { - using namespace detail; - operator_result( - L - , (self(args...), detail::operator_void_return()) - , (Policies*)0 - ); - } - }; - - static char const* name() { return "__call"; } - }; - - } -} // namespace luabind::operators +#include namespace luabind { - template - struct self_base - { - template< typename... Args > - operators::call_operator operator()(const Args&...) const - { - return 0; - } - }; + template + struct self_base + { + operators::call_operator0 operator()() const + { + return 0; + } + +#define BOOST_PP_LOCAL_MACRO(n) \ + template \ + BOOST_PP_CAT(operators::call_operator, n)< \ + Derived \ + BOOST_PP_ENUM_TRAILING_PARAMS(n, A) \ + >\ + operator()( \ + BOOST_PP_ENUM_BINARY_PARAMS(n, A, const& BOOST_PP_INTERCEPT) \ + ) const \ + { \ + return 0; \ + } - struct self_type : self_base - { - }; +#define BOOST_PP_LOCAL_LIMITS (1, LUABIND_MAX_ARITY) +#include BOOST_PP_LOCAL_ITERATE() - struct const_self_type : self_base - { - }; + }; - namespace detail { + struct self_type : self_base + { + }; - template - struct unwrap_parameter_type - { - using type = typename meta::select_ < - meta::case_< std::is_same, W& >, - meta::case_< std::is_same, W const& >, - meta::default_< typename unwrap_other::type > - > ::type; - }; + struct const_self_type : self_base + { + }; - template - struct binary_operator - : operator_ > - { - binary_operator(int) {} +namespace detail { - template - struct apply - { - using arg0 = typename unwrap_parameter_type::type; - using arg1 = typename unwrap_parameter_type::type; + template + struct unwrap_parameter_type + { + typedef typename boost::mpl::eval_if< + boost::is_same + , boost::mpl::identity + , boost::mpl::eval_if< + boost::is_same + , boost::mpl::identity + , unwrap_other + > + >::type type; + }; - static void execute(lua_State* L, arg0 _0, arg1 _1) - { - Derived::template apply::execute( - L, _0, _1); - } - }; + template + struct binary_operator + : operator_ > + { + binary_operator(int) {} - static char const* name() - { - return Derived::name(); - } - }; + template + struct apply + { + typedef typename unwrap_parameter_type::type arg0; + typedef typename unwrap_parameter_type::type arg1; - template - struct unary_operator - : operator_ > - { - unary_operator(int) {} + static void execute(lua_State* L, arg0 _0, arg1 _1) + { + Derived::template apply::execute( + L, _0, _1); + } + }; - template - struct apply - { - using arg0 = typename unwrap_parameter_type::type; + static char const* name() + { + return Derived::name(); + } + }; - static void execute(lua_State* L, arg0 _0) - { - Derived::template apply::execute(L, _0); - } - }; + template + struct unary_operator + : operator_ > + { + unary_operator(int) {} + + template + struct apply + { + typedef typename unwrap_parameter_type::type arg0; - static char const* name() - { - return Derived::name(); - } - }; + static void execute(lua_State* L, arg0 _0) + { + Derived::template apply::execute(L, _0); + } + }; - } -} // namespace detail::luabind + static char const* name() + { + return Derived::name(); + } + }; + + template + inline void operator_result(lua_State* L, operator_void_return, Policies*) + { + } + + namespace mpl = boost::mpl; + + template + inline void operator_result(lua_State* L, T const& x, Policies*) + { + typedef typename find_conversion_policy< + 0 + , Policies + >::type cv_policy; + + typename mpl::apply_wrap2::type cv; + + cv.apply(L, x); + } + +}} // namespace detail::luabind namespace luabind { @@ -273,17 +281,16 @@ namespace luabind { return 0; \ } - LUABIND_BINARY_OPERATOR(add, +) - LUABIND_BINARY_OPERATOR(sub, -) - LUABIND_BINARY_OPERATOR(mul, *) - LUABIND_BINARY_OPERATOR(div, / ) - LUABIND_BINARY_OPERATOR(mod, %) - LUABIND_BINARY_OPERATOR(pow, ^) - LUABIND_BINARY_OPERATOR(lt, < ) - LUABIND_BINARY_OPERATOR(le, <= ) - LUABIND_BINARY_OPERATOR(eq, == ) + LUABIND_BINARY_OPERATOR(add, +) + LUABIND_BINARY_OPERATOR(sub, -) + LUABIND_BINARY_OPERATOR(mul, *) + LUABIND_BINARY_OPERATOR(div, /) + LUABIND_BINARY_OPERATOR(pow, ^) + LUABIND_BINARY_OPERATOR(lt, <) + LUABIND_BINARY_OPERATOR(le, <=) + LUABIND_BINARY_OPERATOR(eq, ==) -#undef LUABIND_BINARY_OPERATOR +#undef LUABIND_UNARY_OPERATOR #define LUABIND_UNARY_OPERATOR(name_, op, fn) \ namespace operators { \ @@ -317,29 +324,31 @@ namespace luabind { return 0; \ } - template - std::string tostring_operator(T const& x) - { + template + std::string tostring_operator(T const& x) + { #ifdef LUABIND_NO_STRINGSTREAM - std::strstream s; - s << x << std::ends; + std::strstream s; + s << x << std::ends; #else - std::stringstream s; - s << x; + std::stringstream s; + s << x; #endif - return s.str(); - } + return s.str(); + } + + LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring) + LUABIND_UNARY_OPERATOR(unm, -, operator-) - LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring) - LUABIND_UNARY_OPERATOR(unm, -, operator-) +#undef LUABIND_BINARY_OPERATOR -#undef LUABIND_UNARY_OPERATOR - - - extern LUABIND_API self_type self; - extern LUABIND_API const_self_type const_self; + namespace { + LUABIND_ANONYMOUS_FIX self_type self; + LUABIND_ANONYMOUS_FIX const_self_type const_self; + } // namespace unnamed + } // namespace luabind #endif // OPERATOR_040729_HPP diff --git a/libs/luabind/luabind/out_value_policy.hpp b/libs/luabind/luabind/out_value_policy.hpp index 5fb5ada33..ca496b527 100644 --- a/libs/luabind/luabind/out_value_policy.hpp +++ b/libs/luabind/luabind/out_value_policy.hpp @@ -25,247 +25,255 @@ #define LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED #include -#include // for find_conversion_policy, etc -#include // for decorated_type -#include // for by_pointer, by_reference, etc -#include // for is_nonconst_pointer, is_nonconst_reference, etc -#include // for operator new +#include +#include -namespace luabind { - namespace detail { +namespace luabind { namespace detail +{ + template + struct char_array + { + char storage[N]; + }; - template - struct char_array +#if defined(__GNUC__) && ( __GNUC__ == 3 && __GNUC_MINOR__ == 1 ) + + template + char_array indirect_sizeof_test(by_reference); + + template + char_array indirect_sizeof_test(by_const_reference); + + template + char_array indirect_sizeof_test(by_pointer); + + template + char_array indirect_sizeof_test(by_const_pointer); + + template + char_array indirect_sizeof_test(by_value); + +#else + + template + char_array::type)> indirect_sizeof_test(by_reference); + + template + char_array::type)> indirect_sizeof_test(by_const_reference); + + template + char_array::type)> indirect_sizeof_test(by_pointer); + + template + char_array::type)> indirect_sizeof_test(by_const_pointer); + + template + char_array::type)> indirect_sizeof_test(by_value); + +#endif + + template + struct indirect_sizeof + { + BOOST_STATIC_CONSTANT(int, value = sizeof(indirect_sizeof_test(LUABIND_DECORATE_TYPE(T)))); + }; + + namespace mpl = boost::mpl; + + template + struct out_value_converter + { + int const consumed_args(...) + { + return 1; + } + + template + T& apply(lua_State* L, by_reference, int index) { - char storage[N]; - }; - - template - char_array::type)> indirect_sizeof_test(by_reference); - - template - char_array::type)> indirect_sizeof_test(by_const_reference); - - template - char_array::type)> indirect_sizeof_test(by_pointer); - - template - char_array::type)> indirect_sizeof_test(by_const_pointer); - - template - char_array::type)> indirect_sizeof_test(by_value); - - template - struct indirect_sizeof - { - static const int value = sizeof(indirect_sizeof_test(decorate_type_t())); - }; - - namespace out_value_detail { - - template< int Size > - struct temporary_storage_size { - - template< typename T, typename... Args > - void construct(Args&&... args) - { - new (&m_storage) T(std::forward(args)...); - } - - template - T& get() { - return *reinterpret_cast(&m_storage); - } - - template - const T& get() const { - return *reinterpret_cast(&m_storage); - } - - template - void destroy() - { - get().~T(); - } - - typename std::aligned_storage::type m_storage; - - }; - - template< typename T > - struct temporary_storage_type { - - template< typename... Args > - void construct(Args&&... args) - { - new (&m_storage) T(std::forward(args)...); - } - - T& get() { - return *reinterpret_cast(&m_storage); - } - - const T& get() const { - return *reinterpret_cast(&m_storage); - } - - void destroy() - { - get().~T(); - } - - typename std::aligned_storage::type m_storage; - - }; - + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + new (m_storage) T(converter.apply(L, LUABIND_DECORATE_TYPE(T), index)); + return *reinterpret_cast(m_storage); } - // See note in out_value_policy about why we're not templating - // for the parameter type. - template - struct out_value_converter + template + static int match(lua_State* L, by_reference, int index) { - enum { consumed_args = 1 }; + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typedef typename mpl::apply_wrap2::type converter; + return converter::match(L, LUABIND_DECORATE_TYPE(T), index); + } - T& to_cpp(lua_State* L, by_reference, int index) - { - //specialized_converter_policy_n<1, Policies, T, lua_to_cpp> converter; - storage_.construct(converter_.to_cpp(L, decorate_type_t(), index)); - return storage_.get(); - } - - int match(lua_State* L, by_reference, int index) - { - return converter_.match(L, decorate_type_t(), index); - } - - void converter_postcall(lua_State* L, by_reference, int) - { - //specialized_converter_policy_n<2,Policies,T,cpp_to_lua> converter; - converter_.to_lua(L, storage_.get()); - storage_.destroy(); - } - - T* to_cpp(lua_State* L, by_pointer, int index) - { - storage_.construct(converter_.to_cpp(L, decorate_type_t(), index)); - return &storage_.get(); - } - - int match(lua_State* L, by_pointer, int index) - { - return converter_.match(L, decorate_type_t(), index); - } - - void converter_postcall(lua_State* L, by_pointer, int) - { - //specialized_converter_policy_n<2, Policies, T, cpp_to_lua> converter; - converter_.to_lua(L, storage_.get()); - storage_.destroy(); - } - - private: - specialized_converter_policy_n<1, Policies, T, lua_to_cpp > converter_; - out_value_detail::temporary_storage_type storage_; - }; - - template - struct out_value_policy + template + void converter_postcall(lua_State* L, by_reference, int) { - struct only_accepts_nonconst_references_or_pointers {}; - struct can_only_convert_from_lua_to_cpp {}; + typedef typename find_conversion_policy<2, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + converter.apply(L, *reinterpret_cast(m_storage)); + reinterpret_cast(m_storage)->~T(); + } - template - struct specialize - { - static_assert(std::is_same< Direction, lua_to_cpp >::value, "Out value policy can only convert from lua to cpp"); - static_assert(meta::or_< is_nonconst_reference, is_nonconst_pointer >::value, "Out value policy only accepts non const references or pointers"); - - // Note to myself: - // Using the size and template members instead of a policy templated for the type seems - // to be done to tame template bloat. Need to check if this is worth is. - using base_type = typename std::remove_pointer< typename std::remove_reference< T >::type >::type; - using type = out_value_converter; - }; - }; - - template - struct pure_out_value_converter + template + T* apply(lua_State* L, by_pointer, int index) { - enum { consumed_args = 0 }; + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + new (m_storage) T(converter.apply(L, LUABIND_DECORATE_TYPE(T), index)); + return reinterpret_cast(m_storage); + } - template - T& to_cpp(lua_State*, by_reference, int) - { - storage_.decltype(storage_)::template construct(); - return storage_.template get(); - } - - template - static int match(lua_State*, by_reference, int) - { - return 0; - } - - template - void converter_postcall(lua_State* L, by_reference, int) - { - specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter; - converter.to_lua(L, storage_.template get()); - storage_.template destroy(); - } - - template - T* to_cpp(lua_State*, by_pointer, int) - { - storage_.decltype(storage_)::template construct(); - return &storage_.template get(); - } - - template - static int match(lua_State*, by_pointer, int) - { - return 0; - } - - template - void converter_postcall(lua_State* L, by_pointer, int) - { - specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter; - converter.to_lua(L, storage_.template get()); - storage_.template destroy(); - } - - private: - out_value_detail::temporary_storage_size storage_; - }; - - template - struct pure_out_value_policy + template + static int match(lua_State* L, by_pointer, int index) { - struct only_accepts_nonconst_references_or_pointers {}; - struct can_only_convert_from_lua_to_cpp {}; + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typedef typename mpl::apply_wrap2::type converter; + return converter::match(L, LUABIND_DECORATE_TYPE(T), index); + } - template - struct specialize - { - static_assert(std::is_same< Direction, lua_to_cpp >::value, "Pure out value policy can only convert from lua to cpp"); - static_assert(meta::or_< is_nonconst_reference, is_nonconst_pointer >::value, "Pure out value policy only accepts non const references or pointers"); + template + void converter_postcall(lua_State* L, by_pointer, int) + { + typedef typename find_conversion_policy<2, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + converter.apply(L, *reinterpret_cast(m_storage)); + reinterpret_cast(m_storage)->~T(); + } - using type = pure_out_value_converter::value, Policies>; - }; + char m_storage[Size]; + }; + + template + struct out_value_policy : conversion_policy + { + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + + struct only_accepts_nonconst_references_or_pointers {}; + struct can_only_convert_from_lua_to_cpp {}; + + template + struct apply + { + typedef typename boost::mpl::if_ + , typename boost::mpl::if_, is_nonconst_pointer > + , out_value_converter::value, Policies> + , only_accepts_nonconst_references_or_pointers + >::type + , can_only_convert_from_lua_to_cpp + >::type type; }; + }; - } -} + template + struct pure_out_value_converter + { + int const consumed_args(...) + { + return 0; + } + + template + T& apply(lua_State*, by_reference, int) + { + new (m_storage) T(); + return *reinterpret_cast(m_storage); + } + + template + static int match(lua_State*, by_reference, int) + { + return 0; + } + + template + void converter_postcall(lua_State* L, by_reference, int) + { + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + converter.apply(L, *reinterpret_cast(m_storage)); + reinterpret_cast(m_storage)->~T(); + } + + template + T* apply(lua_State*, by_pointer, int) + { + new (m_storage) T(); + return reinterpret_cast(m_storage); + } + + template + static int match(lua_State*, by_pointer, int) + { + return 0; + } + + template + void converter_postcall(lua_State* L, by_pointer, int) + { + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + converter.apply(L, *reinterpret_cast(m_storage)); + reinterpret_cast(m_storage)->~T(); + } + + + char m_storage[Size]; + }; + + template + struct pure_out_value_policy : conversion_policy + { + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + + struct only_accepts_nonconst_references_or_pointers {}; + struct can_only_convert_from_lua_to_cpp {}; + + template + struct apply + { + typedef typename boost::mpl::if_ + , typename boost::mpl::if_, is_nonconst_pointer > + , pure_out_value_converter::value, Policies> + , only_accepts_nonconst_references_or_pointers + >::type + , can_only_convert_from_lua_to_cpp + >::type type; + }; + }; + +}} namespace luabind { - template - using out_value = meta::type_list>>; + template + detail::policy_cons, detail::null_type> + out_value(LUABIND_PLACEHOLDER_ARG(N)) + { + return detail::policy_cons, detail::null_type>(); + } - template - using pure_out_value = meta::type_list>>; + template + detail::policy_cons, detail::null_type> + out_value(LUABIND_PLACEHOLDER_ARG(N), const Policies&) + { + return detail::policy_cons, detail::null_type>(); + } + + template + detail::policy_cons, detail::null_type> + pure_out_value(LUABIND_PLACEHOLDER_ARG(N)) + { + return detail::policy_cons, detail::null_type>(); + } + + template + detail::policy_cons, detail::null_type> + pure_out_value(LUABIND_PLACEHOLDER_ARG(N), const Policies&) + { + return detail::policy_cons, detail::null_type>(); + } } #endif // LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/pointer_traits.hpp b/libs/luabind/luabind/pointer_traits.hpp deleted file mode 100644 index 899d40f74..000000000 --- a/libs/luabind/luabind/pointer_traits.hpp +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (c) 2005 Daniel Wallin - -// 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 LUABIND_GET_POINTER_051023_HPP -# define LUABIND_GET_POINTER_051023_HPP -#include -#include - -// TODO: Rename to pointer_traits - -namespace luabind { - - template - T* get_pointer(T* pointer) - { - return pointer; - } - - template - T* get_pointer(const std::unique_ptr& pointer) - { - return pointer.get(); - } - - template - T* get_pointer(const std::shared_ptr& pointer) - { - return pointer.get(); - } - - - namespace detail { - - template - struct pointer_traits { - enum { is_pointer = false }; - }; - - template - struct pointer_traits - { - enum { is_pointer = true }; - using value_type = T; - }; - - template - struct pointer_traits> - { - enum { is_pointer = true }; - using value_type = T; - }; - - template - struct pointer_traits> - { - enum { is_pointer = true }; - using value_type = T; - }; - - template - using is_pointer_to_const = std::is_const< typename pointer_traits::value_type >; - - template - void release_ownership(std::unique_ptr& p) - { - p.release(); - } - - template - void release_ownership(P const&) - { - throw std::runtime_error( - "luabind: smart pointer does not allow ownership transfer"); - } - - namespace has_get_pointer_ - { - - struct any - { - template any(T const&); - }; - - struct no_overload_tag - {}; - - typedef char(&yes)[1]; - typedef char(&no)[2]; - - no_overload_tag operator, (no_overload_tag, int); - - template - T* get_pointer(T const volatile*); - - template - T* get_pointer(std::unique_ptr const&); - - template - T* get_pointer(std::shared_ptr const&); - - detail::has_get_pointer_::no_overload_tag - get_pointer(detail::has_get_pointer_::any); - - ///@TODO: Rework - template - yes check(T const&); - no check(no_overload_tag); - - template - struct impl - { - static typename std::add_lvalue_reference::type x; - static const bool value = (sizeof(has_get_pointer_::check((get_pointer(x), 0))) == 1); - typedef std::integral_constant type; - }; - - } // namespace has_get_pointer_ - - template - struct has_get_pointer - : has_get_pointer_::impl::type - {}; - - } // namespace detail - -} // namespace luabind - -#endif // LUABIND_GET_POINTER_051023_HPP - diff --git a/libs/luabind/luabind/raw_policy.hpp b/libs/luabind/luabind/raw_policy.hpp index ad3ecbfc1..6d22da246 100644 --- a/libs/luabind/luabind/raw_policy.hpp +++ b/libs/luabind/luabind/raw_policy.hpp @@ -27,40 +27,58 @@ #include #include +namespace luabind { namespace detail { + + struct raw_converter + { + int const consumed_args(...) + { + return 0; + } + + lua_State* apply(lua_State* L, by_pointer, int) + { + return L; + } + + static int match(...) + { + return 0; + } + + void converter_postcall(lua_State*, by_pointer, int) {} + }; + + template + struct raw_policy : conversion_policy + { + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + + template + struct apply + { + typedef raw_converter type; + }; + }; + +}} // namespace luabind::detail + namespace luabind { - namespace detail { - - struct raw_converter - { - enum { consumed_args = 0 }; - - lua_State* to_cpp(lua_State* L, by_pointer, int) - { - return L; - } - - static int match(...) - { - return 0; - } - - void converter_postcall(lua_State*, by_pointer, int) {} - }; - - struct raw_policy - { - template - struct specialize - { - using type = raw_converter; - }; - }; + template + detail::policy_cons< + detail::raw_policy + , detail::null_type + > + inline raw(LUABIND_PLACEHOLDER_ARG(N)) + { + return detail::policy_cons< + detail::raw_policy + , detail::null_type + >(); } - template - using raw_policy = meta::type_list< converter_policy_injector< N, detail::raw_policy > >(); - } // namespace luabind #endif // LUABIND_RAW_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/return_reference_to_policy.hpp b/libs/luabind/luabind/return_reference_to_policy.hpp index e9e8846bf..1432f79e0 100644 --- a/libs/luabind/luabind/return_reference_to_policy.hpp +++ b/libs/luabind/luabind/return_reference_to_policy.hpp @@ -23,49 +23,50 @@ #ifndef LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED #define LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED -#include // for index_map, policy_cons, etc -#include // for lua_State, lua_pushnil, etc - -namespace luabind { - namespace detail { - - struct cpp_to_lua; +namespace luabind { namespace detail +{ + template + struct return_reference_to_converter; + template<> + struct return_reference_to_converter + { template - struct return_reference_to_converter; - - template<> - struct return_reference_to_converter + void apply(lua_State* L, const T&) { - template - void to_lua(lua_State* L, const T&) - { - lua_pushnil(L); - } - }; + lua_pushnil(L); + } + }; - template< unsigned int N > - struct return_reference_to_policy : detail::converter_policy_has_postcall_tag + template + struct return_reference_to_policy : conversion_policy<0> + { + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State* L, const index_map& indices) { - template - static void postcall(lua_State* L, int results, StackIndexList) - { - lua_pushvalue(L, (meta::get::value)); - lua_replace(L, (meta::get::value + results)); - } + int result_index = indices[0]; + int ref_to_index = indices[N]; - template - struct specialize - { - using type = return_reference_to_converter; - }; + lua_pushvalue(L, ref_to_index); + lua_replace(L, result_index); + } + + template + struct apply + { + typedef return_reference_to_converter type; }; + }; +}} +namespace luabind +{ + template + detail::policy_cons, detail::null_type> + return_reference_to(LUABIND_PLACEHOLDER_ARG(N)) + { + return detail::policy_cons, detail::null_type>(); } - - template - using return_reference_to = meta::type_list>>; - } #endif // LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/scope.hpp b/libs/luabind/luabind/scope.hpp index ff0237f4a..3b5f293bf 100644 --- a/libs/luabind/luabind/scope.hpp +++ b/libs/luabind/luabind/scope.hpp @@ -25,79 +25,77 @@ #include #include -#include +#include #include -namespace luabind { - - struct scope; +namespace luabind { + + struct scope; } // namespace luabind -namespace luabind { - namespace detail { +namespace luabind { namespace detail { - struct LUABIND_API registration - { - registration(); - virtual ~registration(); + struct LUABIND_API registration + { + registration(); + virtual ~registration(); - protected: - virtual void register_(lua_State*) const = 0; + protected: + virtual void register_(lua_State*) const = 0; - private: - friend struct ::luabind::scope; - registration* m_next; - }; + private: + friend struct ::luabind::scope; + registration* m_next; + }; - } -} // namespace luabind::detail +}} // namespace luabind::detail namespace luabind { - struct LUABIND_API scope - { - scope(); - explicit scope(std::unique_ptr reg); - scope(scope const& other_); - ~scope(); + struct LUABIND_API scope + { + scope(); + explicit scope(std::auto_ptr reg); + scope(scope const& other_); + ~scope(); - scope& operator=(scope const& other_); + scope& operator=(scope const& other_); - scope& operator,(scope s); + scope& operator,(scope s); - void register_(lua_State* L) const; + void register_(lua_State* L) const; - private: - detail::registration* m_chain; - }; + private: + detail::registration* m_chain; + }; - class LUABIND_API namespace_ : public scope - { - public: - explicit namespace_(char const* name); - namespace_& operator[](scope s); + class LUABIND_API namespace_ : public scope + { + public: + explicit namespace_(char const* name); + namespace_& operator[](scope s); - private: - struct registration_; - registration_* m_registration; - }; + private: + struct registration_; + registration_* m_registration; + }; - class LUABIND_API module_ - { - public: - module_(lua_State* L_, char const* name); - void operator[](scope s); + class LUABIND_API module_ + { + public: + module_(lua_State* L_, char const* name); + void operator[](scope s); - private: - lua_State* m_state; - char const* m_name; - }; + private: + lua_State* m_state; + char const* m_name; + }; - inline module_ module(lua_State* L, char const* name = 0) - { - return module_(L, name); - } + inline module_ module(lua_State* L, char const* name = 0) + { + return module_(L, name); + } } // namespace luabind diff --git a/libs/luabind/luabind/set_package_preload.hpp b/libs/luabind/luabind/set_package_preload.hpp deleted file mode 100644 index 3ea227359..000000000 --- a/libs/luabind/luabind/set_package_preload.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/** @file - @brief Header - - @date 2012 - - @author - Ryan Pavlik - and - http://academic.cleardefinition.com/ - Iowa State University Virtual Reality Applications Center - Human-Computer Interaction Graduate Program -*/ - -// Copyright Iowa State University 2012. -// 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 INCLUDED_set_package_preload_hpp_GUID_563c882e_86f7_4ea7_8603_4594ea41737e -#define INCLUDED_set_package_preload_hpp_GUID_563c882e_86f7_4ea7_8603_4594ea41737e - -// Internal Includes -#include -#include - -// Library/third-party includes -// - none - -// Standard includes -// - none - - -namespace luabind { - - LUABIND_API void set_package_preload(lua_State * L, const char * modulename, int(*loader) (lua_State *)); -} -#endif // INCLUDED_set_package_preload_hpp_GUID_563c882e_86f7_4ea7_8603_4594ea41737e - diff --git a/libs/luabind/luabind/shared_ptr_converter.hpp b/libs/luabind/luabind/shared_ptr_converter.hpp index d5c0d50e6..2f61b5cff 100644 --- a/libs/luabind/luabind/shared_ptr_converter.hpp +++ b/libs/luabind/luabind/shared_ptr_converter.hpp @@ -5,79 +5,79 @@ #ifndef LUABIND_SHARED_PTR_CONVERTER_090211_HPP # define LUABIND_SHARED_PTR_CONVERTER_090211_HPP -#include -#include // for default_converter, etc -#include // for get_main_thread -#include // for handle -#include // for decorated_type -#include +# include +# include +# include +# include namespace luabind { - namespace detail - { +namespace detail +{ - struct shared_ptr_deleter - { - shared_ptr_deleter(lua_State* L, int index) - : life_support(get_main_thread(L), L, index) - {} + struct shared_ptr_deleter + { + shared_ptr_deleter(lua_State* L, int index) + : life_support(get_main_thread(L), L, index) + {} - void operator()(void const*) - { - handle().swap(life_support); - } + void operator()(void const*) + { + handle().swap(life_support); + } - handle life_support; - }; + handle life_support; + }; - } // namespace detail +} // namespace detail - template - struct default_converter > - : default_converter - { - using is_native = std::false_type; +template +struct default_converter > + : default_converter +{ + typedef boost::mpl::false_ is_native; - template - int match(lua_State* L, U, int index) - { - return default_converter::match(L, decorate_type_t(), index); - } + template + int match(lua_State* L, U, int index) + { + return default_converter::match( + L, LUABIND_DECORATE_TYPE(T*), index); + } - template - std::shared_ptr to_cpp(lua_State* L, U, int index) - { - T* raw_ptr = default_converter::to_cpp(L, decorate_type_t(), index); + template + boost::shared_ptr apply(lua_State* L, U, int index) + { + T* raw_ptr = default_converter::apply( + L, LUABIND_DECORATE_TYPE(T*), index); + if (!raw_ptr) + return boost::shared_ptr(); + return boost::shared_ptr( + raw_ptr, detail::shared_ptr_deleter(L, index)); + } - if(!raw_ptr) { - return std::shared_ptr(); - } else { - return std::shared_ptr(raw_ptr, detail::shared_ptr_deleter(L, index)); - } - } + void apply(lua_State* L, boost::shared_ptr const& p) + { + if (detail::shared_ptr_deleter* d = + boost::get_deleter(p)) + { + d->life_support.push(L); + } + else + { + detail::value_converter().apply(L, p); + } + } - void to_lua(lua_State* L, std::shared_ptr const& p) - { - if(detail::shared_ptr_deleter* d = std::get_deleter(p)) - { - d->life_support.push(L); - } else { - detail::value_converter().to_lua(L, p); - } - } + template + void converter_postcall(lua_State*, U const&, int) + {} +}; - template - void converter_postcall(lua_State*, U const&, int) - {} - }; - - template - struct default_converter const&> - : default_converter > - {}; +template +struct default_converter const&> + : default_converter > +{}; } // namespace luabind #endif // LUABIND_SHARED_PTR_CONVERTER_090211_HPP - diff --git a/libs/luabind/luabind/tag_function.hpp b/libs/luabind/luabind/tag_function.hpp index ba8382ee5..51fe97b75 100644 --- a/libs/luabind/luabind/tag_function.hpp +++ b/libs/luabind/luabind/tag_function.hpp @@ -2,62 +2,87 @@ // subject to 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) -#ifndef LUABIND_TAG_FUNCTION_081129_HPP -#define LUABIND_TAG_FUNCTION_081129_HPP +#if !BOOST_PP_IS_ITERATING -#include -#include -#include +# ifndef LUABIND_TAG_FUNCTION_081129_HPP +# define LUABIND_TAG_FUNCTION_081129_HPP + +# if LUABIND_MAX_ARITY <= 8 +# include +# else +# include +# endif +# include +# include +# include +# include namespace luabind { - template - struct tagged_function - { - tagged_function(F f) - : f(f) - {} +namespace detail +{ - F f; - }; + template + struct tagged_function + { + tagged_function(F f) + : f(f) + {} - namespace detail - { + F f; + }; - struct invoke_context; - struct function_object; + template + Signature deduce_signature(tagged_function const&, ...) + { + return Signature(); + } -#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS - template - int invoke( - lua_State* L, function_object const& self, invoke_context& ctx - // std::bind operator() is nonconst... is that fixable? - , tagged_function /*const*/& tagged - , Signature, meta::type_list const& injectors) - { - return invoke(L, self, ctx, tagged.f, Signature(), injectors); - } -#else - //template< typename PolicyList, typename Signature, typename F> - //inline int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f) + template + int invoke( + lua_State* L, function_object const& self, invoke_context& ctx + , tagged_function const& tagged + , Signature, Policies const& policies) + { + return invoke(L, self, ctx, tagged.f, Signature(), policies); + } - template < typename PolicyList, typename Signature, typename F > - int invoke(lua_State* L, function_object const& self, invoke_context& ctx, tagged_function /*const*/& tagged) - { - return invoke(L, self, ctx, tagged.f); - } -#endif + template + struct signature_from_function; - } // namespace detail +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() - template - tagged_function, F > - tag_function(F f) - { - return f; - } +} // namespace detail + +template +detail::tagged_function< + typename detail::signature_from_function::type + , F +> +tag_function(F f) +{ + return f; +} } // namespace luabind # endif // LUABIND_TAG_FUNCTION_081129_HPP +#else // BOOST_PP_IS_ITERATING + +# define N BOOST_PP_ITERATION() +# define NPLUS1 BOOST_PP_INC(N) + +template +struct signature_from_function +{ + typedef BOOST_PP_CAT(mpl::vector, NPLUS1)< + R BOOST_PP_ENUM_TRAILING_PARAMS(N, A) + > type; +}; + +#endif // BOOST_PP_IS_ITERATING + + diff --git a/libs/luabind/luabind/typeid.hpp b/libs/luabind/luabind/typeid.hpp index 9f8161bd3..d92d8fbac 100644 --- a/libs/luabind/luabind/typeid.hpp +++ b/libs/luabind/luabind/typeid.hpp @@ -5,50 +5,59 @@ #ifndef LUABIND_TYPEID_081227_HPP # define LUABIND_TYPEID_081227_HPP +# include # include -# include +# include namespace luabind { - class type_id - { - public: - type_id() - : id(&typeid(null_type)) - {} +# ifdef BOOST_MSVC +# pragma warning(push) +// std::type_info::before() returns int, rather than bool. +// At least on MSVC7.1, this is true for the comparison +// operators as well. +# pragma warning(disable:4800) +# endif - type_id(std::type_info const& id) - : id(&id) - {} +class type_id + : public boost::less_than_comparable +{ +public: + type_id() + : id(&typeid(detail::null_type)) + {} - bool operator!=(type_id const& other) const - { - return *id != *other.id; - } + type_id(std::type_info const& id) + : id(&id) + {} - bool operator==(type_id const& other) const - { - return *id == *other.id; - } + bool operator!=(type_id const& other) const + { + return *id != *other.id; + } - bool operator<(type_id const& other) const - { - return id->before(*other.id); - } + bool operator==(type_id const& other) const + { + return *id == *other.id; + } - size_t hash_code() const - { - return id->hash_code(); - } + bool operator<(type_id const& other) const + { + return id->before(*other.id); + } - char const* name() const - { - return id->name(); - } + char const* name() const + { + return id->name(); + } - private: - std::type_info const* id; - }; +private: + std::type_info const* id; +}; + +# ifdef BOOST_MSVC +# pragma warning(pop) +# endif } // namespace luabind diff --git a/libs/luabind/luabind/value_wrapper.hpp b/libs/luabind/luabind/value_wrapper.hpp new file mode 100644 index 000000000..8e09395d5 --- /dev/null +++ b/libs/luabind/luabind/value_wrapper.hpp @@ -0,0 +1,168 @@ +// Copyright (c) 2005 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_VALUE_WRAPPER_050419_HPP +#define LUABIND_VALUE_WRAPPER_050419_HPP + +#include +#include +#include + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# define LUABIND_USE_VALUE_WRAPPER_TAG +#else +#endif + +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +namespace luabind { + +// +// Concept ``ValueWrapper`` +// + +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG +template +struct value_wrapper_traits; + +namespace detail +{ + + BOOST_MPL_HAS_XXX_TRAIT_DEF(value_wrapper_tag); + + struct unspecialized_value_wrapper_traits + { + typedef boost::mpl::false_ is_specialized; + }; + + template + struct value_wrapper_traits_aux + { + typedef value_wrapper_traits type; + }; + +} // namespace detail +#endif + +template +struct value_wrapper_traits +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG + : boost::mpl::eval_if< + boost::mpl::and_< + boost::mpl::not_< + boost::mpl::or_< + boost::is_reference + , boost::is_pointer + , boost::is_array + > + > + , detail::has_value_wrapper_tag + > + , detail::value_wrapper_traits_aux + , boost::mpl::identity + >::type +{}; +#else +{ + typedef boost::mpl::false_ is_specialized; +}; +#endif + +template +struct is_value_wrapper + : boost::mpl::aux::msvc_eti_base< + typename value_wrapper_traits::is_specialized + >::type +{}; + +} // namespace luabind + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +# include +# include + +namespace luabind { + +template +struct is_value_wrapper_arg + : is_value_wrapper< + typename boost::remove_const< + typename boost::remove_reference::type + >::type + > +{}; + +} // namespace luabind + +#else + +# include +# include + +namespace luabind { + +namespace detail +{ + template + typename is_value_wrapper::type is_value_wrapper_arg_check(T const*); + + yes_t to_yesno(boost::mpl::true_); + no_t to_yesno(boost::mpl::false_); + + template + struct is_value_wrapper_arg_aux + { + static typename boost::add_reference::type x; + + BOOST_STATIC_CONSTANT(bool, value = + sizeof(to_yesno(is_value_wrapper_arg_check(&x))) + == sizeof(yes_t) + ); + + typedef boost::mpl::bool_ type; + }; + +} // namespace detail + +template +struct is_value_wrapper_arg + : detail::is_value_wrapper_arg_aux::type +{ +}; + +} // namespace luabind + +#endif + +#endif // LUABIND_VALUE_WRAPPER_050419_HPP + diff --git a/libs/luabind/luabind/version.hpp b/libs/luabind/luabind/version.hpp index 89625ac5b..63acaf765 100644 --- a/libs/luabind/luabind/version.hpp +++ b/libs/luabind/luabind/version.hpp @@ -14,4 +14,3 @@ // patch = LUABIND_VERSION % 100 #endif // LUABIND_VERSION_090216_HPP - diff --git a/libs/luabind/luabind/weak_ref.hpp b/libs/luabind/luabind/weak_ref.hpp index c7a2a32ce..e08e250dc 100644 --- a/libs/luabind/luabind/weak_ref.hpp +++ b/libs/luabind/luabind/weak_ref.hpp @@ -25,33 +25,33 @@ #include -#include +struct lua_State; namespace luabind { - class LUABIND_API weak_ref - { - public: - weak_ref(); - weak_ref(lua_State* main, lua_State* L, int index); - weak_ref(weak_ref const&); - ~weak_ref(); + class LUABIND_API weak_ref + { + public: + weak_ref(); + weak_ref(lua_State* main, lua_State* L, int index); + weak_ref(weak_ref const&); + ~weak_ref(); - weak_ref& operator=(weak_ref const&); + weak_ref& operator=(weak_ref const&); - void swap(weak_ref&); + void swap(weak_ref&); // returns a unique id that no // other weak ref will return int id() const; - lua_State* state() const; - void get(lua_State* L) const; + lua_State* state() const; + void get(lua_State* L) const; - private: - struct impl; - impl* m_impl; - }; + private: + struct impl; + impl* m_impl; + }; } // namespace luabind diff --git a/libs/luabind/luabind/wrapper_base.hpp b/libs/luabind/luabind/wrapper_base.hpp index 7845e12d3..9adc05a35 100644 --- a/libs/luabind/luabind/wrapper_base.hpp +++ b/libs/luabind/luabind/wrapper_base.hpp @@ -20,14 +20,19 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. +#if !BOOST_PP_IS_ITERATING + #ifndef LUABIND_WRAPPER_BASE_HPP_INCLUDED #define LUABIND_WRAPPER_BASE_HPP_INCLUDED #include #include #include -#include -#include +#include + +#include +#include + #include namespace luabind @@ -43,15 +48,9 @@ namespace luabind // on the top of the stack (the input self reference will // be popped) LUABIND_API void do_call_member_selection(lua_State* L, char const* name); - - template, unsigned int... Indices, typename... Args> - R call_member_impl(lua_State* L, std::true_type /*void*/, meta::index_list, Args&&... args); - - template, unsigned int... Indices, typename... Args> - R call_member_impl(lua_State* L, std::false_type /*void*/, meta::index_list, Args&&... args); } - struct wrapped_self_t : weak_ref + struct wrapped_self_t: weak_ref { detail::lua_reference m_strong_ref; }; @@ -61,41 +60,16 @@ namespace luabind friend struct detail::wrap_access; wrap_base() {} - template - R call(char const* name, Args&&... args) const - { - // this will be cleaned up by the proxy object - // once the call has been made - - // TODO: what happens if this virtual function is - // dispatched from a lua thread where the state - // pointer is different? - - // get the function - lua_State* L = m_self.state(); - m_self.get(L); - assert(!lua_isnil(L, -1)); - detail::do_call_member_selection(L, name); - - if(lua_isnil(L, -1)) - { - lua_pop(L, 1); - throw std::runtime_error("Attempt to call nonexistent function"); - } - - // push the self reference as the first parameter - m_self.get(L); - - // now the function and self objects - // are on the stack. These will both - // be popped by pcall - return detail::call_member_impl(L, std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); - } + #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) + #include BOOST_PP_ITERATE() private: wrapped_self_t m_self; }; +#define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 2)) +#include BOOST_PP_ITERATE() + namespace detail { struct wrap_access @@ -115,3 +89,104 @@ namespace luabind #endif // LUABIND_WRAPPER_BASE_HPP_INCLUDED +#else +#if BOOST_PP_ITERATION_FLAGS() == 1 + +#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * +#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n + + template + typename boost::mpl::if_ + , luabind::detail::proxy_member_void_caller > + , luabind::detail::proxy_member_caller > >::type + call(char const* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _), detail::type_* = 0) const + { + typedef boost::tuples::tuple tuple_t; + #if BOOST_PP_ITERATION() == 0 + tuple_t args; + #else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); + #endif + + typedef typename boost::mpl::if_ + , luabind::detail::proxy_member_void_caller > + , luabind::detail::proxy_member_caller > >::type proxy_type; + + // this will be cleaned up by the proxy object + // once the call has been made + + // TODO: what happens if this virtual function is + // dispatched from a lua thread where the state + // pointer is different? + + // get the function + lua_State* L = m_self.state(); + m_self.get(L); + assert(!lua_isnil(L, -1)); + detail::do_call_member_selection(L, name); + + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + throw std::runtime_error("Attempt to call nonexistent function"); + } + + // push the self reference as the first parameter + m_self.get(L); + + // now the function and self objects + // are on the stack. These will both + // be popped by pcall + return proxy_type(L, args); + } + +#undef LUABIND_CALL_MEMBER_NAME +#undef LUABIND_OPERATOR_PARAMS +#undef LUABIND_TUPLE_PARAMS + +#else // free call_member forwardarding functions + +#define N BOOST_PP_ITERATION() + +#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * +#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n + + template< + class R + BOOST_PP_ENUM_TRAILING_PARAMS(N, class A) + > + typename boost::mpl::if_< + boost::is_void + , detail::proxy_member_void_caller< + boost::tuples::tuple< + BOOST_PP_ENUM(N, LUABIND_TUPLE_PARAMS, _) + > + > + , detail::proxy_member_caller< + R + , boost::tuples::tuple< + BOOST_PP_ENUM(N, LUABIND_TUPLE_PARAMS, _) + > + > + >::type + call_member( + wrap_base const* self + , char const* fn + BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, A, &a) + , detail::type_* = 0 + ) + { + return self->call( + fn + BOOST_PP_ENUM_TRAILING_PARAMS(N, a) + , (detail::type_*)0 + ); + } + +#undef LUABIND_OPERATOR_PARAMS +#undef LUABIND_TUPLE_PARAMS + +#undef N + +#endif +#endif \ No newline at end of file diff --git a/libs/luabind/luabind/yield_policy.hpp b/libs/luabind/luabind/yield_policy.hpp index 5622b62a3..9dbbefa29 100644 --- a/libs/luabind/luabind/yield_policy.hpp +++ b/libs/luabind/luabind/yield_policy.hpp @@ -27,18 +27,40 @@ #include #include -namespace luabind { +namespace luabind { namespace detail +{ + struct yield_policy + { + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + }; - namespace detail { + template + struct has_yield + { + BOOST_STATIC_CONSTANT(bool, + value = (boost::is_same::value || + has_yield::value)); + }; - struct yield_policy - { - static void postcall(lua_State*, int /*results*/, meta::index_list_tag) {} - }; + template<> + struct has_yield + { + BOOST_STATIC_CONSTANT(bool, value = false); + }; +}} - } +namespace luabind +{ + detail::policy_cons const yield = {}; - using yield = policy_list>; + namespace detail + { + inline void ignore_unused_yield() + { + (void)yield; + } + } } #endif // LUABIND_YIELD_POLICY_HPP_INCLUDED diff --git a/libs/luabind/src/CMakeLists.txt b/libs/luabind/src/CMakeLists.txt deleted file mode 100644 index a839fb65a..000000000 --- a/libs/luabind/src/CMakeLists.txt +++ /dev/null @@ -1,182 +0,0 @@ -# Build for LuaBind -# Ryan Pavlik -# http://academic.cleardefinition.com/ -# Iowa State University HCI Graduate Program/VRAC - -set(LUABIND_SRCS - class.cpp - class_info.cpp - class_registry.cpp - class_rep.cpp - create_class.cpp - error.cpp - exception_handler.cpp - function.cpp - function_introspection.cpp - inheritance.cpp - link_compatibility.cpp - object_rep.cpp - open.cpp - operator.cpp - pcall.cpp - scope.cpp - set_package_preload.cpp - stack_content_by_name.cpp - weak_ref.cpp - wrapper_base.cpp) - -set(LUABIND_API - ../luabind/back_reference_fwd.hpp - ../luabind/back_reference.hpp - ../luabind/class.hpp - ../luabind/class_info.hpp - ../luabind/config.hpp - ../luabind/error.hpp - ../luabind/error_callback_fun.hpp - ../luabind/exception_handler.hpp - ../luabind/from_stack.hpp - ../luabind/function.hpp - ../luabind/function_introspection.hpp - ../luabind/get_main_thread.hpp - ../luabind/pointer_traits.hpp - ../luabind/handle.hpp - ../luabind/luabind.hpp - ../luabind/lua_argument_proxy.hpp - ../luabind/lua_include.hpp - ../luabind/lua_index_proxy.hpp - ../luabind/lua_iterator_proxy.hpp - ../luabind/lua_proxy_interface.hpp - ../luabind/lua_state_fwd.hpp - ../luabind/make_function.hpp - ../luabind/nil.hpp - ../luabind/object.hpp - ../luabind/open.hpp - ../luabind/operator.hpp - ../luabind/prefix.hpp - ../luabind/scope.hpp - ../luabind/set_package_preload.hpp - ../luabind/shared_ptr_converter.hpp - ../luabind/tag_function.hpp - ../luabind/typeid.hpp - ../luabind/lua_proxy.hpp - ../luabind/version.hpp - ../luabind/weak_ref.hpp - ../luabind/wrapper_base.hpp -) -source_group(API FILES ${LUABIND_API}) - -set(LUABIND_DETAIL_API - ../luabind/detail/meta.hpp - ../luabind/detail/call_traits.hpp - ../luabind/detail/call_shared.hpp - ../luabind/detail/crtp_iterator.hpp - ../luabind/detail/call_function.hpp - ../luabind/detail/call.hpp - ../luabind/detail/call_member.hpp - ../luabind/detail/class_registry.hpp - ../luabind/detail/class_rep.hpp - ../luabind/detail/constructor.hpp - ../luabind/detail/conversion_storage.hpp - ../luabind/detail/push_to_lua.hpp - ../luabind/detail/debug.hpp - ../luabind/detail/decorate_type.hpp - ../luabind/detail/deduce_signature.hpp - ../luabind/detail/enum_maker.hpp - ../luabind/detail/format_signature.hpp - ../luabind/detail/garbage_collector.hpp - ../luabind/detail/inheritance.hpp - ../luabind/detail/instance_holder.hpp - ../luabind/detail/link_compatibility.hpp - ../luabind/detail/make_instance.hpp - ../luabind/detail/object.hpp - ../luabind/detail/object_rep.hpp - ../luabind/detail/open.hpp - ../luabind/detail/operator_id.hpp - ../luabind/detail/other.hpp - ../luabind/detail/pcall.hpp - ../luabind/detail/policy.hpp - ../luabind/detail/primitives.hpp - ../luabind/detail/property.hpp - ../luabind/detail/ref.hpp - ../luabind/detail/signature_match.hpp - ../luabind/detail/stack_utils.hpp - ../luabind/detail/type_traits.hpp -) -source_group(Internal FILES ${LUABIND_DETAIL_API}) - -set(LUABIND_DEFAULT_POLICIES - ../luabind/detail/conversion_policies/pointer_converter.hpp - ../luabind/detail/conversion_policies/reference_converter.hpp - ../luabind/detail/conversion_policies/value_converter.hpp - ../luabind/detail/conversion_policies/enum_converter.hpp - ../luabind/detail/conversion_policies/function_converter.hpp - ../luabind/detail/conversion_policies/conversion_base.hpp - ../luabind/detail/conversion_policies/conversion_policies.hpp - ../luabind/detail/conversion_policies/lua_proxy_converter.hpp - ../luabind/detail/conversion_policies/native_converter.hpp - ) -source_group("Default Policies" FILES ${LUABIND_DEFAULT_POLICIES} ) - -set(LUABIND_USER_POLICIES - ../luabind/yield_policy.hpp - ../luabind/no_dependency.hpp - ../luabind/iterator_policy.hpp - ../luabind/container_policy.hpp - ../luabind/copy_policy.hpp - ../luabind/dependency_policy.hpp - ../luabind/discard_result_policy.hpp - ../luabind/adopt_policy.hpp - ../luabind/out_value_policy.hpp - ../luabind/return_reference_to_policy.hpp - ../luabind/raw_policy.hpp -) -source_group("User Policies" FILES ${LUABIND_USER_POLICIES} ) - -set(LUABIND_EXTRA_LIBS) -if(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251") -elseif(CMAKE_COMPILER_IS_GNUCXX) - list(APPEND LUABIND_EXTRA_LIBS m) -endif() - -add_library(luabind ${LUABIND_SRCS} ${LUABIND_API} ${LUABIND_DETAIL_API} ${LUABIND_DEFAULT_POLICIES} ${LUABIND_USER_POLICIES}) -target_link_libraries(luabind ${LUA_LIBRARIES} ${LUABIND_EXTRA_LIBS}) - -set_property(TARGET luabind PROPERTY COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS}) -set_property(TARGET luabind PROPERTY PROJECT_LABEL "LuaBind Library") - -set(ALLHEADERS ${LUABIND_API} ${LUABIND_DETAIL_API} PARENT_SCOPE) -set(APIHEADERS ${LUABIND_API} PARENT_SCOPE) - -if(LUABIND_INSTALL) - if(NOT INCLUDE_DIR) - set(INCLUDE_DIR include) - endif() - if(NOT LIB_DIR) - set(LIB_DIR lib) - endif() - if(NOT ARCH_DIR) - set(ARCH_DIR lib) - endif() - if(NOT BIN_DIR) - set(BIN_DIR bin) - endif() - install(FILES ${LUABIND_API} - DESTINATION ${INCLUDE_DIR}/luabind - COMPONENT sdk) - install(FILES ${LUABIND_USER_POLICIES} - DESTINATION ${INCLUDE_DIR}/luabind - COMPONENT sdk) - install(FILES ${LUABIND_DETAIL_API} - DESTINATION ${INCLUDE_DIR}/luabind/detail - COMPONENT sdk) - install(FILES ${LUABIND_DEFAULT_POLICIES} - DESTINATION ${INCLUDE_DIR}/luabind/detail/conversion_policies - COMPONENT sdk) - install(TARGETS luabind - EXPORT luabind - RUNTIME DESTINATION ${BIN_DIR} COMPONENT runtime - LIBRARY DESTINATION ${LIB_DIR} COMPONENT runtime - ARCHIVE DESTINATION ${ARCH_DIR} COMPONENT sdk) -endif() - diff --git a/libs/luabind/src/class.cpp b/libs/luabind/src/class.cpp index ee772b643..8a67cf6f3 100644 --- a/libs/luabind/src/class.cpp +++ b/libs/luabind/src/class.cpp @@ -22,307 +22,316 @@ #define LUABIND_BUILDING +#include + #include #include #include #include -#include #include #include -namespace luabind { - namespace detail { +namespace luabind +{ + LUABIND_API detail::nil_type nil; +} +namespace luabind { namespace detail { + - namespace - { - struct cast_entry - { - cast_entry(class_id src, class_id target, cast_function cast) - : src(src) - , target(target) - , cast(cast) - {} + namespace + { + struct cast_entry + { + cast_entry(class_id src, class_id target, cast_function cast) + : src(src) + , target(target) + , cast(cast) + {} - class_id src; - class_id target; - cast_function cast; - }; + class_id src; + class_id target; + cast_function cast; + }; - } // namespace unnamed + } // namespace unnamed - struct class_registration : registration - { - class_registration(char const* name); + struct class_registration : registration + { + class_registration(char const* name); - void register_(lua_State* L) const; + void register_(lua_State* L) const; - const char* m_name; + const char* m_name; - mutable std::map m_static_constants; + mutable std::map m_static_constants; - using base_desc = std::pair; - mutable std::vector m_bases; + typedef std::pair base_desc; + mutable std::vector m_bases; - type_id m_type; - class_id m_id; - class_id m_wrapper_id; - type_id m_wrapper_type; - std::vector m_casts; + type_id m_type; + class_id m_id; + class_id m_wrapper_id; + type_id m_wrapper_type; + std::vector m_casts; - scope m_scope; - scope m_members; - scope m_default_members; - }; + scope m_scope; + scope m_members; + scope m_default_members; + }; - class_registration::class_registration(char const* name) - { - m_name = name; - } + class_registration::class_registration(char const* name) + { + m_name = name; + } - void class_registration::register_(lua_State* L) const - { - LUABIND_CHECK_STACK(L); + void class_registration::register_(lua_State* L) const + { + LUABIND_CHECK_STACK(L); - assert(lua_type(L, -1) == LUA_TTABLE); + assert(lua_type(L, -1) == LUA_TTABLE); - lua_pushstring(L, m_name); + lua_pushstring(L, m_name); - detail::class_rep* crep; + detail::class_rep* crep; - detail::class_registry* r = detail::class_registry::get_registry(L); - // create a class_rep structure for this class. - // allocate it within lua to let lua collect it on - // lua_close(). This is better than allocating it - // as a static, since it will then be destructed - // when the program exits instead. - // warning: we assume that lua will not - // move the userdata memory. - lua_newuserdata(L, sizeof(detail::class_rep)); - crep = reinterpret_cast(lua_touserdata(L, -1)); + detail::class_registry* r = detail::class_registry::get_registry(L); + // create a class_rep structure for this class. + // allocate it within lua to let lua collect it on + // lua_close(). This is better than allocating it + // as a static, since it will then be destructed + // when the program exits instead. + // warning: we assume that lua will not + // move the userdata memory. + lua_newuserdata(L, sizeof(detail::class_rep)); + crep = reinterpret_cast(lua_touserdata(L, -1)); - new(crep) detail::class_rep( - m_type - , m_name - , L - ); + new(crep) detail::class_rep( + m_type + , m_name + , L + ); - // register this new type in the class registry - r->add_class(m_type, crep); + // register this new type in the class registry + r->add_class(m_type, crep); - lua_pushstring(L, "__luabind_class_map"); - lua_rawget(L, LUA_REGISTRYINDEX); - class_map& classes = *static_cast( - lua_touserdata(L, -1)); - lua_pop(L, 1); + lua_pushstring(L, "__luabind_class_map"); + lua_rawget(L, LUA_REGISTRYINDEX); + class_map& classes = *static_cast( + lua_touserdata(L, -1)); + lua_pop(L, 1); - classes.put(m_id, crep); + classes.put(m_id, crep); - bool const has_wrapper = m_wrapper_id != registered_class::id; + bool const has_wrapper = m_wrapper_id != registered_class::id; - if(has_wrapper) - classes.put(m_wrapper_id, crep); + if (has_wrapper) + classes.put(m_wrapper_id, crep); - crep->m_static_constants.swap(m_static_constants); + crep->m_static_constants.swap(m_static_constants); - detail::class_registry* registry = detail::class_registry::get_registry(L); + detail::class_registry* registry = detail::class_registry::get_registry(L); - crep->get_default_table(L); - m_scope.register_(L); - m_default_members.register_(L); - lua_pop(L, 1); + crep->get_default_table(L); + m_scope.register_(L); + m_default_members.register_(L); + lua_pop(L, 1); + crep->get_table(L); + m_members.register_(L); + lua_pop(L, 1); + + lua_pushstring(L, "__luabind_cast_graph"); + lua_gettable(L, LUA_REGISTRYINDEX); + cast_graph* const casts = static_cast( + lua_touserdata(L, -1)); + lua_pop(L, 1); + + lua_pushstring(L, "__luabind_class_id_map"); + lua_gettable(L, LUA_REGISTRYINDEX); + class_id_map* const class_ids = static_cast( + lua_touserdata(L, -1)); + lua_pop(L, 1); + + class_ids->put(m_id, m_type); + + if (has_wrapper) + class_ids->put(m_wrapper_id, m_wrapper_type); + + BOOST_FOREACH(cast_entry const& e, m_casts) + { + casts->insert(e.src, e.target, e.cast); + } + + for (std::vector::iterator i = m_bases.begin(); + i != m_bases.end(); ++i) + { + LUABIND_CHECK_STACK(L); + + // the baseclass' class_rep structure + detail::class_rep* bcrep = registry->find_class(i->first); + + detail::class_rep::base_info base; + base.pointer_offset = 0; + base.base = bcrep; + + crep->add_base_class(base); + + // copy base class table crep->get_table(L); - m_members.register_(L); - lua_pop(L, 1); + bcrep->get_table(L); + lua_pushnil(L); - lua_pushstring(L, "__luabind_cast_graph"); - lua_gettable(L, LUA_REGISTRYINDEX); - cast_graph* const casts = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + while (lua_next(L, -2)) + { + lua_pushvalue(L, -2); // copy key + lua_gettable(L, -5); - lua_pushstring(L, "__luabind_class_id_map"); - lua_gettable(L, LUA_REGISTRYINDEX); - class_id_map* const class_ids = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + if (!lua_isnil(L, -1)) + { + lua_pop(L, 2); + continue; + } - class_ids->put(m_id, m_type); + lua_pop(L, 1); + lua_pushvalue(L, -2); // copy key + lua_insert(L, -2); - if(has_wrapper) { - class_ids->put(m_wrapper_id, m_wrapper_type); - } + lua_settable(L, -5); + } + lua_pop(L, 2); - for(auto const& e : m_casts) { - casts->insert(e.src, e.target, e.cast); - } + // copy base class detaults table + crep->get_default_table(L); + bcrep->get_default_table(L); + lua_pushnil(L); - for(const auto& base_pair : m_bases) { - LUABIND_CHECK_STACK(L); + while (lua_next(L, -2)) + { + lua_pushvalue(L, -2); // copy key + lua_gettable(L, -5); - // the baseclass' class_rep structure - detail::class_rep* bcrep = registry->find_class(base_pair.first); + if (!lua_isnil(L, -1)) + { + lua_pop(L, 2); + continue; + } - detail::class_rep::base_info base; - base.pointer_offset = 0; - base.base = bcrep; + lua_pop(L, 1); + lua_pushvalue(L, -2); // copy key + lua_insert(L, -2); - crep->add_base_class(base); + lua_settable(L, -5); + } + lua_pop(L, 2); - // copy base class table - crep->get_table(L); - bcrep->get_table(L); - lua_pushnil(L); - - while(lua_next(L, -2)) - { - lua_pushvalue(L, -2); // copy key - lua_gettable(L, -5); - - if(!lua_isnil(L, -1)) - { - lua_pop(L, 2); - continue; - } - - lua_pop(L, 1); - lua_pushvalue(L, -2); // copy key - lua_insert(L, -2); - - lua_settable(L, -5); - } - lua_pop(L, 2); - - // copy base class detaults table - crep->get_default_table(L); - bcrep->get_default_table(L); - lua_pushnil(L); - - while(lua_next(L, -2)) - { - lua_pushvalue(L, -2); // copy key - lua_gettable(L, -5); - - if(!lua_isnil(L, -1)) - { - lua_pop(L, 2); - continue; - } - - lua_pop(L, 1); - lua_pushvalue(L, -2); // copy key - lua_insert(L, -2); - - lua_settable(L, -5); - } - lua_pop(L, 2); - - } - - lua_settable(L, -3); } - // -- interface --------------------------------------------------------- + lua_settable(L, -3); + } + + // -- interface --------------------------------------------------------- - class_base::class_base(char const* name) - : scope(std::unique_ptr( - m_registration = new class_registration(name)) - ) - { - } + class_base::class_base(char const* name) + : scope(std::auto_ptr( + m_registration = new class_registration(name)) + ) + { + } - void class_base::init( - type_id const& type_id_, class_id id - , type_id const& wrapper_type, class_id wrapper_id) - { - m_registration->m_type = type_id_; - m_registration->m_id = id; - m_registration->m_wrapper_type = wrapper_type; - m_registration->m_wrapper_id = wrapper_id; - } + void class_base::init( + type_id const& type_id_, class_id id + , type_id const& wrapper_type, class_id wrapper_id) + { + m_registration->m_type = type_id_; + m_registration->m_id = id; + m_registration->m_wrapper_type = wrapper_type; + m_registration->m_wrapper_id = wrapper_id; + } - void class_base::add_base(type_id const& base, cast_function cast) - { - m_registration->m_bases.push_back(std::make_pair(base, cast)); - } - - void class_base::add_member(registration* member) - { - std::unique_ptr ptr(member); - m_registration->m_members.operator,(scope(std::move(ptr))); - } - - void class_base::add_default_member(registration* member) - { - std::unique_ptr ptr(member); - m_registration->m_default_members.operator,(scope(std::move(ptr))); - } - - const char* class_base::name() const - { - return m_registration->m_name; - } - - void class_base::add_static_constant(const char* name, int val) - { - m_registration->m_static_constants[name] = val; - } - - void class_base::add_inner_scope(scope& s) - { - m_registration->m_scope.operator,(s); - } - - void class_base::add_cast( - class_id src, class_id target, cast_function cast) - { - m_registration->m_casts.push_back(cast_entry(src, target, cast)); - } - - void add_custom_name(type_id const& i, std::string& s) - { - s += " ["; - s += i.name(); - s += "]"; - } - - std::string get_class_name(lua_State* L, type_id const& i) - { - std::string ret; - - assert(L); - - class_registry* r = class_registry::get_registry(L); - class_rep* crep = r->find_class(i); - - if(crep == 0) - { - ret = "custom"; - add_custom_name(i, ret); - } else - { - /* TODO reimplement this? - if (i == crep->holder_type()) - { - ret += "smart_ptr<"; - ret += crep->name(); - ret += ">"; - } - else if (i == crep->const_holder_type()) - { - ret += "smart_ptrname(); - ret += ">"; - } - else*/ - { - ret += crep->name(); - } - } - return ret; - } + void class_base::add_base(type_id const& base, cast_function cast) + { + m_registration->m_bases.push_back(std::make_pair(base, cast)); + } + void class_base::add_member(registration* member) + { + std::auto_ptr ptr(member); + m_registration->m_members.operator,(scope(ptr)); } -} // namespace luabind::detail + + void class_base::add_default_member(registration* member) + { + std::auto_ptr ptr(member); + m_registration->m_default_members.operator,(scope(ptr)); + } + + const char* class_base::name() const + { + return m_registration->m_name; + } + + void class_base::add_static_constant(const char* name, int val) + { + m_registration->m_static_constants[name] = val; + } + + void class_base::add_inner_scope(scope& s) + { + m_registration->m_scope.operator,(s); + } + + void class_base::add_cast( + class_id src, class_id target, cast_function cast) + { + m_registration->m_casts.push_back(cast_entry(src, target, cast)); + } + + void add_custom_name(type_id const& i, std::string& s) + { + s += " ["; + s += i.name(); + s += "]"; + } + + std::string get_class_name(lua_State* L, type_id const& i) + { + std::string ret; + + assert(L); + + class_registry* r = class_registry::get_registry(L); + class_rep* crep = r->find_class(i); + + if (crep == 0) + { + ret = "custom"; + add_custom_name(i, ret); + } + else + { + /* TODO reimplement this? + if (i == crep->holder_type()) + { + ret += "smart_ptr<"; + ret += crep->name(); + ret += ">"; + } + else if (i == crep->const_holder_type()) + { + ret += "smart_ptrname(); + ret += ">"; + } + else*/ + { + ret += crep->name(); + } + } + return ret; + } + +}} // namespace luabind::detail diff --git a/libs/luabind/src/class_info.cpp b/libs/luabind/src/class_info.cpp index 3f219e827..531f6e0cc 100644 --- a/libs/luabind/src/class_info.cpp +++ b/libs/luabind/src/class_info.cpp @@ -27,111 +27,94 @@ #include #include #include -#include -#include - -/* -#include -#define VERBOSE(X) std::cout << __FILE__ << ":" << __LINE__ << ": " << X << std::endl -*/ -#define VERBOSE(X) - -namespace luabind { +namespace luabind +{ LUABIND_API class_info get_class_info(argument const& o) { lua_State* L = o.interpreter(); - detail::class_rep * crep = NULL; - + o.push(L); - if(detail::is_class_rep(L, -1)) { - VERBOSE("OK, got a class rep"); - // OK, o is a class rep, now at the top of the stack - crep = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); - } else { + detail::object_rep* obj = detail::get_instance(L, -1); - VERBOSE("Not a class rep"); - detail::object_rep* obj = detail::get_instance(L, -1); + if (!obj) + { + class_info result; + result.name = lua_typename(L, lua_type(L, -1)); + lua_pop(L, 1); + result.methods = newtable(L); + result.attributes = newtable(L); + return result; + } - if(!obj) - { - VERBOSE("Not a obj rep"); - class_info result; - result.name = lua_typename(L, lua_type(L, -1)); - lua_pop(L, 1); - result.methods = newtable(L); - result.attributes = newtable(L); - return result; - } else { - lua_pop(L, 1); - // OK, we were given an object - gotta get the crep. - crep = obj->crep(); - } - } - crep->get_table(L); - object table(from_stack(L, -1)); - lua_pop(L, 1); + lua_pop(L, 1); - class_info result; - result.name = crep->name(); - result.methods = newtable(L); - result.attributes = newtable(L); + obj->crep()->get_table(L); + object table(from_stack(L, -1)); + lua_pop(L, 1); - std::size_t index = 1; + class_info result; + result.name = obj->crep()->name(); + result.methods = newtable(L); + result.attributes = newtable(L); - for(iterator i(table), e; i != e; ++i) - { - if(type(*i) != LUA_TFUNCTION) - continue; + std::size_t index = 1; - // We have to create a temporary `object` here, otherwise the proxy - // returned by operator->() will mess up the stack. This is a known - // problem that probably doesn't show up in real code very often. - object member(*i); - member.push(L); - detail::stack_pop pop(L, 1); + for (iterator i(table), e; i != e; ++i) + { + if (type(*i) != LUA_TFUNCTION) + continue; - if(lua_tocfunction(L, -1) == &detail::property_tag) - { - result.attributes[index++] = i.key(); - } else - { - result.methods[i.key()] = *i; - } - } + // We have to create a temporary `object` here, otherwise the proxy + // returned by operator->() will mess up the stack. This is a known + // problem that probably doesn't show up in real code very often. + object member(*i); + member.push(L); + detail::stack_pop pop(L, 1); - return result; + if (lua_tocfunction(L, -1) == &detail::property_tag) + { + result.attributes[index++] = i.key(); + } + else + { + result.methods[i.key()] = *i; + } + } + + return result; } - LUABIND_API object get_class_names(lua_State* L) - { - detail::class_registry* reg = detail::class_registry::get_registry(L); + LUABIND_API object get_class_names(lua_State* L) + { + detail::class_registry* reg = detail::class_registry::get_registry(L); - std::map const& classes = reg->get_classes(); + std::map const& classes = reg->get_classes(); - object result = newtable(L); - std::size_t index = 1; + object result = newtable(L); + std::size_t index = 1; - for(const auto& cl : classes) { - result[index++] = cl.second->name(); - } + for (std::map::const_iterator iter = classes.begin(); + iter != classes.end(); ++iter) + { + result[index++] = iter->second->name(); + } - return result; - } + return result; + } LUABIND_API void bind_class_info(lua_State* L) { module(L) - [ - class_("class_info_data") + [ + class_("class_info_data") .def_readonly("name", &class_info::name) - .def_readonly("methods", &class_info::methods) - .def_readonly("attributes", &class_info::attributes), - - def("class_info", &get_class_info), - def("class_names", &get_class_names) - ]; + .def_readonly("methods", &class_info::methods) + .def_readonly("attributes", &class_info::attributes), + + def("class_info", &get_class_info), + def("class_names", &get_class_names) + ]; } } diff --git a/libs/luabind/src/class_registry.cpp b/libs/luabind/src/class_registry.cpp index 046cb689b..79df30ade 100644 --- a/libs/luabind/src/class_registry.cpp +++ b/libs/luabind/src/class_registry.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2004 Daniel Wallin +// Copyright (c) 2004 Daniel Wallin // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -22,121 +22,145 @@ #define LUABIND_BUILDING -#include // for lua_pushstring, lua_rawset, etc +#include -#include // for LUABIND_API -#include // for type_id -#include // for class_registry -#include // for class_rep -#include // for garbage_collector +#include +#include +#include +#include +namespace luabind { namespace detail { -#include // for assert -#include // for map, etc -#include // for pair + LUABIND_API void push_instance_metatable(lua_State* L); -namespace luabind { - namespace detail { + namespace { - LUABIND_API void push_instance_metatable(lua_State* L); + int create_cpp_class_metatable(lua_State* L) + { + lua_newtable(L); - namespace { + // mark the table with our (hopefully) unique tag + // that says that the user data that has this + // metatable is a class_rep + lua_pushstring(L, "__luabind_classrep"); + lua_pushboolean(L, 1); + lua_rawset(L, -3); - /// @todo is this redundant with the following function? All that differs is the __gc closure - int create_cpp_class_metatable(lua_State* L) - { - lua_newtable(L); + lua_pushstring(L, "__gc"); + lua_pushcclosure( + L + , &garbage_collector_s< + detail::class_rep + >::apply + , 0); - // mark the table with our (hopefully) unique tag - // that says that the user data that has this - // metatable is a class_rep - lua_pushstring(L, "__luabind_classrep"); - lua_pushboolean(L, 1); - lua_rawset(L, -3); + lua_rawset(L, -3); - lua_pushstring(L, "__gc"); - lua_pushcclosure(L, &garbage_collector, 0); + lua_pushstring(L, "__call"); + lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0); + lua_rawset(L, -3); - lua_rawset(L, -3); + lua_pushstring(L, "__index"); + lua_pushcclosure(L, &class_rep::static_class_gettable, 0); + lua_rawset(L, -3); - lua_pushstring(L, "__call"); - lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0); - lua_rawset(L, -3); + lua_pushstring(L, "__newindex"); + lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0); + lua_rawset(L, -3); - lua_pushstring(L, "__index"); - lua_pushcclosure(L, &class_rep::static_class_gettable, 0); - lua_rawset(L, -3); + return luaL_ref(L, LUA_REGISTRYINDEX); + } - lua_pushstring(L, "__newindex"); - lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0); - lua_rawset(L, -3); + int create_lua_class_metatable(lua_State* L) + { + lua_newtable(L); - return luaL_ref(L, LUA_REGISTRYINDEX); - } + lua_pushstring(L, "__luabind_classrep"); + lua_pushboolean(L, 1); + lua_rawset(L, -3); - int create_lua_class_metatable(lua_State* L) - { - return create_cpp_class_metatable(L); - } + lua_pushstring(L, "__gc"); + lua_pushcclosure( + L + , &detail::garbage_collector_s< + detail::class_rep + >::apply + , 0); - } // namespace unnamed + lua_rawset(L, -3); - class class_rep; + lua_pushstring(L, "__newindex"); + lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0); + lua_rawset(L, -3); - class_registry::class_registry(lua_State* L) - : m_cpp_class_metatable(create_cpp_class_metatable(L)) - , m_lua_class_metatable(create_lua_class_metatable(L)) - { - push_instance_metatable(L); - m_instance_metatable = luaL_ref(L, LUA_REGISTRYINDEX); - } + lua_pushstring(L, "__call"); + lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0); + lua_rawset(L, -3); - class_registry* class_registry::get_registry(lua_State* L) - { + lua_pushstring(L, "__index"); + lua_pushcclosure(L, &class_rep::static_class_gettable, 0); + lua_rawset(L, -3); + + return luaL_ref(L, LUA_REGISTRYINDEX); + } + + } // namespace unnamed + + class class_rep; + + class_registry::class_registry(lua_State* L) + : m_cpp_class_metatable(create_cpp_class_metatable(L)) + , m_lua_class_metatable(create_lua_class_metatable(L)) + { + push_instance_metatable(L); + m_instance_metatable = luaL_ref(L, LUA_REGISTRYINDEX); + } + + class_registry* class_registry::get_registry(lua_State* L) + { #ifdef LUABIND_NOT_THREADSAFE - // if we don't have to be thread safe, we can keep a - // chache of the class_registry pointer without the - // need of a mutex - static lua_State* cache_key = 0; - static class_registry* registry_cache = 0; - if(cache_key == L) return registry_cache; + // if we don't have to be thread safe, we can keep a + // chache of the class_registry pointer without the + // need of a mutex + static lua_State* cache_key = 0; + static class_registry* registry_cache = 0; + if (cache_key == L) return registry_cache; #endif - lua_pushstring(L, "__luabind_classes"); - lua_gettable(L, LUA_REGISTRYINDEX); - class_registry* p = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + lua_pushstring(L, "__luabind_classes"); + lua_gettable(L, LUA_REGISTRYINDEX); + class_registry* p = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); #ifdef LUABIND_NOT_THREADSAFE - cache_key = L; - registry_cache = p; + cache_key = L; + registry_cache = p; #endif - return p; - } + return p; + } - void class_registry::add_class(type_id const& info, class_rep* crep) - { - // class is already registered - assert((m_classes.find(info) == m_classes.end()) - && "you are trying to register a class twice"); - m_classes[info] = crep; - } + void class_registry::add_class(type_id const& info, class_rep* crep) + { + // class is already registered + assert((m_classes.find(info) == m_classes.end()) + && "you are trying to register a class twice"); + m_classes[info] = crep; + } - class_rep* class_registry::find_class(type_id const& info) const - { - std::map::const_iterator i( - m_classes.find(info)); + class_rep* class_registry::find_class(type_id const& info) const + { + std::map::const_iterator i( + m_classes.find(info)); - if(i == m_classes.end()) return 0; // the type is not registered - return i->second; - } + if (i == m_classes.end()) return 0; // the type is not registered + return i->second; + } - } // namespace detail -} // namespace luabind +}} // namespace luabind::detail diff --git a/libs/luabind/src/class_rep.cpp b/libs/luabind/src/class_rep.cpp index f6d7da015..5f03f3931 100644 --- a/libs/luabind/src/class_rep.cpp +++ b/libs/luabind/src/class_rep.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -31,23 +31,17 @@ #include #include -#if LUA_VERSION_NUM < 502 -# define lua_rawlen lua_objlen -#endif - using namespace luabind::detail; -namespace luabind { - namespace detail +namespace luabind { namespace detail +{ + LUABIND_API int property_tag(lua_State* L) { - LUABIND_API int property_tag(lua_State* L) - { - lua_pushstring(L, "luabind: property_tag function can't be called"); - lua_error(L); - return 0; - } + lua_pushstring(L, "luabind: property_tag function can't be called"); + lua_error(L); + return 0; } -} +}} luabind::detail::class_rep::class_rep(type_id const& type , const char* name @@ -58,11 +52,6 @@ luabind::detail::class_rep::class_rep(type_id const& type , m_class_type(cpp_class) , m_operator_cache(0) { - shared_init(L); -} - - -void luabind::detail::class_rep::shared_init(lua_State * L) { lua_newtable(L); handle(L, -1).swap(m_table); lua_newtable(L); @@ -70,27 +59,25 @@ void luabind::detail::class_rep::shared_init(lua_State * L) { lua_pop(L, 2); class_registry* r = class_registry::get_registry(L); - // the following line should be equivalent whether or not this is a cpp class assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()"); - lua_rawgeti(L, LUA_REGISTRYINDEX, (m_class_type == cpp_class) ? r->cpp_class() : r->lua_class()); + lua_rawgeti(L, LUA_REGISTRYINDEX, r->cpp_class()); lua_setmetatable(L, -2); lua_pushvalue(L, -1); // duplicate our user data m_self_ref.set(L); - m_instance_metatable = (m_class_type == cpp_class) ? r->cpp_instance() : r->lua_instance(); + m_instance_metatable = r->cpp_instance(); - lua_pushstring(L, "__luabind_cast_graph"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_casts = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); - - lua_pushstring(L, "__luabind_class_id_map"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_classes = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + lua_pushstring(L, "__luabind_cast_graph"); + lua_gettable(L, LUA_REGISTRYINDEX); + m_casts = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); + lua_pushstring(L, "__luabind_class_id_map"); + lua_gettable(L, LUA_REGISTRYINDEX); + m_classes = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); } luabind::detail::class_rep::class_rep(lua_State* L, const char* name) @@ -99,7 +86,31 @@ luabind::detail::class_rep::class_rep(lua_State* L, const char* name) , m_class_type(lua_class) , m_operator_cache(0) { - shared_init(L); + lua_newtable(L); + handle(L, -1).swap(m_table); + lua_newtable(L); + handle(L, -1).swap(m_default_table); + lua_pop(L, 2); + + class_registry* r = class_registry::get_registry(L); + assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()"); + + lua_rawgeti(L, LUA_REGISTRYINDEX, r->lua_class()); + lua_setmetatable(L, -2); + lua_pushvalue(L, -1); // duplicate our user data + m_self_ref.set(L); + + m_instance_metatable = r->lua_instance(); + + lua_pushstring(L, "__luabind_cast_graph"); + lua_gettable(L, LUA_REGISTRYINDEX); + m_casts = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); + + lua_pushstring(L, "__luabind_class_id_map"); + lua_gettable(L, LUA_REGISTRYINDEX); + m_classes = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); } luabind::detail::class_rep::~class_rep() @@ -107,61 +118,61 @@ luabind::detail::class_rep::~class_rep() } // leaves object on lua stack -std::pair +std::pair luabind::detail::class_rep::allocate(lua_State* L) const { const int size = sizeof(object_rep); char* mem = static_cast(lua_newuserdata(L, size)); - return std::pair(mem, (void*)0); + return std::pair(mem, (void*)0); } namespace { - bool super_deprecation_disabled = false; + bool super_deprecation_disabled = false; } // namespace unnamed // this is called as metamethod __call on the class_rep. int luabind::detail::class_rep::constructor_dispatcher(lua_State* L) { - class_rep* cls = static_cast(lua_touserdata(L, 1)); + class_rep* cls = static_cast(lua_touserdata(L, 1)); - int args = lua_gettop(L); + int args = lua_gettop(L); - push_new_instance(L, cls); + push_new_instance(L, cls); - if(super_deprecation_disabled - && cls->get_class_type() == class_rep::lua_class - && !cls->bases().empty()) - { - lua_pushvalue(L, 1); - lua_pushvalue(L, -2); - lua_pushcclosure(L, super_callback, 2); - lua_setglobal(L, "super"); - } + if (super_deprecation_disabled + && cls->get_class_type() == class_rep::lua_class + && !cls->bases().empty()) + { + lua_pushvalue(L, 1); + lua_pushvalue(L, -2); + lua_pushcclosure(L, super_callback, 2); + lua_setglobal(L, "super"); + } - lua_pushvalue(L, -1); - lua_replace(L, 1); + lua_pushvalue(L, -1); + lua_replace(L, 1); - cls->get_table(L); - lua_pushliteral(L, "__init"); - lua_gettable(L, -2); + cls->get_table(L); + lua_pushliteral(L, "__init"); + lua_gettable(L, -2); - lua_insert(L, 1); + lua_insert(L, 1); - lua_pop(L, 1); - lua_insert(L, 1); + lua_pop(L, 1); + lua_insert(L, 1); - lua_call(L, args, 0); + lua_call(L, args, 0); - if(super_deprecation_disabled) - { - lua_pushnil(L); - lua_setglobal(L, "super"); - } + if (super_deprecation_disabled) + { + lua_pushnil(L); + lua_setglobal(L, "super"); + } - return 1; + return 1; } void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep::base_info& binfo) @@ -176,9 +187,11 @@ void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep class_rep* bcrep = binfo.base; // import all static constants - for(const auto& scon : bcrep->m_static_constants) { - int& v = m_static_constants[scon.first]; - v = scon.second; + for (std::map::const_iterator i = bcrep->m_static_constants.begin(); + i != bcrep->m_static_constants.end(); ++i) + { + int& v = m_static_constants[i->first]; + v = i->second; } // also, save the baseclass info to be used for typecasts @@ -187,17 +200,17 @@ void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep LUABIND_API void luabind::disable_super_deprecation() { - super_deprecation_disabled = true; + super_deprecation_disabled = true; } int luabind::detail::class_rep::super_callback(lua_State* L) { int args = lua_gettop(L); - + class_rep* crep = static_cast(lua_touserdata(L, lua_upvalueindex(1))); class_rep* base = crep->bases()[0].base; - if(base->bases().empty()) + if (base->bases().empty()) { lua_pushnil(L); lua_setglobal(L, "super"); @@ -252,7 +265,7 @@ int luabind::detail::class_rep::lua_settable_dispatcher(lua_State* L) lua_rawset(L, -3); crep->m_operator_cache = 0; // invalidate cache - + return 0; } @@ -269,12 +282,12 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) crep->get_default_table(L); lua_pushvalue(L, 2); lua_gettable(L, -2); - if(!lua_isnil(L, -1)) return 1; + if (!lua_isnil(L, -1)) return 1; else lua_pop(L, 2); const char* key = lua_tostring(L, 2); - if(std::strlen(key) != lua_rawlen(L, 2)) + if (std::strlen(key) != lua_strlen(L, 2)) { lua_pushnil(L); return 1; @@ -282,7 +295,7 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) std::map::const_iterator j = crep->m_static_constants.find(key); - if(j != crep->m_static_constants.end()) + if (j != crep->m_static_constants.end()) { lua_pushnumber(L, j->second); return 1; @@ -290,7 +303,14 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) #ifndef LUABIND_NO_ERROR_CHECKING - lua_pushfstring(L, "no static '%s' in class '%s'", key, crep->name()); + { + std::string msg = "no static '"; + msg += key; + msg += "' in class '"; + msg += crep->name(); + msg += "'"; + lua_pushstring(L, msg.c_str()); + } lua_error(L); #endif @@ -300,13 +320,13 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) return 1; } -LUABIND_API bool luabind::detail::is_class_rep(lua_State* L, int index) +bool luabind::detail::is_class_rep(lua_State* L, int index) { - if(lua_getmetatable(L, index) == 0) return false; + if (lua_getmetatable(L, index) == 0) return false; lua_pushstring(L, "__luabind_classrep"); lua_gettable(L, -2); - if(lua_toboolean(L, -1)) + if (lua_toboolean(L, -1)) { lua_pop(L, 2); return true; @@ -318,15 +338,15 @@ LUABIND_API bool luabind::detail::is_class_rep(lua_State* L, int index) void luabind::detail::finalize(lua_State* L, class_rep* crep) { - if(crep->get_class_type() != class_rep::lua_class) return; + if (crep->get_class_type() != class_rep::lua_class) return; - // lua_pushvalue(L, -1); // copy the object ref +// lua_pushvalue(L, -1); // copy the object ref crep->get_table(L); - lua_pushliteral(L, "__finalize"); + lua_pushliteral(L, "__finalize"); lua_gettable(L, -2); lua_remove(L, -2); - if(lua_isnil(L, -1)) + if (lua_isnil(L, -1)) { lua_pop(L, 1); } @@ -336,8 +356,10 @@ void luabind::detail::finalize(lua_State* L, class_rep* crep) lua_call(L, 1, 0); } - for(const auto& baseinfo : crep->bases()) { - if(baseinfo.base) finalize(L, baseinfo.base); + for (std::vector::const_iterator + i = crep->bases().begin(); i != crep->bases().end(); ++i) + { + if (i->base) finalize(L, i->base); } } @@ -345,13 +367,13 @@ void luabind::detail::class_rep::cache_operators(lua_State* L) { m_operator_cache = 0x1; - for(int i = 0; i < number_of_operators; ++i) + for (int i = 0; i < number_of_operators; ++i) { get_table(L); lua_pushstring(L, get_operator_name(i)); lua_rawget(L, -2); - if(lua_isfunction(L, -1)) m_operator_cache |= 1 << (i + 1); + if (lua_isfunction(L, -1)) m_operator_cache |= 1 << (i + 1); lua_pop(L, 2); } @@ -359,11 +381,10 @@ void luabind::detail::class_rep::cache_operators(lua_State* L) bool luabind::detail::class_rep::has_operator_in_lua(lua_State* L, int id) { - if((m_operator_cache & 0x1) == 0) + if ((m_operator_cache & 0x1) == 0) cache_operators(L); const int mask = 1 << (id + 1); return (m_operator_cache & mask) != 0; } - diff --git a/libs/luabind/src/create_class.cpp b/libs/luabind/src/create_class.cpp index 4468374b7..47251ef23 100644 --- a/libs/luabind/src/create_class.cpp +++ b/libs/luabind/src/create_class.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -26,122 +26,114 @@ #include -#if LUA_VERSION_NUM < 502 -# define lua_compare(L, index1, index2, fn) fn(L, index1, index2) -# define LUA_OPEQ lua_equal -# define lua_rawlen lua_objlen -#endif +namespace luabind { namespace detail +{ + namespace + { + // expects two tables on the lua stack: + // 1: destination + // 2: source + void copy_member_table(lua_State* L) + { + lua_pushnil(L); -namespace luabind { - namespace detail { - namespace { - - // expects two tables on the lua stack: - // 1: destination - // 2: source - void copy_member_table(lua_State* L) + while (lua_next(L, -2)) { - lua_pushnil(L); - - while(lua_next(L, -2)) + lua_pushstring(L, "__init"); + if (lua_equal(L, -1, -3)) { - lua_pushstring(L, "__init"); - if(lua_compare(L, -1, -3, LUA_OPEQ)) - { - lua_pop(L, 2); - continue; - } - else lua_pop(L, 1); // __init string - - lua_pushstring(L, "__finalize"); - if(lua_compare(L, -1, -3, LUA_OPEQ)) - { - lua_pop(L, 2); - continue; - } - else lua_pop(L, 1); // __finalize string - - lua_pushvalue(L, -2); // copy key - lua_insert(L, -2); - lua_settable(L, -5); + lua_pop(L, 2); + continue; } + else lua_pop(L, 1); // __init string + + lua_pushstring(L, "__finalize"); + if (lua_equal(L, -1, -3)) + { + lua_pop(L, 2); + continue; + } + else lua_pop(L, 1); // __finalize string + + lua_pushvalue(L, -2); // copy key + lua_insert(L, -2); + lua_settable(L, -5); } - - } // namespace unnamed + } + } - int create_class::stage2(lua_State* L) + int create_class::stage2(lua_State* L) + { + class_rep* crep = static_cast(lua_touserdata(L, lua_upvalueindex(1))); + assert((crep != 0) && "internal error, please report"); + assert((is_class_rep(L, lua_upvalueindex(1))) && "internal error, please report"); + + #ifndef LUABIND_NO_ERROR_CHECKING + + if (!is_class_rep(L, 1)) { - class_rep* crep = static_cast(lua_touserdata(L, lua_upvalueindex(1))); - assert((crep != 0) && "internal error, please report"); - assert((is_class_rep(L, lua_upvalueindex(1))) && "internal error, please report"); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if(!is_class_rep(L, 1)) - { - lua_pushstring(L, "expected class to derive from or a newline"); - lua_error(L); - } - -#endif - - class_rep* base = static_cast(lua_touserdata(L, 1)); - class_rep::base_info binfo; - - binfo.pointer_offset = 0; - binfo.base = base; - crep->add_base_class(binfo); - - // copy base class members - - crep->get_table(L); - base->get_table(L); - copy_member_table(L); - - crep->get_default_table(L); - base->get_default_table(L); - copy_member_table(L); - - crep->set_type(base->type()); - - return 0; + lua_pushstring(L, "expected class to derive from or a newline"); + lua_error(L); } - int create_class::stage1(lua_State* L) + #endif + + class_rep* base = static_cast(lua_touserdata(L, 1)); + class_rep::base_info binfo; + + binfo.pointer_offset = 0; + binfo.base = base; + crep->add_base_class(binfo); + + // copy base class members + + crep->get_table(L); + base->get_table(L); + copy_member_table(L); + + crep->get_default_table(L); + base->get_default_table(L); + copy_member_table(L); + + crep->set_type(base->type()); + + return 0; + } + + int create_class::stage1(lua_State* L) + { + + #ifndef LUABIND_NO_ERROR_CHECKING + + if (lua_gettop(L) != 1 || lua_type(L, 1) != LUA_TSTRING || lua_isnumber(L, 1)) { - -#ifndef LUABIND_NO_ERROR_CHECKING - - if(lua_gettop(L) != 1 || lua_type(L, 1) != LUA_TSTRING || lua_isnumber(L, 1)) - { - lua_pushstring(L, "invalid construct, expected class name"); - lua_error(L); - } - - if(std::strlen(lua_tostring(L, 1)) != lua_rawlen(L, 1)) - { - lua_pushstring(L, "luabind does not support class names with extra nulls"); - lua_error(L); - } - -#endif - - const char* name = lua_tostring(L, 1); - - void* c = lua_newuserdata(L, sizeof(class_rep)); - new(c) class_rep(L, name); - - // make the class globally available - lua_pushvalue(L, -1); - lua_setglobal(L, name); - - // also add it to the closure as return value - lua_pushcclosure(L, &stage2, 1); - - return 1; + lua_pushstring(L, "invalid construct, expected class name"); + lua_error(L); } - } // namespace detail -} // namespace luabind + if (std::strlen(lua_tostring(L, 1)) != lua_strlen(L, 1)) + { + lua_pushstring(L, "luabind does not support class names with extra nulls"); + lua_error(L); + } + + #endif + + const char* name = lua_tostring(L, 1); + + void* c = lua_newuserdata(L, sizeof(class_rep)); + new(c) class_rep(L, name); + + // make the class globally available + lua_pushvalue(L, -1); + lua_setglobal(L, name); + + // also add it to the closure as return value + lua_pushcclosure(L, &stage2, 1); + + return 1; + } + +}} diff --git a/libs/luabind/src/error.cpp b/libs/luabind/src/error.cpp index 07e352026..73bbf5c62 100644 --- a/libs/luabind/src/error.cpp +++ b/libs/luabind/src/error.cpp @@ -23,32 +23,11 @@ #define LUABIND_BUILDING #include -#ifndef LUA_INCLUDE_HPP_INCLUDED -#include -#endif -namespace luabind { +namespace luabind +{ -#ifndef LUABIND_NO_EXCEPTIONS - error::error(lua_State* L) - { - const char* message = lua_tostring(L, -1); - - if(message) - { - m_message = message; - } - - lua_pop(L, 1); - } - - - const char* error::what() const throw() - { - return m_message.c_str(); - } -#endif namespace { pcall_callback_fun pcall_callback = 0; @@ -61,6 +40,9 @@ namespace luabind { #ifdef LUABIND_NO_EXCEPTIONS + typedef void(*error_callback_fun)(lua_State*); + typedef void(*cast_failed_callback_fun)(lua_State*, type_id const&); + void set_error_callback(error_callback_fun e) { error_callback = e; @@ -94,4 +76,3 @@ namespace luabind { } } - diff --git a/libs/luabind/src/exception_handler.cpp b/libs/luabind/src/exception_handler.cpp index d4ee7764a..555d3858c 100644 --- a/libs/luabind/src/exception_handler.cpp +++ b/libs/luabind/src/exception_handler.cpp @@ -4,93 +4,84 @@ #define LUABIND_BUILDING -#include - -#include // for LUABIND_API +#include +#include +#include +#include #ifndef LUABIND_NO_EXCEPTIONS -#include // for error -#include // for exception_handler_base -#include // for exception -#include // for logic_error, runtime_error +namespace luabind { namespace detail { -namespace luabind { - namespace detail { +namespace +{ + exception_handler_base* handler_chain = 0; - namespace { + void push_exception_string(lua_State* L, char const* exception, char const* what) + { + lua_pushstring(L, exception); + lua_pushstring(L, ": '"); + lua_pushstring(L, what); + lua_pushstring(L, "'"); + lua_concat(L, 4); + } +} - exception_handler_base* handler_chain = 0; +void exception_handler_base::try_next(lua_State* L) const +{ + if (next) + next->handle(L); + else + throw; +} - void push_exception_string(lua_State* L, char const* exception, char const* what) - { - lua_pushstring(L, exception); - lua_pushstring(L, ": '"); - lua_pushstring(L, what); - lua_pushstring(L, "'"); - lua_concat(L, 4); - } - } +LUABIND_API void handle_exception_aux(lua_State* L) +{ + try + { + if (handler_chain) + handler_chain->handle(L); + else + throw; + } + catch (error const&) + {} + catch (std::logic_error const& e) + { + push_exception_string(L, "std::logic_error", e.what()); + } + catch (std::runtime_error const& e) + { + push_exception_string(L, "std::runtime_error", e.what()); + } + catch (std::exception const& e) + { + push_exception_string(L, "std::exception", e.what()); + } + catch (char const* str) + { + push_exception_string(L, "c-string", str); + } + catch (...) + { + lua_pushstring(L, "Unknown C++ exception"); + } +} - void exception_handler_base::try_next(lua_State* L) const - { - if(next) - next->handle(L); - else - throw; - } +LUABIND_API void register_exception_handler(exception_handler_base* handler) +{ + if (!handler_chain) handler_chain = handler; + else + { + exception_handler_base* p = handler_chain; - LUABIND_API void handle_exception_aux(lua_State* L) - { - try - { - if(handler_chain) - handler_chain->handle(L); - else - throw; - } - catch(error const&) - { - // is always thrown in the context where an error message was already pushed to the lua stack. - } - catch(std::logic_error const& e) - { - push_exception_string(L, "std::logic_error", e.what()); - } - catch(std::runtime_error const& e) - { - push_exception_string(L, "std::runtime_error", e.what()); - } - catch(std::exception const& e) - { - push_exception_string(L, "std::exception", e.what()); - } - catch(char const* str) - { - push_exception_string(L, "c-string", str); - } - catch(...) - { - lua_pushstring(L, "Unknown C++ exception"); - } - } + for (; p->next; p = p->next); - LUABIND_API void register_exception_handler(exception_handler_base* handler) - { - if(!handler_chain) handler_chain = handler; - else - { - exception_handler_base* p = handler_chain; + handler->next = 0; + p->next = handler; + } +} - for(; p->next; p = p->next); - - handler->next = 0; - p->next = handler; - } - } - - } // namespace detail -} // namespace luabind +}} // namespace luabind::detail #endif // LUABIND_NO_EXCEPTIONS - diff --git a/libs/luabind/src/function.cpp b/libs/luabind/src/function.cpp index cacaf777c..20569b2bd 100644 --- a/libs/luabind/src/function.cpp +++ b/libs/luabind/src/function.cpp @@ -4,139 +4,133 @@ #define LUABIND_BUILDING -#include #include -#include -#include -namespace luabind { - namespace detail { +namespace luabind { namespace detail { - namespace { +namespace +{ - int function_destroy(lua_State* L) - { - function_object* fn = *(function_object**)lua_touserdata(L, 1); - delete fn; - return 0; - } + int function_destroy(lua_State* L) + { + function_object* fn = *(function_object**)lua_touserdata(L, 1); + delete fn; + return 0; + } - void push_function_metatable(lua_State* L) - { - lua_pushstring(L, "luabind.function"); - lua_rawget(L, LUA_REGISTRYINDEX); + void push_function_metatable(lua_State* L) + { + lua_pushstring(L, "luabind.function"); + lua_rawget(L, LUA_REGISTRYINDEX); - if(lua_istable(L, -1)) - return; + if (lua_istable(L, -1)) + return; - lua_pop(L, 1); + lua_pop(L, 1); - lua_newtable(L); + lua_newtable(L); - lua_pushstring(L, "__gc"); - lua_pushcclosure(L, &function_destroy, 0); - lua_rawset(L, -3); + lua_pushstring(L, "__gc"); + lua_pushcclosure(L, &function_destroy, 0); + lua_rawset(L, -3); - lua_pushstring(L, "luabind.function"); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - } + lua_pushstring(L, "luabind.function"); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } - // A pointer to this is used as a tag value to identify functions exported - // by luabind. - int function_tag = 0; + // A pointer to this is used as a tag value to identify functions exported + // by luabind. + int function_tag = 0; - } // namespace unnamed +} // namespace unnamed - LUABIND_API bool is_luabind_function(lua_State* L, int index) - { - if(!lua_getupvalue(L, index, 2)) - return false; - bool result = lua_touserdata(L, -1) == &function_tag; - lua_pop(L, 1); - return result; - } +LUABIND_API bool is_luabind_function(lua_State* L, int index) +{ + if (!lua_getupvalue(L, index, 2)) + return false; + bool result = lua_touserdata(L, -1) == &function_tag; + lua_pop(L, 1); + return result; +} - namespace - { +namespace +{ - inline bool is_luabind_function(object const& obj) - { - obj.push(obj.interpreter()); - bool result = detail::is_luabind_function(obj.interpreter(), -1); - lua_pop(obj.interpreter(), 1); - return result; - } + inline bool is_luabind_function(object const& obj) + { + obj.push(obj.interpreter()); + bool result = detail::is_luabind_function(obj.interpreter(), -1); + lua_pop(obj.interpreter(), 1); + return result; + } - } // namespace unnamed +} // namespace unnamed - LUABIND_API void add_overload( - object const& context, char const* name, object const& fn) - { - function_object* f = *touserdata(std::get<1>(getupvalue(fn, 1))); - f->name = name; +LUABIND_API void add_overload( + object const& context, char const* name, object const& fn) +{ + function_object* f = *touserdata(getupvalue(fn, 1)); + f->name = name; - if(object overloads = context[name]) - { - if(is_luabind_function(overloads) && is_luabind_function(fn)) - { - f->next = *touserdata(std::get<1>(getupvalue(overloads, 1))); - f->keepalive = overloads; - } - } + if (object overloads = context[name]) + { + if (is_luabind_function(overloads) && is_luabind_function(fn)) + { + f->next = *touserdata(getupvalue(overloads, 1)); + f->keepalive = overloads; + } + } - context[name] = fn; - } + context[name] = fn; +} - LUABIND_API object make_function_aux(lua_State* L, function_object* impl) - { - void* storage = lua_newuserdata(L, sizeof(function_object*)); - push_function_metatable(L); - *(function_object**)storage = impl; - lua_setmetatable(L, -2); +LUABIND_API object make_function_aux(lua_State* L, function_object* impl) +{ + void* storage = lua_newuserdata(L, sizeof(function_object*)); + push_function_metatable(L); + *(function_object**)storage = impl; + lua_setmetatable(L, -2); - lua_pushlightuserdata(L, &function_tag); - lua_pushcclosure(L, impl->entry, 2); - stack_pop pop(L, 1); + lua_pushlightuserdata(L, &function_tag); + lua_pushcclosure(L, impl->entry, 2); + stack_pop pop(L, 1); - return object(from_stack(L, -1)); - } + return object(from_stack(L, -1)); +} - void invoke_context::format_error( - lua_State* L, function_object const* overloads) const - { - char const* function_name = - overloads->name.empty() ? "" : overloads->name.c_str(); +void invoke_context::format_error( + lua_State* L, function_object const* overloads) const +{ + char const* function_name = + overloads->name.empty() ? "" : overloads->name.c_str(); - if(candidate_index == 0) - { - int stacksize = lua_gettop(L); - lua_pushstring(L, "No matching overload found, candidates:\n"); - int count = 0; - for(function_object const* f = overloads; f != 0; f = f->next) - { - if(count != 0) - lua_pushstring(L, "\n"); - f->format_signature(L, function_name); - ++count; - } - lua_concat(L, lua_gettop(L) - stacksize); - } - else - { - // Ambiguous - int stacksize = lua_gettop(L); - lua_pushstring(L, "Ambiguous, candidates:\n"); - for(int i = 0; i < candidate_index; ++i) - { - if(i != 0) - lua_pushstring(L, "\n"); - candidates[i]->format_signature(L, function_name); - } - lua_concat(L, lua_gettop(L) - stacksize); - } - } + if (candidate_index == 0) + { + lua_pushstring(L, "No matching overload found, candidates:\n"); + int count = 0; + for (function_object const* f = overloads; f != 0; f = f->next) + { + if (count != 0) + lua_pushstring(L, "\n"); + f->format_signature(L, function_name); + ++count; + } + lua_concat(L, count * 2); + } + else + { + // Ambiguous + lua_pushstring(L, "Ambiguous, candidates:\n"); + for (int i = 0; i < candidate_index; ++i) + { + if (i != 0) + lua_pushstring(L, "\n"); + candidates[i]->format_signature(L, function_name); + } + lua_concat(L, candidate_index * 2); + } +} - } // namespace detail -} // namespace luabind +}} // namespace luabind::detail diff --git a/libs/luabind/src/function_introspection.cpp b/libs/luabind/src/function_introspection.cpp deleted file mode 100644 index aed60e40e..000000000 --- a/libs/luabind/src/function_introspection.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/** - @file - @brief Implementation - - @date 2012 - - @author - Ryan Pavlik - and - http://academic.cleardefinition.com/ - Iowa State University Virtual Reality Applications Center - Human-Computer Interaction Graduate Program -*/ - -// Copyright Iowa State University 2012. -// 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. - -#define LUABIND_BUILDING - -// Internal Includes -#include -#include // for LUABIND_API - -#include -#include - -#include // for stack_pop -#include // for def, is_luabind_function -#include // for function_object -#include // for argument, object, etc -#include // for from_stack -#include // for module, module_, scope -#include -#include - -// Library/third-party includes -// - none - -// Standard includes -#include // for string -#include // for NULL - -namespace luabind { - - namespace { - detail::function_object* get_function_object(argument const& fn) { - lua_State * L = fn.interpreter(); - { - fn.push(L); - detail::stack_pop pop(L, 1); - if(!detail::is_luabind_function(L, -1)) { - return NULL; - } - } - return *touserdata(std::get<1>(getupvalue(fn, 1))); - } - - std::string get_function_name(argument const& fn) { - detail::function_object * f = get_function_object(fn); - if(!f) { - return ""; - } - return f->name; - } - - object get_function_overloads(argument const& fn) { - lua_State * L = fn.interpreter(); - detail::function_object * fobj = get_function_object(fn); - if(!fobj) { - return object(); - } - object overloadTable(newtable(L)); - int count = 1; - const char* function_name = fobj->name.c_str(); - for(detail::function_object const* f = fobj; f != 0; f = f->next) - { - f->format_signature(L, function_name); - detail::stack_pop pop(L, 1); - overloadTable[count] = object(from_stack(L, -1)); - - ++count; - } - /// @todo - - return overloadTable; - } - - } - - LUABIND_API int bind_function_introspection(lua_State * L) { - module(L, "function_info")[ - def("get_function_overloads", &get_function_overloads), - def("get_function_name", &get_function_name) - ]; - return 0; - } - -} // end of namespace luabind - diff --git a/libs/luabind/src/headertest.cpp b/libs/luabind/src/headertest.cpp deleted file mode 100644 index 2061691f6..000000000 --- a/libs/luabind/src/headertest.cpp +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/libs/luabind/src/inheritance.cpp b/libs/luabind/src/inheritance.cpp index a3de45859..2e2ec902a 100644 --- a/libs/luabind/src/inheritance.cpp +++ b/libs/luabind/src/inheritance.cpp @@ -8,224 +8,251 @@ #include #include #include -#include +#include +#include +#include +#include #include #include -namespace luabind { - namespace detail { +namespace luabind { namespace detail { - class_id const class_id_map::local_id_base = std::numeric_limits::max() / 2; +class_id const class_id_map::local_id_base = + std::numeric_limits::max() / 2; - namespace - { +namespace +{ - struct edge - { - edge(class_id target, cast_function cast) - : target(target), cast(cast) - {} + struct edge + { + edge(class_id target, cast_function cast) + : target(target) + , cast(cast) + {} - class_id target; - cast_function cast; - }; + class_id target; + cast_function cast; + }; - bool operator<(edge const& x, edge const& y) - { - return x.target < y.target; - } + bool operator<(edge const& x, edge const& y) + { + return x.target < y.target; + } - struct vertex - { - vertex(class_id id) - : id(id) - {} + struct vertex + { + vertex(class_id id) + : id(id) + {} - class_id id; - std::vector edges; - }; + class_id id; + std::vector edges; + }; - using cache_entry = std::pair; + typedef std::pair cache_entry; - class cache - { - public: - static constexpr std::ptrdiff_t unknown = std::numeric_limits::max(); - static constexpr std::ptrdiff_t invalid = unknown - 1; + class cache + { + public: + static std::ptrdiff_t const unknown; + static std::ptrdiff_t const invalid; - cache_entry get(class_id src, class_id target, class_id dynamic_id, std::ptrdiff_t object_offset) const; + cache_entry get( + class_id src, class_id target, class_id dynamic_id + , std::ptrdiff_t object_offset) const; - void put(class_id src, class_id target, class_id dynamic_id, std::ptrdiff_t object_offset, std::ptrdiff_t offset, int distance); - void invalidate(); + void put( + class_id src, class_id target, class_id dynamic_id + , std::ptrdiff_t object_offset + , std::size_t distance, std::ptrdiff_t offset); - private: - using key_type = std::tuple; - using map_type = std::map; - map_type m_cache; - }; + void invalidate(); - constexpr std::ptrdiff_t cache::unknown; - constexpr std::ptrdiff_t cache::invalid; + private: + typedef boost::tuple< + class_id, class_id, class_id, std::ptrdiff_t> key_type; + typedef std::map map_type; + map_type m_cache; + }; - cache_entry cache::get(class_id src, class_id target, class_id dynamic_id, std::ptrdiff_t object_offset) const - { - map_type::const_iterator i = m_cache.find( - key_type(src, target, dynamic_id, object_offset)); - return i != m_cache.end() ? i->second : cache_entry(unknown, -1); - } + std::ptrdiff_t const cache::unknown = + std::numeric_limits::max(); + std::ptrdiff_t const cache::invalid = cache::unknown - 1; - void cache::put(class_id src, class_id target, class_id dynamic_id, std::ptrdiff_t object_offset, std::ptrdiff_t offset, int distance) - { - m_cache.insert(std::make_pair(key_type(src, target, dynamic_id, object_offset), cache_entry(offset, distance))); - } + cache_entry cache::get( + class_id src, class_id target, class_id dynamic_id + , std::ptrdiff_t object_offset) const + { + map_type::const_iterator i = m_cache.find( + key_type(src, target, dynamic_id, object_offset)); + return i != m_cache.end() ? i->second : cache_entry(unknown, -1); + } - void cache::invalidate() - { - m_cache.clear(); - } + void cache::put( + class_id src, class_id target, class_id dynamic_id + , std::ptrdiff_t object_offset, std::size_t distance, std::ptrdiff_t offset) + { + m_cache.insert(std::make_pair( + key_type(src, target, dynamic_id, object_offset) + , cache_entry(offset, distance) + )); + } - } // namespace anonymous + void cache::invalidate() + { + m_cache.clear(); + } - class cast_graph::impl - { - public: - std::pair cast( - void* p, class_id src, class_id target - , class_id dynamic_id, void const* dynamic_ptr) const; - void insert(class_id src, class_id target, cast_function cast); +} // namespace unnamed - private: - std::vector m_vertices; - mutable cache m_cache; - }; +class cast_graph::impl +{ +public: + std::pair cast( + void* p, class_id src, class_id target + , class_id dynamic_id, void const* dynamic_ptr) const; + void insert(class_id src, class_id target, cast_function cast); - namespace - { +private: + std::vector m_vertices; + mutable cache m_cache; +}; - struct queue_entry - { - queue_entry(void* p, class_id vertex_id, int distance) - : p(p) - , vertex_id(vertex_id) - , distance(distance) - {} +namespace +{ - void* p; - class_id vertex_id; - int distance; - }; + struct queue_entry + { + queue_entry(void* p, class_id vertex_id, int distance) + : p(p) + , vertex_id(vertex_id) + , distance(distance) + {} - } // namespace anonymous + void* p; + class_id vertex_id; + int distance; + }; - std::pair cast_graph::impl::cast(void* const p, class_id src, class_id target, class_id dynamic_id, void const* dynamic_ptr) const - { - if(src == target) return std::make_pair(p, 0); - if(src >= m_vertices.size() || target >= m_vertices.size()) return std::pair((void*)0, -1); +} // namespace unnamed - std::ptrdiff_t const object_offset = (char const*)dynamic_ptr - (char const*)p; - cache_entry cached = m_cache.get(src, target, dynamic_id, object_offset); +std::pair cast_graph::impl::cast( + void* const p, class_id src, class_id target + , class_id dynamic_id, void const* dynamic_ptr) const +{ + if (src == target) + return std::make_pair(p, 0); - if(cached.first != cache::unknown) - { - if(cached.first == cache::invalid) - return std::pair((void*)0, -1); - return std::make_pair((char*)p + cached.first, cached.second); - } + if (src >= m_vertices.size() || target >= m_vertices.size()) + return std::pair((void*)0, -1); - std::queue q; - q.push(queue_entry(p, src, 0)); + std::ptrdiff_t const object_offset = + (char const*)dynamic_ptr - (char const*)p; - // Original source used boost::dynamic_bitset but didn't make use - // of its advanced capability of set operations, that's why I think - // it's safe to use a std::vector here. + cache_entry cached = m_cache.get(src, target, dynamic_id, object_offset); - std::vector visited(m_vertices.size(), false); + if (cached.first != cache::unknown) + { + if (cached.first == cache::invalid) + return std::pair((void*)0, -1); + return std::make_pair((char*)p + cached.first, cached.second); + } - while(!q.empty()) - { - queue_entry const qe = q.front(); - q.pop(); + std::queue q; + q.push(queue_entry(p, src, 0)); - visited[qe.vertex_id] = true; - vertex const& v = m_vertices[qe.vertex_id]; + boost::dynamic_bitset<> visited(m_vertices.size()); - if(v.id == target) - { - m_cache.put( - src, target, dynamic_id, object_offset - , (char*)qe.p - (char*)p, qe.distance - ); + while (!q.empty()) + { + queue_entry const qe = q.front(); + q.pop(); - return std::make_pair(qe.p, qe.distance); - } + visited[qe.vertex_id] = true; + vertex const& v = m_vertices[qe.vertex_id]; - for(auto const& e : v.edges) { - if(visited[e.target]) - continue; - if(void* casted = e.cast(qe.p)) - q.push(queue_entry(casted, e.target, qe.distance + 1)); - } - } + if (v.id == target) + { + m_cache.put( + src, target, dynamic_id, object_offset + , qe.distance, (char*)qe.p - (char*)p + ); - m_cache.put(src, target, dynamic_id, object_offset, cache::invalid, -1); + return std::make_pair(qe.p, qe.distance); + } - return std::pair((void*)0, -1); - } + BOOST_FOREACH(edge const& e, v.edges) + { + if (visited[e.target]) + continue; + if (void* casted = e.cast(qe.p)) + q.push(queue_entry(casted, e.target, qe.distance + 1)); + } + } - void cast_graph::impl::insert(class_id src, class_id target, cast_function cast) - { - class_id const max_id = std::max(src, target); + m_cache.put(src, target, dynamic_id, object_offset, cache::invalid, -1); - if(max_id >= m_vertices.size()) - { - m_vertices.reserve(max_id + 1); - for(class_id i = m_vertices.size(); i < max_id + 1; ++i) - m_vertices.push_back(vertex(i)); - } + return std::pair((void*)0, -1); +} - std::vector& edges = m_vertices[src].edges; +void cast_graph::impl::insert( + class_id src, class_id target, cast_function cast) +{ + class_id const max_id = std::max(src, target); - std::vector::iterator i = std::lower_bound( - edges.begin(), edges.end(), edge(target, 0) - ); + if (max_id >= m_vertices.size()) + { + m_vertices.reserve(max_id + 1); + for (class_id i = m_vertices.size(); i < max_id + 1; ++i) + m_vertices.push_back(vertex(i)); + } - if(i == edges.end() || i->target != target) - { - edges.insert(i, edge(target, cast)); - m_cache.invalidate(); - } - } + std::vector& edges = m_vertices[src].edges; - std::pair cast_graph::cast(void* p, class_id src, class_id target, class_id dynamic_id, void const* dynamic_ptr) const - { - return m_impl->cast(p, src, target, dynamic_id, dynamic_ptr); - } + std::vector::iterator i = std::lower_bound( + edges.begin(), edges.end(), edge(target, 0) + ); - void cast_graph::insert(class_id src, class_id target, cast_function cast) - { - m_impl->insert(src, target, cast); - } + if (i == edges.end() || i->target != target) + { + edges.insert(i, edge(target, cast)); + m_cache.invalidate(); + } +} - cast_graph::cast_graph() - : m_impl(new impl) - {} +std::pair cast_graph::cast( + void* p, class_id src, class_id target + , class_id dynamic_id, void const* dynamic_ptr) const +{ + return m_impl->cast(p, src, target, dynamic_id, dynamic_ptr); +} - cast_graph::~cast_graph() - {} +void cast_graph::insert(class_id src, class_id target, cast_function cast) +{ + m_impl->insert(src, target, cast); +} - LUABIND_API class_id allocate_class_id(type_id const& cls) - { - using map_type = std::map; +cast_graph::cast_graph() + : m_impl(new impl) +{} - static map_type registered; - static class_id id = 0; +cast_graph::~cast_graph() +{} - std::pair inserted = registered.insert(std::make_pair(cls, id)); - if(inserted.second) ++id; +LUABIND_API class_id allocate_class_id(type_id const& cls) +{ + typedef std::map map_type; - return inserted.first->second; - } + static map_type registered; + static class_id id = 0; - } // namespace detail -} // namespace luabind + std::pair inserted = registered.insert( + std::make_pair(cls, id)); + if (inserted.second) + ++id; + + return inserted.first->second; +} + +}} // namespace luabind::detail diff --git a/libs/luabind/src/link_compatibility.cpp b/libs/luabind/src/link_compatibility.cpp index 60a02f1c6..515e0e392 100644 --- a/libs/luabind/src/link_compatibility.cpp +++ b/libs/luabind/src/link_compatibility.cpp @@ -24,21 +24,20 @@ #include -namespace luabind { - namespace detail { +namespace luabind { namespace detail +{ #ifdef LUABIND_NOT_THREADSAFE - void not_threadsafe_defined_conflict() {} + void not_threadsafe_defined_conflict() {} #else - void not_threadsafe_not_defined_conflict() {} + void not_threadsafe_not_defined_conflict() {} #endif #ifdef LUABIND_NO_ERROR_CHECKING - void no_error_checking_defined_conflict() {} + void no_error_checking_defined_conflict() {} #else - void no_error_checking_not_defined_conflict() {} + void no_error_checking_not_defined_conflict() {} #endif - } -} +}} diff --git a/libs/luabind/src/object_rep.cpp b/libs/luabind/src/object_rep.cpp index 4d5f39bdf..afc6d9800 100644 --- a/libs/luabind/src/object_rep.cpp +++ b/libs/luabind/src/object_rep.cpp @@ -24,243 +24,250 @@ #include #include +#include -#if LUA_VERSION_NUM < 502 -# define lua_getuservalue lua_getfenv -# define lua_setuservalue lua_setfenv -#endif +namespace luabind { namespace detail +{ -namespace luabind { - namespace detail { - - // dest is a function that is called to delete the c++ object this struct holds - object_rep::object_rep(instance_holder* instance, class_rep* crep) - : m_instance(instance) - , m_classrep(crep) - { - } - - object_rep::~object_rep() - { - if(!m_instance) - return; - m_instance->~instance_holder(); - deallocate(m_instance); - } - - void object_rep::add_dependency(lua_State* L, int index) - { - if(!m_dependency_ref.is_valid()) - { - lua_newtable(L); - m_dependency_ref.set(L); - } - m_dependency_ref.get(L); - - lua_pushvalue(L, index); - lua_pushnumber(L, 0); - lua_rawset(L, -3); - lua_pop(L, 1); - } - - int destroy_instance(lua_State* L) - { - object_rep* instance = static_cast(lua_touserdata(L, 1)); - - lua_pushstring(L, "__finalize"); - lua_gettable(L, 1); - - if(lua_isnil(L, -1)) - { - lua_pop(L, 1); - } - else - { - lua_pushvalue(L, 1); - lua_call(L, 1, 0); - } - - instance->~object_rep(); - - lua_pushnil(L); - lua_setmetatable(L, 1); - return 0; - } - - namespace - { - - int set_instance_value(lua_State* L) - { - lua_getuservalue(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - - if(lua_isnil(L, -1) && lua_getmetatable(L, -2)) - { - lua_pushvalue(L, 2); - lua_rawget(L, -2); - lua_replace(L, -3); - lua_pop(L, 1); - } - - if(lua_tocfunction(L, -1) == &property_tag) - { - // this member is a property, extract the "set" function and call it. - lua_getupvalue(L, -1, 2); - - if(lua_isnil(L, -1)) - { - lua_pushfstring(L, "property '%s' is read only", lua_tostring(L, 2)); - lua_error(L); - } - - lua_pushvalue(L, 1); - lua_pushvalue(L, 3); - lua_call(L, 2, 0); - return 0; - } - - lua_pop(L, 1); - - if(!lua_getmetatable(L, 4)) - { - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setuservalue(L, 1); - lua_pushvalue(L, 4); - lua_setmetatable(L, -2); - } - else - { - lua_pop(L, 1); - } - - lua_pushvalue(L, 2); - lua_pushvalue(L, 3); - lua_rawset(L, -3); - - return 0; - } - - int get_instance_value(lua_State* L) - { - lua_getuservalue(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - - if(lua_isnil(L, -1) && lua_getmetatable(L, -2)) - { - lua_pushvalue(L, 2); - lua_rawget(L, -2); - } - - if(lua_tocfunction(L, -1) == &property_tag) - { - // this member is a property, extract the "get" function and call it. - lua_getupvalue(L, -1, 1); - lua_pushvalue(L, 1); - lua_call(L, 1, 1); - } - - return 1; - } - - int dispatch_operator(lua_State* L) - { - for(int i = 0; i < 2; ++i) - { - if(get_instance(L, 1 + i)) - { - int nargs = lua_gettop(L); - - lua_pushvalue(L, lua_upvalueindex(1)); - lua_gettable(L, 1 + i); - - if(lua_isnil(L, -1)) - { - lua_pop(L, 1); - continue; - } - - lua_insert(L, 1); // move the function to the bottom - - nargs = lua_toboolean(L, lua_upvalueindex(2)) ? 1 : nargs; - - if(lua_toboolean(L, lua_upvalueindex(2))) // remove trailing nil - lua_remove(L, 3); - - lua_call(L, nargs, 1); - return 1; - } - } - - lua_pop(L, lua_gettop(L)); - lua_pushstring(L, "No such operator defined"); - lua_error(L); - - return 0; - } - - } // namespace unnamed - - LUABIND_API void push_instance_metatable(lua_State* L) - { - lua_newtable(L); - - // This is used as a tag to determine if a userdata is a luabind - // instance. We use a numeric key and a cclosure for fast comparison. - lua_pushnumber(L, 1); - lua_pushcclosure(L, get_instance_value, 0); - lua_rawset(L, -3); - - lua_pushcclosure(L, destroy_instance, 0); - lua_setfield(L, -2, "__gc"); - - lua_pushcclosure(L, get_instance_value, 0); - lua_setfield(L, -2, "__index"); - - lua_pushcclosure(L, set_instance_value, 0); - lua_setfield(L, -2, "__newindex"); - - for(int op = 0; op < number_of_operators; ++op) - { - lua_pushstring(L, get_operator_name(op)); - lua_pushvalue(L, -1); - lua_pushboolean(L, op == op_unm || op == op_len); - lua_pushcclosure(L, &dispatch_operator, 2); - lua_settable(L, -3); - } - } - - LUABIND_API object_rep* get_instance(lua_State* L, int index) - { - object_rep* result = static_cast(lua_touserdata(L, index)); - - if(!result || !lua_getmetatable(L, index)) - return 0; - - lua_rawgeti(L, -1, 1); - - if(lua_tocfunction(L, -1) != &get_instance_value) - result = 0; - - lua_pop(L, 2); - - return result; - } - - LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls) - { - void* storage = lua_newuserdata(L, sizeof(object_rep)); - object_rep* result = new (storage) object_rep(0, cls); - cls->get_table(L); - lua_setuservalue(L, -2); - lua_rawgeti(L, LUA_REGISTRYINDEX, cls->metatable_ref()); - lua_setmetatable(L, -2); - return result; - } + // dest is a function that is called to delete the c++ object this struct holds + object_rep::object_rep(instance_holder* instance, class_rep* crep) + : m_instance(instance) + , m_classrep(crep) + , m_dependency_cnt(0) + {} + object_rep::~object_rep() + { + if (!m_instance) + return; + m_instance->~instance_holder(); + deallocate(m_instance); } -} + + void object_rep::add_dependency(lua_State* L, int index) + { + assert(m_dependency_cnt < sizeof(object_rep)); + + void* key = (char*)this + m_dependency_cnt; + + lua_pushlightuserdata(L, key); + lua_pushvalue(L, index); + lua_rawset(L, LUA_REGISTRYINDEX); + + ++m_dependency_cnt; + } + + void object_rep::release_dependency_refs(lua_State* L) + { + for (std::size_t i = 0; i < m_dependency_cnt; ++i) + { + void* key = (char*)this + i; + lua_pushlightuserdata(L, key); + lua_pushnil(L); + lua_rawset(L, LUA_REGISTRYINDEX); + } + } + + int destroy_instance(lua_State* L) + { + object_rep* instance = static_cast(lua_touserdata(L, 1)); + + lua_pushstring(L, "__finalize"); + lua_gettable(L, 1); + + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + } + else + { + lua_pushvalue(L, 1); + lua_call(L, 1, 0); + } + + instance->release_dependency_refs(L); + instance->~object_rep(); + return 0; + } + + namespace + { + + int set_instance_value(lua_State* L) + { + lua_getfenv(L, 1); + lua_pushvalue(L, 2); + lua_rawget(L, -2); + + if (lua_isnil(L, -1) && lua_getmetatable(L, -2)) + { + lua_pushvalue(L, 2); + lua_rawget(L, -2); + lua_replace(L, -3); + lua_pop(L, 1); + } + + if (lua_tocfunction(L, -1) == &property_tag) + { + // this member is a property, extract the "set" function and call it. + lua_getupvalue(L, -1, 2); + + if (lua_isnil(L, -1)) + { + lua_pushfstring(L, "property '%s' is read only", lua_tostring(L, 2)); + lua_error(L); + } + + lua_pushvalue(L, 1); + lua_pushvalue(L, 3); + lua_call(L, 2, 0); + return 0; + } + + lua_pop(L, 1); + + if (!lua_getmetatable(L, 4)) + { + lua_newtable(L); + lua_pushvalue(L, -1); + lua_setfenv(L, 1); + lua_pushvalue(L, 4); + lua_setmetatable(L, -2); + } + else + { + lua_pop(L, 1); + } + + lua_pushvalue(L, 2); + lua_pushvalue(L, 3); + lua_rawset(L, -3); + + return 0; + } + + int get_instance_value(lua_State* L) + { + lua_getfenv(L, 1); + lua_pushvalue(L, 2); + lua_rawget(L, -2); + + if (lua_isnil(L, -1) && lua_getmetatable(L, -2)) + { + lua_pushvalue(L, 2); + lua_rawget(L, -2); + } + + if (lua_tocfunction(L, -1) == &property_tag) + { + // this member is a property, extract the "get" function and call it. + lua_getupvalue(L, -1, 1); + lua_pushvalue(L, 1); + lua_call(L, 1, 1); + } + + return 1; + } + + int dispatch_operator(lua_State* L) + { + for (int i = 0; i < 2; ++i) + { + if (get_instance(L, 1 + i)) + { + int nargs = lua_gettop(L); + + lua_pushvalue(L, lua_upvalueindex(1)); + lua_gettable(L, 1 + i); + + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + continue; + } + + lua_insert(L, 1); // move the function to the bottom + + nargs = lua_toboolean(L, lua_upvalueindex(2)) ? 1 : nargs; + + if (lua_toboolean(L, lua_upvalueindex(2))) // remove trailing nil + lua_remove(L, 3); + + lua_call(L, nargs, 1); + return 1; + } + } + + lua_pop(L, lua_gettop(L)); + lua_pushstring(L, "No such operator defined"); + lua_error(L); + + return 0; + } + + } // namespace unnamed + + LUABIND_API void push_instance_metatable(lua_State* L) + { + lua_newtable(L); + + // just indicate that this really is a class and not just + // any user data + lua_pushboolean(L, 1); + lua_setfield(L, -2, "__luabind_class"); + + // This is used as a tag to determine if a userdata is a luabind + // instance. We use a numeric key and a cclosure for fast comparision. + lua_pushnumber(L, 1); + lua_pushcclosure(L, get_instance_value, 0); + lua_rawset(L, -3); + + lua_pushcclosure(L, destroy_instance, 0); + lua_setfield(L, -2, "__gc"); + + lua_pushcclosure(L, get_instance_value, 0); + lua_setfield(L, -2, "__index"); + + lua_pushcclosure(L, set_instance_value, 0); + lua_setfield(L, -2, "__newindex"); + + for (int op = 0; op < number_of_operators; ++op) + { + lua_pushstring(L, get_operator_name(op)); + lua_pushvalue(L, -1); + lua_pushboolean(L, op == op_unm || op == op_len); + lua_pushcclosure(L, &dispatch_operator, 2); + lua_settable(L, -3); + } + } + + LUABIND_API object_rep* get_instance(lua_State* L, int index) + { + object_rep* result = static_cast(lua_touserdata(L, index)); + + if (!result || !lua_getmetatable(L, index)) + return 0; + + lua_rawgeti(L, -1, 1); + + if (lua_tocfunction(L, -1) != &get_instance_value) + result = 0; + + lua_pop(L, 2); + + return result; + } + + LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls) + { + void* storage = lua_newuserdata(L, sizeof(object_rep)); + object_rep* result = new (storage) object_rep(0, cls); + cls->get_table(L); + lua_setfenv(L, -2); + lua_rawgeti(L, LUA_REGISTRYINDEX, cls->metatable_ref()); + lua_setmetatable(L, -2); + return result; + } + +}} diff --git a/libs/luabind/src/open.cpp b/libs/luabind/src/open.cpp index bfdcbb8ec..ec8e4ff64 100644 --- a/libs/luabind/src/open.cpp +++ b/libs/luabind/src/open.cpp @@ -24,129 +24,173 @@ #include -#include +#include +#include #include -#include -#include -#include namespace luabind { - namespace - { +namespace +{ - int make_property(lua_State* L) - { - int args = lua_gettop(L); + int make_property(lua_State* L) + { + int args = lua_gettop(L); - if(args == 0 || args > 2) - { - lua_pushstring(L, "make_property() called with wrong number of arguments."); - lua_error(L); - } + if (args == 0 || args > 2) + { + lua_pushstring(L, "make_property() called with wrong number of arguments."); + lua_error(L); + } - if(args == 1) - lua_pushnil(L); + if (args == 1) + lua_pushnil(L); - lua_pushcclosure(L, &detail::property_tag, 2); - return 1; - } + lua_pushcclosure(L, &detail::property_tag, 2); + return 1; + } - int main_thread_tag; + int main_thread_tag; - int deprecated_super(lua_State* L) - { - lua_pushstring(L, - "DEPRECATION: 'super' has been deprecated in favor of " - "directly calling the base class __init() function. " - "This error can be disabled by calling 'luabind::disable_super_deprecation()'." - ); - lua_error(L); + int deprecated_super(lua_State* L) + { + lua_pushstring(L, + "DEPRECATION: 'super' has been deprecated in favor of " + "directly calling the base class __init() function. " + "This error can be disabled by calling 'luabind::disable_super_deprecation()'." + ); + lua_error(L); - return 0; - } + return 0; + } - } // namespace unnamed + int destroy_class_id_map(lua_State* L) + { + detail::class_id_map* m = + (detail::class_id_map*)lua_touserdata(L, 1); + m->~class_id_map(); + return 0; + } - LUABIND_API lua_State* get_main_thread(lua_State* L) - { - lua_pushlightuserdata(L, &main_thread_tag); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_State* result = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + int destroy_cast_graph(lua_State* L) + { + detail::cast_graph* g = + (detail::cast_graph*)lua_touserdata(L, 1); + g->~cast_graph(); + return 0; + } - if(!result) - throw std::runtime_error("Unable to get main thread, luabind::open() not called?"); + int destroy_class_map(lua_State* L) + { + detail::class_map* m = + (detail::class_map*)lua_touserdata(L, 1); + m->~class_map(); + return 0; + } - return result; - } +} // namespace unnamed - namespace { + LUABIND_API lua_State* get_main_thread(lua_State* L) + { + lua_pushlightuserdata(L, &main_thread_tag); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_State* result = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); - template - inline void * shared_create_userdata(lua_State* L, const char * name) { - lua_pushstring(L, name); - void* storage = lua_newuserdata(L, sizeof(T)); + if (!result) + throw std::runtime_error("Unable to get main thread, luabind::open() not called?"); - // set gc metatable - lua_newtable(L); - lua_pushcclosure(L, &detail::garbage_collector, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); + return result; + } - lua_settable(L, LUA_REGISTRYINDEX); - return storage; - } + LUABIND_API void open(lua_State* L) + { + bool is_main_thread = lua_pushthread(L) == 1; + lua_pop(L, 1); - template - inline void createGarbageCollectedRegistryUserdata(lua_State* L, const char * name) { - void * storage = shared_create_userdata(L, name); - // placement "new" - new (storage) T; - } + if (!is_main_thread) + { + throw std::runtime_error( + "luabind::open() must be called with the main thread " + "lua_State*" + ); + } - template - inline void createGarbageCollectedRegistryUserdata(lua_State* L, const char * name, A1 constructorArg) { - void * storage = shared_create_userdata(L, name); + if (detail::class_registry::get_registry(L)) + return; - // placement "new" - new (storage) T(constructorArg); - } + lua_pushstring(L, "__luabind_classes"); + detail::class_registry* r = static_cast( + lua_newuserdata(L, sizeof(detail::class_registry))); - } // namespace anonymous + // set gc metatable + lua_newtable(L); + lua_pushstring(L, "__gc"); + lua_pushcclosure( + L + , detail::garbage_collector_s< + detail::class_registry + >::apply + , 0); - LUABIND_API void open(lua_State* L) - { - bool is_main_thread = lua_pushthread(L) == 1; - lua_pop(L, 1); + lua_settable(L, -3); + lua_setmetatable(L, -2); - if(!is_main_thread) - { - throw std::runtime_error( - "luabind::open() must be called with the main thread " - "lua_State*" - ); - } + new(r) detail::class_registry(L); + lua_settable(L, LUA_REGISTRYINDEX); - createGarbageCollectedRegistryUserdata(L, "__luabind_classes", L); - createGarbageCollectedRegistryUserdata(L, "__luabind_class_id_map"); - createGarbageCollectedRegistryUserdata(L, "__luabind_cast_graph"); - createGarbageCollectedRegistryUserdata(L, "__luabind_class_map"); + lua_pushstring(L, "__luabind_class_id_map"); + void* classes_storage = lua_newuserdata(L, sizeof(detail::class_id_map)); + detail::class_id_map* class_ids = new (classes_storage) detail::class_id_map; + (void)class_ids; - // add functions (class, cast etc...) - lua_pushcclosure(L, detail::create_class::stage1, 0); - lua_setglobal(L, "class"); + lua_newtable(L); + lua_pushcclosure(L, &destroy_class_id_map, 0); + lua_setfield(L, -2, "__gc"); + lua_setmetatable(L, -2); - lua_pushcclosure(L, &make_property, 0); - lua_setglobal(L, "property"); + lua_settable(L, LUA_REGISTRYINDEX); - lua_pushlightuserdata(L, &main_thread_tag); - lua_pushlightuserdata(L, L); - lua_rawset(L, LUA_REGISTRYINDEX); + lua_pushstring(L, "__luabind_cast_graph"); + void* cast_graph_storage = lua_newuserdata( + L, sizeof(detail::cast_graph)); + detail::cast_graph* graph = new (cast_graph_storage) detail::cast_graph; + (void)graph; - lua_pushcclosure(L, &deprecated_super, 0); - lua_setglobal(L, "super"); - } + lua_newtable(L); + lua_pushcclosure(L, &destroy_cast_graph, 0); + lua_setfield(L, -2, "__gc"); + lua_setmetatable(L, -2); + + lua_settable(L, LUA_REGISTRYINDEX); + + lua_pushstring(L, "__luabind_class_map"); + void* class_map_storage = lua_newuserdata( + L, sizeof(detail::class_map)); + detail::class_map* classes = new (class_map_storage) detail::class_map; + (void)classes; + + lua_newtable(L); + lua_pushcclosure(L, &destroy_class_map, 0); + lua_setfield(L, -2, "__gc"); + lua_setmetatable(L, -2); + + lua_settable(L, LUA_REGISTRYINDEX); + + // add functions (class, cast etc...) + lua_pushcclosure(L, detail::create_class::stage1, 0); + lua_setglobal(L, "class"); + + lua_pushcclosure(L, &make_property, 0); + lua_setglobal(L, "property"); + + lua_pushlightuserdata(L, &main_thread_tag); + lua_pushlightuserdata(L, L); + lua_rawset(L, LUA_REGISTRYINDEX); + + lua_pushcclosure(L, &deprecated_super, 0); + lua_setglobal(L, "super"); + } } // namespace luabind diff --git a/libs/luabind/src/pcall.cpp b/libs/luabind/src/pcall.cpp index 07b3d9241..1bf642531 100644 --- a/libs/luabind/src/pcall.cpp +++ b/libs/luabind/src/pcall.cpp @@ -26,38 +26,40 @@ #include #include -namespace luabind { - namespace detail { - - int pcall(lua_State *L, int nargs, int nresults) +namespace luabind { namespace detail +{ + int pcall(lua_State *L, int nargs, int nresults) + { + pcall_callback_fun e = get_pcall_callback(); + int en = 0; + if ( e ) { - pcall_callback_fun e = get_pcall_callback(); - int en = 0; - if(e) - { - int base = lua_gettop(L) - nargs; - e(L); - lua_insert(L, base); // push pcall_callback under chunk and args - en = base; - } - int result = lua_pcall(L, nargs, nresults, en); - if(en) - lua_remove(L, en); // remove pcall_callback - return result; - } - - int resume_impl(lua_State *L, int nargs, int) - { -#if LUA_VERSION_NUM >= 502 - int res = lua_resume(L, NULL, nargs); -#else - int res = lua_resume(L, nargs); -#endif - // Lua 5.1 added LUA_YIELD as a possible return value, - // this was causing crashes, because the caller expects 0 on success. - return (res == LUA_YIELD) ? 0 : res; - } - + int base = lua_gettop(L) - nargs; + lua_pushcfunction(L, e); + lua_insert(L, base); // push pcall_callback under chunk and args + en = base; + } + int result = lua_pcall(L, nargs, nresults, en); + if ( en ) + lua_remove(L, en); // remove pcall_callback + return result; } -} + int resume_impl(lua_State *L, int nargs, int) + { +#if LUA_VERSION_NUM >= 502 + int res = lua_resume(L, NULL, nargs); +#else + int res = lua_resume(L, nargs); +#endif + +#if LUA_VERSION_NUM >= 501 + // Lua 5.1 added LUA_YIELD as a possible return value, + // this was causing crashes, because the caller expects 0 on success. + return (res == LUA_YIELD) ? 0 : res; +#else + return res; +#endif + } + +}} diff --git a/libs/luabind/src/scope.cpp b/libs/luabind/src/scope.cpp index 0137af674..52bd132f9 100644 --- a/libs/luabind/src/scope.cpp +++ b/libs/luabind/src/scope.cpp @@ -27,182 +27,182 @@ #include #include #include +#include #include -#if LUA_VERSION_NUM < 502 -# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) -#endif +namespace luabind { namespace detail { -namespace luabind { - namespace detail { + registration::registration() + : m_next(0) + { + } - registration::registration() - : m_next(0) - { - } + registration::~registration() + { + delete m_next; + } - registration::~registration() - { - delete m_next; - } + } // namespace detail + + scope::scope() + : m_chain(0) + { + } + + scope::scope(std::auto_ptr reg) + : m_chain(reg.release()) + { + } - } // namespace detail + scope::scope(scope const& other) + : m_chain(other.m_chain) + { + const_cast(other).m_chain = 0; + } - scope::scope() - : m_chain(0) - { - } + scope& scope::operator=(scope const& other_) + { + delete m_chain; + m_chain = other_.m_chain; + const_cast(other_).m_chain = 0; + return *this; + } - scope::scope(std::unique_ptr reg) - : m_chain(reg.release()) - { - } + scope::~scope() + { + delete m_chain; + } + + scope& scope::operator,(scope s) + { + if (!m_chain) + { + m_chain = s.m_chain; + s.m_chain = 0; + return *this; + } + + for (detail::registration* c = m_chain;; c = c->m_next) + { + if (!c->m_next) + { + c->m_next = s.m_chain; + s.m_chain = 0; + break; + } + } - scope::scope(scope const& other) - : m_chain(other.m_chain) - { - const_cast(other).m_chain = 0; - } + return *this; + } - scope& scope::operator=(scope const& other_) - { - delete m_chain; - m_chain = other_.m_chain; - const_cast(other_).m_chain = 0; - return *this; - } - - scope::~scope() - { - delete m_chain; - } - - scope& scope::operator,(scope s) - { - if(!m_chain) - { - m_chain = s.m_chain; - s.m_chain = 0; - return *this; - } - - for(detail::registration* c = m_chain;; c = c->m_next) - { - if(!c->m_next) - { - c->m_next = s.m_chain; - s.m_chain = 0; - break; - } - } - - return *this; - } - - void scope::register_(lua_State* L) const - { - for(detail::registration* r = m_chain; r != 0; r = r->m_next) - { + void scope::register_(lua_State* L) const + { + for (detail::registration* r = m_chain; r != 0; r = r->m_next) + { LUABIND_CHECK_STACK(L); - r->register_(L); - } - } - - namespace { - - struct lua_pop_stack - { - lua_pop_stack(lua_State* L) - : m_state(L) - { - } - - ~lua_pop_stack() - { - lua_pop(m_state, 1); - } - - lua_State* m_state; - }; - - } // namespace unnamed - - module_::module_(lua_State* L, char const* name = 0) - : m_state(L) - , m_name(name) - { - } - - void module_::operator[](scope s) - { - if(m_name) - { - lua_getglobal(m_state, m_name); - - if(!lua_istable(m_state, -1)) - { - lua_pop(m_state, 1); - - lua_newtable(m_state); - lua_pushvalue(m_state, -1); - lua_setglobal(m_state, m_name); - } - } - else - { - lua_pushglobaltable(m_state); - } - - lua_pop_stack guard(m_state); - - s.register_(m_state); - } - - struct namespace_::registration_ : detail::registration - { - registration_(char const* name) - : m_name(name) - { - } - - void register_(lua_State* L) const - { - LUABIND_CHECK_STACK(L); - assert(lua_gettop(L) >= 1); - - lua_pushstring(L, m_name); - lua_gettable(L, -2); - - detail::stack_pop p(L, 1); // pops the table on exit - - if(!lua_istable(L, -1)) - { - lua_pop(L, 1); - - lua_newtable(L); - lua_pushstring(L, m_name); - lua_pushvalue(L, -2); - lua_settable(L, -4); - } - - m_scope.register_(L); - } - - char const* m_name; - scope m_scope; - }; - - namespace_::namespace_(char const* name) - : scope(std::unique_ptr( - m_registration = new registration_(name))) - { - } - - namespace_& namespace_::operator[](scope s) - { - m_registration->m_scope.operator,(s); - return *this; - } + r->register_(L); + } + } + +} // namespace luabind + +namespace luabind { + + namespace { + + struct lua_pop_stack + { + lua_pop_stack(lua_State* L) + : m_state(L) + { + } + + ~lua_pop_stack() + { + lua_pop(m_state, 1); + } + + lua_State* m_state; + }; + + } // namespace unnamed + + module_::module_(lua_State* L, char const* name = 0) + : m_state(L) + , m_name(name) + { + } + + void module_::operator[](scope s) + { + if (m_name) + { + lua_getglobal(m_state, m_name); + + if (!lua_istable(m_state, -1)) + { + lua_pop(m_state, 1); + + lua_newtable(m_state); + lua_pushvalue(m_state, -1); + lua_setglobal(m_state, m_name); + } + } + else + { + lua_pushglobaltable(m_state); + } + + lua_pop_stack guard(m_state); + + s.register_(m_state); + } + + struct namespace_::registration_ : detail::registration + { + registration_(char const* name) + : m_name(name) + { + } + + void register_(lua_State* L) const + { + LUABIND_CHECK_STACK(L); + assert(lua_gettop(L) >= 1); + + lua_pushstring(L, m_name); + lua_gettable(L, -2); + + detail::stack_pop p(L, 1); // pops the table on exit + + if (!lua_istable(L, -1)) + { + lua_pop(L, 1); + + lua_newtable(L); + lua_pushstring(L, m_name); + lua_pushvalue(L, -2); + lua_settable(L, -4); + } + + m_scope.register_(L); + } + + char const* m_name; + scope m_scope; + }; + + namespace_::namespace_(char const* name) + : scope(std::auto_ptr( + m_registration = new registration_(name))) + { + } + + namespace_& namespace_::operator[](scope s) + { + m_registration->m_scope.operator,(s); + return *this; + } } // namespace luabind diff --git a/libs/luabind/src/set_package_preload.cpp b/libs/luabind/src/set_package_preload.cpp deleted file mode 100644 index 166835c66..000000000 --- a/libs/luabind/src/set_package_preload.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/** - @file - @brief Implementation - - @date 2012 - - @author - Ryan Pavlik - and - http://academic.cleardefinition.com/ - Iowa State University Virtual Reality Applications Center - Human-Computer Interaction Graduate Program -*/ - -// Copyright Iowa State University 2012. -// 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. - -#define LUABIND_BUILDING - -// Internal Includes -#include -#include // for LUABIND_API -#include // for object, rawget, globals -#include - -// Library/third-party includes -#include // for lua_pushstring, lua_rawset, etc - -// Standard includes -// - none - - -namespace luabind { - LUABIND_API void set_package_preload(lua_State * L, const char * modulename, int(*loader) (lua_State *)) { - rawget(rawget(globals(L), "package"), "preload").push(L); - lua_pushcclosure(L, loader, 0); - lua_setfield(L, -2, modulename); - lua_pop(L, 1); - } - -} // namespace luabind - diff --git a/libs/luabind/src/stack_content_by_name.cpp b/libs/luabind/src/stack_content_by_name.cpp index e141c4054..38b5c691d 100644 --- a/libs/luabind/src/stack_content_by_name.cpp +++ b/libs/luabind/src/stack_content_by_name.cpp @@ -22,12 +22,9 @@ #define LUABIND_BUILDING -#include // for lua_gettop, lua_touserdata, etc +#include -#include // for class_rep, is_class_rep -#include // for get_instance, object_rep - -#include // for string +#include using namespace luabind::detail; @@ -35,27 +32,27 @@ std::string luabind::detail::stack_content_by_name(lua_State* L, int start_index { std::string ret; int top = lua_gettop(L); - for(int i = start_index; i <= top; ++i) + for (int i = start_index; i <= top; ++i) { object_rep* obj = get_instance(L, i); - class_rep* crep = is_class_rep(L, i) ? (class_rep*)lua_touserdata(L, i) : 0; - if(obj == 0 && crep == 0) + class_rep* crep = is_class_rep(L, i)?(class_rep*)lua_touserdata(L, i):0; + if (obj == 0 && crep == 0) { int type = lua_type(L, i); ret += lua_typename(L, type); } - else if(obj) + else if (obj) { - if(obj->is_const()) ret += "const "; + if (obj->is_const()) ret += "const "; ret += obj->crep()->name(); } - else if(crep) + else if (crep) { ret += "<"; ret += crep->name(); ret += ">"; } - if(i < top) ret += ", "; + if (i < top) ret += ", "; } return ret; } diff --git a/libs/luabind/src/weak_ref.cpp b/libs/luabind/src/weak_ref.cpp index b73ba3876..245b26c2e 100644 --- a/libs/luabind/src/weak_ref.cpp +++ b/libs/luabind/src/weak_ref.cpp @@ -32,155 +32,126 @@ namespace luabind { - namespace - { +namespace +{ - int weak_table_tag; - int impl_table_tag; + int weak_table_tag; - } // namespace unnamed +} // namespace unnamed - LUABIND_API void get_weak_table(lua_State* L) - { - lua_pushlightuserdata(L, &weak_table_tag); - lua_rawget(L, LUA_REGISTRYINDEX); +LUABIND_API void get_weak_table(lua_State* L) +{ + lua_pushlightuserdata(L, &weak_table_tag); + lua_rawget(L, LUA_REGISTRYINDEX); - if(lua_isnil(L, -1)) - { - lua_pop(L, 1); - lua_newtable(L); - // metatable - lua_createtable(L, 0, 1); // One non-sequence entry for __mode. - lua_pushliteral(L, "__mode"); - lua_pushliteral(L, "v"); - lua_rawset(L, -3); - // set metatable - lua_setmetatable(L, -2); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_newtable(L); + // metatable + lua_newtable(L); + lua_pushliteral(L, "__mode"); + lua_pushliteral(L, "v"); + lua_rawset(L, -3); + // set metatable + lua_setmetatable(L, -2); - lua_pushlightuserdata(L, &weak_table_tag); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - - } - - } - - LUABIND_API void get_impl_table(lua_State* L) - { - - lua_pushlightuserdata(L, &impl_table_tag); - lua_rawget(L, LUA_REGISTRYINDEX); - - if(lua_isnil(L, -1)) - { - lua_pop(L, 1); - - lua_newtable(L); - lua_pushlightuserdata(L, &impl_table_tag); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - - } - - } + lua_pushlightuserdata(L, &weak_table_tag); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } +} } // namespace luabind namespace luabind { - struct weak_ref::impl - { - impl(lua_State* main, lua_State* s, int index) - : count(0) - , state(main) - , ref(0) - { + struct weak_ref::impl + { + impl(lua_State* main, lua_State* s, int index) + : count(0) + , state(main) + , ref(0) + { + get_weak_table(s); + lua_pushvalue(s, index); + ref = luaL_ref(s, -2); + lua_pop(s, 1); + } - get_impl_table(s); - lua_pushlightuserdata(s, this); - ref = luaL_ref(s, -2); - lua_pop(s, 1); + ~impl() + { + get_weak_table(state); + luaL_unref(state, -1, ref); + lua_pop(state, 1); + } - get_weak_table(s); - lua_pushvalue(s, index); - lua_rawseti(s, -2, ref); - lua_pop(s, 1); + int count; + lua_State* state; + int ref; + }; - } + weak_ref::weak_ref() + : m_impl(0) + { + } + + weak_ref::weak_ref(lua_State* main, lua_State* L, int index) + : m_impl(new impl(main, L, index)) + { + m_impl->count = 1; + } - ~impl() - { - get_impl_table(state); - luaL_unref(state, -1, ref); - lua_pop(state, 1); - } + weak_ref::weak_ref(weak_ref const& other) + : m_impl(other.m_impl) + { + if (m_impl) ++m_impl->count; + } - int count; - lua_State* state; - int ref; - }; + weak_ref::~weak_ref() + { + if (m_impl && --m_impl->count == 0) + { + delete m_impl; + } + } - weak_ref::weak_ref() - : m_impl(0) - { - } + weak_ref& weak_ref::operator=(weak_ref const& other) + { + weak_ref(other).swap(*this); + return *this; + } - weak_ref::weak_ref(lua_State* main, lua_State* L, int index) - : m_impl(new impl(main, L, index)) - { - m_impl->count = 1; - } + void weak_ref::swap(weak_ref& other) + { + std::swap(m_impl, other.m_impl); + } - weak_ref::weak_ref(weak_ref const& other) - : m_impl(other.m_impl) - { - if(m_impl) ++m_impl->count; - } - - weak_ref::~weak_ref() - { - if(m_impl && --m_impl->count == 0) - { - delete m_impl; - } - } - - weak_ref& weak_ref::operator=(weak_ref const& other) - { - weak_ref(other).swap(*this); - return *this; - } - - void weak_ref::swap(weak_ref& other) - { - std::swap(m_impl, other.m_impl); - } - - int weak_ref::id() const - { - assert(m_impl); + int weak_ref::id() const + { + assert(m_impl); return m_impl->ref; - } + } // L may not be the same pointer as // was used when creating this reference // since it may be a thread that shares // the same globals table. - void weak_ref::get(lua_State* L) const - { - assert(m_impl); + void weak_ref::get(lua_State* L) const + { + assert(m_impl); assert(L); - get_weak_table(L); - lua_rawgeti(L, -1, m_impl->ref); - lua_remove(L, -2); - } - - lua_State* weak_ref::state() const - { - assert(m_impl); - return m_impl->state; - } + get_weak_table(L); + lua_rawgeti(L, -1, m_impl->ref); + lua_remove(L, -2); + } + lua_State* weak_ref::state() const + { + assert(m_impl); + return m_impl->state; + } + } // namespace luabind diff --git a/libs/luabind/src/wrapper_base.cpp b/libs/luabind/src/wrapper_base.cpp index d09dfe983..9fb54a5db 100644 --- a/libs/luabind/src/wrapper_base.cpp +++ b/libs/luabind/src/wrapper_base.cpp @@ -29,29 +29,27 @@ #include #include -namespace luabind { - namespace detail { +namespace luabind { namespace detail +{ + LUABIND_API void do_call_member_selection(lua_State* L, char const* name) + { + object_rep* obj = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); // pop self - LUABIND_API void do_call_member_selection(lua_State* L, char const* name) - { - object_rep* obj = static_cast(lua_touserdata(L, -1)); - assert(obj); + obj->crep()->get_table(L); // push the crep table + lua_pushstring(L, name); + lua_gettable(L, -2); + lua_remove(L, -2); // remove the crep table - lua_pushstring(L, name); - lua_gettable(L, -2); - lua_replace(L, -2); + if (!is_luabind_function(L, -1)) + return; - if(!is_luabind_function(L, -1)) - return; - - // this (usually) means the function has not been - // overridden by lua, call the default implementation - lua_pop(L, 1); - obj->crep()->get_default_table(L); // push the crep table - lua_pushstring(L, name); - lua_gettable(L, -2); - lua_remove(L, -2); // remove the crep table - } + // this (usually) means the function has not been + // overridden by lua, call the default implementation + lua_pop(L, 1); + obj->crep()->get_default_table(L); // push the crep table + lua_pushstring(L, name); + lua_gettable(L, -2); + lua_remove(L, -2); // remove the crep table } -} - +}} diff --git a/loginserver/CMakeLists.txt b/loginserver/CMakeLists.txt index 7d60655fc..43217a48d 100644 --- a/loginserver/CMakeLists.txt +++ b/loginserver/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(eqlogin_sources account_management.cpp @@ -28,10 +28,14 @@ SET(eqlogin_headers world_server.h ) +FIND_PACKAGE(OpenSSL REQUIRED) + +INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR}) + ADD_EXECUTABLE(loginserver ${eqlogin_sources} ${eqlogin_headers}) INSTALL(TARGETS loginserver RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) -TARGET_LINK_LIBRARIES(loginserver ${SERVER_LIBS}) +TARGET_LINK_LIBRARIES(loginserver ${SERVER_LIBS} ${OPENSSL_LIBRARIES}) SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) diff --git a/loginserver/encryption.cpp b/loginserver/encryption.cpp index 6450f7493..27d22cca8 100644 --- a/loginserver/encryption.cpp +++ b/loginserver/encryption.cpp @@ -1,306 +1,268 @@ -#include "encryption.h" -#ifdef EQEMU_USE_OPENSSL +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + #include #include #include -#endif -#ifdef EQEMU_USE_MBEDTLS -#include -#include -#include -#include -#endif #include #include + #ifdef ENABLE_SECURITY + #include + #endif -std::string GetEncryptionByModeId(uint32 mode) { - switch (mode) { - case EncryptionModeMD5: - return "MD5"; - case EncryptionModeMD5PassUser: - return "MD5PassUser"; - case EncryptionModeMD5UserPass: - return "MD5UserPass"; - case EncryptionModeMD5Triple: - return "MD5Triple"; - case EncryptionModeSHA: - return "SHA"; - case EncryptionModeSHAPassUser: - return "SHAPassUser"; - case EncryptionModeSHAUserPass: - return "SHAUserPass"; - case EncryptionModeSHATriple: - return "SHATriple"; - case EncryptionModeSHA512: - return "SHA512"; - case EncryptionModeSHA512PassUser: - return "SHA512PassUser"; - case EncryptionModeSHA512UserPass: - return "SHA512UserPass"; - case EncryptionModeSHA512Triple: - return "SHA512Triple"; - case EncryptionModeArgon2: - return "Argon2"; - case EncryptionModeSCrypt: - return "SCrypt"; - default: - return ""; - } -} +#include "encryption.h" -const char* eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char* buffer_out, bool enc) { -#ifdef EQEMU_USE_MBEDTLS - if (enc) { - if (buffer_in_sz % 8 != 0) { - auto temp_buffer_sz = ((buffer_in_sz / 8) + 1) * 8; - unsigned char *temp_buffer = new unsigned char[temp_buffer_sz]; - unsigned char *temp_buffer_in = &temp_buffer[0]; - unsigned char *temp_buffer_out = &temp_buffer[temp_buffer_sz]; - - memset(temp_buffer, 0, temp_buffer_sz * 2); - memcpy(temp_buffer_in, buffer_in, buffer_in_sz); - - unsigned char key[MBEDTLS_DES_KEY_SIZE]; - unsigned char iv[8]; - memset(&key, 0, MBEDTLS_DES_KEY_SIZE); - memset(&iv, 0, 8); - - mbedtls_des_context context; - mbedtls_des_setkey_enc(&context, key); - mbedtls_des_crypt_cbc(&context, MBEDTLS_DES_ENCRYPT, temp_buffer_sz, iv, (const unsigned char*)temp_buffer_in, (unsigned char*)temp_buffer_out); - - memcpy(buffer_out, temp_buffer_out, temp_buffer_sz); - delete[] temp_buffer; - } - else { - unsigned char key[MBEDTLS_DES_KEY_SIZE]; - unsigned char iv[8]; - memset(&key, 0, MBEDTLS_DES_KEY_SIZE); - memset(&iv, 0, 8); - - mbedtls_des_context context; - mbedtls_des_setkey_enc(&context, key); - mbedtls_des_crypt_cbc(&context, MBEDTLS_DES_ENCRYPT, buffer_in_sz, iv, (const unsigned char*)buffer_in, (unsigned char*)buffer_out); - } - } - else { - if (buffer_in_sz && buffer_in_sz % 8 != 0) { - return nullptr; - } - - unsigned char key[MBEDTLS_DES_KEY_SIZE]; - unsigned char iv[8]; - memset(&key, 0, MBEDTLS_DES_KEY_SIZE); - memset(&iv, 0, 8); - - mbedtls_des_context context; - mbedtls_des_setkey_dec(&context, key); - mbedtls_des_crypt_cbc(&context, MBEDTLS_DES_DECRYPT, buffer_in_sz, iv, (const unsigned char*)buffer_in, (unsigned char*)buffer_out); - } -#endif - -#ifdef EQEMU_USE_OPENSSL +/** + * @param buffer_in + * @param buffer_in_sz + * @param buffer_out + * @param enc + * @return + */ +const char *eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char *buffer_out, bool enc) +{ DES_key_schedule k; - DES_cblock v; - + DES_cblock v; + memset(&k, 0, sizeof(DES_key_schedule)); memset(&v, 0, sizeof(DES_cblock)); - + if (!enc && buffer_in_sz && buffer_in_sz % 8 != 0) { return nullptr; } - - DES_ncbc_encrypt((const unsigned char*)buffer_in, (unsigned char*)buffer_out, (long)buffer_in_sz, &k, &v, enc); -#endif + + DES_ncbc_encrypt((const unsigned char *) buffer_in, (unsigned char *) buffer_out, (long) buffer_in_sz, &k, &v, enc); return buffer_out; } -std::string eqcrypt_md5(const std::string &msg) { - std::string ret; - ret.reserve(32); - -#ifdef EQEMU_USE_MBEDTLS - unsigned char digest[16]; - char temp[4]; - - if (0 == mbedtls_md5_ret((const unsigned char*)msg.c_str(), msg.length(), digest)) { - for (int i = 0; i < 16; ++i) { - sprintf(&temp[0], "%02x", digest[i]); - ret.push_back(temp[0]); - ret.push_back(temp[1]); - } - } -#endif - -#ifdef EQEMU_USE_OPENSSL +/** + * @param msg + * @return + */ +std::string eqcrypt_md5(const std::string &msg) +{ + std::string ret; unsigned char md5_digest[16]; - char tmp[4]; + char tmp[4]; - MD5((const unsigned char*)msg.c_str(), msg.length(), md5_digest); + MD5((const unsigned char *) msg.c_str(), msg.length(), md5_digest); for (int i = 0; i < 16; ++i) { sprintf(&tmp[0], "%02x", md5_digest[i]); ret.push_back(tmp[0]); ret.push_back(tmp[1]); } -#endif return ret; } -std::string eqcrypt_sha1(const std::string &msg) { - std::string ret; - ret.reserve(40); - -#ifdef EQEMU_USE_MBEDTLS - unsigned char digest[20]; - char temp[4]; - - if (0 == mbedtls_sha1_ret((const unsigned char*)msg.c_str(), msg.length(), digest)) { - for (int i = 0; i < 20; ++i) { - sprintf(&temp[0], "%02x", digest[i]); - ret.push_back(temp[0]); - ret.push_back(temp[1]); - } - } -#endif - -#ifdef EQEMU_USE_OPENSSL +/** + * @param msg + * @return + */ +std::string eqcrypt_sha1(const std::string &msg) +{ + std::string ret; unsigned char sha_digest[20]; - char tmp[4]; + char tmp[4]; - SHA1((const unsigned char*)msg.c_str(), msg.length(), sha_digest); + SHA1((const unsigned char *) msg.c_str(), msg.length(), sha_digest); for (int i = 0; i < 20; ++i) { sprintf(&tmp[0], "%02x", sha_digest[i]); ret.push_back(tmp[0]); ret.push_back(tmp[1]); } -#endif return ret; } -std::string eqcrypt_sha512(const std::string &msg) { - std::string ret; - ret.reserve(128); - -#ifdef EQEMU_USE_MBEDTLS - unsigned char digest[64]; - char temp[4]; - - if (0 == mbedtls_sha512_ret((const unsigned char*)msg.c_str(), msg.length(), digest, 0)) { - for (int i = 0; i < 64; ++i) { - sprintf(&temp[0], "%02x", digest[i]); - ret.push_back(temp[0]); - ret.push_back(temp[1]); - } - } -#endif - -#ifdef EQEMU_USE_OPENSSL +/** + * @param msg + * @return + */ +std::string eqcrypt_sha512(const std::string &msg) +{ + std::string ret; unsigned char sha_digest[64]; - char tmp[4]; + char tmp[4]; - SHA512((const unsigned char*)msg.c_str(), msg.length(), sha_digest); + SHA512((const unsigned char *) msg.c_str(), msg.length(), sha_digest); for (int i = 0; i < 64; ++i) { sprintf(&tmp[0], "%02x", sha_digest[i]); ret.push_back(tmp[0]); ret.push_back(tmp[1]); } -#endif return ret; } #ifdef ENABLE_SECURITY +/** + * @param msg + * @return + */ std::string eqcrypt_argon2(const std::string &msg) { - std::string ret; - ret.resize(crypto_pwhash_STRBYTES); + char buffer[crypto_pwhash_STRBYTES]; - if (crypto_pwhash_str(&ret[0], &msg[0], msg.length(), crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE) != 0) { + if (crypto_pwhash_str( + &buffer[0], + &msg[0], + msg.length(), + crypto_pwhash_OPSLIMIT_INTERACTIVE, + crypto_pwhash_MEMLIMIT_INTERACTIVE + ) != 0) { return ""; } - return ret; + return buffer; } +/** + * @param msg + * @return + */ std::string eqcrypt_scrypt(const std::string &msg) { - std::string ret; - ret.resize(crypto_pwhash_scryptsalsa208sha256_STRBYTES); + char buffer[crypto_pwhash_scryptsalsa208sha256_STRBYTES]; - if (crypto_pwhash_scryptsalsa208sha256_str(&ret[0], &msg[0], msg.length(), - crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE, crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE) != 0) { + if (crypto_pwhash_scryptsalsa208sha256_str( + &buffer[0], &msg[0], msg.length(), + crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE, crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE + ) != 0) { return ""; } - return ret; + return buffer; } #endif -std::string eqcrypt_hash(const std::string &username, const std::string &password, int mode) { - switch (mode) - { - case 1: - return eqcrypt_md5(password); - case 2: - return eqcrypt_md5(password + ":" + username); - case 3: - return eqcrypt_md5(username + ":" + password); - case 4: - return eqcrypt_md5(eqcrypt_md5(username) + eqcrypt_md5(password)); - case 5: - return eqcrypt_sha1(password); - case 6: - return eqcrypt_sha1(password + ":" + username); - case 7: - return eqcrypt_sha1(username + ":" + password); - case 8: - return eqcrypt_sha1(eqcrypt_sha1(username) + eqcrypt_sha1(password)); - case 9: - return eqcrypt_sha512(password); - case 10: - return eqcrypt_sha512(password + ":" + username); - case 11: - return eqcrypt_sha512(username + ":" + password); - case 12: - return eqcrypt_sha512(eqcrypt_sha512(username) + eqcrypt_sha512(password)); +/** + * @param username + * @param password + * @param mode + * @return + */ +std::string eqcrypt_hash(const std::string &username, const std::string &password, int mode) +{ + switch (mode) { + case EncryptionModeMD5: + return eqcrypt_md5(password); + case EncryptionModeMD5PassUser: + return eqcrypt_md5(password + ":" + username); + case EncryptionModeMD5UserPass: + return eqcrypt_md5(username + ":" + password); + case EncryptionModeMD5Triple: + return eqcrypt_md5(eqcrypt_md5(username) + eqcrypt_md5(password)); + case EncryptionModeSHA: + return eqcrypt_sha1(password); + case EncryptionModeSHAPassUser: + return eqcrypt_sha1(password + ":" + username); + case EncryptionModeSHAUserPass: + return eqcrypt_sha1(username + ":" + password); + case EncryptionModeSHATriple: + return eqcrypt_sha1(eqcrypt_sha1(username) + eqcrypt_sha1(password)); + case EncryptionModeSHA512: + return eqcrypt_sha512(password); + case EncryptionModeSHA512PassUser: + return eqcrypt_sha512(password + ":" + username); + case EncryptionModeSHA512UserPass: + return eqcrypt_sha512(username + ":" + password); + case EncryptionModeSHA512Triple: + return eqcrypt_sha512(eqcrypt_sha512(username) + eqcrypt_sha512(password)); #ifdef ENABLE_SECURITY - case 13: - return eqcrypt_argon2(password); - case 14: - return eqcrypt_scrypt(password); + case EncryptionModeArgon2: + return eqcrypt_argon2(password); + case EncryptionModeSCrypt: + return eqcrypt_scrypt(password); #endif - //todo bcrypt? pbkdf2? - default: - return ""; - break; + //todo bcrypt? pbkdf2? + default: + return ""; + break; } } -bool eqcrypt_verify_hash(const std::string &username, const std::string &password, const std::string &pwhash, int mode) { - switch (mode) - { +/** + * @param username + * @param password + * @param pwhash + * @param mode + * @return + */ +bool eqcrypt_verify_hash(const std::string &username, const std::string &password, const std::string &pwhash, int mode) +{ + switch (mode) { #ifdef ENABLE_SECURITY - case 13: - return crypto_pwhash_str_verify(&pwhash[0], &password[0], password.length()) == 0; - case 14: - return crypto_pwhash_scryptsalsa208sha256_str_verify(&pwhash[0], &password[0], password.length()) == 0; + case 13: + return crypto_pwhash_str_verify(&pwhash[0], &password[0], password.length()) == 0; + case 14: + return crypto_pwhash_scryptsalsa208sha256_str_verify(&pwhash[0], &password[0], password.length()) == 0; #endif - default: - { - auto hash = eqcrypt_hash(username, password, mode); - return hash.compare(pwhash) == 0; - } + default: { + auto hash = eqcrypt_hash(username, password, mode); + return hash.compare(pwhash) == 0; + } } return false; } + +std::string GetEncryptionByModeId(uint32 mode) { + switch (mode) { + case EncryptionModeMD5: + return "MD5"; + case EncryptionModeMD5PassUser: + return "MD5PassUser"; + case EncryptionModeMD5UserPass: + return "MD5UserPass"; + case EncryptionModeMD5Triple: + return "MD5Triple"; + case EncryptionModeSHA: + return "SHA"; + case EncryptionModeSHAPassUser: + return "SHAPassUser"; + case EncryptionModeSHAUserPass: + return "SHAUserPass"; + case EncryptionModeSHATriple: + return "SHATriple"; + case EncryptionModeSHA512: + return "SHA512"; + case EncryptionModeSHA512PassUser: + return "SHA512PassUser"; + case EncryptionModeSHA512UserPass: + return "SHA512UserPass"; + case EncryptionModeSHA512Triple: + return "SHA512Triple"; + case EncryptionModeArgon2: + return "Argon2"; + case EncryptionModeSCrypt: + return "SCrypt"; + default: + return ""; + } +} \ No newline at end of file diff --git a/queryserv/CMakeLists.txt b/queryserv/CMakeLists.txt index 15c900e53..393747a91 100644 --- a/queryserv/CMakeLists.txt +++ b/queryserv/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(qserv_sources database.cpp diff --git a/shared_memory/CMakeLists.txt b/shared_memory/CMakeLists.txt index 6902a8b83..1844df758 100644 --- a/shared_memory/CMakeLists.txt +++ b/shared_memory/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(shared_memory_sources base_data.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e7b97b57f..b404bab99 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) ADD_SUBDIRECTORY(cppunit) diff --git a/tests/cppunit/CMakeLists.txt b/tests/cppunit/CMakeLists.txt index 16747f785..e60e2134f 100644 --- a/tests/cppunit/CMakeLists.txt +++ b/tests/cppunit/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(cppunit_sources collectoroutput.cpp diff --git a/ucs/CMakeLists.txt b/ucs/CMakeLists.txt index a1c0b32b4..e09e12781 100644 --- a/ucs/CMakeLists.txt +++ b/ucs/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(ucs_sources chatchannel.cpp diff --git a/wi/.gitignore b/wi/.gitignore new file mode 100644 index 000000000..b449f1759 --- /dev/null +++ b/wi/.gitignore @@ -0,0 +1,47 @@ +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity diff --git a/wi/BUILD.md b/wi/BUILD.md new file mode 100644 index 000000000..a3fa9a989 --- /dev/null +++ b/wi/BUILD.md @@ -0,0 +1,17 @@ +# Building EQEmu Web Interface Reference Implementation + +## Required Software +- [NodeJS](https://nodejs.org) + +## Install + +First: Make sure you have required software installed. + +Install 3rd Party Libraries first with the following command: + npm install + + +## Run + +Run with either your favorite NodeJS process manager or with the following command: + node . \ No newline at end of file diff --git a/wi/core/jwt_auth.js b/wi/core/jwt_auth.js new file mode 100644 index 000000000..f63f22346 --- /dev/null +++ b/wi/core/jwt_auth.js @@ -0,0 +1,27 @@ +const jwt = require('jsonwebtoken'); + +var Auth = function (req, res, next) { + var token = ''; + try { + token = req.headers.authorization.substring(7); + } catch(ex) { + console.log(ex); + res.sendStatus(401); + return; + } + + jwt.verify(token, req.key, function(err, decoded) { + if(err) { + console.log(err); + res.sendStatus(401); + return; + } + + req.token = decoded; + next(); + }); +}; + +module.exports = { + 'auth': Auth +} diff --git a/wi/generate_pw_hash.js b/wi/generate_pw_hash.js new file mode 100644 index 000000000..6648e48c3 --- /dev/null +++ b/wi/generate_pw_hash.js @@ -0,0 +1,4 @@ +var sodium = require('libsodium-wrappers-sumo'); + +var hash = sodium.crypto_pwhash_str('password', 3, 32768); +console.log(hash); \ No newline at end of file diff --git a/wi/http/common.js b/wi/http/common.js new file mode 100644 index 000000000..c049520e9 --- /dev/null +++ b/wi/http/common.js @@ -0,0 +1,26 @@ +var auth = require('../core/jwt_auth.js').auth; + +function RegisterFunction(path, fn, app, api) { + app.post(path, auth, function (req, res) { + var params = req.body.params || []; + + api.Call(fn, params) + .then(function(value) { + res.send({ response: value }); + }) + .catch(function(reason) { + if(reason.message) { + res.send({ status: reason.message }); + } + else if(reason === 'Not connected to world server.') { + res.send({ status: 'ENCONNECTED' }); + } else { + res.sendStatus(500); + } + }); + }); +} + +module.exports = { + 'Register': RegisterFunction +} \ No newline at end of file diff --git a/wi/http/data/account.js b/wi/http/data/account.js new file mode 100644 index 000000000..29cf1e2f8 --- /dev/null +++ b/wi/http/data/account.js @@ -0,0 +1,16 @@ +var endpoint = require('./endpoint.js'); +var auth = require('../../core/jwt_auth.js').auth; +var sql = require('./sql.js'); + +var RegisterAPI = function(app, api) { + endpoint.Register(app, api, 'account', 'account', 'id'); + + //Can register custom controller actions here. + app.post('/api/data/account/search', auth, function (req, res) { + sql.Search(req, res, 'account', 'id', ['id', 'name']); + }); +}; + +module.exports = { + 'Register': RegisterAPI +} \ No newline at end of file diff --git a/wi/http/data/endpoint.js b/wi/http/data/endpoint.js new file mode 100644 index 000000000..574ea56ec --- /dev/null +++ b/wi/http/data/endpoint.js @@ -0,0 +1,20 @@ +var auth = require('../../core/jwt_auth.js').auth; +var sql = require('./sql.js'); + +var RegisterEndpoint = function(app, api, endpoint_verb, table_name, pkey) { + app.get('/api/data/' + endpoint_verb + '/:' + pkey, auth, function (req, res) { + sql.Retrieve(req, res, table_name, pkey); + }); + + app.put('/api/data/' + endpoint_verb + '/:' + pkey, auth, function (req, res) { + sql.CreateUpdate(req, res, table_name, pkey); + }); + + app.delete('/api/data/' + endpoint_verb + '/:' + pkey, auth, function (req, res) { + sql.Delete(req, res, table_name, pkey); + }); +}; + +module.exports = { + 'Register': RegisterEndpoint +} diff --git a/wi/http/data/index.js b/wi/http/data/index.js new file mode 100644 index 000000000..b9bd6bc0e --- /dev/null +++ b/wi/http/data/index.js @@ -0,0 +1,8 @@ +var RegisterAPI = function(app, api) { + require('./account.js').Register(app, api); + require('./item.js').Register(app, api); +}; + +module.exports = { + 'Register': RegisterAPI +} \ No newline at end of file diff --git a/wi/http/data/item.js b/wi/http/data/item.js new file mode 100644 index 000000000..f88d80bfa --- /dev/null +++ b/wi/http/data/item.js @@ -0,0 +1,16 @@ +var endpoint = require('./endpoint.js'); +var auth = require('../../core/jwt_auth.js').auth; +var sql = require('./sql.js'); + +var RegisterAPI = function(app, api) { + endpoint.Register(app, api, 'item', 'items', 'id'); + + //Can register custom controller actions here. + app.post('/api/data/item/search', auth, function (req, res) { + sql.Search(req, res, 'items', 'id', ['id', 'name', 'icon']); + }); +}; + +module.exports = { + 'Register': RegisterAPI +} \ No newline at end of file diff --git a/wi/http/data/sql.js b/wi/http/data/sql.js new file mode 100644 index 000000000..22416f3ba --- /dev/null +++ b/wi/http/data/sql.js @@ -0,0 +1,319 @@ +var moment = require('moment'); + +function CreateReplace(table, body, fields) { + try { + var query = 'REPLACE INTO ' + table + ' VALUES('; + var first = true; + var args = []; + + for(var idx in fields) { + if(first) { + first = false; + } else { + query += ','; + } + + query += '?'; + + var entry = fields[idx]; + if(entry.type === 12) { + try { + var d = new moment(body[entry.name]); + + if(d.isValid()) { + args.push(d.format('YYYY-MM-DD HH:mm:ss')); + } else { + args.push(null); + } + } catch(ex) { + args.push(null); + } + } else { + args.push(body[entry.name]); + } + } + + query += ')'; + + return { 'query': query, 'args': args }; + } catch(ex) { + return { 'query': '', 'args': [] }; + } +} + +function CreateUpdate(req, res, table, pkey) { + req.mysql.getConnection(function(err, connection) { + try { + if(err) { + console.log(err); + connection.release(); + res.sendStatus(500); + return; + } + + if(req.body[pkey] !== parseInt(req.params[pkey], 10)) { + connection.release(); + res.sendStatus(400); + return; + } + + connection.query('SELECT * FROM ' + table + ' WHERE ' + pkey + '=? LIMIT 1', [req.params[pkey]], function (error, results, fields) { + try { + if(error) { + console.log(error); + connection.release(); + res.sendStatus(400); + return; + } + + var replace = CreateReplace(table, req.body, fields); + if(replace.query === '') { + connection.release(); + res.sendStatus(400); + return; + } + + connection.query(replace.query, replace.args, function(error, results, fields) { + try { + if(error) { + console.log(error); + connection.release(); + res.sendStatus(400); + return; + } + + connection.release(); + res.sendStatus(200); + } catch(ex) { + console.log(ex); + connection.release(); + res.sendStatus(500); + } + }); + } catch(ex) { + console.log(ex); + connection.release(); + res.sendStatus(500); + } + }); + } catch(ex) { + console.log(ex); + connection.release(); + res.sendStatus(500); + } + }); +} + +function Retrieve(req, res, table, pkey) { + req.mysql.getConnection(function(err, connection) { + try { + if(err) { + console.log(err); + connection.release(); + res.sendStatus(500); + return; + } + + connection.query('SELECT * FROM ' + table + ' WHERE ' + pkey + '=? LIMIT 1', [req.params[pkey]], function (error, results, fields) { + try { + if(results.length == 0) { + connection.release(); + res.sendStatus(404); + return; + } + + var result = results[0]; + var ret = { }; + + for(var idx in result) { + var value = result[idx]; + ret[idx] = value; + } + + connection.release(); + res.json(ret); + } catch(ex) { + console.log(ex); + connection.release(); + res.sendStatus(500); + } + }); + } catch(ex) { + console.log(ex); + connection.release(); + res.sendStatus(500); + } + }); +} + +function Delete(req, res, table, pkey) { + req.mysql.getConnection(function(err, connection) { + try { + if(err) { + console.log(err); + connection.release(); + res.sendStatus(500); + return; + } + + connection.query('DELETE FROM ' + table + ' WHERE ' + pkey + '=? LIMIT 1', [req.params[pkey]], function (error, results, fields) { + try { + if(error) { + console.log(error); + connection.release(); + res.sendStatus(400); + return; + } + + connection.release(); + res.sendStatus(200); + } catch(ex) { + console.log(ex); + connection.release(); + res.sendStatus(500); + } + }); + } catch(ex) { + console.log(ex); + connection.release(); + res.sendStatus(500); + } + }); +} + +function getLimit(req, columns) { + var limit = ''; + + var len = parseInt(req.body['length']); + if(len > 100) { + len = 100; + } + + if(req.body.hasOwnProperty('start') && len != -1) { + limit = 'LIMIT ' + req.body['start'] + ', ' + req.body['length']; + } + + return limit; +} + +function getOrder(req, columns) { + var order = ''; + + if (req.body.hasOwnProperty('order') && req.body['order'].length) { + var orderBy = []; + for(var i = 0; i < req.body['order'].length; ++i) { + var columnIdx = parseInt(req.body['order'][i].column); + var column = req.body['columns'][columnIdx]; + var columnId = column.data; + var dir = req.body['order'][i].dir === 'asc' ? 'ASC' : 'DESC'; + orderBy.push(req.mysql.escapeId(columnId) + ' ' + dir); + } + + order = 'ORDER BY ' + orderBy.join(','); + } + + return order; +} + +function filter(req, columns, args) { + var where = ''; + var globalSearch = []; + var columnSearch = []; + + if (req.body.hasOwnProperty('search') && req.body['search'].value.length) { + var searchTerm = req.body['search'].value; + for(var i = 0; i < req.body['columns'].length; ++i) { + var column = req.body['columns'][i]; + + if(column.searchable) { + globalSearch.push(req.mysql.escapeId(column.data) + ' LIKE ?'); + args.push('%' + searchTerm + '%'); + } + } + } + + for(var i = 0; i < req.body['columns'].length; ++i) { + var column = req.body['columns'][i]; + var searchTerm = column.search.value; + + if(searchTerm !== '' && column.searchable) { + columnSearch.push(req.mysql.escapeId(column.data) + ' LIKE ?'); + args.push('%' + searchTerm + '%'); + } + } + + if(globalSearch.length) { + where = globalSearch.join(' OR '); + } + + if(columnSearch.length) { + if(where === '') { + where = columnSearch.join(' AND '); + } else { + where += ' AND '; + where += columnSearch.join(' AND '); + } + } + + if(where !== '') { + where = 'WHERE ' + where; + } + + return where; +} + +function Search(req, res, table, pkey, columns) { + var args = []; + var limit = getLimit(req, columns); + var order = getOrder(req, columns); + var where = filter(req, columns, args); + + var query = 'SELECT ' + columns.join(', ') + ' FROM ' + table + ' ' + where + ' ' + order + ' ' + limit; + + req.mysql.getConnection(function(err, connection) { + try { + if(err) { + console.log(err); + connection.release(); + res.sendStatus(500); + return; + } + + connection.query(query, args, function (error, results, fields) { + try { + var ret = []; + + for(var i in results) { + var result = results[i]; + + var obj = { }; + for(var idx in result) { + var value = result[idx]; + obj[idx] = value; + } + + ret.push(obj); + } + + connection.release(); + res.json(ret); + } catch(ex) { + console.log(ex); + connection.release(); + res.sendStatus(500); + } + }); + } catch(ex) { + console.log(ex); + connection.release(); + res.sendStatus(500); + } + }); +}; + +module.exports = { + 'CreateUpdate': CreateUpdate, + 'Retrieve': Retrieve, + 'Delete': Delete, + 'Search': Search, +} \ No newline at end of file diff --git a/wi/http/eqw.js b/wi/http/eqw.js new file mode 100644 index 000000000..9a72e6114 --- /dev/null +++ b/wi/http/eqw.js @@ -0,0 +1,16 @@ +const common = require('./common.js'); + +var RegisterEQW = function(app, api) { + common.Register('/api/eqw/getconfig', 'EQW::GetConfig', app, api); + common.Register('/api/eqw/islocked', 'EQW::IsLocked', app, api); + common.Register('/api/eqw/lock', 'EQW::Lock', app, api); + common.Register('/api/eqw/unlock', 'EQW::Unlock', app, api); + common.Register('/api/eqw/getplayercount', 'EQW::GetPlayerCount', app, api); + common.Register('/api/eqw/getzonecount', 'EQW::GetZoneCount', app, api); + common.Register('/api/eqw/getlaunchercount', 'EQW::GetLauncherCount', app, api); + common.Register('/api/eqw/getloginservercount', 'EQW::GetLoginServerCount', app, api); +}; + +module.exports = { + 'Register': RegisterEQW +} diff --git a/wi/http/index.js b/wi/http/index.js new file mode 100644 index 000000000..46e2f6d71 --- /dev/null +++ b/wi/http/index.js @@ -0,0 +1,9 @@ +var RegisterAPI = function(app, api) { + require('./eqw.js').Register(app, api); + require('./token.js').Register(app); + require('./data').Register(app, api); +}; + +module.exports = { + 'Register': RegisterAPI +} \ No newline at end of file diff --git a/wi/http/token.js b/wi/http/token.js new file mode 100644 index 000000000..a3815121f --- /dev/null +++ b/wi/http/token.js @@ -0,0 +1,43 @@ +const sodium = require('libsodium-wrappers-sumo'); +const jwt = require('jsonwebtoken'); + +var RegisterToken = function(app) { + app.post('/api/token', function (req, res) { + try { + req.mysql.getConnection(function(err, connection) { + if(err) { + console.log(err); + res.sendStatus(500); + connection.release(); + return; + } + + connection.query('SELECT password FROM account WHERE name = ? LIMIT 1', [req.body.username], function (error, results, fields) { + if(results.length == 0) { + res.sendStatus(401); + connection.release(); + return; + } + + + if(sodium.crypto_pwhash_str_verify(results[0].password, req.body.password)) { + var expires = Math.floor(Date.now() / 1000) + (60 * 60 * 24 * 7); + var token = jwt.sign({ username: req.body.username, exp: expires }, req.key); + res.send({token: token, expires: expires}); + connection.release(); + } else { + res.sendStatus(401); + connection.release(); + } + }); + }); + } catch(ex) { + res.sendStatus(500); + console.log(ex); + } + }); +}; + +module.exports = { + 'Register': RegisterToken +} \ No newline at end of file diff --git a/wi/index.js b/wi/index.js new file mode 100644 index 000000000..822592b8d --- /dev/null +++ b/wi/index.js @@ -0,0 +1,56 @@ +const fs = require('fs'); +const settings = JSON.parse(fs.readFileSync('settings.json', 'utf8')); +const key = fs.readFileSync(settings.key, 'utf8'); + +var server; +if(settings.https.enabled) { + const options = { + key: fs.readFileSync(settings.https.key), + cert: fs.readFileSync(settings.https.cert) + }; + + server = require('https').createServer(); +} else { + server = require('http').createServer(); +} + +const servertalk = require('./network/servertalk_api.js'); +const websocket_iterface = require('./ws/ws_interface.js'); +const express = require('express'); +const app = express(); +const bodyParser = require('body-parser'); +const uuid = require('node-uuid'); +const jwt = require('jsonwebtoken'); +var mysql = require('mysql').createPool(settings.db); + +var api = new servertalk.api(); +var wsi = new websocket_iterface.wsi(server, key, api); +api.Init(settings.servertalk.addr, settings.servertalk.port, false, settings.servertalk.key); + +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); + +app.use(function(req, res, next) { + res.header("Access-Control-Allow-Origin", "*"); + res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT"); + res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization"); + next(); +}); + +//make sure all routes can see our injected dependencies +app.use(function (req, res, next) { + req.servertalk = api; + req.mysql = mysql; + req.key = key; + next(); +}); + +app.get('/', function (req, res) { + res.send({ status: "online" }); +}); + +require('./http').Register(app, api); +require('./ws').Register(wsi, api); + +server.on('request', app); +server.listen(settings.port, function () { console.log('Listening on ' + server.address().port) }); diff --git a/wi/key.pem b/wi/key.pem new file mode 100644 index 000000000..1f0cbdc91 --- /dev/null +++ b/wi/key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAoijNhaW4sH2yLEQOUCNLSU0qIGnr9mxewEPXSNURKFExC1WE +ah983xy+WTbKjakH6Rp2OwCvLxNIu6QBKRgcJ963ICWY7ysn4bU2Q2KoSJgAEel8 +UMDHWYfyyAPdr4DUwUw7YMf4LBThCGBC5DTPilZiVqQNyOf8KL5w/oKcavVMddod +eBNE1ewoxVveHN6WUDkYQKZK2AsrpNG6TjfJc3wI3Z722tRHui4E772l/sD0SuEj +41pBzOG0VM7DHwUpHQosnvnwx9kjefPNE/uvo14PuzP5yYG2h2PFkQ7uuXjK2/le +iVcyap/zgheOHjlYmOJGT1cnVSodv+rY56eilwIDAQABAoIBAQAM/sAZqcI3Qpt4 +uKt8+Jcb9Lcfid2DDgQ53DXwfEK3vGn1wpCuAH/9UUxf0ehBmf4sTBaVe+SOHTmC +8A23wVrgRxTd2qV65TZ4/BCxLcLWrney98cioZBYOHDYXpbxbZ2fMADCLMRSpAm0 +piI2L5VCPNH8p4EDTLQEf96GRulKGOWETeVNai3C7Ept6Fxv0YIiiER8j2oPsb1O +LVCBKBPsNs0IlabJAzfDnaqdfWzuLWIT0L4w/qvzfwkdM8tVxch2zjEVosbz4ser +rPO3tle3mobgDvXrW9jEYkIpOtEqCS7l4ybidVuEfY55KlkZ7rGBQ2N1jbLvKjb5 +AUyHUBchAoGBAOKjzzBPB/mofycF8iF1QJwripGTDUGM7aXBS0Clp4mh0ksvBsUf +Zg+Qnzr2xZaN53lU65xQlMrebMJow4iJj71VesF9FWPPNbIhh7eMTX4pABcKZNvc +Y0iFf5XZAl3LFdDocQSuB3j5WLNrjSFMBZuYUiZhgiRadtcdpQr+O4lbAoGBALcq +ltbFogxXoo7/CIajbYdNUGbba96jQMOzC1D7yeim1MTtDNGs56ZhDjFZepMRMyfX +/Z7iqxjZQQ1m1THtuiM4g+ug08EYI8G/7DYO5DqMABGFb3vKU9ilhYASqfznpKMJ +2sl/d5j8ocS7crkKwR8Tbo3ZG8NgObQNTL+mIFR1AoGAJS66zzIoHM2IDt7q2pJi +Bz0dfsShaB+23XrY3cJPukTSO4N7mNuN4v/XH9VclVayozVLclnGD4JuVXbanYv0 +CRv9B8F9wOI97PuTSIm8LPaNDTqnUWrW3w8H34261ah768o2wI3MrAw8gTMj9FKE +mQJkd+eHcm9lD+XNLgCHxAECgYBiMQ2t00L89NnraKLscp4b44GPsl9QehoVD12o +q2JhO1Ziv2WY3eVNV0hhgkNopdbTrEGFNKRebNEn2xG9c2DO0tQ9s/jw0f0RN87s +Z+1HyZebzPmn1h4+zPUVZGwGbTPgRz8nuBKoS/541bg5pJ9FBojEuDfe9C3a7SpQ +r0EzpQKBgBmYrKi07wTUSZ3TjHWvOK75XhJ5pOdfbuDZk+N02jzhmihzI2M/Sh7s +l1gavtY9o9JGUAW35L/Ju4X1Xgm3t5Cg9+4n6ecOfSKP9nJpgj1EvHyWvw9t8ZSg +V9M0Hf5EoSPWuEj+mlWrIuvV/HgkouUVqDzUm6wUuyTqdTCgUQrA +-----END RSA PRIVATE KEY----- diff --git a/wi/network/servertalk_api.js b/wi/network/servertalk_api.js new file mode 100644 index 000000000..be4220edf --- /dev/null +++ b/wi/network/servertalk_api.js @@ -0,0 +1,148 @@ +const servertalk = require('./servertalk_client.js'); +const uuid = require('node-uuid'); + +class ServertalkAPI +{ + Init(addr, port, ipv6, credentials) { + this.client = new servertalk.client(); + this.client.Init(addr, port, ipv6, 'WebInterface', credentials); + this.pending_calls = {}; + this.subscriptions = {}; + var self = this; + + this.client.on('connecting', function() { + //console.log('Connecting...'); + }); + + this.client.on('connect', function(){ + //console.log('Connected'); + }); + + this.client.on('close', function(){ + //console.log('Closed'); + }); + + this.client.on('error', function(err){ + }); + + this.client.on('message', function(opcode, packet) { + if(opcode == 47) { + var response = Buffer.from(packet).toString('utf8'); + try { + var res = JSON.parse(response); + + if(res.id) { + if(self.pending_calls.hasOwnProperty(res.id)) { + var entry = self.pending_calls[res.id]; + + if(res.error) { + var reject = entry[1]; + reject(res.error); + } else { + var resolve = entry[0]; + resolve(res.response); + } + + delete self.pending_calls[res.id]; + } + } + } catch(ex) { + console.log('Error processing response from server:\n', ex); + } + } else if(opcode == 104) { + var message = Buffer.from(packet).toString('utf8'); + try { + var msg = JSON.parse(message); + + if(msg.event) { + if(self.subscriptions.hasOwnProperty(msg.event)) { + var subs = self.subscriptions[msg.event]; + + for(var idx in subs) { + try { + var sub = subs[idx]; + sub.emit('subscriptionMessage', msg); + } catch(ex) { + console.log('Error dispatching subscription message', ex); + } + } + } + } + } catch(ex) { + console.log('Error processing response from server:\n', ex); + } + } + }); + } + + Call(method, args, timeout) { + if(!timeout) { + timeout = 15000 + } + + var self = this; + return new Promise( + function(resolve, reject) { + if(!self.client.Connected()) { + reject('Not connected to world server.'); + return; + } + + var id = uuid.v4(); + + self.pending_calls[id] = [resolve, reject]; + + var c = { id: id, method: method, params: args }; + self.client.Send(47, Buffer.from(JSON.stringify(c))); + + setTimeout(function() { + delete self.pending_calls[id]; + reject('Request timed out after ' + timeout + 'ms'); + }, timeout); + } + ); + } + + Notify(method, args) { + var c = { method: method, params: args }; + client.Send(47, Buffer.from(JSON.stringify(c))); + } + + Subscribe(event_id, who) { + this.Unsubscribe(event_id, who); + + var subs = this.subscriptions[event_id]; + if(subs) { + //console.log('Subscribe', who.uuid, 'to', event_id); + subs[who.uuid] = who; + } else { + //console.log('Subscribe', who.uuid, 'to', event_id); + this.subscriptions[event_id] = { }; + this.subscriptions[event_id][who.uuid] = who; + //Tell our server we have a subscription for event_id + } + } + + Unsubscribe(event_id, who) { + var subs = this.subscriptions[event_id]; + if(subs) { + //console.log('Unsubscribe', who.uuid, 'from', event_id); + delete subs[who.uuid]; + + if(Object.keys(subs).length === 0) { + delete this.subscriptions[event_id]; + //Tell our server we no longer have a subscription for event_id + } + } + } + + UnsubscribeAll(who) { + for(var sub_idx in this.subscriptions) { + this.Unsubscribe(sub_idx, who); + } + } +} + +module.exports = { + 'api': ServertalkAPI +} \ No newline at end of file diff --git a/wi/network/servertalk_client.js b/wi/network/servertalk_client.js new file mode 100644 index 000000000..4197a1aa4 --- /dev/null +++ b/wi/network/servertalk_client.js @@ -0,0 +1,299 @@ +var net = require('net'); +var sodium = require('libsodium-wrappers'); +const EventEmitter = require('events'); + +var ServertalkPacketType = +{ + ServertalkClientHello: 1, + ServertalkServerHello: 2, + ServertalkClientHandshake: 3, + ServertalkClientDowngradeSecurityHandshake: 4, + ServertalkMessage: 5, +}; + +class ServertalkClient extends EventEmitter +{ + Init(addr, port, ipv6, identifier, credentials) { + this.m_addr = addr; + this.m_identifier = identifier; + this.m_credentials = credentials; + this.m_connecting = false; + this.m_port = port; + this.m_ipv6 = ipv6; + this.m_encrypted = false; + this.m_connection = null; + this.m_buffer = Buffer.alloc(0); + this.m_public_key_ours = null; + this.m_private_key_ours = null; + this.m_nonce_ours = null; + this.m_public_key_theirs = null; + this.m_nonce_theirs = null; + this.m_shared_key = null; + + var self = this; + setInterval(function() { self.Connect(); }, 100); + } + + Send(opcode, p) { + try { + var out; + if(this.m_encrypted) { + if(p.length == 0) { + p = Buffer.alloc(1); + } + + out = Buffer.alloc(6); + out.writeUInt32LE(p.length + sodium.crypto_secretbox_MACBYTES, 0); + out.writeUInt16LE(opcode, 4); + + var cipher = sodium.crypto_box_easy_afternm(p, this.m_nonce_ours, this.m_shared_key); + this.IncrementUint64(this.m_nonce_ours); + + out = Buffer.concat([out, Buffer.from(cipher)], out.length + cipher.length); + } else { + out = Buffer.alloc(6); + out.writeUInt32LE(p.length, 0); + out.writeUInt16LE(opcode, 4); + out = Buffer.concat([out, p], out.length + p.length); + } + + this.InternalSend(ServertalkPacketType.ServertalkMessage, out); + } catch(ex) { + this.emit('error', new Error(ex)); + } + } + + Connected() { + return this.m_connection && !this.m_connecting; + } + + Connect() { + if (this.m_port == 0 || this.m_connection || this.m_connecting) { + return; + } + + this.m_connecting = true; + + this.emit('connecting'); + + var self = this; + this.m_connection = net.connect({port: this.m_port, host: this.m_addr}, function() { + self.m_connection.on('close', function(had_error) { + self.emit('close'); + self.m_connection = null; + self.m_encrypted = false; + }); + + self.m_connection.on('data', function(buffer) { + self.ProcessData(buffer); + }); + + self.SendHello(); + self.m_connecting = false; + }); + + this.m_connection.on('error', function() { + self.emit('close'); + self.m_connection = null; + self.m_connecting = false; + }); + } + + ProcessData(buffer) { + this.m_buffer = Buffer.concat([this.m_buffer, buffer], this.m_buffer.length + buffer.length); + this.ProcessReadBuffer(); + } + + SendHello() { + var p = Buffer.alloc(0); + this.InternalSend(ServertalkPacketType.ServertalkClientHello, p); + } + + InternalSend(type, p) { + if(!this.m_connection) { + return; + } + + var out = Buffer.alloc(5); + out.writeUInt32LE(p.length, 0); + out.writeUInt8(type, 4); + + if (p.length > 0) { + out = Buffer.concat([out, p], out.length + p.length); + } + + this.m_connection.write(out); + } + + ProcessReadBuffer() { + var current = 0; + var total = this.m_buffer.length; + + while (current < total) { + var left = total - current; + + var length = 0; + var type = 0; + if (left < 5) { + break; + } + + length = this.m_buffer.readUInt32LE(current); + type = this.m_buffer.readUInt8(current + 4); + + if (current + 5 + length > total) { + break; + } + + if (length == 0) { + var p = Buffer.alloc(0); + switch (type) { + case ServertalkPacketType.ServertalkServerHello: + this.ProcessHello(p); + break; + case ServertalkPacketType.ServertalkMessage: + this.ProcessMessage(p); + break; + } + } + else { + var p = this.m_buffer.slice(current + 5, current + 5 + length); + switch (type) { + case ServertalkPacketType.ServertalkServerHello: + this.ProcessHello(p); + break; + case ServertalkPacketType.ServertalkMessage: + this.ProcessMessage(p); + break; + } + } + + current += length + 5; + } + + if (current == total) { + this.m_buffer = Buffer.alloc(0); + } + else { + this.m_buffer = this.m_buffer.slice(current); + } + } + + ProcessHello(p) { + this.m_encrypted = false; + this.m_public_key_ours = null; + this.m_public_key_theirs = null; + this.m_private_key_ours = null; + this.m_nonce_ours = null; + this.m_nonce_theirs = null; + this.m_shared_key = null; + + try { + var enc = p.readUInt8(0) == 1 ? true : false; + if (enc) { + if (p.length == (1 + sodium.crypto_box_PUBLICKEYBYTES + sodium.crypto_box_NONCEBYTES)) { + this.m_public_key_theirs = p.slice(1, 1 + sodium.crypto_box_PUBLICKEYBYTES); + this.m_nonce_theirs = p.slice(1 + sodium.crypto_box_PUBLICKEYBYTES, 1 + sodium.crypto_box_PUBLICKEYBYTES + sodium.crypto_box_NONCEBYTES); + this.m_encrypted = true; + this.SendHandshake(false); + + this.emit('connect'); + } + else { + this.emit('error', new Error('Could not process hello, size !=', 1 + sodium.crypto_box_PUBLICKEYBYTES + sodium.crypto_box_NONCEBYTES)); + } + } else { + this.SendHandshake(false); + + this.emit('connect'); + } + } catch(ex) { + this.emit('error', new Error(ex)); + } + } + + ProcessMessage(p) { + try { + var length = p.readUInt32LE(0); + var opcode = p.readUInt16LE(4); + if(length > 0) { + var data = p.slice(6); + + if(this.m_encrypted) { + var message_len = length - sodium.crypto_secretbox_MACBYTES; + + var decrypted = sodium.crypto_box_open_easy_afternm(data, this.m_nonce_theirs, this.m_shared_key); + + this.IncrementUint64(this.m_nonce_theirs); + + this.emit('message', opcode, decrypted); + } else { + this.emit('message', opcode, data); + } + } else { + this.emit('message', opcode, Buffer.alloc(0)); + } + } catch(ex) { + this.emit('error', new Error(ex)); + } + } + + SendHandshake() { + var handshake; + + if(this.m_encrypted) { + var keypair = sodium.crypto_box_keypair(); + this.m_public_key_ours = keypair.publicKey; + this.m_private_key_ours = keypair.privateKey; + this.m_nonce_ours = Buffer.from(sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES)); + this.m_shared_key = sodium.crypto_box_beforenm(this.m_public_key_theirs, this.m_private_key_ours); + + this.m_public_key_theirs = null; + this.m_private_key_ours = null; + + var message = Buffer.alloc(this.m_identifier.length + this.m_credentials.length + 2); + message.write(this.m_identifier, 0); + message.write(this.m_credentials, this.m_identifier.length + 1); + + var ciphertext = sodium.crypto_box_easy_afternm(message, this.m_nonce_ours, this.m_shared_key); + + handshake = Buffer.concat([Buffer.from(this.m_public_key_ours), Buffer.from(this.m_nonce_ours), Buffer.from(ciphertext)], sodium.crypto_box_PUBLICKEYBYTES + sodium.crypto_box_NONCEBYTES + ciphertext.length); + this.IncrementUint64(this.m_nonce_ours); + + this.m_public_key_ours = null; + } else { + handshake = Buffer.alloc(this.m_identifier.length + this.m_credentials.length + 2); + handshake.write(this.m_identifier, 0); + handshake.write(this.m_credentials, this.m_identifier.length() + 1); + } + + this.InternalSend(ServertalkPacketType.ServertalkClientHandshake, handshake); + } + + IncrementUint64(value) { + var bytes = []; + for(var i = 0; i < 8; ++i) { + bytes[i] = value[i]; + } + + bytes[0] += 1; + for(i = 0; i < 7; ++i) { + if(bytes[i] >= 0x100) { + bytes[0] = 0; + bytes[i + 1] += 1; + } + } + + if(bytes[7] >= 0x100) { + bytes[7] = 0; + } + + for(var i = 0; i < 8; ++i) { + value[i] = bytes[i]; + } + } +} + +module.exports = { + 'client': ServertalkClient +} \ No newline at end of file diff --git a/wi/package.json b/wi/package.json new file mode 100644 index 000000000..43b9e9f98 --- /dev/null +++ b/wi/package.json @@ -0,0 +1,24 @@ +{ + "name": "wi", + "version": "1.0.0", + "description": "Web interface connection for EQEmu", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "KimLS", + "license": "GPL-3.0", + "dependencies": { + "body-parser": "^1.15.2", + "express": "^4.14.0", + "hammerjs": "^2.0.8", + "jsonwebtoken": "^7.2.1", + "libsodium": "^0.4.8", + "libsodium-wrappers": "^0.4.8", + "libsodium-wrappers-sumo": "^0.4.8", + "moment": "^2.17.1", + "mysql": "^2.12.0", + "node-uuid": "^1.4.7", + "ws": "^1.1.1" + } +} diff --git a/wi/settings.json b/wi/settings.json new file mode 100644 index 000000000..de325ddde --- /dev/null +++ b/wi/settings.json @@ -0,0 +1,21 @@ +{ + "db": { + "connectionLimit": 10, + "host": "localhost", + "user": "root", + "password": "blink", + "database": "eqdb" + }, + "servertalk": { + "addr": "localhost", + "port": "9101", + "key": "ujwn2isnal1987scanb" + }, + "https": { + "enabled": false, + "key": "key.pem", + "cert": "cert.pem" + }, + "port": 9080, + "key": "key.pem" +} \ No newline at end of file diff --git a/wi/test.js b/wi/test.js new file mode 100644 index 000000000..0ede3b12c --- /dev/null +++ b/wi/test.js @@ -0,0 +1,11 @@ +const WebSocket = require('ws'); +const ws = new WebSocket('ws://localhost:9080'); + +ws.on('open', function open() { + ws.send(JSON.stringify({authorization: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IktTcHJpdGUxIiwiZXhwIjoxNDg2MzI4MDI3LCJpYXQiOjE0ODU3MjMyMjd9.fJUeSQsxb5C13ICANox81YdE5yImkrVw-lRCP3O40-E', method: 'EQW::ZoneUpdate::Subscribe'})); + ws.send(JSON.stringify({authorization: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IktTcHJpdGUxIiwiZXhwIjoxNDg2MzI4MDI3LCJpYXQiOjE0ODU3MjMyMjd9.fJUeSQsxb5C13ICANox81YdE5yImkrVw-lRCP3O40-E', method: 'EQW::ClientUpdate::Subscribe'})); +}); + +ws.on('message', function(data, flags) { + console.log(data); +}); \ No newline at end of file diff --git a/wi/ws/eqw.js b/wi/ws/eqw.js new file mode 100644 index 000000000..81d5c22f4 --- /dev/null +++ b/wi/ws/eqw.js @@ -0,0 +1,18 @@ +const common = require('./wi_common.js'); + +var RegisterEQW = function(wsi, api) { + common.Register('EQW::GetConfig', wsi, api); + common.Register('EQW::IsLocked', wsi, api); + common.Register('EQW::Lock', wsi, api); + common.Register('EQW::Unlock', wsi, api); + common.Register('EQW::GetPlayerCount', wsi, api); + common.Register('EQW::GetZoneCount', wsi, api); + common.Register('EQW::GetLauncherCount', wsi, api); + common.Register('EQW::GetLoginServerCount', wsi, api); + common.RegisterSubscription('EQW::ZoneUpdate', wsi, api); + common.RegisterSubscription('EQW::ClientUpdate', wsi, api); +}; + +module.exports = { + 'Register': RegisterEQW +} \ No newline at end of file diff --git a/wi/ws/index.js b/wi/ws/index.js new file mode 100644 index 000000000..1d4f92a56 --- /dev/null +++ b/wi/ws/index.js @@ -0,0 +1,7 @@ +var RegisterAPI = function(wsi, api) { + require('./eqw.js').Register(wsi, api); +}; + +module.exports = { + 'Register': RegisterAPI +} \ No newline at end of file diff --git a/wi/ws/wi_common.js b/wi/ws/wi_common.js new file mode 100644 index 000000000..a2712783a --- /dev/null +++ b/wi/ws/wi_common.js @@ -0,0 +1,27 @@ +function Register(name, wsi, api) { + wsi.Register(name, + function(request) { + api.Call(name, request.params) + .then(function(value) { + wsi.Send(request, value); + }) + .catch(function(reason) { + wsi.SendError(request, reason); + }); + }, true); +} + +function RegisterSubscription(event, wsi, api) { + wsi.Register(event + '::Subscribe', function(request) { + api.Subscribe(event, request.ws); + }); + + wsi.Register(event + '::Unsubscribe', function(request) { + api.Unsubscribe(event, request.ws); + }); +} + +module.exports = { + 'Register': Register, + 'RegisterSubscription': RegisterSubscription +} diff --git a/wi/ws/ws_interface.js b/wi/ws/ws_interface.js new file mode 100644 index 000000000..ea60ca2fd --- /dev/null +++ b/wi/ws/ws_interface.js @@ -0,0 +1,118 @@ +const WebSocketServer = require('ws').Server; +const jwt = require('jsonwebtoken'); +const uuid = require('node-uuid'); + +class WebSocketInterface +{ + constructor(server, key, api) { + this.wss = new WebSocketServer({ server: server }); + this.methods = {}; + var self = this; + + this.wss.on('connection', function connection(ws) { + self.ws = ws; + ws.uuid = uuid.v4(); + ws.on('message', function incoming(message) { + try { + var request = JSON.parse(message); + request.ws = ws; + + if(request.method) { + var method = self.methods[request.method]; + if(!method) { + self.SendError(request, 'Method not found: ' + request.method); + return; + } + + if(method.requires_auth) { + if(!request.authorization) { + self.SendError(request, 'Authorization Required'); + return; + } + + jwt.verify(request.authorization, key, function(err, decoded) { + if(err) { + self.SendError(request, 'Authorization Required'); + return; + } + + request.token = decoded; + method.fn(request); + }); + + return; + } + + method.fn(request); + + } else { + self.SendError(request, 'No method supplied'); + } + + } catch(ex) { + console.log('Error parsing message:', ex); + self.SendError(null, 'No method supplied'); + } + }); + + ws.on('close', function() { + api.UnsubscribeAll(ws); + }); + + ws.on('subscriptionMessage', function(msg) { + self.SendRaw(msg); + }); + }); + } + + Register(method, fn, requires_auth) { + var entry = { fn: fn, requires_auth: requires_auth }; + this.methods[method] = entry; + } + + SendError(request, msg) { + try { + if(this.ws) { + var error = {}; + + if(request && request.id) { + error.id = request.id; + } + + error.error = msg; + this.ws.send(JSON.stringify(error)); + } + } catch(ex) { + console.log(ex); + } + } + + Send(request, value) { + try { + if(this.ws) { + var response = {}; + + if(request && request.id) { + response.id = response.id; + } + + response.response = value; + this.ws.send(JSON.stringify(response)); + } + } catch(ex) { + console.log(ex); + } + } + + SendRaw(obj) { + try { + this.ws.send(JSON.stringify(obj)); + } catch(ex) { + console.log(ex); + } + } +} + +module.exports = { + 'wsi': WebSocketInterface +} \ No newline at end of file diff --git a/world/CMakeLists.txt b/world/CMakeLists.txt index c042a7364..fa4b6ecc6 100644 --- a/world/CMakeLists.txt +++ b/world/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(world_sources adventure.cpp @@ -42,6 +42,7 @@ SET(world_headers lfplist.h login_server.h login_server_list.h + net.h queryserv.h sof_char_create_data.h ucs.h @@ -64,4 +65,8 @@ ADD_DEFINITIONS(-DWORLD) TARGET_LINK_LIBRARIES(world ${SERVER_LIBS}) +IF(EQEMU_BUILD_PERL) + TARGET_LINK_LIBRARIES(world ${PERL_LIBRARY}) +ENDIF() + SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index f75e963f9..2de1ac1f6 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(zone_sources aa.cpp @@ -79,7 +79,6 @@ SET(zone_sources horse.cpp inventory.cpp loottables.cpp - main.cpp map.cpp merc.cpp mob.cpp @@ -88,6 +87,7 @@ SET(zone_sources mob_movement_manager.cpp mob_info.cpp mod_functions.cpp + net.cpp npc.cpp npc_ai.cpp npc_scale_manager.cpp @@ -210,6 +210,7 @@ SET(zone_headers merc.h mob.h mob_movement_manager.h + net.h npc.h npc_ai.h npc_scale_manager.h @@ -257,4 +258,12 @@ ADD_DEFINITIONS(-DZONE) TARGET_LINK_LIBRARIES(zone ${SERVER_LIBS}) +IF(EQEMU_BUILD_PERL) + TARGET_LINK_LIBRARIES(zone ${PERL_LIBRARY}) +ENDIF() + +IF(EQEMU_BUILD_LUA) + TARGET_LINK_LIBRARIES(zone luabind ${LUA_LIBRARY}) +ENDIF(EQEMU_BUILD_LUA) + SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) diff --git a/zone/attack.cpp b/zone/attack.cpp index 32fd7e6da..7c58f5059 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -40,6 +40,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include #include #include +#include #ifdef BOTS #include "bot.h" diff --git a/zone/client.cpp b/zone/client.cpp index 25b39330a..3c16b8a9b 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -41,6 +41,7 @@ extern volatile bool RunLoops; #include "../common/profanity_manager.h" #include "data_bucket.h" #include "position.h" +#include "net.h" #include "worldserver.h" #include "zonedb.h" #include "petitions.h" @@ -66,8 +67,6 @@ extern PetitionList petition_list; bool commandlogged; char entirecommand[255]; -void UpdateWindowTitle(char* iNewTitle); - Client::Client(EQStreamInterface* ieqs) : Mob("No name", // name "", // lastname @@ -245,7 +244,7 @@ Client::Client(EQStreamInterface* ieqs) PendingRezzSpellID = 0; numclients++; // emuerror; - UpdateWindowTitle(nullptr); + UpdateWindowTitle(); horseId = 0; tgb = false; tribute_master_id = 0xFFFFFFFF; @@ -454,7 +453,7 @@ Client::~Client() { ClearRespawnOptions(); numclients--; - UpdateWindowTitle(nullptr); + UpdateWindowTitle(); if(zone) zone->RemoveAuth(GetName(), lskey); diff --git a/zone/embperl.h b/zone/embperl.h index 816e9b84a..ebd76fa0e 100644 --- a/zone/embperl.h +++ b/zone/embperl.h @@ -25,10 +25,6 @@ Eglin #ifndef WIN32 extern "C" { //the perl headers dont do this for us... #endif -#if _MSC_VER -#define __inline__ __inline -#define __builtin_expect -#endif #include #include #ifndef WIN32 diff --git a/zone/embxs.h b/zone/embxs.h index 97e3bb573..67a37a6da 100644 --- a/zone/embxs.h +++ b/zone/embxs.h @@ -8,10 +8,6 @@ #ifndef WIN32 extern "C" { //the perl headers dont do this for us... #endif -#if _MSC_VER -#define __inline__ __inline -#define __builtin_expect -#endif #include #include #ifndef WIN32 diff --git a/zone/entity.cpp b/zone/entity.cpp index 7f016f197..084e0fc93 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -33,6 +33,7 @@ #include "../common/guilds.h" #include "guild_mgr.h" +#include "net.h" #include "petitions.h" #include "quest_parser_collection.h" #include "raids.h" @@ -55,6 +56,7 @@ extern Zone *zone; extern volatile bool is_zone_loaded; extern WorldServer worldserver; +extern NetConnection net; extern uint32 numclients; extern PetitionList petition_list; @@ -298,13 +300,6 @@ const Bot *Entity::CastToBot() const #endif EntityList::EntityList() - : - object_timer(5000), - door_timer(5000), - corpse_timer(2000), - group_timer(1000), - raid_timer(1000), - trap_timer(1000) { // set up ids between 1 and 1500 // neither client or server performs well if you have @@ -354,7 +349,7 @@ void EntityList::TrapProcess() return; if (trap_list.empty()) { - trap_timer.Disable(); + net.trap_timer.Disable(); return; } @@ -393,7 +388,7 @@ void EntityList::GroupProcess() return; if (group_list.empty()) { - group_timer.Disable(); + net.group_timer.Disable(); return; } @@ -417,7 +412,7 @@ void EntityList::RaidProcess() return; if (raid_list.empty()) { - raid_timer.Disable(); + net.raid_timer.Disable(); return; } @@ -432,7 +427,7 @@ void EntityList::DoorProcess() return; #endif if (door_list.empty()) { - door_timer.Disable(); + net.door_timer.Disable(); return; } @@ -450,7 +445,7 @@ void EntityList::DoorProcess() void EntityList::ObjectProcess() { if (object_list.empty()) { - object_timer.Disable(); + net.object_timer.Disable(); return; } @@ -469,7 +464,7 @@ void EntityList::ObjectProcess() void EntityList::CorpseProcess() { if (corpse_list.empty()) { - corpse_timer.Disable(); // No corpses in list + net.corpse_timer.Disable(); // No corpses in list return; } @@ -611,8 +606,8 @@ void EntityList::AddGroup(Group *group, uint32 gid) { group->SetID(gid); group_list.push_back(group); - if (!group_timer.Enabled()) - group_timer.Start(); + if (!net.group_timer.Enabled()) + net.group_timer.Start(); #if EQDEBUG >= 5 CheckGroupList(__FILE__, __LINE__); #endif @@ -636,8 +631,8 @@ void EntityList::AddRaid(Raid *raid, uint32 gid) { raid->SetID(gid); raid_list.push_back(raid); - if (!raid_timer.Enabled()) - raid_timer.Start(); + if (!net.raid_timer.Enabled()) + net.raid_timer.Start(); } @@ -654,8 +649,8 @@ void EntityList::AddCorpse(Corpse *corpse, uint32 in_id) corpse->CalcCorpseName(); corpse_list.insert(std::pair(corpse->GetID(), corpse)); - if (!corpse_timer.Enabled()) - corpse_timer.Start(); + if (!net.corpse_timer.Enabled()) + net.corpse_timer.Start(); } void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue) @@ -757,8 +752,8 @@ void EntityList::AddObject(Object *obj, bool SendSpawnPacket) object_list.insert(std::pair(obj->GetID(), obj)); - if (!object_timer.Enabled()) - object_timer.Start(); + if (!net.object_timer.Enabled()) + net.object_timer.Start(); } void EntityList::AddDoor(Doors *door) @@ -766,16 +761,16 @@ void EntityList::AddDoor(Doors *door) door->SetEntityID(GetFreeID()); door_list.insert(std::pair(door->GetEntityID(), door)); - if (!door_timer.Enabled()) - door_timer.Start(); + if (!net.door_timer.Enabled()) + net.door_timer.Start(); } void EntityList::AddTrap(Trap *trap) { trap->SetID(GetFreeID()); trap_list.insert(std::pair(trap->GetID(), trap)); - if (!trap_timer.Enabled()) - trap_timer.Start(); + if (!net.trap_timer.Enabled()) + net.trap_timer.Start(); } void EntityList::AddBeacon(Beacon *beacon) diff --git a/zone/entity.h b/zone/entity.h index 6b22f1a4c..339bbfd8a 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -538,13 +538,6 @@ private: std::list area_list; std::queue free_ids; - Timer object_timer; - Timer door_timer; - Timer corpse_timer; - Timer group_timer; - Timer raid_timer; - Timer trap_timer; - // Please Do Not Declare Any EntityList Class Members After This Comment #ifdef BOTS public: diff --git a/zone/lua_entity_list.cpp b/zone/lua_entity_list.cpp index 3d53b6166..abfc020d6 100644 --- a/zone/lua_entity_list.cpp +++ b/zone/lua_entity_list.cpp @@ -508,37 +508,37 @@ luabind::scope lua_register_entity_list() { luabind::scope lua_register_mob_list() { return luabind::class_("MobList") - .def_readwrite("entries", &Lua_Mob_List::entries, luabind::return_stl_iterator()); + .def_readwrite("entries", &Lua_Mob_List::entries, luabind::return_stl_iterator); } luabind::scope lua_register_client_list() { return luabind::class_("ClientList") - .def_readwrite("entries", &Lua_Client_List::entries, luabind::return_stl_iterator()); + .def_readwrite("entries", &Lua_Client_List::entries, luabind::return_stl_iterator); } luabind::scope lua_register_npc_list() { return luabind::class_("NPCList") - .def_readwrite("entries", &Lua_NPC_List::entries, luabind::return_stl_iterator()); + .def_readwrite("entries", &Lua_NPC_List::entries, luabind::return_stl_iterator); } luabind::scope lua_register_corpse_list() { return luabind::class_("CorpseList") - .def_readwrite("entries", &Lua_Corpse_List::entries, luabind::return_stl_iterator()); + .def_readwrite("entries", &Lua_Corpse_List::entries, luabind::return_stl_iterator); } luabind::scope lua_register_object_list() { return luabind::class_("ObjectList") - .def_readwrite("entries", &Lua_Object_List::entries, luabind::return_stl_iterator()); + .def_readwrite("entries", &Lua_Object_List::entries, luabind::return_stl_iterator); } luabind::scope lua_register_door_list() { return luabind::class_("DoorList") - .def_readwrite("entries", &Lua_Doors_List::entries, luabind::return_stl_iterator()); + .def_readwrite("entries", &Lua_Doors_List::entries, luabind::return_stl_iterator); } luabind::scope lua_register_spawn_list() { return luabind::class_("SpawnList") - .def_readwrite("entries", &Lua_Spawn_List::entries, luabind::return_stl_iterator()); + .def_readwrite("entries", &Lua_Spawn_List::entries, luabind::return_stl_iterator); } #endif diff --git a/zone/lua_hate_list.cpp b/zone/lua_hate_list.cpp index 82d79f977..e8c6a52df 100644 --- a/zone/lua_hate_list.cpp +++ b/zone/lua_hate_list.cpp @@ -63,7 +63,7 @@ luabind::scope lua_register_hate_entry() { luabind::scope lua_register_hate_list() { return luabind::class_("HateList") - .def_readwrite("entries", &Lua_HateList::entries, luabind::return_stl_iterator()); + .def_readwrite("entries", &Lua_HateList::entries, luabind::return_stl_iterator); } #endif diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 7913f528a..7d769b8dd 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -2229,9 +2229,9 @@ bool Lua_Mob::IsBerserk() { return self->IsBerserk(); } -bool Lua_Mob::TryFinishingBlow(Lua_Mob defender, int *damage) { +bool Lua_Mob::TryFinishingBlow(Lua_Mob defender, int &damage) { Lua_Safe_Call_Bool(); - return self->TryFinishingBlow(defender, *damage); + return self->TryFinishingBlow(defender, damage); } int Lua_Mob::GetBodyType() @@ -2636,7 +2636,7 @@ luabind::scope lua_register_mob() { .def("AttackAnimation", &Lua_Mob::AttackAnimation) .def("GetWeaponDamage", &Lua_Mob::GetWeaponDamage) .def("IsBerserk", &Lua_Mob::IsBerserk) - .def("TryFinishingBlow", (bool(Lua_Mob::*)(int*))&Lua_Mob::TryFinishingBlow) + .def("TryFinishingBlow", &Lua_Mob::TryFinishingBlow) .def("GetBodyType", &Lua_Mob::GetBodyType) .def("GetOrigBodyType", &Lua_Mob::GetOrigBodyType) .def("CheckNumHitsRemaining", &Lua_Mob::CheckNumHitsRemaining); diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 69ede413b..592ac6243 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -418,7 +418,7 @@ public: int AttackAnimation(int Hand, Lua_ItemInst weapon); int GetWeaponDamage(Lua_Mob against, Lua_ItemInst weapon); bool IsBerserk(); - bool TryFinishingBlow(Lua_Mob defender, int *damage); + bool TryFinishingBlow(Lua_Mob defender, int &damage); int GetBodyType(); int GetOrigBodyType(); void CheckNumHitsRemaining(int type, int32 buff_slot, uint16 spell_id); diff --git a/zone/lua_mod.cpp b/zone/lua_mod.cpp index 8dc77f4f7..a891fb064 100644 --- a/zone/lua_mod.cpp +++ b/zone/lua_mod.cpp @@ -1,5 +1,3 @@ -#ifdef LUA_EQEMU - #include "lua.hpp" #include #include @@ -631,5 +629,3 @@ void LuaMod::GetExperienceForKill(Client *self, Mob *against, uint32 &returnValu lua_pop(L, n); } } - -#endif diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 7c7242e4c..2c7cfe53e 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -1300,6 +1300,8 @@ QuestEventID LuaParser::ConvertLuaEvent(QuestEventID evt) { } } +#endif + void LuaParser::MeleeMitigation(Mob *self, Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault) { for (auto &mod : mods_) { @@ -1372,5 +1374,3 @@ uint32 LuaParser::GetExperienceForKill(Client *self, Mob *against, bool &ignoreD } return retval; } - -#endif diff --git a/zone/lua_stat_bonuses.cpp b/zone/lua_stat_bonuses.cpp index d311cf123..282aaad38 100644 --- a/zone/lua_stat_bonuses.cpp +++ b/zone/lua_stat_bonuses.cpp @@ -1,5 +1,3 @@ -#ifdef LUA_EQEMU - #include "lua.hpp" #include @@ -1544,6 +1542,4 @@ luabind::scope lua_register_stat_bonuses() { .def("Assassinate", &Lua_StatBonuses::GetAssassinate) .def("AssassinateLevel", &Lua_StatBonuses::GetAssassinateLevel) .def("ReduceTradeskillFail", &Lua_StatBonuses::GetReduceTradeskillFail); -} - -#endif +} \ No newline at end of file diff --git a/zone/main.cpp b/zone/net.cpp similarity index 92% rename from zone/main.cpp rename to zone/net.cpp index 9ee3eda25..0ce901359 100644 --- a/zone/main.cpp +++ b/zone/net.cpp @@ -47,6 +47,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "zone_config.h" #include "masterentity.h" #include "worldserver.h" +#include "net.h" #include "zone.h" #include "queryserv.h" #include "command.h" @@ -95,6 +96,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA volatile bool RunLoops = true; extern volatile bool is_zone_loaded; +NetConnection net; EntityList entity_list; WorldServer worldserver; uint32 numclients = 0; @@ -113,9 +115,6 @@ const ZoneConfig *Config; double frame_time = 0.0; void Shutdown(); -void UpdateWindowTitle(char* iNewTitle); -void CatchSignal(int sig_num); - extern void MapOpcodes(); int main(int argc, char** argv) { @@ -441,7 +440,7 @@ int main(int argc, char** argv) { bool websocker_server_opened = false; Timer quest_timers(100); - UpdateWindowTitle(nullptr); + UpdateWindowTitle(); std::shared_ptr eqss; EQStreamInterface *eqsi; std::unique_ptr eqsm; @@ -515,12 +514,23 @@ int main(int argc, char** argv) { if (is_zone_loaded) { { - entity_list.GroupProcess(); - entity_list.DoorProcess(); - entity_list.ObjectProcess(); - entity_list.CorpseProcess(); - entity_list.TrapProcess(); - entity_list.RaidProcess(); + if (net.group_timer.Enabled() && net.group_timer.Check()) + entity_list.GroupProcess(); + + if (net.door_timer.Enabled() && net.door_timer.Check()) + entity_list.DoorProcess(); + + if (net.object_timer.Enabled() && net.object_timer.Check()) + entity_list.ObjectProcess(); + + if (net.corpse_timer.Enabled() && net.corpse_timer.Check()) + entity_list.CorpseProcess(); + + if (net.trap_timer.Enabled() && net.trap_timer.Check()) + entity_list.TrapProcess(); + + if (net.raid_timer.Enabled() && net.raid_timer.Check()) + entity_list.RaidProcess(); entity_list.Process(); entity_list.MobProcess(); @@ -612,6 +622,60 @@ void Shutdown() LogSys.CloseFileLogs(); } +uint32 NetConnection::GetIP() +{ + char name[255 + 1]; + size_t len = 0; + hostent* host = 0; + + if (gethostname(name, len) < 0 || len <= 0) + { + return 0; + } + + host = (hostent*)gethostbyname(name); + if (host == 0) + { + return 0; + } + + return inet_addr(host->h_addr); +} + +uint32 NetConnection::GetIP(char* name) +{ + hostent* host = 0; + + host = (hostent*)gethostbyname(name); + if (host == 0) + { + return 0; + } + + return inet_addr(host->h_addr); + +} + +NetConnection::NetConnection() + : + object_timer(5000), + door_timer(5000), + corpse_timer(2000), + group_timer(1000), + raid_timer(1000), + trap_timer(1000) +{ + group_timer.Disable(); + raid_timer.Disable(); + corpse_timer.Disable(); + door_timer.Disable(); + object_timer.Disable(); + trap_timer.Disable(); +} + +NetConnection::~NetConnection() { +} + /* Update Window Title with relevant information */ void UpdateWindowTitle(char* iNewTitle) { #ifdef _WINDOWS diff --git a/zone/net.h b/zone/net.h new file mode 100644 index 000000000..4d44b6058 --- /dev/null +++ b/zone/net.h @@ -0,0 +1,48 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifdef _WINDOWS + #include + #include +#else + #include + #include + #include + #include + #include +#endif + +#include "../common/types.h" +#include "../common/timer.h" +void CatchSignal(int); +void UpdateWindowTitle(char* iNewTitle = 0); + +class NetConnection +{ +public: + ~NetConnection(); + NetConnection(); + + uint32 GetIP(); + uint32 GetIP(char* name); + Timer object_timer; + Timer door_timer; + Timer corpse_timer; + Timer group_timer; + Timer raid_timer; + Timer trap_timer; +}; diff --git a/zone/oldcode.cpp b/zone/oldcode.cpp new file mode 100644 index 000000000..7329c73f3 --- /dev/null +++ b/zone/oldcode.cpp @@ -0,0 +1,1851 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2004 EQEMu Development Team (http://eqemu.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "../common/debug.h" +#include +using namespace std; +#include +#include +#include +#include +#include + #ifdef _CRTDBG_MAP_ALLOC + #undef new + #endif +#include + #ifdef _CRTDBG_MAP_ALLOC + #define new new(_NORMAL_BLOCK, __FILE__, __LINE__) + #endif +using namespace std; +#ifdef WIN32 +#include +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif + +bool spells_loaded = false; +volatile bool RunLoops = true; +extern volatile bool ZoneLoaded; +#ifdef SHAREMEM + #include "../common/EMuShareMem.h" + extern LoadEMuShareMemDLL EMuShareMemDLL; + #ifndef WIN32 + #include + #include + #include + #include +#ifndef FREEBSD + union semun { + int val; + struct semid_ds *buf; + ushort *array; + struct seminfo *__buf; + void *__pad; + }; +#endif + #endif +#endif + + + + +#include "../common/queue.h" +#include "../common/timer.h" +#include "../common/eq_stream.h" +#include "../common/eq_packet_structs.h" +#include "../common/mutex.h" +#include "../common/version.h" +#include "../common/files.h" +#include "../common/eqemu_error.h" +#include "../common/packet_dump_file.h" + +#include "masterentity.h" +#include "worldserver.h" +#include "net.h" +#include "spdat.h" +#include "zone.h" +#include "command.h" +#include "parser.h" +#include "embparser.h" + + +#ifndef NEW_LoadSPDat +void LoadSPDat(SPDat_Spell_Struct** SpellsPointer) { + //FILE *fp; + //cout << "Beginning Spells memset." << endl; + int u; + //for (u = 0; u < SPDAT_RECORDS; u++) + //{ //cout << u << ' '; + memset((char*) &spells,0,sizeof(SPDat_Spell_Struct)*SPDAT_RECORDS); + //} + //cout << "Memset finished\n"; + char temp=' '; + int tempid=0; + char token[64]=""; + int a = 0; + char sep='^'; + LogFile->write(EQEMuLog::Normal, "If this is the last message you see, you forgot to move spells_en.txt from your EQ dir to this dir."); + +#ifdef FREEBSD +#error ifstreams seem to break BSD... +#endif + ifstream in;in.open(SPELLS_FILE); + + if(!in.is_open()){ + LogFile->write(EQEMuLog::Error, "File '%s' not found in same directory as zone.exe, spell loading FAILED!", SPELLS_FILE); + return; + } + //while(!in.eof()) + //{in >> temp;} + //for(int x =0; x< spellsen_size; x++) + // memset((char*) &spells[x],0,sizeof(SPDat_Spell_Struct)); + while(tempid <= SPDAT_RECORDS-1) + { + //if(tempid>3490) + //{ + // cout << "BLEH"; + // getch(); + //} + + //in.getline(&temp, 624); + in.get(temp); + while(chrcmpI(&temp, &sep)) + { + strncat(token,&temp,1); + a++;//cout << temp<< ' '; + in.get(temp); + } + tempid=atoi(token); + if(tempid>=SPDAT_RECORDS) + break; + //cout << "TempID: " << tempid << endl; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + strncpy(spells[tempid].name,token,a); + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + //cout << spells[tempid].name << '^'; + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + strncpy(spells[tempid].player_1,token,a); + //cout << spells[tempid].player_1 << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + strncpy(spells[tempid].teleport_zone,token,a); + //cout << spells[tempid].teleport_zone << '^'; + a=0; + + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + strncpy(spells[tempid].you_cast,token,a); + //cout << spells[tempid].you_cast << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + strncpy(spells[tempid].other_casts,token,a); + //cout << spells[tempid].other_casts << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + strncpy(spells[tempid].cast_on_you,token,a); + //cout << spells[tempid].cast_on_you << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + strncpy(spells[tempid].cast_on_other,token,a); + //cout << spells[tempid].cast_on_other << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + strncpy(spells[tempid].spell_fades,token,a); + //cout << spells[tempid].spell_fades << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + in.get(temp); + } + spells[tempid].range=atof(token); + //cout << spells[tempid].range << '^'; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].aoerange=atof(token); + //cout << spells[tempid].aoerange << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].pushback=atof(token); + //cout << spells[tempid].pushback << '^'; + a=0; + + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].pushup=atof(token); + //cout << spells[tempid].pushup << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].cast_time=atoi(token); + + //cout << spells[tempid].cast_time << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].recovery_time=atoi(token); + //cout << spells[tempid].recovery_time << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].recast_time=atoi(token); + //cout << spells[tempid].recast_time << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].buffdurationformula=atoi(token); + //cout << spells[tempid].buffdurationformula << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].buffduration=atoi(token); + //cout << spells[tempid].buffduration << '^'; + + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].ImpactDuration=atoi(token); + //cout << spells[tempid].ImpactDuration<< '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].mana=atoi(token); + //cout << spells[tempid].mana << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + int y; + for(y=0; y< 12;y++) + { + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].base[y]=atoi(token); + //cout << spells[tempid].base[y] << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + + } + for(y=0; y< 12;y++) + { + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].max[y]=atoi(token); + //cout << spells[tempid].max[y] << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + } + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].icon=atoi(token); + //cout << spells[tempid].icon << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].memicon=atoi(token); + //cout << spells[tempid].memicon << '^'; + + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + for(y=0; y< 4;y++) + { + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].components[y]=atoi(token); + //cout << spells[tempid].components[y] << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + } + for(y=0; y< 4;y++) + { + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].component_counts[y]=atoi(token);//atoi(token); + //cout << spells[tempid].component_counts[y] << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + } + for(y=0; y< 4;y++) + { + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].NoexpendReagent[y]=atoi(token); //NoExpend Reagent + //cout << spells[tempid].NoexpendReagent[y] << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + } + for(y=0; y< 12;y++) + { + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].formula[y]=atoi(token); + //cout << spells[tempid].formula[y] << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + } + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + + spells[tempid].LightType=atoi(token); + //cout << spells[tempid].LightType << '^'; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].goodEffect=atoi(token); + //cout << spells[tempid].goodEffect << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].Activated=atoi(token); + //cout << spells[tempid].Activated << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].resisttype=atoi(token); + //cout << spells[tempid].resisttype << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + for(y=0; y< 12;y++) + { + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].effectid[y]=atoi(token); + //cout << spells[tempid].effectid[y] << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + } + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].targettype=atoi(token); + //cout << spells[tempid].targettype << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].basediff=atoi(token); + //cout << spells[tempid].basediff<< '^'; + a=0; + for(u=0;u<64;u++) + + token[u]=(char)0; + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].skill=atoi(token); + //cout << spells[tempid].skill << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].zonetype=atoi(token); + //cout << spells[tempid].zonetype << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].EnvironmentType=atoi(token); + //cout << spells[tempid].EnvironmentType << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + + in.get(temp); + } + spells[tempid].TimeOfDay=atoi(token); + //cout << spells[tempid].TimeOfDay << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + for(y=0; y< 15;y++) + { + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].classes[y]= atoi(token); + //cout << spells[tempid].classes[y] << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + } //cout << "end class"; + /*for(y=0; y< 3;y++) + { + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].unknown1[y]=atoi(token); + cout << spells[tempid].unknown1[y] << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + } + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].unknown2=atoi(token); + cout << spells[tempid].unknown2 << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + */ + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].CastingAnim=atoi(token); + //cout << spells[tempid].CastingAnim << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].TargetAnim=atoi(token); + //cout << spells[tempid].TargetAnim << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].TravelType=atoi(token); + //cout << spells[tempid].TravelType << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].SpellAffectIndex=atoi(token); + //cout << spells[tempid].SpellAffectIndex << '^'; + + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + for(y=0; y< 23;y++) + { + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].Spacing2[y]=atoi(token); + //cout << spells[tempid].base[y] << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + } + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].ResistDiff=atoi(token); + //cout << spells[tempid].ResistDiff << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + in.get(temp); + for(y=0; y< 2;y++) + { + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].Spacing3[y]=atoi(token); + //cout << spells[tempid].base[y] << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + } + + in.get(temp); + while(chrcmpI(&temp,&sep)) + { + strncat(token,&temp,1); + a++; + in.get(temp); + } + spells[tempid].RecourseLink = atoi(token); + //cout << spells[tempid].RecourseLink << '^'; + a=0; + for(u=0;u<64;u++) + token[u]=(char)0; + + while(temp!='\n') + in.get(temp); + + //cout << endl; + if(tempid==SPDAT_RECORDS-1) break; + } + //for(u=0;u< SPDAT_RECORDS;u++) + // cout << u << ' ' << spells[u].name << '^'; + + spells_loaded = true; + cout << "Spells loaded.\n"; + in.close(); + +} +#endif + + +/*void EntityList::SendAATimer(uint32 charid,UseAA_Struct* uaa){ + Client* client2=this->GetClientByCharID(charid); + if(!client2){ + LogFile->write(EQEMuLog::Error, "Error in SendAATimer: Couldnt find character!"); + return; + } + client2->SendAATimer(uaa); +} + +void ZoneDatabase::UpdateAndDeleteAATimers(uint32 charid){ + char errbuf[MYSQL_ERRMSG_SIZE]; + char *query = 0; + char *query2 = 0; + + if (!RunQuery(query, MakeAnyLenString(&query, "delete from aa_timers where charid=%i and UNIX_TIMESTAMP(now())>=end",charid), errbuf)) { + LogFile->write(EQEMuLog::Error, "UpdateAATimers query '%s' %s", query, errbuf); + } + if (!RunQuery(query2, MakeAnyLenString(&query2, "update aa_timers set end=end-(UNIX_TIMESTAMP(now())-begin),begin=UNIX_TIMESTAMP(now()) where charid=%i",charid), errbuf)) { + LogFile->write(EQEMuLog::Error, "UpdateAATimers query '%s' %s", query2, errbuf); + } + safe_delete_array(query); + safe_delete_array(query2); +} + +void ZoneDatabase::UpdateTimersClientConnected(uint32 charid){ + char errbuf[MYSQL_ERRMSG_SIZE]; + char *query = 0; + if (!RunQuery(query, MakeAnyLenString(&query, "update aa_timers set end=(UNIX_TIMESTAMP(now())+(end-begin)),begin=UNIX_TIMESTAMP(now()) where charid=%i",charid), errbuf)) { + LogFile->write(EQEMuLog::Error, "UpdateAATimers query '%s' %s", query, errbuf); + } + safe_delete_array(query); +} + +void ZoneDatabase::GetAATimers(uint32 charid){ + char errbuf[MYSQL_ERRMSG_SIZE]; + char *query = 0; + MYSQL_RES *result; + MYSQL_ROW row; + + if (RunQuery(query, MakeAnyLenString(&query, "SELECT ability,begin,end from aa_timers WHERE charid=%i", charid), errbuf, &result)) { + while( ( row = mysql_fetch_row(result) ) ){ + UseAA_Struct* uaa=new UseAA_Struct(); + uaa->ability=atoi(row[0]); + uaa->begin=atoi(row[1]); + uaa->end=atoi(row[2]); + entity_list.SendAATimer(charid,uaa); + safe_delete(uaa); + } + mysql_free_result(result); + } + else { + LogFile->write(EQEMuLog::Error, "Database::GetAATimers query '%s' %s", query, errbuf); + } + safe_delete_array(query); +} + +uint32 ZoneDatabase::GetTimerRemaining(uint32 charid,uint32 ability){ + char errbuf[MYSQL_ERRMSG_SIZE]; + char *query = 0; + MYSQL_RES *result; + MYSQL_ROW row; + uint32 remain=0; + if (RunQuery(query, MakeAnyLenString(&query, "SELECT end-begin from aa_timers WHERE charid=%i and ability=%i", charid,ability), errbuf, &result)) { + if((row=mysql_fetch_row(result))){ + remain=atoi(row[0]); + } + mysql_free_result(result); + } + else { + LogFile->write(EQEMuLog::Error, "Database::GetTimerRemaining query '%s' %s", query, errbuf); + } + safe_delete_array(query); + return remain; +} + +void ZoneDatabase::UpdateAATimers(uint32 charid,uint32 endtime,uint32 begintime,uint32 ability){ + char errbuf[MYSQL_ERRMSG_SIZE]; + char *query = 0; + if(begintime==0){ + if (!RunQuery(query, MakeAnyLenString(&query, "replace into aa_timers (charid,end,begin,ability) values(%i,UNIX_TIMESTAMP(now())+%i,UNIX_TIMESTAMP(now()),%i)",charid,endtime,ability), errbuf)) { + LogFile->write(EQEMuLog::Error, "UpdateAATimers query '%s' %s", query, errbuf); + } + } + else{ + if (!RunQuery(query, MakeAnyLenString(&query, "replace into aa_timers (charid,end,begin,ability) values(%i,%i,%i,%i)",charid,endtime,begintime,ability), errbuf)) { + LogFile->write(EQEMuLog::Error, "UpdateAATimers query '%s' %s", query, errbuf); + } + } + safe_delete_array(query); +}*/ + +/* +uint16 Client::GetCombinedAC_TEST() { + int ac1; + + ac1 = GetRawItemAC(); + if (m_pp.class_ != WIZARD && m_pp.class_ != MAGICIAN && m_pp.class_ != NECROMANCER && m_pp.class_ != ENCHANTER) { + ac1 = ac1*4/3; + } + ac1 += GetSkill(DEFENSE)/3; + if (GetAGI() > 70) { + ac1 += GetAGI()/20; + } + + int ac2; + + ac2 = GetRawItemAC(); + if (m_pp.class_ != WIZARD && m_pp.class_ != MAGICIAN && m_pp.class_ != NECROMANCER && m_pp.class_ != ENCHANTER) { + ac2 = ac2*4/3; + } + ac2 += GetSkill(DEFENSE)*400/255; + + int combined_ac = (ac1+ac2)*1000/847; + return combined_ac; + float combined_ac = ((float)ac1+(float)ac2)*1000.0f/847.0f; + return (uint16) combined_ac;//*10.0f)-10; +} +*/ + + +/*bool Client::GetIncreaseSpellDurationItem(uint16 &spell_id, char *itemname) +{ + for (int i=0; i<22; i++) { + const ItemInst* inst = m_inv[i]; + if (!inst || !inst->IsType(ItemTypeCommon)) + continue; + + const Item_Struct* item = inst->GetItem(); + if (item->FocusId && (item->FocusId != 0xFFFF)) { + if (IsIncreaseDurationSpell(item->FocusId)) { + spell_id = item->FocusId; + if (itemname) + strcpy(itemname, item->Name); + return true; + } + } + } + return false; +} + +bool Client::GetReduceManaCostItem(uint16 &spell_id, char *itemname) +{ + for (int i=0; i<22; i++) { + const ItemInst* inst = m_inv[i]; + if (!inst || !inst->IsType(ItemTypeCommon)) + continue; + + const Item_Struct* item = inst->GetItem(); + if (item->FocusId && (item->FocusId != 0xFFFF)) { + if (IsReduceManaSpell(item->FocusId)) { + spell_id = item->FocusId; + if (itemname) + strcpy(itemname, item->Name); + return true; + } + } + } + return false; +} + +bool Client::GetReduceCastTimeItem(uint16 &spell_id, char *itemname) +{ + for (int i=0; i<22; i++) { + const ItemInst* inst = m_inv[i]; + if (!inst || !inst->IsType(ItemTypeCommon)) + continue; + + const Item_Struct* item = inst->GetItem(); + if (item->FocusId && (item->FocusId != 0xFFFF)) { + if (IsReduceCastTimeSpell(item->FocusId)) { + spell_id = item->FocusId; + if (itemname) + strcpy(itemname, item->Name); + return true; + } + } + } + return false; +} + +bool Client::GetExtendedRangeItem(uint16 &spell_id, char *itemname) +{ + for (int i=0; i<22; i++) { + const ItemInst* inst = m_inv[i]; + if (!inst || !inst->IsType(ItemTypeCommon)) + continue; + + const Item_Struct* item = inst->GetItem(); + if (item->FocusId && (item->FocusId != 0xFFFF)) { + if (IsExtRangeSpell(item->FocusId)) { + spell_id = item->FocusId; + if (itemname) + strcpy(itemname, item->Name); + return true; + } + } + } + return false; +} + +bool Client::GetImprovedHealingItem(uint16 &spell_id, char *itemname) +{ + for (int i=0; i<22; i++) { + const ItemInst* inst = m_inv[i]; + if (!inst || !inst->IsType(ItemTypeCommon)) + continue; + + const Item_Struct* item = inst->GetItem(); + if (item->FocusId && (item->FocusId != 0xFFFF)) { + if (IsImprovedHealingSpell(item->FocusId)) { + spell_id = item->FocusId; + if (itemname) + strcpy(itemname, item->Name); + return true; + } + } + } + return false; +} + +bool Client::GetImprovedDamageItem(uint16 &spell_id, char *itemname) +{ + for (int i=0; i<22; i++) { + const ItemInst* inst = m_inv[i]; + if (!inst || !inst->IsType(ItemTypeCommon)) + continue; + + const Item_Struct* item = inst->GetItem(); + if (item->FocusId && (item->FocusId != 0xFFFF)) { + if (IsImprovedDamageSpell(item->FocusId)) { + spell_id = item->FocusId; + if (itemname) + strcpy(itemname, item->Name); + return true; + } + } + } + return false; +} + +int32 Client::GenericFocus(uint16 spell_id, uint16 modspellid) +{ + int modifier = 100, i; + const SPDat_Spell_Struct &spell = spells[spell_id]; + const SPDat_Spell_Struct &modspell = spells[modspellid]; + + for (i = 0; i < EFFECT_COUNT; i++) + { + if(IsBlankSpellEffect(modspellid, i)) + continue; + switch( spells[modspellid].effectid[i] ) + { + case SE_LimitMaxLevel: + if (spell.classes[(GetClass()%17) - 1] > modspell.base[i]) + return 100; + break; + case SE_LimitMinLevel: + if (spell.classes[(GetClass()%17) - 1] < modspell.base[i]) + return 100; + break; + case SE_IncreaseRange: + modifier += modspell.base[i]; + break; + case SE_IncreaseSpellHaste: + modifier -= modspell.base[i]; + break; + case SE_IncreaseSpellDuration: + modifier += modspell.base[i]; + break; + case SE_LimitSpell: + // negative sign means exclude + // positive sign means include + if (modspell.base[i] < 0) + { + if (modspell.base[i] * (-1) == spell_id) + return 100; + } + else + { + if (spells[modspellid].base[i] != spell_id) + return 100; + } + break; + case SE_LimitEffect: + switch( spells[modspellid].base[i] ) + { + case -147: + if (IsPercentalHealSpell(spell_id)) + return 100; + break; + case -101: + if (IsCHDurationSpell(spell_id)) + return 100; + break; + case -40: + if (IsInvulnerabilitySpell(spell_id)) + return 100; + break; + case -32: + if (IsSummonItemSpell(spell_id)) + return 100; + break; + case 0: + if (!IsEffectHitpointsSpell(spell_id)) + return 100; + break; + case 33: + if (!IsSummonPetSpell(spell_id)) + return 100; + break; + case 36: + if (!IsPoisonCounterSpell(spell_id)) + return 100; + break; + case 71: + if (!IsSummonSkeletonSpell(spell_id)) + return 100; + break; + default: + LogFile->write(EQEMuLog::Normal, "GenericFocus: unknown limit effect %d", spells[modspellid].base[i]); + } + break; + case SE_LimitCastTime: + if (modspell.base[i] > (int16)spell.cast_time) + return 100; + break; + case SE_LimitSpellType: + switch( spells[modspellid].base[i] ) + { + case 0: + if (!IsDetrimentalSpell(spell_id)) + return 100; + break; + case 1: + if (!IsBeneficialSpell(spell_id)) + return 100; + break; + default: + LogFile->write(EQEMuLog::Normal, "GenericFocus: unknown limit spelltype %d", spells[modspellid].base[i]); + } + break; + case SE_LimitMinDur: + if (modspell.base[i] > CalcBuffDuration_formula(GetLevel(), spell.buffdurationformula, spell.buffduration)) + return 100; + break; + case SE_ImprovedDamage: + case SE_ImprovedHeal: + modifier += modspell.base[i]; + break; + case SE_ReduceManaCost: + modifier -= modspell.base[i]; + break; + default: + LogFile->write(EQEMuLog::Normal, "GenericFocus: unknown effectid %d", modspell.effectid[i]); + } + } + + return modifier; +} +*/ + + + +/*void Client::Discipline(ClientDiscipline_Struct* disc_in, Mob* tar) { +Message(0, "Disc packet id=%d, %x,%x,%x", disc_in->disc_id, disc_in->unknown3[0], disc_in->unknown3[1], disc_in->unknown3[2]); + if (!p_timers.Expired(&database, pTimerDisciplineReuse)) { + char val1[20]={0}; + char val2[20]={0}; + uint32 remain = p_timers.GetRemainingTime(pTimerDisciplineReuse); + MessageString(Chat::White,DISCIPLINE_CANUSEIN,ConvertArray((remain)/60,val1),ConvertArray(remain%60,val2)); + //Message(0,"You can use a new discipline in %i minutes %i seconds.", (disc_timer.GetRemainingTime()/1000)/60, disc_timer.GetRemainingTime()/1000%60); + return; + } + + //reuse times are a little messes up, they should scale down somehow + //as you gain in levels, but im not sure how, so its just a lvl 60 bonus right now + + //should change this to check classes better. + + //both in seconds, converted at the end. + uint32 duration = 0; + uint32 reuse = 0; + + switch(disc_in->disc_id){ + // Shared? + case discResistant: { // Resistant + // 1 minute duration + // 1 hour reuse + // +3 to +10 to resists + if (GetLevel()<=29) + return; + duration = 60; + reuse = 60*60; + entity_list.MessageClose(this, false, 100, 0, "%s has become more resistant!", GetName()); + break; + } + case discFearless: { // Fearless + // 11 second duration + // 1 hour reuse + // 100% fear immunity + if (GetLevel()<=39) + return; + duration = 11; + reuse = 60*60; + entity_list.MessageCloseString(this, false, 100, 0, DISCIPLINE_FEARLESS, GetName()); + //entity_list.MessageClose(this, false, 100, 0, "%s becomes fearless!", GetName()); + break; + } + case discWhirlwind: { // Counterattack/Whirlwind/Furious + // warrior level 56 + // rogue/monk level 53 + // 9 second duration + // 1 hour reuse + if ((GetClass() == WARRIOR && GetLevel() <= 56) + ||(GetLevel() <= 53) + ) return; + duration = 9; + reuse = 60*60; + entity_list.MessageClose(this, false, 100, 0, "%s\'s face becomes twisted with fury!", GetName()); + break; + } + case discFellstrike: { // Duelist/Innerflame/Fellstrike + // monk level 56 + // rogue level 59 + // warrior level 58 + // 12 second duration + // 30 minute reuse + // min 4*base hand/weapon damage + if ((GetClass() == MONK && GetLevel() <= 55) + ||(GetClass() == WARRIOR && GetLevel() <= 58) + ||(GetClass() == ROGUE && GetLevel() <= 59) + ) return; + duration = 12; + reuse = 60*30; + entity_list.MessageClose(this, false, 100, 0, "%s\'s muscles bulge with force of will!", GetName()); + break; + } + case discBlindingSpeed: { // Blindingspeed/Hundredfist + // rogue level 58 + // monk level 57 + // 15 second duration + // 30 minute reuse + if ((GetClass() == MONK && GetLevel() <= 58) + ||(GetClass() == ROGUE && GetLevel() <= 57) + ) return; + //disc_timer.Start(1000*60*30); + //disc_elapse.Start(1000*15); + duration = 15; + reuse = 60*30; + Message(0, "This discipline not implemented.."); + break; + } + case discDeadeye: { // Deadeye/Charge + // warrior level 53 + // rogue level 54 + // 14 second duration + // 30 minute reuse + if ((GetClass() == WARRIOR && GetLevel() <= 53) + ||(GetClass() == ROGUE && GetLevel() <= 54) + ) return; + duration = 14; + reuse = 60*30; + entity_list.MessageClose(this, false, 100, 0, "%s feels unstopable!", GetName()); + break; + } + // Warrior + case discEvasive: { // Evasive + // level 52 + // 3 minute duration + // 15 minute reuse + // +35% avoidance + // -15% out + duration = 3*60; + reuse = 15*60; + break; + } + case discMightystrike: { // Mightystrike + // level 54 + // 10 second duration + // 1 hour reuse + // Auto crit + duration = 10; + reuse = 60*60; + break; + } + case discDefensive: { // Defensive + // level 55 + // 3 minute duration + // 15 minute reuse, 10 after 60 + // +35% mitigation + // -15% out + duration = 3*60; + if(level > 59) + reuse = 10*60; + else + reuse = 15*60; + break; + } + case discPrecise: { // Precise + // level 57 + // 3 minute duration + // 30 minute reuse + // -15% avoidance + // +35% out + duration = 3*60; + reuse = 30*60; + break; + } + case discAggressive: { // Aggressive + // level 60 + // 3 minute duration + // 27 minute reuse + // -15% mitigation + // +35% out + duration = 3*60; + reuse = 27*60; + break; + } + // Monk + case discStonestance: { // Stonestance + // level 51 + duration = 12; + if(level > 59) + reuse = 3*60; + else + reuse = 12*60; + break; + } + case discThunderkick: { // Thunderkick + // level 52 + if(level > 59) + reuse = 1*60; + else + reuse = 7*60; + duration = 5*60; //hack for now, checked in combat and expired once used. + break; + } + case discVoidance: { // Voidance + // level 54 + if(level > 59) + reuse = 54*60; + else + reuse = 60*60; + duration = 8; + break; + } + case discSilentfist: { // Silentfist + // level 59 + // 6-7 minute reuse + // Dragon punch damage bonus + // Chance to stun + if(level > 59) + reuse = 6*60; + else + reuse = 7*60; + duration = 5*60; //hack for now, checked in combat and expired once used. + break; + } + case discAshenhand: { // Ashenhand + // level 60 + // 72 minute reuse + // Eagle Strike damage bonus + // Chance to slay + reuse = 72*60; + duration = 5*60; //hack for now, checked in combat and expired once used. + break; + } + // Rogue + case discNimble: { // Nimble + // level 55 + // 12 second duration + // 30 minute reuse + // Auto dodge + if(level > 59) + reuse = 25*60; + else + reuse = 30*60; + duration = 12; + break; + } + case discKinesthetics: { // Kinesthetics + // level 57 + // 18 second duration + // 30,27 minute reuse + // Auto dualwield + // Auto double attack + if(level > 59) + reuse = 27*60; + else + reuse = 30*60; + duration = 18; + break; + } + // Paladin + case discHolyforge: { // Holyforge + // level 55 + // 2 minute duration + // 72 minute reuse + // Crit/Crip undead + // +15% to crit chance + if(level > 59) + reuse = 65*60; + else + reuse = 72*60; + duration = 5*60; + break; + } + case discSanctification: { // Sanctification + // level 60 + // 10 second duration + // 72 minute reuse + // Spell immunity + reuse = 72*60; + duration = 15; + break; + } + // Ranger + case discTrueshot: { // Trueshot + // level 55 + // 2 minute duration + // 72 minute reuse + // Max to two times max bow damage + // +15% to hit + if(level > 59) + reuse = 67*60; + else + reuse = 72*60; + duration = 2*60; + break; + } + case discWeaponshield: { // Weaponshield + // level 60 + // 15 second duration + // 72 minute reuse + // auto parry + reuse = 72*60; + duration = 20; + break; + } + // Bard + case discDeftdance: { // Deftdance + // level 55 + // 10 second duration + // 72 minute reuse + // auto dodge + // auto dualwield + if(level > 59) + reuse = 67*60; + else + reuse = 72*60; + duration = 10; + break; + } + case discPuretone: { // Puretone + // level 60 + // 2 minute duration + // 72 minute reuse + // Auto instrument + reuse = 72*60; + duration = 4*60; + break; + } + // Shadow knight + case discUnholyAura: { // Unholy + // level 55 + // 72 minute reuse + // +25% to harmtouch + // -300 to resist + if(level > 59) + reuse = 67*60; + else + reuse = 72*60; + duration = 5*60; //hack for now, checked in combat and expired once used. + break; + } + case discLeechCurse: { // Leech curse + // level 60 + // 15 second duration + // 72 minute reuse + // Heal self for each point of melee damage done + reuse = 72*60; + duration = 15; + break; + } + // Default + case 0:{ // Timer request + break; + } + default: + LogFile->write(EQEMuLog::Error, "Unknown Discipline requested by client: %s class: %i Disciline:%i", GetName(), class_,disc_in->disc_id); + return; + } + + if(reuse != 0) { + p_timers.Start(pTimerDisciplineReuse, reuse); + //nonpersistent timer for the 'discipline ready' message + disc_timer.Start(1000*reuse); + } + if(duration != 0) + disc_elapse.Start(1000*duration); + + disc_inuse = disc_in->disc_id; +}*/ + +#if 0 // solar: this is old code +/*void EntityList::AESpell(Mob* caster, Mob* center, float dist, uint16 spell_id, bool group) +{ + LinkedListIterator iterator(mob_list); + iterator.Reset(); + while(iterator.MoreElements()) { + Mob* mob = iterator.GetData(); + if (group){ + // Client casting group spell with out target group buffs enabled + // Skip non group members + if (caster->IsClient() + && !caster->CastToClient()->TGB() + && GetGroupByMob(mob) != 0 + && !GetGroupByMob(mob)->IsGroupMember(caster) + ) { + LogFile->write(EQEMuLog::Debug, "Group spell skipping %s", mob->GetName()); + iterator.Advance(); + continue; + } + // Client casting group spell with target group buffs enabled + else if (caster->IsClient() + && caster->CastToClient()->TGB() + && GetGroupByMob(mob) != 0 + && GetGroupByMob(mob)->IsGroupMember(caster) + ){ + LogFile->write(EQEMuLog::Debug, "Group spell TGB on %s's Group", mob->GetName()); + GetGroupByMob(mob)->CastGroupSpell(caster, spell_id); + iterator.Advance(); + continue; + } + else if (caster->IsClient() + && caster->CastToClient()->TGB() + && GetGroupByMob(mob) == 0 + && mob == center + ){ + LogFile->write(EQEMuLog::Debug, "Group spell TGB on %s", mob->GetName()); + caster->SpellOnTarget(spell_id, mob); + return; + } + } + if ( + mob->DistNoZ(*center) <= dist + && !(mob->IsClient() && mob->CastToClient()->GMHideMe()) + && !mob->IsCorpse() + ) { + //cout << "AE Spell Hit: t=" << iterator.GetData()->GetName() << ", d=" << iterator.GetData()->CastToMob()->DistNoRoot(center) << ", x=" << iterator.GetData()->CastToMob()->GetX() << ", y=" << iterator.GetData()->CastToMob()->GetY() << endl; + if (caster == mob) { + // Caster gets the first hit, already handled in spells.cpp + } + #ifdef IPC + else if(caster->IsNPC() && !caster->CastToNPC()->IsInteractive()) { + #else + else if(caster->IsNPC()) { + #endif + // Npc + if (caster->IsAttackAllowed(mob) && spells[spell_id].targettype != ST_AEBard) { + caster->SpellOnTarget(spell_id, mob); + } + else if (mob->IsAIControlled() && spells[spell_id].targettype == ST_AEBard) { + caster->SpellOnTarget(spell_id, mob); + } + else { + } + } + #ifdef IPC + else if(caster->IsNPC() && caster->CastToNPC()->IsInteractive()) { + // Interactive npc + if (caster->IsAttackAllowed(mob) && spells[spell_id].targettype != ST_AEBard && spells[spell_id].targettype != ST_GroupTeleport) { + caster->SpellOnTarget(spell_id, mob); + } + else if (!mob->IsAIControlled() && (spells[spell_id].targettype == ST_AEBard||group) && mob->CastToClient()->GetPVP() == caster->CastToClient()->GetPVP()) { + if (group && GetGroupByMob(mob) != GetGroupByMob(caster)) { + iterator.Advance(); + continue; + } + caster->SpellOnTarget(spell_id, mob); + } + else { + } + } + #endif + else if (caster->IsClient() && !(caster->CastToClient()->IsBecomeNPC())) { + // Client + if (caster->IsAttackAllowed(mob) && spells[spell_id].targettype != ST_AEBard){ + caster->SpellOnTarget(spell_id, mob); + } + else if(spells[spell_id].targettype == ST_GroupTeleport && mob->IsClient() && mob->isgrouped && caster->isgrouped && entity_list.GetGroupByMob(caster)) + { + Group* caster_group = entity_list.GetGroupByMob(caster); + if(caster_group != 0 && caster_group->IsGroupMember(mob)) + caster->SpellOnTarget(spell_id,mob); + } + else if (mob->IsClient() && (spells[spell_id].targettype == ST_AEBard||group) && mob->CastToClient()->GetPVP() == caster->CastToClient()->GetPVP()) { + if (group && GetGroupByMob(mob) != GetGroupByMob(caster)) { + iterator.Advance(); + continue; + } + else if (mob->IsClient() && spells[spell_id].targettype == ST_AEBard && mob->CastToClient()->GetPVP() == caster->CastToClient()->GetPVP()) + caster->SpellOnTarget(spell_id, mob); + #ifdef IPC + else if (mob->IsNPC() && mob->CastToNPC()->IsInteractive()) { + if (group && GetGroupByMob(mob) != GetGroupByMob(caster)) + continue; + caster->SpellOnTarget(spell_id, mob); + } + #endif + } + } + else if (caster->IsClient()) { + // Client BecomeNPC + caster->SpellOnTarget(spell_id, mob); + } + } + iterator.Advance(); + } +}*/ +#endif // solar: old code + +/*#if 0 +// Queries the loottable: adds item & coin to the npc +void ZoneDatabase::AddLootTableToNPC(uint32 loottable_id, ItemList* itemlist, uint32* copper, uint32* silver, uint32* gold, uint32* plat) { + char errbuf[MYSQL_ERRMSG_SIZE]; + char *query = 0; + MYSQL_RES *result; + MYSQL_ROW row; + *copper = 0; + *silver = 0; + *gold = 0; + *plat = 0; + + if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, mincash, maxcash, avgcoin FROM loottable WHERE id=%i", loottable_id), errbuf, &result)) { + safe_delete_array(query); + if (mysql_num_rows(result) == 1) { + row = mysql_fetch_row(result); + uint32 mincash = atoi(row[1]); + uint32 maxcash = atoi(row[2]); + if (mincash > maxcash) { + cerr << "Error in loottable #" << row[0] << ": mincash > maxcash" << endl; + } + else if (maxcash != 0) { + uint32 cash = 0; + if (mincash == maxcash) + cash = mincash; + else + cash = (rand() % (maxcash - mincash)) + mincash; + if (cash != 0) { + uint32 coinavg = atoi(row[3]); + if (coinavg != 0) { + uint32 mincoin = (uint32) (coinavg * 0.75 + 1); + uint32 maxcoin = (uint32) (coinavg * 1.25 + 1); + *copper = (rand() % (maxcoin - mincoin)) + mincoin - 1; + *silver = (rand() % (maxcoin - mincoin)) + mincoin - 1; + *gold = (rand() % (maxcoin - mincoin)) + mincoin - 1; + cash -= *copper; + cash -= *silver * 10; + cash -= *gold * 10; + } + *plat = cash / 1000; + cash -= *plat * 1000; + uint32 gold2 = cash / 100; + cash -= gold2 * 100; + uint32 silver2 = cash / 10; + cash -= silver2 * 10; + *gold += gold2; + *silver += silver2; + *copper += cash; + } + } + } + else { + mysql_free_result(result); + return; + } + mysql_free_result(result); + } + else + { + cerr << "Error in AddLootTableToNPC get coin query '" << query << "' " << errbuf << endl; + safe_delete_array(query); + return; + } + + if (RunQuery(query, MakeAnyLenString(&query, "SELECT loottable_id, lootdrop_id, multiplier, probability FROM loottable_entries WHERE loottable_id=%i", loottable_id), errbuf, &result)) { + safe_delete_array(query); + while ((row = mysql_fetch_row(result))) { + int multiplier = atoi(row[2]); + for (int i = 1; i <= multiplier; i++) { + if ( ((rand()%1)*100) < atoi(row[3])) { + AddLootDropToNPC(atoi(row[1]), itemlist); + } + } + } + mysql_free_result(result); + } + else { + cerr << "Error in AddLootTableToNPC get items query '" << query << "' " << errbuf << endl; + safe_delete_array(query); + return; + } + + return; +} + +// Called by AddLootTableToNPC +// maxdrops = size of the array npcd +void ZoneDatabase::AddLootDropToNPC(uint32 lootdrop_id, ItemList* itemlist) { + char errbuf[MYSQL_ERRMSG_SIZE]; + char *query = 0; + MYSQL_RES *result; + MYSQL_ROW row; + +// This is Wiz's updated Pool Looting functionality. Eventually, the database format should be moved over to use this +// or implemented to support both methods. (A unique identifier in lootable_entries indicates to roll for a pool item +// in another table. +#ifdef POOLLOOTING + uint32 chancepool = 0; + uint32 items[50]; + uint32 itemchance[50]; + uint16 itemcharges[50]; + uint8 i = 0; + + for (int m=0;m < 50;m++) + { + items[m]=0; + itemchance[m]=0; + itemcharges[m]=0; + } + + if (RunQuery(query, MakeAnyLenString(&query, "SELECT lootdrop_id, item_id, item_charges, equip_item, chance FROM lootdrop_entries WHERE lootdrop_id=%i order by chance desc", lootdrop_id), errbuf, &result)) + { + safe_delete_array(query); + while (row = mysql_fetch_row(result)) + { + items[i] = atoi(row[1]); + itemchance[i] = atoi(row[4]) + chancepool; + itemcharges[i] = atoi(row[2]); + chancepool += atoi(row[4]); + i++; + } + uint32 res; + i = 0; + + if (chancepool!=0) //avoid divide by zero if some mobs have 0 for chancepool + { + res = rand()%chancepool; + } + else + { + res = 0; + } + + while (items[i] != 0) + { + if (res <= itemchance[i]) + break; + else + i++; + } + const Item_Struct* dbitem = database.GetItem(items[i]); + if (dbitem == 0) + { + LogFile->write(EQEMuLog::Error, "AddLootDropToNPC: dbitem=0, item#=%i, lootdrop_id=%i", items[i], lootdrop_id); + } + else + { + //cout << "Adding item to Mob" << endl; + ServerLootItem_Struct* item = new ServerLootItem_Struct; + item->item_id = dbitem->ItemNumber; + item->charges = itemcharges[i]; + item->equipSlot = 0; + (*itemlist).Append(item); + } + mysql_free_result(result); + } +#else + if (RunQuery(query, MakeAnyLenString(&query, "SELECT lootdrop_id, item_id, item_charges, equip_item, chance FROM lootdrop_entries WHERE lootdrop_id=%i order by chance desc", lootdrop_id), errbuf, &result)) + { + safe_delete_array(query); + while ((row = mysql_fetch_row(result))) + { + uint8 LootDropMod=1; // place holder till I put it in a database variable to make it configurable. + if( (rand()%100) < ((atoi(row[4]) * LootDropMod)) ) + { + uint32 itemid = atoi(row[1]); + const Item_Struct* dbitem = database.GetItem(itemid); + if (dbitem == 0) + { + LogFile->write(EQEMuLog::Error, "AddLootDropToNPC: dbitem=0, item#=%i, lootdrop_id=%i", itemid, lootdrop_id); + } + else + { + printf("Adding item: %i",item->ItemNumber); + ServerLootItem_Struct* item = new ServerLootItem_Struct; + item->item_id = dbitem->item_id; + item->charges = atoi(row[2]); + item->equipSlot = 0; + (*itemlist).Append(item); + } + + //mysql_free_result(result); + //return; + } + } + mysql_free_result(result); + } +#endif + else + { + LogFile->write(EQEMuLog::Error, "Error in AddLootDropToNPC query '%s' %s", query, errbuf); + safe_delete_array(query); + return; + } + + return; +} +#endif*/ diff --git a/zone/oldcode.h b/zone/oldcode.h new file mode 100644 index 000000000..6decf7f76 --- /dev/null +++ b/zone/oldcode.h @@ -0,0 +1,22 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2004 EQEMu Development Team (http://eqemu.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef OLDCODE_H +#define OLDCODE_H + +#endif + diff --git a/zone/queryserv.cpp b/zone/queryserv.cpp index 6e8b57423..691943a7c 100644 --- a/zone/queryserv.cpp +++ b/zone/queryserv.cpp @@ -21,6 +21,7 @@ Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net) #include "../common/string_util.h" #include "queryserv.h" #include "worldserver.h" +#include "net.h" extern WorldServer worldserver; diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 4f7e35ace..1ed7d4998 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -44,6 +44,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "quest_parser_collection.h" #include "guild_mgr.h" #include "mob.h" +#include "net.h" #include "petitions.h" #include "raids.h" #include "string_ids.h" @@ -58,6 +59,7 @@ extern Zone* zone; extern volatile bool is_zone_loaded; extern void CatchSignal(int); extern WorldServer worldserver; +extern NetConnection net; extern PetitionList petition_list; extern uint32 numclients; extern volatile bool RunLoops; diff --git a/zone/zone.cpp b/zone/zone.cpp index 99c120cab..1bb8b8c36 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -39,6 +39,7 @@ #include "guild_mgr.h" #include "map.h" +#include "net.h" #include "npc.h" #include "object.h" #include "pathfinder_null.h" @@ -67,6 +68,7 @@ #endif extern bool staticzone; +extern NetConnection net; extern PetitionList petition_list; extern QuestParserCollection* parse; extern uint32 numclients; @@ -79,8 +81,6 @@ Mutex MZoneShutdown; volatile bool is_zone_loaded = false; Zone* zone = 0; -void UpdateWindowTitle(char* iNewTitle); - bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) { const char* zonename = database.GetZoneName(iZoneID); @@ -147,7 +147,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) { LogInfo("---- Zone server [{}], listening on port:[{}] ----", zonename, ZoneConfig::get()->ZonePort); LogInfo("Zone Bootup: [{}] ([{}]: [{}])", zonename, iZoneID, iInstanceID); parse->Init(); - UpdateWindowTitle(nullptr); + UpdateWindowTitle(); zone->GetTimeSync(); zone->RequestUCSServerStatus(); @@ -727,7 +727,7 @@ void Zone::Shutdown(bool quiet) safe_delete(zone); entity_list.ClearAreas(); parse->ReloadQuests(true); - UpdateWindowTitle(nullptr); + UpdateWindowTitle(); LogSys.CloseFileLogs(); @@ -2422,4 +2422,4 @@ void Zone::CalculateNpcUpdateDistanceSpread() update_distance, combined_spread ); -} +} \ No newline at end of file