mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
Updated sol2, made lua console not crash for nil data (nw)
This commit is contained in:
parent
fffd464d34
commit
c2a75cb179
3
3rdparty/sol2/.gitignore
vendored
3
3rdparty/sol2/.gitignore
vendored
@ -66,6 +66,7 @@ lua53.dll
|
||||
main.exe
|
||||
main.o
|
||||
lua-5.3.3/
|
||||
*.pdf
|
||||
main.lua
|
||||
LuaJIT-2.1.0/
|
||||
lua-5.3.3-cxx/
|
||||
lua-5.3.3.vcxproj-cxx.filters
|
||||
|
5
3rdparty/sol2/.gitmodules
vendored
5
3rdparty/sol2/.gitmodules
vendored
@ -1,6 +1,3 @@
|
||||
[submodule "Catch"]
|
||||
path = Catch
|
||||
url = https://github.com/philsquared/Catch.git
|
||||
[submodule "Optional"]
|
||||
path = Optional
|
||||
url = https://github.com/ThePhD/Optional.git
|
||||
url = https://github.com/philsquared/Catch.git
|
142
3rdparty/sol2/Optional/optional.hpp
vendored
142
3rdparty/sol2/Optional/optional.hpp
vendored
@ -21,10 +21,7 @@
|
||||
# define TR2_OPTIONAL_REQUIRES(...) typename ::std::enable_if<__VA_ARGS__::value, bool>::type = false
|
||||
|
||||
# if defined __GNUC__ // NOTE: GNUC is also defined for Clang
|
||||
# if (__GNUC__ >= 5)
|
||||
# define TR2_OPTIONAL_GCC_5_0_AND_HIGHER___
|
||||
# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
|
||||
# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
|
||||
# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
|
||||
# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
|
||||
# elif (__GNUC__ > 4)
|
||||
# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
|
||||
@ -258,99 +255,80 @@ public:
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
union storage_t
|
||||
{
|
||||
unsigned char dummy_;
|
||||
T value_;
|
||||
|
||||
constexpr storage_t( trivial_init_t ) noexcept : dummy_() {};
|
||||
|
||||
template <class... Args>
|
||||
constexpr storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
|
||||
|
||||
~storage_t(){}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
union constexpr_storage_t
|
||||
{
|
||||
unsigned char dummy_;
|
||||
T value_;
|
||||
|
||||
constexpr constexpr_storage_t( trivial_init_t ) noexcept : dummy_() {};
|
||||
|
||||
template <class... Args>
|
||||
constexpr constexpr_storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
|
||||
|
||||
~constexpr_storage_t() = default;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct optional_base
|
||||
{
|
||||
bool init_;
|
||||
char storage_[sizeof(T)];
|
||||
storage_t<T> storage_;
|
||||
|
||||
constexpr optional_base() noexcept : init_(false), storage_() {};
|
||||
constexpr optional_base() noexcept : init_(false), storage_(trivial_init) {};
|
||||
|
||||
explicit optional_base(const T& v) : init_(true), storage_() {
|
||||
new (&storage())T(v);
|
||||
}
|
||||
explicit constexpr optional_base(const T& v) : init_(true), storage_(v) {}
|
||||
|
||||
explicit optional_base(T&& v) : init_(true), storage_() {
|
||||
new (&storage())T(constexpr_move(v));
|
||||
}
|
||||
explicit constexpr optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {}
|
||||
|
||||
template <class... Args> explicit optional_base(in_place_t, Args&&... args)
|
||||
: init_(true), storage_() {
|
||||
new (&storage())T(constexpr_forward<Args>(args)...);
|
||||
}
|
||||
: init_(true), storage_(constexpr_forward<Args>(args)...) {}
|
||||
|
||||
template <class U, class... Args, TR2_OPTIONAL_REQUIRES(::std::is_constructible<T, ::std::initializer_list<U>>)>
|
||||
explicit optional_base(in_place_t, ::std::initializer_list<U> il, Args&&... args)
|
||||
: init_(true), storage_() {
|
||||
new (&storage())T(il, constexpr_forward<Args>(args)...);
|
||||
}
|
||||
#if defined __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#endif
|
||||
T& storage() {
|
||||
return *reinterpret_cast<T*>(&storage_[0]);
|
||||
}
|
||||
: init_(true), storage_(il, ::std::forward<Args>(args)...) {}
|
||||
|
||||
constexpr const T& storage() const {
|
||||
return *reinterpret_cast<T const*>(&storage_[0]);
|
||||
}
|
||||
#if defined __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
~optional_base() { if (init_) { storage().T::~T(); } }
|
||||
~optional_base() { if (init_) storage_.value_.T::~T(); }
|
||||
};
|
||||
|
||||
#if defined __GNUC__ && !defined TR2_OPTIONAL_GCC_5_0_AND_HIGHER___
|
||||
// Sorry, GCC 4.x; you're just a piece of shit
|
||||
template <typename T>
|
||||
using constexpr_optional_base = optional_base<T>;
|
||||
#else
|
||||
|
||||
template <class T>
|
||||
struct constexpr_optional_base
|
||||
{
|
||||
bool init_;
|
||||
char storage_[sizeof(T)];
|
||||
constexpr constexpr_optional_base() noexcept : init_(false), storage_() {}
|
||||
bool init_;
|
||||
constexpr_storage_t<T> storage_;
|
||||
|
||||
explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_() {
|
||||
new (&storage())T(v);
|
||||
}
|
||||
constexpr constexpr_optional_base() noexcept : init_(false), storage_(trivial_init) {};
|
||||
|
||||
explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_() {
|
||||
new (&storage())T(constexpr_move(v));
|
||||
}
|
||||
explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_(v) {}
|
||||
|
||||
explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {}
|
||||
|
||||
template <class... Args> explicit constexpr constexpr_optional_base(in_place_t, Args&&... args)
|
||||
: init_(true), storage_() {
|
||||
new (&storage())T(constexpr_forward<Args>(args)...);
|
||||
}
|
||||
: init_(true), storage_(constexpr_forward<Args>(args)...) {}
|
||||
|
||||
template <class U, class... Args, TR2_OPTIONAL_REQUIRES(::std::is_constructible<T, ::std::initializer_list<U>>)>
|
||||
OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, ::std::initializer_list<U> il, Args&&... args)
|
||||
: init_(true), storage_() {
|
||||
new (&storage())T(il, constexpr_forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#if defined __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#endif
|
||||
T& storage() {
|
||||
return (*reinterpret_cast<T*>(&storage_[0]));
|
||||
}
|
||||
|
||||
constexpr const T& storage() const {
|
||||
return (*reinterpret_cast<T const*>(&storage_[0]));
|
||||
}
|
||||
#if defined __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, ::std::initializer_list<U> il, Args&&... args)
|
||||
: init_(true), storage_(il, ::std::forward<Args>(args)...) {}
|
||||
|
||||
~constexpr_optional_base() = default;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
using OptionalBase = typename ::std::conditional<
|
||||
@ -369,21 +347,21 @@ class optional : private OptionalBase<T>
|
||||
|
||||
|
||||
constexpr bool initialized() const noexcept { return OptionalBase<T>::init_; }
|
||||
typename ::std::remove_const<T>::type* dataptr() { return ::std::addressof(OptionalBase<T>::storage()); }
|
||||
constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase<T>::storage()); }
|
||||
typename ::std::remove_const<T>::type* dataptr() { return ::std::addressof(OptionalBase<T>::storage_.value_); }
|
||||
constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase<T>::storage_.value_); }
|
||||
|
||||
# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
|
||||
constexpr const T& contained_val() const& { return OptionalBase<T>::storage(); }
|
||||
constexpr const T& contained_val() const& { return OptionalBase<T>::storage_.value_; }
|
||||
# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
|
||||
OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return ::std::move(OptionalBase<T>::storage()); }
|
||||
OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase<T>::storage(); }
|
||||
OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return ::std::move(OptionalBase<T>::storage_.value_); }
|
||||
OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase<T>::storage_.value_; }
|
||||
# else
|
||||
T& contained_val() & { return OptionalBase<T>::storage(); }
|
||||
T&& contained_val() && { return ::std::move(OptionalBase<T>::storage()); }
|
||||
T& contained_val() & { return OptionalBase<T>::storage_.value_; }
|
||||
T&& contained_val() && { return ::std::move(OptionalBase<T>::storage_.value_); }
|
||||
# endif
|
||||
# else
|
||||
constexpr const T& contained_val() const { return OptionalBase<T>::storage(); }
|
||||
T& contained_val() { return OptionalBase<T>::storage(); }
|
||||
constexpr const T& contained_val() const { return OptionalBase<T>::storage_.value_; }
|
||||
T& contained_val() { return OptionalBase<T>::storage_.value_; }
|
||||
# endif
|
||||
|
||||
void clear() noexcept {
|
||||
@ -715,10 +693,10 @@ public:
|
||||
return ref != nullptr;
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
constexpr T& value_or(V&& v) const
|
||||
template <class V>
|
||||
constexpr typename ::std::decay<T>::type value_or(V&& v) const
|
||||
{
|
||||
return *this ? **this : detail_::convert<T&>(constexpr_forward<V>(v));
|
||||
return *this ? **this : detail_::convert<typename ::std::decay<T>::type>(constexpr_forward<V>(v));
|
||||
}
|
||||
};
|
||||
|
||||
|
13
3rdparty/sol2/README.md
vendored
13
3rdparty/sol2/README.md
vendored
@ -1,4 +1,6 @@
|
||||
## Sol 2.14
|
||||
## Sol 2.15
|
||||
|
||||
[](https://gitter.im/chat-sol2/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
[](https://travis-ci.org/ThePhD/sol2)
|
||||
[](http://sol2.readthedocs.io/en/latest/?badge=latest)
|
||||
@ -44,13 +46,20 @@ int main() {
|
||||
|
||||
More examples are given in the examples directory.
|
||||
|
||||
## Presentations
|
||||
|
||||
"A Sun For the Moon - A Zero-Overhead Lua Abstraction using C++"
|
||||
ThePhD
|
||||
Lua Workshop 2016 - Mashape, San Francisco, CA
|
||||
[Deck](https://github.com/ThePhD/sol2/blob/develop/docs/presentations/ThePhD%20-%20No%20Overhead%20C%20Abstraction%20-%202016.10.14.pdf)
|
||||
|
||||
## Creating a single header
|
||||
|
||||
You can grab a single header out of the library [here](https://github.com/ThePhD/sol2/tree/develop/single/sol). For stable version, check the releases tab on github for a provided single header file for maximum ease of use. A script called `single.py` is provided in the repository if there's some bleeding edge change that hasn't been published on the releases page. You can run this script to create a single file version of the library so you can only include that part of it. Check `single.py --help` for more info.
|
||||
|
||||
## Features
|
||||
|
||||
- [Fastest in the land](http://sol2.readthedocs.io/en/latest/benchmarks.html) (see: sol2 graph and table entries).
|
||||
- [Fastest in the land](http://sol2.readthedocs.io/en/latest/benchmarks.html) (see: sol bar in graph).
|
||||
- Supports retrieval and setting of multiple types including `std::string` and `std::map/unordered_map`.
|
||||
- Lambda, function, and member function bindings are supported.
|
||||
- Intermediate type for checking if a variable exists.
|
||||
|
BIN
3rdparty/sol2/docs/presentations/ThePhD - No Overhead C Abstraction - 2016.10.14.pdf
vendored
Normal file
BIN
3rdparty/sol2/docs/presentations/ThePhD - No Overhead C Abstraction - 2016.10.14.pdf
vendored
Normal file
Binary file not shown.
1
3rdparty/sol2/docs/source/api/api-top.rst
vendored
1
3rdparty/sol2/docs/source/api/api-top.rst
vendored
@ -12,6 +12,7 @@ Browse the various function and classes :doc:`Sol<../index>` utilizes to make yo
|
||||
state
|
||||
table
|
||||
proxy
|
||||
containers
|
||||
as_table
|
||||
usertype
|
||||
simple_usertype
|
||||
|
6
3rdparty/sol2/docs/source/api/as_table.rst
vendored
6
3rdparty/sol2/docs/source/api/as_table.rst
vendored
@ -21,4 +21,8 @@ This function serves the purpose of ensuring that an object is pushed -- if poss
|
||||
lua.script("for k, v in ipairs(my_table) do print(k, v) assert(k == v) end");
|
||||
|
||||
|
||||
Note that any caveats with Lua tables apply the moment it is serialized, and the data cannot be gotten out back out in C++ as a vector without explicitly using the ``as_table_t`` marker for your get and conversion operations using Sol.
|
||||
Note that any caveats with Lua tables apply the moment it is serialized, and the data cannot be gotten out back out in C++ as a C++ type without explicitly using the ``as_table_t`` marker for your get and conversion operations using Sol.
|
||||
|
||||
If you need this functionality with a member variable, use a :doc:`property on a getter function<property>` that returns the result of ``sol::as_table``.
|
||||
|
||||
This marker does NOT apply to :doc:`usertypes<usertype>`.
|
93
3rdparty/sol2/docs/source/api/containers.rst
vendored
Normal file
93
3rdparty/sol2/docs/source/api/containers.rst
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
containers
|
||||
==========
|
||||
for handling ``std::vector/map/set`` and others
|
||||
-----------------------------------------------
|
||||
|
||||
Sol2 automatically converts containers (detected using the ``sol::is_container<T>`` type trait, which simply looks for begin / end) to be a special kind of userdata with metatable on it. For Lua 5.2 and 5.3, this is extremely helpful as you can make typical containers behave like Lua tables without losing the actual container that they came from, as well as a small amount of indexing and other operations that behave properly given the table type.
|
||||
|
||||
|
||||
a complete example
|
||||
------------------
|
||||
|
||||
Here's a complete working example of it working for Lua 5.3 and Lua 5.2, and how you can retrieve out the container in all versions:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: containers.cpp
|
||||
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#include <sol.hpp>
|
||||
|
||||
int main() {
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.script(R"(
|
||||
function f (x)
|
||||
print('--- Calling f ---')
|
||||
for k, v in pairs(x) do
|
||||
print(k, v)
|
||||
end
|
||||
end
|
||||
)");
|
||||
|
||||
// Have the function we
|
||||
// just defined in Lua
|
||||
sol::function f = lua["f"];
|
||||
|
||||
// Set a global variable called
|
||||
// "arr" to be a vector of 5 lements
|
||||
lua["arr"] = std::vector<int>{ 2, 4, 6, 8, 10 };
|
||||
|
||||
// Call it, see 5 elements
|
||||
// printed out
|
||||
f(lua["arr"]);
|
||||
|
||||
// Mess with it in C++
|
||||
std::vector<int>& reference_to_arr = lua["arr"];
|
||||
reference_to_arr.push_back(12);
|
||||
|
||||
// Call it, see *6* elements
|
||||
// printed out
|
||||
f(lua["arr"]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Note that this will not work well in 5.1, as it has explicit table checks and does not check metamethods, even when ``pairs`` or ``ipairs`` is passed a table. In that case, you will need to use a more manual iteration scheme or you will have to convert it to a table. In C++, you can use :doc:`sol::as_table<as_table>` when passing something to the library to get a table out of it.
|
||||
|
||||
|
||||
additional functions
|
||||
--------------------
|
||||
|
||||
Based on the type pushed, a few additional functions are added as "member functions" (``self`` functions called with ``obj:func()`` or ``obj.func(obj)`` syntax) within a Lua script:
|
||||
|
||||
* ``my_container:clear()``: This will call the underlying containers ``clear`` function.
|
||||
* ``my_container:add( key, value )`` or ``my_container:add( value )``: this will add to the end of the container, or if it is an associative or ordered container, simply put in an expected key-value pair into it.
|
||||
* ``my_contaner:insert( where, value )`` or ``my_contaner:insert( key, value )``: similar to add, but it only takes two arguments. In the case of ``std::vector`` and the like, the first argument is a ``where`` integer index. The second argument is the value. For associative containers, a key and value argument are expected.
|
||||
|
||||
|
||||
.. _container-detection:
|
||||
|
||||
too-eager container detection?
|
||||
------------------------------
|
||||
|
||||
|
||||
If you have a type that has ``begin`` or ``end`` member functions but don't provide iterators, you can specialize ``sol::is_container<T>`` to be ``std::false_type``, and that will treat the type as a regular usertype and push it as a regular userdata:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: specialization.hpp
|
||||
|
||||
struct not_container {
|
||||
void begin() {
|
||||
|
||||
}
|
||||
|
||||
void end() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
namespace sol {
|
||||
template <>
|
||||
struct is_container<not_container> : std::false_type {};
|
||||
}
|
15
3rdparty/sol2/docs/source/api/function.rst
vendored
15
3rdparty/sol2/docs/source/api/function.rst
vendored
@ -3,6 +3,10 @@ function
|
||||
calling functions bound to Lua
|
||||
------------------------------
|
||||
|
||||
.. note::
|
||||
|
||||
This abstraction assumes the function runs safely. If you expect your code to have errors (e.g., you don't always have explicit control over it or are trying to debug errors), please use :doc:`sol::protected_function<protected_function>`.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class function : public reference;
|
||||
@ -83,6 +87,17 @@ Calls the function. The second ``operator()`` lets you specify the templated ret
|
||||
All arguments are forwarded. Unlike :doc:`get/set/operator[] on sol::state<state>` or :doc:`sol::table<table>`, value semantics are not used here. It is forwarding reference semantics, which do not copy/move unless it is specifically done by the receiving functions / specifically done by the user.
|
||||
|
||||
|
||||
.. _function-argument-handling:
|
||||
|
||||
.. note::
|
||||
|
||||
This also means that you should pass and receive arguments in certain ways to maximize efficiency. For example, ``sol::table``, ``sol::object``, ``sol::userdata`` and friends are fairly cheap to copy, and should simply by taken as values. This includes primitive types like ``int`` and ``double``. However, C++ types -- if you do not want copies -- should be taken as ``const type&`` or ``type&``, to save on copies if it's important. Note that taking references from Lua also means you can modify the data inside of Lua directly, so be careful. Lua by default deals with things mostly by reference (save for primitive types).
|
||||
|
||||
You can get even more speed out of ``sol::object`` style of types by taking a ``sol::stack_object`` (or ``sol::stack_...``, where ``...`` is ``userdata``, ``reference``, ``table``, etc.). These reference a stack position directly rather than cheaply/safely the internal Lua reference to make sure it can't be swept out from under you. Note that if you manipulate the stack out from under these objects, they may misbehave, so please do not blow up your Lua stack when working with these types.
|
||||
|
||||
``std::string`` (and ``std::wstring``) are special. Lua stores strings as ``const char*`` null-terminated strings. ``std::string`` will copy, so taking a ``std::string`` by value or by const reference still invokes a copy operation. You can take a ``const char*``, but that will mean you're exposed to what happens on the Lua stack (if you change it and start chopping off function arguments from it in your function calls and such, as warned about previously).
|
||||
|
||||
|
||||
function call safety
|
||||
--------------------
|
||||
|
||||
|
@ -183,3 +183,5 @@ The error-handler that is called should a runtime error that Lua can detect occu
|
||||
.. note::
|
||||
|
||||
``protected_function_result`` safely pops its values off the stack when its destructor is called, keeping track of the index and number of arguments that were supposed to be returned. If you remove items below it using ``lua_remove``, for example, it will not behave as expected. Please do not perform fundamentally stack-rearranging operations until the destructor is called (pushing/popping above it is just fine).
|
||||
|
||||
To know more about how function arguments are handled, see :ref:`this note<function-argument-handling>`.
|
||||
|
61
3rdparty/sol2/docs/source/api/readonly.rst
vendored
61
3rdparty/sol2/docs/source/api/readonly.rst
vendored
@ -1,6 +1,6 @@
|
||||
readonly
|
||||
========
|
||||
Routine to mark a member variable as read-only
|
||||
routine to mark a member variable as read-only
|
||||
----------------------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
@ -8,4 +8,61 @@ Routine to mark a member variable as read-only
|
||||
template <typename T>
|
||||
auto readonly( T&& value );
|
||||
|
||||
The goal of read-only is to protect a variable set on a usertype or a function. Simply wrap it around a member variable, e.g. ``sol::readonly( &my_class::my_member_variable )`` in the appropriate place to use it. If someone tries to set it, it will throw an error.
|
||||
The goal of read-only is to protect a variable set on a usertype or a function. Simply wrap it around a member variable, e.g. ``sol::readonly( &my_class::my_member_variable )`` in the appropriate place to use it. If someone tries to set it, it will throw an error. This can ONLY work on :doc:`usertypes<usertype>` and when you specifically set a member variable as a function and wrap it with this. It will NOT work anywhere else: doing so will invoke compiler errors.
|
||||
|
||||
If you are looking to make a read-only table, you need to go through a bit of a complicated song and dance by overriding the ``__index`` metamethod. Here's a complete example on the way to do that using ``sol``:
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: read-only.cpp
|
||||
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
struct object {
|
||||
void my_func() {
|
||||
std::cout << "hello\n";
|
||||
}
|
||||
};
|
||||
|
||||
int deny(lua_State* L) {
|
||||
return luaL_error(L, "HAH! Deniiiiied!");
|
||||
}
|
||||
|
||||
int main() {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
object my_obj;
|
||||
|
||||
sol::table obj_table = lua.create_named_table("object");
|
||||
|
||||
sol::table obj_metatable = lua.create_table_with();
|
||||
obj_metatable.set_function("my_func", &object::my_func, &my_obj);
|
||||
// Set whatever else you need to
|
||||
// on the obj_metatable,
|
||||
// not on the obj_table itself!
|
||||
|
||||
// Properly self-index metatable to block things
|
||||
obj_metatable[sol::meta_function::new_index] = deny;
|
||||
obj_metatable[sol::meta_function::index] = obj_metatable;
|
||||
|
||||
// Set it on the actual table
|
||||
obj_table[sol::metatable_key] = obj_metatable;
|
||||
|
||||
try {
|
||||
lua.script(R"(
|
||||
print(object.my_func)
|
||||
object["my_func"] = 24
|
||||
print(object.my_func)
|
||||
)");
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
It is a verbose example, but it explains everything. Because the process is a bit involved and can have unexpected consequences for users that make their own tables, making read-only tables is something that we ask the users to do themselves with the above code, as getting the semantics right for the dozens of use cases would be tremendously difficult.
|
||||
|
@ -1,4 +1,4 @@
|
||||
simple_usertype
|
||||
simple_usertype<T>
|
||||
==================
|
||||
structures and classes from C++ made available to Lua code (simpler)
|
||||
--------------------------------------------------------------------
|
||||
@ -6,11 +6,28 @@ structures and classes from C++ made available to Lua code (simpler)
|
||||
|
||||
This type is no different from :doc:`regular usertype<usertype>`, but allows much of its work to be done at runtime instead of compile-time. You can reduce compilation times from a plain `usertype` when you have an exceedingly bulky registration listing.
|
||||
|
||||
You can set functions incrementally to reduce compile-time burden with ``simple_usertype`` as well, as shown in `this example`_.
|
||||
You can set functions incrementally to reduce compile-time burden with ``simple_usertype`` as well, as shown in `this example`_. This means both adding incrementally during registration, and afterwards by adding items to the metatable at runtime.
|
||||
|
||||
Some developers used ``simple_usertype`` in older versions to have variables automatically be functions. To achieve this behavior, wrap the desired variable into :doc:`sol::as_function<as_function>`.
|
||||
|
||||
The performance `seems to be good enough`_ (see below graphs as well) to not warn about any implications of having to serialize things at runtime. You do run the risk of using (slightly?) more memory, since variables and functions need to be stored differently and separately from the metatable data itself like with a regular ``usertype``. The goal here was to avoid compiler complaints about too-large usertypes (some individuals needed to register 190+ functions, and the compiler choked from the templated implementation of ``usertype``). As of Sol 2.14, this implementation has been heavily refactored to allow for all the same syntax and uses of usertype to apply here, with no caveats/exceptions.
|
||||
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20member%20function%20calls%20(simple).png
|
||||
:target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20member%20function%20calls%20(simple).png
|
||||
:alt: bind several member functions to an object and call them in Lua code
|
||||
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20userdata%20variable%20access%20(simple).png
|
||||
:target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20userdata%20variable%20access%20(simple).png
|
||||
:alt: bind a member variable to an object and modify it with Lua code
|
||||
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20many%20userdata%20variables%20access%2C%20last%20registered%20(simple).png
|
||||
:target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20many%20userdata%20variables%20access%2C%20last%20registered%20(simple).png
|
||||
:alt: bind MANY member variables to an object and modify it with Lua code
|
||||
|
||||
Some developers used ``simple_usertype`` to have variables automatically be functions. To achieve this behavior, wrap the desired variable into :doc:`sol::as_function<as_function>`.
|
||||
|
||||
The performance `seems to be good enough`_ to not warn about any implications of having to serialize things at runtime. You do run the risk of using (slightly?) more memory, however, since variables and functions need to be stored differently and separately from the metatable data itself like with a regular ``usertype``. The goal here was to avoid compiler complaints about too-large usertypes (some individuals needed to register 190+ functions, and the compiler choked from the templated implementation of ``usertype``). As of Sol 2.14, this implementation has been heavily refactored to allow for all the same syntax and uses of usertype to apply here, with no caveats/exceptions.
|
||||
|
||||
.. _seems to be good enough: https://github.com/ThePhD/sol2/issues/202#issuecomment-246767629
|
||||
.. _this example: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_simple.cpp
|
12
3rdparty/sol2/docs/source/api/state.rst
vendored
12
3rdparty/sol2/docs/source/api/state.rst
vendored
@ -53,6 +53,7 @@ This function takes a number of :ref:`sol::lib<lib-enum>` as arguments and opens
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: script / script_file
|
||||
:name: state-script-function
|
||||
|
||||
sol::function_result script(const std::string& code);
|
||||
sol::function_result script_file(const std::string& filename);
|
||||
@ -82,6 +83,15 @@ Thanks to `Eric (EToreo) for the suggestion on this one`_!
|
||||
|
||||
These functions *load* the desired blob of either code that is in a string, or code that comes from a filename, on the ``lua_State*``. It will not run: it returns a ``load_result`` proxy that can be called to actually run the code, turned into a ``sol::function``, a ``sol::protected_function``, or some other abstraction. If it is called, it will run on the object's current ``lua_State*``: it is not isolated. If you need isolation, consider creating a new state or traditional Lua sandboxing techniques.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: do_string / do_file
|
||||
:name: state-do-code
|
||||
|
||||
sol::protected_function_result do_string(const std::string& code);
|
||||
sol::protected_function_result do_file(const std::string& filename);
|
||||
|
||||
These functions *loads and performs* the desired blob of either code that is in a string, or code that comes from a filename, on the ``lua_State*``. It *will* run, and then return a ``protected_function_result`` proxy that can be examined for either an error or the return value.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: global table / registry table
|
||||
|
||||
@ -97,7 +107,7 @@ Get either the global table or the Lua registry as a :doc:`sol::table<table>`, w
|
||||
|
||||
void set_panic(lua_CFunction panic);
|
||||
|
||||
Overrides the panic function Lua calls when something unrecoverable or unexpected happens in the Lua VM. Must be a function of the that matches the ``int(*)(lua_State*)`` function signature.
|
||||
Overrides the panic function Lua calls when something unrecoverable or unexpected happens in the Lua VM. Must be a function of the that matches the ``int(lua_State*)`` function signature.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: make a table
|
||||
|
2
3rdparty/sol2/docs/source/api/usertype.rst
vendored
2
3rdparty/sol2/docs/source/api/usertype.rst
vendored
@ -5,7 +5,7 @@ structures and classes from C++ made available to Lua code
|
||||
|
||||
*Note: ``T`` refers to the type being turned into a usertype.*
|
||||
|
||||
While other frameworks extend lua's syntax or create Data Structure Languages (DSLs) to create classes in lua, :doc:`sol<../index>` instead offers the ability to generate easy bindings. These use metatables and userdata in lua for their implementation. Given this C++ class:
|
||||
While other frameworks extend lua's syntax or create Data Structure Languages (DSLs) to create classes in lua, :doc:`Sol<../index>` instead offers the ability to generate easy bindings. These use metatables and userdata in lua for their implementation. If you need a usertype that is also extensible at runtime and has less compiler crunch to it, try the :doc:`simple version of this after reading these docs<simple_usertype>` Given this C++ class:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
@ -5,7 +5,7 @@ usertype memory
|
||||
|
||||
Sol does not take ownership of raw pointers, returned from functions or set through the ``set`` functions. Return a value, a ``std::unique_ptr``, a ``std::shared_ptr`` of some kind, or hook up the :doc:`unique usertypes traits<unique_usertype_traits>` to work for some specific handle structure you use (AKA, for ``boost::shared_ptr``).
|
||||
|
||||
The userdata generated by Sol has a specific layout, depending on how Sol recognizes userdata passed into it. All of the referred to metatable names are generated from :ref:`usertype_traits\<T><usertype-traits>`
|
||||
The userdata generated by Sol has a specific layout, depending on how Sol recognizes userdata passed into it. All of the referred to metatable names are generated from :ref:`usertype_traits\<T><usertype-traits>`. Note that we use 1 metatable per the 3 styles listed below, plus 1 additional metatable that is used for the actual table that you bind with the name when calling ``table::new/set_(simple_)usertype``.
|
||||
|
||||
In general, we always insert a T* in the first `sizeof(T*)` bytes, so the any framework that pulls out those first bytes expecting a pointer will work. The rest of the data has some different alignments and contents based on what it's used for and how it's used.
|
||||
|
||||
@ -37,11 +37,11 @@ That is it. No destruction semantics need to be called.
|
||||
For ``std::unique_ptr<T, D>`` and ``std::shared_ptr<T>``
|
||||
--------------------------------------------------------
|
||||
|
||||
These are classified as :ref:`"unique usertypes"<unique-usertype>`, and have a special metatable for them as well. The special metatable is either generated when you add the usertype to Lua using :ref:`set_usertype<set-usertype>` or when you first push one of these special types. In addition to the data, a deleter function that understands the following layout is injected into the usertype.
|
||||
These are classified as :ref:`"unique usertypes"<unique-usertype>`, and have a special metatable for them as well. The special metatable is either generated when you add the usertype to Lua using :ref:`set_usertype<set-usertype>` or when you first push one of these special types. In addition to the data, a deleter function that understands the following layout is injected into the userdata layout.
|
||||
|
||||
The data layout for these kinds of types is as follows::
|
||||
|
||||
| T* | void(*)(void*) function_pointer | T |
|
||||
^-sizeof(T*) bytes-^-sizeof(void(*)(void*)) bytes, deleter-^- sizeof(T) bytes, actal data -^
|
||||
|
||||
Note that we put a special deleter function before the actual data. This is because the custom deleter must know where the offset to the data is, not the rest of the library. Sol just needs to know about ``T*`` and the userdata (and userdata metatable) to work, everything else is for preserving construction / destruction semantics.
|
||||
Note that we put a special deleter function before the actual data. This is because the custom deleter must know where the offset to the data is and where the special deleter is. In other words, fixed-size-fields come before any variably-sized data (T can be known at compile time, but when serialized into Lua in this manner it becomes a runtime entity). Sol just needs to know about ``T*`` and the userdata (and userdata metatable) to work, everything else is for preserving construction / destruction semantics.
|
8
3rdparty/sol2/docs/source/benchmarks.rst
vendored
8
3rdparty/sol2/docs/source/benchmarks.rst
vendored
@ -21,12 +21,12 @@ Bars go up to the average execution time. Lower is better. Reported times are fo
|
||||
:target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20member%20function%20calls.png
|
||||
:alt: bind several member functions to an object and call them in Lua code
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20member%20variable.png
|
||||
:target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20member%20variable.png
|
||||
.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20userdata%20variable%20access.png
|
||||
:target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20userdata%20variable%20access.png
|
||||
:alt: bind a variable to an object and call it in Lua code
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20member%20variable.png
|
||||
:target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20many%20member%20variables.png
|
||||
.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20many%20userdata%20variables%20access.png
|
||||
:target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20many%20userdata%20variables%20access.png
|
||||
:alt: bind MANY variables to an object and call it in Lua code
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20c%20function%20through%20lua.png
|
||||
|
4
3rdparty/sol2/docs/source/conf.py
vendored
4
3rdparty/sol2/docs/source/conf.py
vendored
@ -59,9 +59,9 @@ author = 'ThePhD'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '2.14'
|
||||
version = '2.15'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '2.14.8'
|
||||
release = '2.15.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
35
3rdparty/sol2/docs/source/errors.rst
vendored
Normal file
35
3rdparty/sol2/docs/source/errors.rst
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
errors
|
||||
======
|
||||
how to handle exceptions or other errors
|
||||
----------------------------------------
|
||||
|
||||
Here is some advice and some tricks to use when dealing with thrown exceptions, error conditions and the like in Sol.
|
||||
|
||||
Catch and CRASH!
|
||||
----------------
|
||||
|
||||
By default, Sol will add a ``default_at_panic`` handler. If exceptions are not turned off, this handler will throw to allow the user a chance to recover. However, in almost all cases, when Lua calls ``lua_atpanic`` and hits this function, it means that something *irreversibly wrong* occured in your code or the Lua code and the VM is in an unpredictable or dead state. Catching an error thrown from the default handler and then proceeding as if things are cleaned up or okay is NOT the best idea. Unexpected bugs in optimized and release mode builds can result, among other serious issues.
|
||||
|
||||
|
||||
It is preferred if you catch an error that you log what happened, terminate the Lua VM as soon as possible, and then crash if your application cannot handle spinning up a new Lua state. Catching can be done, but you should understand the risks of what you're doing when you do it.
|
||||
|
||||
|
||||
Destructors and Safety
|
||||
----------------------
|
||||
|
||||
Another issue is that Lua is a C API. It uses ``setjmp`` and ``longjmp`` to jump out of code when an error occurs. This means it will ignore destructors in your code if you use the library or the underlying Lua VM improperly. To solve this issue, build Lua as C++. When a Lua VM error occurs and ``lua_error`` is triggered, it raises it as an exception which will provoke proper unwinding semantics.
|
||||
|
||||
|
||||
Protected Functions and Access
|
||||
------------------------------
|
||||
|
||||
By default, :doc:`sol::function<api/function>` assumes the code ran just fine and there are no problems. :ref:`sol::state(_view)::script(_file)<state-script-function>` also assumes that code ran just fine. Use :doc:`sol::protected_function<api/protected_function>` to have function access where you can check if things worked out. Use :doc:`sol::optional<api/optional>` to get a value safely from Lua. Use :ref:`sol::state(_view)::do_string/do_file/load/load_file<state-do-code>` to safely load and get results from a script. The defaults are provided to be simple and fast with thrown exceptions to violently crash the VM in case things go wrong.
|
||||
|
||||
Raw Functions
|
||||
-------------
|
||||
|
||||
When you push a function into Lua using Sol using any methods and that function exactly matches the signature ``int( lua_State* );``, it will be treated as a *raw C function*. This means that the usual exception trampoline Sol wraps your other function calls in will not be present. You will be responsible for catching exceptions and handling them before they explode into the C API (and potentially destroy your code). Sol in all other cases adds an exception-handling trampoline that turns exceptions into Lua errors that can be caught by the above-mentioned protected functions and accessors.
|
||||
|
||||
.. warning::
|
||||
|
||||
Do NOT assume that building Lua as C++ will allow you to throw directly from a raw function. If an exception is raised and it bubbles into the Lua framework, even if you compile as C++, Lua does not recognize exceptions other than the ones that it uses with ``lua_error``. In other words, it will return some completely bogus result, potentially leave your Lua stack thrashed, and the rest of your VM *can* be in a semi-trashed state. Please avoid this!
|
21
3rdparty/sol2/docs/source/features.rst
vendored
21
3rdparty/sol2/docs/source/features.rst
vendored
@ -78,7 +78,7 @@ Explanations for a few categories are below (rest are self-explanatory).
|
||||
* arbitrary keys: Letting C++ code use userdata, other tables, integers, etc. as keys for into a table.
|
||||
* user-defined types (udts): C++ types given form and function in Lua code.
|
||||
* udts - member functions: C++ member functions on a type, usually callable with ``my_object:foo(1)`` or similar in Lua.
|
||||
* udts - variables: C++ member variables, manipulated by ``my_object.var = 24`` and friends
|
||||
* udts - table variables: C++ member variables/properties, manipulated by ``my_object.var = 24`` and in Lua
|
||||
* function binding: Support for binding all types of functions. Lambdas, member functions, free functions, in different contexts, etc...
|
||||
* protected function: Use of ``lua_pcall`` to call a function, which offers error-handling and trampolining (as well as the ability to opt-in / opt-out of this behavior)
|
||||
* multi-return: returning multiple values from and to Lua (generally through ``std::tuple<...>`` or in some other way)
|
||||
@ -104,7 +104,7 @@ Explanations for a few categories are below (rest are self-explanatory).
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
| udts: member functions | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
| udts: variables | ~ | ~ | ~ | ~ | ~ | ✔ | ~ | ~ | ~ | ✗ | ✔ | ✗ | ~ |
|
||||
| udts: table variables | ~ | ~ | ~ | ~ | ~ | ✔ | ~ | ~ | ~ | ✗ | ✔ | ✗ | ~ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
| stack abstractions | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ✗ | ~ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
@ -138,7 +138,7 @@ Explanations for a few categories are below (rest are self-explanatory).
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
| luajit | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✗ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
| distribution | compile | header | both | compile | header | header | compile | compile | header | compile | generated | compile | header |
|
||||
| distribution | compile | header | both | compile | header | header | compile | compile | header | compile | generated | compile | header |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
|
||||
|
||||
@ -153,7 +153,7 @@ Plain C -
|
||||
|
||||
kaguya -
|
||||
|
||||
* member variables are automatically turned into ``obj:x( value )`` to set and ``obj:x()`` to get
|
||||
* Table variables / member variables are automatically turned into ``obj:x( value )`` to set and ``obj:x()`` to get
|
||||
* Has optional support
|
||||
* Inspired coroutine support for Sol
|
||||
* Library author (satoren) is a nice guy!
|
||||
@ -177,12 +177,12 @@ lua-intf -
|
||||
* Macro-based registration (strange pseudo-language)
|
||||
* Fairly fast in most regards
|
||||
* Registering classes/"modules" in using C++ code is extremely verbose
|
||||
* In order to chain lookups, one has to do ``mykey.mykey2`` on the ``operator[]`` lookup (e.g., you can't nest them arbitrarily, you have to pre-compose the proper lookup string) (fails miserably for non-string lookups!).
|
||||
* In order to chain lookups, one has to glue the keys together (e.g. ``"mykey.mykey2"``) on the ``operator[]`` lookup (e.g., you can't nest them arbitrarily, you have to pre-compose the proper lookup string) (fails miserably for non-string lookups!).
|
||||
* Not too shabby!
|
||||
|
||||
Selene -
|
||||
|
||||
* member variables are automatically turned into ``obj:set_x( value )`` to set and ``obj:x()`` to get
|
||||
* Table variables / member variables are automatically turned into ``obj:set_x( value )`` to set and ``obj:x()`` to get
|
||||
* Registering classes/"modules" using C++ code is extremely verbose, similar to lua-intf's style
|
||||
* Eats crap when it comes to performance, most of the time (see :doc:`benchmarks<benchmarks>`)
|
||||
* Lots of users (blogpost etc. made it popular), but the Repository is kinda stagnant...
|
||||
@ -204,7 +204,7 @@ SWIG (3.0) -
|
||||
luacppinterface -
|
||||
|
||||
* The branch that fixes VC++ warnings and introduces some new work has type checker issues, so use the stable branch only
|
||||
* No member variable support
|
||||
* No table variable support
|
||||
* Actually has tables (but no operator[])
|
||||
* Does not support arbitrary keys
|
||||
|
||||
@ -238,13 +238,13 @@ SLB3 -
|
||||
|
||||
oolua -
|
||||
|
||||
* The syntax for this library is thicker than a brick. No, seriously. `Go read the docs`_
|
||||
* The syntax for this library. `Go read the docs`_
|
||||
* The worst in terms of how to use it: may have docs, but the DSL is extraordinarily crappy with thick, hard-to-debug/hard-to-error-check macros
|
||||
- Same problem as lua-api-pp: cannot have the declaration macros anywhere but the toplevel namespace because of template declaration macro
|
||||
* Supports not having exceptions or rtti turned on (shiny!)
|
||||
* Poor RAII support: default-construct-and-get style (requires some form of initalization to perform a ``get`` of an object, and it's hard to extend)
|
||||
- The library author has informed me that he does personally advises individuals do not use the ``Table`` abstraction in OOLua... Do I likewise tell people to consider its table abstractions defunct?
|
||||
* Member variables are turned into function calls (``get_x`` and ``set_x`` by default)
|
||||
* Table variables / member variables from C++ are turned into function calls (``get_x`` and ``set_x`` by default)
|
||||
|
||||
luwra -
|
||||
|
||||
@ -253,6 +253,7 @@ luwra -
|
||||
* Doesn't understand ``std::function`` conversions and the like (but with some extra code can get it to work)
|
||||
* Recently improved by a lot: can chain tables and such, even if performance is a bit sad for that use case
|
||||
* When you do manage to set function calls with the macros they are fast (can a template solution do just as good? Sol is going to find out!)
|
||||
* No member variable support - get turned into getter/setter functions, similar to kaguya
|
||||
* No table variable support - get turned into getter/setter functions, similar to kaguya
|
||||
* Table variables become class statics (surprising)
|
||||
|
||||
.. _Go read the docs: https://oolua.org/docs/index.html
|
||||
|
14
3rdparty/sol2/docs/source/index.rst
vendored
14
3rdparty/sol2/docs/source/index.rst
vendored
@ -7,8 +7,8 @@
|
||||
:target: https://github.com/ThePhD/sol2
|
||||
:alt: sol2 repository
|
||||
|
||||
Sol 2.14
|
||||
========
|
||||
Sol |version|
|
||||
=============
|
||||
a fast, simple C++ and Lua Binding
|
||||
----------------------------------
|
||||
|
||||
@ -18,6 +18,11 @@ When you need to hit the ground running with Lua and C++, `Sol`_ is the go-to fr
|
||||
:target: https://travis-ci.org/ThePhD/sol2
|
||||
:alt: build status
|
||||
|
||||
.. image:: https://badges.gitter.im/chat-sol2/Lobby.svg
|
||||
:target: https://gitter.im/chat-sol2/Lobby
|
||||
:alt: chat about sol2 on gitter
|
||||
|
||||
|
||||
get going:
|
||||
----------
|
||||
|
||||
@ -27,7 +32,10 @@ get going:
|
||||
|
||||
tutorial/all-the-things
|
||||
tutorial/tutorial-top
|
||||
errors
|
||||
features
|
||||
usertypes
|
||||
traits
|
||||
api/api-top
|
||||
mentions
|
||||
benchmarks
|
||||
@ -43,7 +51,7 @@ get going:
|
||||
|
||||
"I need feature X, maybe you have it?"
|
||||
--------------------------------------
|
||||
Take a look at the :doc:`Features<features>` page: it links to much of the API. You can also just straight up browse the :doc:`api<api/api-top>` or ease in with the :doc:`tutorials<tutorial/tutorial-top>`. Don't see a feature you want? Send inquiries for support for a particular abstraction to the `issues`_ tracker.
|
||||
Take a look at the :doc:`Features<features>` page: it links to much of the API. You can also just straight up browse the :doc:`api<api/api-top>` or ease in with the :doc:`tutorials<tutorial/tutorial-top>`. To know more about the implementation for usertypes, see :doc:`here<usertypes>` To know how function arguments are handled, see :ref:`this note<function-argument-handling>`. Don't see a feature you want? Send inquiries for support for a particular abstraction to the `issues`_ tracker.
|
||||
|
||||
|
||||
the basics:
|
||||
|
39
3rdparty/sol2/docs/source/mentions.rst
vendored
39
3rdparty/sol2/docs/source/mentions.rst
vendored
@ -3,6 +3,8 @@ mentions
|
||||
so does anyone cool use this thing...?
|
||||
--------------------------------------
|
||||
|
||||
First off, feel free to `tell me about your uses!`_
|
||||
|
||||
Okay, so the features don't convince you, the documentation doesn't convince you, you want to see what *other* people think about Sol? Well, aside from the well-wishes that come through in the issue tracker, here's a few things floating around about sol2 that I occasionally get pinged about:
|
||||
|
||||
`eevee`_ demonstrating the sheer code reduction by using sol2:
|
||||
@ -24,27 +26,34 @@ Okay, so the features don't convince you, the documentation doesn't convince you
|
||||
|
||||
|
||||
* (CppNow) sol2 was mentioned in a comparison to other scripting languages by ChaiScript developer, Jason Turner (@lefticus), at a conference!
|
||||
- https://github.com/lefticus/presentations/blob/master/HowAndWhyToAddScripting.md
|
||||
- `Jason Turner's presentation`_
|
||||
* (CppCast) Showed up in CppCast with Elias Daler!
|
||||
- https://eliasdaler.github.io/cppcast#read-more
|
||||
- http://cppcast.com/2016/07/elias-daler/
|
||||
- `Elias Daler's blog`_
|
||||
- `CppCast`_
|
||||
* (Eevee) A really nice and neat developer/artist/howaretheysotalented person is attempting to use it for zdoom!
|
||||
- https://eev.ee/dev/2016/08/07/weekly-roundup-three-big-things/
|
||||
- `eevee's blog`_
|
||||
* (Twitter) Twitter has some people that link it:
|
||||
- https://twitter.com/eevee/status/762039984085798913
|
||||
- https://twitter.com/thephantomderp/status/762043162835709952
|
||||
- https://twitter.com/EliasDaler/status/739082026679173120
|
||||
- https://twitter.com/racodslair/status/754031870640267264
|
||||
- The image above, `tweeted out by eevee`_
|
||||
- Eevee: `"I heartily recommend sol2"`_
|
||||
- Elias Daler: `"sol2 saved my life."`_
|
||||
- Racod's Lair: `"from outdated LuaBridge to superior #sol2"`_
|
||||
* (Reddit) Posts on reddit about it!
|
||||
- https://www.reddit.com/r/cpp/comments/4a8gy7/sol2_lua_c_binding_framework/
|
||||
- https://www.reddit.com/r/cpp/comments/4x82hd/plain_c_versus_lua_libraries_benchmarking_speed/
|
||||
- `sol2's initial reddit release`_
|
||||
- `Benchmarking Discussing`_
|
||||
* Somehow landed on a Torque3D thread...
|
||||
- http://forums.torque3d.org/viewtopic.php?f=32&t=629&p=5246&sid=8e759990ab1ce38a48e896fc9fd62653#p5241
|
||||
|
||||
|
||||
`Tell me about your uses!`_
|
||||
|
||||
Are you using sol2 for something neat? Want it to be featured here or think it's unfair that ThePhD hasn't found it yet? Well, drop an issue in the repo or send an e-mail!
|
||||
|
||||
.. _Tell me about your uses!: https://github.com/ThePhD/sol2/issues/189
|
||||
.. _eevee: https://twitter.com/eevee
|
||||
.. _tell me about your uses!: https://github.com/ThePhD/sol2/issues/189
|
||||
.. _eevee: https://twitter.com/eevee
|
||||
.. _eevee's blog: https://eev.ee/dev/2016/08/07/weekly-roundup-three-big-things/
|
||||
.. _Jason Turner's presentation: https://github.com/lefticus/presentations/blob/master/HowAndWhyToAddScripting.md
|
||||
.. _Elias Daler's blog: https://eliasdaler.github.io/cppcast#read-more
|
||||
.. _CppCast: http://cppcast.com/2016/07/elias-daler/
|
||||
.. _tweeted out by eevee: https://twitter.com/eevee/status/762039984085798913
|
||||
.. _"I heartily recommend sol2": https://twitter.com/eevee/status/762040086540144644
|
||||
.. _"from outdated LuaBridge to superior #sol2": https://twitter.com/racodslair/status/754031870640267264
|
||||
.. _sol2's initial reddit release: https://www.reddit.com/r/cpp/comments/4a8gy7/sol2_lua_c_binding_framework/
|
||||
.. _Benchmarking Discussing: https://www.reddit.com/r/cpp/comments/4x82hd/plain_c_versus_lua_libraries_benchmarking_speed/
|
||||
.. _"sol2 saved my life.": https://twitter.com/EliasDaler/status/739215685264494593
|
||||
|
1
3rdparty/sol2/docs/source/performance.rst
vendored
1
3rdparty/sol2/docs/source/performance.rst
vendored
@ -7,6 +7,7 @@ things to make Sol as fast as possible
|
||||
As shown by the :doc:`benchmarks<benchmarks>`, Sol is very performant with its abstractions. However, in the case where you need every last drop of performance from Sol, a number of tips and API usage tricks will be documented here. PLEASE benchmark / profile your code before you start invoking these, as some of them trade in readability / clarity for performance.
|
||||
|
||||
* If you have a bound function call / bound member function that you are going to call in a very tight, performance-heavy loop, considering using :doc:`sol::c_call<api/c_call>`
|
||||
* Be wary of passing by value / reference, and what it means by reading :ref:`this note<function-argument-handling>`.
|
||||
* It is currently undocumented that usertypes will "inherit" member function / member variables from bound classes, mostly because the semantics are unclear and it is not the most performant (although it is flexible: you can register base classes after / whenever you want in relation to the derived class, provided that derived class has its bases listed). Specifying all member functions / member variables for the usertype constructor / ``new_usertype`` function call and not relying on base lookup will boost performance of member lookup
|
||||
* Specifying base classes can make getting the usertype out of Sol a bit slower since we have to check and cast; if you know the exact type wherever you're retrieving it, considering not specifying the bases, retrieving the exact type from Sol, and then casting to a base type yourself
|
||||
* Member variables can sometimes cost an extra lookup to occur within the Lua system (as mentioned :doc:`bottom of the usertype page<api/usertype>`); until we find out a safe way around this, member variables will always incur that extra lookup cost
|
||||
|
15
3rdparty/sol2/docs/source/traits.rst
vendored
Normal file
15
3rdparty/sol2/docs/source/traits.rst
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
customization traits
|
||||
====================
|
||||
|
||||
These are customization points within the library to help you make sol2 work for the types in your framework and types.
|
||||
|
||||
To learn more about various customizable traits, visit:
|
||||
|
||||
* :ref:`containers detection trait<container-detection>`
|
||||
- This is how to work with containers when you have an compiler error when serializing a type that has ``begin`` and ``end`` functions but isn't exactly a container.
|
||||
* :doc:`unique usertype (custom pointer) traits<api/unique_usertype_traits>`
|
||||
- This is how to deal with unique usertypes, e.g. ``boost::shared_ptr``, reference-counted pointers, etc.
|
||||
- Useful for custom pointers from all sorts of frameworks or handle types that employ very specific kinds of destruction semantics and access.
|
||||
* :doc:`customization point tutorial<tutorial/customization>`
|
||||
- This is how to customize a type to work with sol2.
|
||||
- Can be used for specializations to push strings and other class types that are not natively ``std::string`` or ``const char*``.
|
@ -47,6 +47,10 @@ running lua code
|
||||
int value = lua.script("return 54");
|
||||
// value == 54
|
||||
|
||||
To check the success of a loading operation:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// load file without execute
|
||||
sol::load_result script1 = lua.load_file("path/to/luascript.lua");
|
||||
script1(); //execute
|
||||
@ -59,6 +63,24 @@ running lua code
|
||||
// value2 == 24
|
||||
|
||||
|
||||
To check whether a script was successfully run or not (after loading is assumed to be successful):
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// execute and return result
|
||||
sol::protected_function_result result1 = lua.do_string("return 24");
|
||||
if (result1.valid()) {
|
||||
int value = result1;
|
||||
// value == 24
|
||||
// yay!
|
||||
}
|
||||
else {
|
||||
// ahhh :c
|
||||
}
|
||||
|
||||
|
||||
There is also ``lua.do_file("path/to/luascript.lua");``.
|
||||
|
||||
set and get variables
|
||||
---------------------
|
||||
|
||||
|
@ -108,6 +108,9 @@ A few things of note about the implementation: First, there's an auxiliary param
|
||||
|
||||
You can make something pushable into Lua, but not get-able in the same way if you only specialize one part of the system. If you need to retrieve it (as a return using one or multiple values from Lua), you should specialize the ``sol::stack::getter`` template class and the ``sol::stack::checker`` template class. If you need to push it into Lua at some point, then you'll want to specialize the ``sol::stack::pusher`` template class. The ``sol::lua_size`` template class trait needs to be specialized for both cases, unless it only pushes 1 item, in which case the default implementation will assume 1.
|
||||
|
||||
.. note::
|
||||
|
||||
It is important to note here that the ``getter``, ``pusher`` and ``checker`` differentiate between a type ``T`` and a pointer to a type ``T*``. This means that if you want to work purely with, say, a ``T*`` handle that does not have the same semantics as just ``T``, you may need to specify checkers/getters/pushers for both ``T*`` and ``T``. The checkers for ``T*`` forward to the checkers for ``T``, but the getter for ``T*`` does not forward to the getter for ``T`` (e.g., because of ``int*`` not being quite the same as ``int``).
|
||||
|
||||
In general, this is fine since most getters/checkers only use 1 stack point. But, if you're doing more complex nested classes, it would be useful to use ``tracking.last`` to understand how many stack indices the last getter/checker operation did and increment it by ``index + tracking.last`` after using a ``stack::check<..>( L, index, tracking)`` call.
|
||||
|
||||
|
@ -338,4 +338,4 @@ It can be used like so, inconjunction with ``sol::this_state``:
|
||||
}
|
||||
|
||||
|
||||
This covers almost everything you need to know about Functions and how they interact with Sol. For some advanced tricks and neat things, check out :doc:`sol::this_state<../api/this_state>` and :doc:`sol::variadic_args<../api/variadic_args>`. The next stop in this tutorial is about :doc:`C++ types (usertypes) in Lua<cxx-in-lua>`!
|
||||
This covers almost everything you need to know about Functions and how they interact with Sol. For some advanced tricks and neat things, check out :doc:`sol::this_state<../api/this_state>` and :doc:`sol::variadic_args<../api/variadic_args>`. The next stop in this tutorial is about :doc:`C++ types (usertypes) in Lua<cxx-in-lua>`! If you need a bit more information about functions in the C++ side and how to best utilize arguments from C++, see :ref:`this note<function-argument-handling>`.
|
@ -5,14 +5,9 @@ Let's get you going with Sol! To start, you'll need to use a lua distribution of
|
||||
|
||||
If you need help getting or building Lua, check out the `Lua page on getting started`_. Note that for Visual Studio, one can simply download the sources, include all the Lua library files in that project, and then build for debug/release, x86/x64/ARM rather easily and with minimal interference. Just make sure to adjust the Project Property page to build as a static library (or a DLL with the proper define set in the ``Preprocessor`` step).
|
||||
|
||||
After that, make sure you grab either the `single header file release`_, or just perform a clone of the `github repository here`_ and set your include paths up so that you can get at ``sol.hpp`` somehow. Note that we also have the latest version of the single header file with all dependencies included kept in the `repository as well`_. We recommend the single-header-file release, since it's easier to move around, manage and update if you commit it with some form of version control. If you use the github clone method and do not point to the `single/sol/sol.hpp`_ on your include files, you *must* update submodules in order to make sure Optional is present in the repository. Clone with:
|
||||
After that, make sure you grab either the `single header file release`_, or just perform a clone of the `github repository here`_ and set your include paths up so that you can get at ``sol.hpp`` somehow. Note that we also have the latest version of the single header file with all dependencies included kept in the `repository as well`_. We recommend the single-header-file release, since it's easier to move around, manage and update if you commit it with some form of version control. You can also clone/submodule the repository and then point at the `single/sol/sol.hpp`_ on your include files path. Clone with:
|
||||
|
||||
>>> git clone https://github.com/ThePhD/sol2.git
|
||||
>>> git submodule update --init
|
||||
|
||||
or, just run
|
||||
|
||||
>>> git clone --recursive https://github.com/ThePhD/sol2.git
|
||||
|
||||
When you're ready, try compiling this short snippet:
|
||||
|
||||
|
26
3rdparty/sol2/docs/source/usertypes.rst
vendored
Normal file
26
3rdparty/sol2/docs/source/usertypes.rst
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
usertypes
|
||||
=========
|
||||
|
||||
Perhaps the most powerful feature of sol2, ``usertypes`` are the way sol2 and C++ communicate your classes to the Lua runtime and bind things between both tables and to specific blocks of C++ memory, allowing you to treat Lua userdata and other things like classes.
|
||||
|
||||
To learn more about usertypes, visit:
|
||||
|
||||
* :doc:`the basic tutorial<tutorial/cxx-in-lua>`
|
||||
* :doc:`customization point tutorial<tutorial/customization>`
|
||||
* :doc:`api documentation<api/usertype>`
|
||||
* :doc:`memory documentation<api/usertype_memory>`
|
||||
|
||||
The examples folder also has a number of really great examples for you to see. There are also some notes about guarantees you can find about usertypes, and their associated userdata, below:
|
||||
|
||||
* You can push types classified as userdata before you register a usertype.
|
||||
- You can register a usertype with the Lua runtime at any time sol2
|
||||
- You can retrieve them from the Lua runtime as well through sol2
|
||||
- Methods and properties will be added to the type only after you register it in the Lua runtime
|
||||
* Types either copy once or move once into the memory location, if it is a value type. If it is a pointer, we store only the reference.
|
||||
- This means take arguments of class types (not primitive types like strings or integers) by ``T&`` or ``T*`` to modify the data in Lua directly, or by plain ``T`` to get a copy
|
||||
- Return types and passing arguments to ``sol::function`` use perfect forwarding and reference semantics, which means no copies happen unless you specify a value explicitly. See :ref:`this note for details<function-argument-handling>`.
|
||||
* The first ``sizeof( void* )`` bytes is always a pointer to the typed C++ memory. What comes after is based on what you've pushed into the system according to :doc:`the memory specification for usertypes<api/usertype_memory>`. This is compatible with a number of systems.
|
||||
* Member methods, properties, variables and functions taking ``self&`` arguments modify data directly
|
||||
- Work on a copy by taking or returning a copy by value.
|
||||
* The actual metatable associated with the usertype has a long name and is defined to be opaque by the Sol implementation.
|
||||
* Containers get pushed as special usertypes, but can be disabled if problems arising as detailed :doc:`here<api/containers>`.
|
2969
3rdparty/sol2/single/sol/sol.hpp
vendored
2969
3rdparty/sol2/single/sol/sol.hpp
vendored
File diff suppressed because it is too large
Load Diff
57
3rdparty/sol2/sol/call.hpp
vendored
57
3rdparty/sol2/sol/call.hpp
vendored
@ -57,7 +57,7 @@ namespace sol {
|
||||
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) const {
|
||||
detail::default_construct func{};
|
||||
return stack::call_into_lua<false>(r, a, L, start, func, obj);
|
||||
return stack::call_into_lua<stack::stack_detail::default_check_arguments>(r, a, L, start, func, obj);
|
||||
}
|
||||
};
|
||||
|
||||
@ -85,11 +85,50 @@ namespace sol {
|
||||
}
|
||||
return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <std::size_t... M, typename Match, typename... Args>
|
||||
inline int overload_match_arity_single(types<>, std::index_sequence<>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, std::size_t I, std::size_t... M, typename Match, typename... Args>
|
||||
inline int overload_match_arity_single(types<Fx>, std::index_sequence<I>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
|
||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||
typedef typename traits::free_args_list args_list;
|
||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||
if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) {
|
||||
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
if (traits::free_arity != fxarity) {
|
||||
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, typename Fx1, typename... Fxs, std::size_t I, std::size_t I1, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
||||
inline int overload_match_arity_single(types<Fx, Fx1, Fxs...>, std::index_sequence<I, I1, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
|
||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||
typedef typename traits::free_args_list args_list;
|
||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||
if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) {
|
||||
return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
if (traits::free_arity != fxarity) {
|
||||
return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
stack::record tracking{};
|
||||
if (!stack::stack_detail::check_types<true>{}.check(args_list(), L, start, no_panic, tracking)) {
|
||||
return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
} // overload_detail
|
||||
|
||||
template <typename... Functions, typename Match, typename... Args>
|
||||
inline int overload_match_arity(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||
return overload_detail::overload_match_arity(types<Functions...>(), std::make_index_sequence<sizeof...(Functions)>(), std::index_sequence<>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
return overload_detail::overload_match_arity_single(types<Functions...>(), std::make_index_sequence<sizeof...(Functions)>(), std::index_sequence<>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Functions, typename Match, typename... Args>
|
||||
@ -106,9 +145,9 @@ namespace sol {
|
||||
|
||||
template <typename T, typename... TypeLists>
|
||||
inline int construct(lua_State* L) {
|
||||
static const auto& meta = usertype_traits<T>::metatable;
|
||||
static const auto& meta = usertype_traits<T>::metatable();
|
||||
int argcount = lua_gettop(L);
|
||||
call_syntax syntax = argcount > 0 ? stack::get_call_syntax(L, meta, 1) : call_syntax::dot;
|
||||
call_syntax syntax = argcount > 0 ? stack::get_call_syntax(L, &usertype_traits<T>::user_metatable()[0], 1) : call_syntax::dot;
|
||||
argcount -= static_cast<int>(syntax);
|
||||
|
||||
T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
|
||||
@ -344,9 +383,9 @@ namespace sol {
|
||||
typedef constructor_list<Args...> F;
|
||||
|
||||
static int call(lua_State* L, F&) {
|
||||
const auto& metakey = usertype_traits<T>::metatable;
|
||||
const auto& metakey = usertype_traits<T>::metatable();
|
||||
int argcount = lua_gettop(L);
|
||||
call_syntax syntax = argcount > 0 ? stack::get_call_syntax(L, metakey, 1) : call_syntax::dot;
|
||||
call_syntax syntax = argcount > 0 ? stack::get_call_syntax(L, &usertype_traits<T>::user_metatable()[0], 1) : call_syntax::dot;
|
||||
argcount -= static_cast<int>(syntax);
|
||||
|
||||
T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
|
||||
@ -376,7 +415,7 @@ namespace sol {
|
||||
struct onmatch {
|
||||
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start, F& f) {
|
||||
const auto& metakey = usertype_traits<T>::metatable;
|
||||
const auto& metakey = usertype_traits<T>::metatable();
|
||||
T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
|
||||
reference userdataref(L, -1);
|
||||
T*& referencepointer = *pointerpointer;
|
||||
@ -391,7 +430,7 @@ namespace sol {
|
||||
if (type_of(L, -1) == type::nil) {
|
||||
lua_pop(L, 1);
|
||||
std::string err = "sol: unable to get usertype metatable for ";
|
||||
err += usertype_traits<T>::name;
|
||||
err += usertype_traits<T>::name();
|
||||
return luaL_error(L, err.c_str());
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
@ -401,7 +440,7 @@ namespace sol {
|
||||
};
|
||||
|
||||
static int call(lua_State* L, F& f) {
|
||||
call_syntax syntax = stack::get_call_syntax(L, usertype_traits<T>::metatable);
|
||||
call_syntax syntax = stack::get_call_syntax(L, &usertype_traits<T>::user_metatable()[0]);
|
||||
int syntaxval = static_cast<int>(syntax);
|
||||
int argcount = lua_gettop(L) - syntaxval;
|
||||
return construct_match<T, meta::pop_front_type_t<meta::function_args_t<Cxs>>...>(onmatch(), L, argcount, 1 + syntaxval, f);
|
||||
|
2
3rdparty/sol2/sol/compatibility/5.1.0.h
vendored
2
3rdparty/sol2/sol/compatibility/5.1.0.h
vendored
@ -158,7 +158,7 @@ inline const char* kepler_lua_compat_get_string(lua_State* L, void* ud, size_t*
|
||||
return ls->s;
|
||||
}
|
||||
|
||||
#if !defined(SOL_LUAJIT) || ((SOL_LUAJIT_VERSION - 020100) <= 0)
|
||||
#if !defined(SOL_LUAJIT) || ((SOL_LUAJIT_VERSION - 20100) <= 0)
|
||||
// Luajit 2.1.0 has this function already
|
||||
|
||||
inline int luaL_loadbufferx(lua_State* L, const char* buff, size_t size, const char* name, const char*) {
|
||||
|
43
3rdparty/sol2/sol/compatibility/5.2.0.h
vendored
Normal file
43
3rdparty/sol2/sol/compatibility/5.2.0.h
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_5_2_0_H
|
||||
#define SOL_5_2_0_H
|
||||
#include "version.hpp"
|
||||
|
||||
#if SOL_LUA_VERSION < 503
|
||||
|
||||
inline int lua_isinteger(lua_State* L, int idx) {
|
||||
if (lua_type(L, idx) != LUA_TNUMBER)
|
||||
return 0;
|
||||
// This is a very slipshod way to do the testing
|
||||
// but lua_totingerx doesn't play ball nicely
|
||||
// on older versions...
|
||||
lua_Number n = lua_tonumber(L, idx);
|
||||
lua_Integer i = lua_tointeger(L, idx);
|
||||
if (i != n)
|
||||
return 0;
|
||||
// it's DEFINITELY an integer
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // SOL_LUA_VERSION == 502
|
||||
#endif // SOL_5_2_0_H
|
1
3rdparty/sol2/sol/compatibility/5.x.x.inl
vendored
1
3rdparty/sol2/sol/compatibility/5.x.x.inl
vendored
@ -23,6 +23,7 @@
|
||||
#define SOL_5_X_X_INL
|
||||
|
||||
#include "version.hpp"
|
||||
#include "5.2.0.h"
|
||||
#include "5.1.0.h"
|
||||
#include "5.0.0.h"
|
||||
#include "5.x.x.h"
|
||||
|
259
3rdparty/sol2/sol/container_usertype_metatable.hpp
vendored
259
3rdparty/sol2/sol/container_usertype_metatable.hpp
vendored
@ -41,6 +41,19 @@ namespace sol {
|
||||
static const bool value = sizeof(test<T>(0)) == sizeof(char);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_push_back {
|
||||
private:
|
||||
typedef std::array<char, 1> one;
|
||||
typedef std::array<char, 2> two;
|
||||
|
||||
template <typename C> static one test(decltype(&C::push_back));
|
||||
template <typename C> static two test(...);
|
||||
|
||||
public:
|
||||
static const bool value = sizeof(test<T>(0)) == sizeof(char);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T& get_first(const T& t) {
|
||||
return std::forward<T>(t);
|
||||
@ -96,58 +109,65 @@ namespace sol {
|
||||
|
||||
static int real_index_call(lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
auto maybek = stack::check_get<K>(L, 2);
|
||||
if (maybek) {
|
||||
using std::begin;
|
||||
auto it = begin(src);
|
||||
K k = *maybek;
|
||||
if (k <= src.size() && k > 0) {
|
||||
--k;
|
||||
std::advance(it, k);
|
||||
return stack::push_reference(L, *it);
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
if (k > src.size() || k < 1) {
|
||||
return stack::push(L, nil);
|
||||
}
|
||||
#else
|
||||
#endif // Safety
|
||||
--k;
|
||||
std::advance(it, k);
|
||||
return stack::push_reference(L, *it);
|
||||
}
|
||||
else {
|
||||
auto maybename = stack::check_get<string_detail::string_shim>(L, 2);
|
||||
if (maybename) {
|
||||
auto& name = *maybename;
|
||||
if (name == "add") {
|
||||
return stack::push(L, &add_call);
|
||||
}
|
||||
else if (name == "insert") {
|
||||
return stack::push(L, &insert_call);
|
||||
}
|
||||
else if (name == "clear") {
|
||||
return stack::push(L, &clear_call);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stack::push(L, nil);
|
||||
#else
|
||||
using std::begin;
|
||||
auto it = begin(src);
|
||||
K k = stack::get<K>(L, 2);
|
||||
--k;
|
||||
std::advance(it, k);
|
||||
return stack::push_reference(L, *it);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
template <bool b, meta::disable<meta::boolean<b>> = meta::enabler>
|
||||
static int real_new_index_call_const(std::integral_constant<bool, b>, lua_State* L) {
|
||||
static int real_new_index_call_const(std::false_type, lua_State* L) {
|
||||
luaL_error(L, "sol: cannot write to a const value type or an immutable iterator (e.g., std::set)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <bool b, meta::enable<meta::boolean<b>> = meta::enabler>
|
||||
static int real_new_index_call_const(std::integral_constant<bool, b>, lua_State* L) {
|
||||
static int real_new_index_call_const(std::true_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
auto maybek = stack::check_get<K>(L, 2);
|
||||
if (maybek) {
|
||||
K k = *maybek;
|
||||
if (k <= src.size() && k > 0) {
|
||||
--k;
|
||||
using std::begin;
|
||||
auto it = begin(src);
|
||||
std::advance(it, k);
|
||||
*it = stack::get<V>(L, 3);
|
||||
}
|
||||
if (!maybek) {
|
||||
return stack::push(L, nil);
|
||||
}
|
||||
K k = *maybek;
|
||||
#else
|
||||
K k = stack::get<K>(L, 2);
|
||||
#endif
|
||||
using std::begin;
|
||||
auto it = begin(src);
|
||||
K k = stack::get<K>(L, 2);
|
||||
if (k == src.size()) {
|
||||
real_add_call_push(std::integral_constant<bool, detail::has_push_back<T>::value>(), L, src, 1);
|
||||
return 0;
|
||||
}
|
||||
--k;
|
||||
std::advance(it, k);
|
||||
*it = stack::get<V>(L, 3);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -183,13 +203,22 @@ namespace sol {
|
||||
return stack::push(L, src.size());
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int real_push_back_call(lua_State*L) {
|
||||
auto& src = get_src(L);
|
||||
src.push_back(stack::get<V>(L, 2));
|
||||
static int real_add_call_push(std::true_type, lua_State*L, T& src, int boost = 0) {
|
||||
src.push_back(stack::get<V>(L, 2 + boost));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_add_call_push(std::false_type, lua_State*L, T& src, int boost = 0) {
|
||||
using std::end;
|
||||
src.insert(end(src), stack::get<V>(L, 2 + boost));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_add_call(lua_State*L) {
|
||||
auto& src = get_src(L);
|
||||
return real_add_call_push(std::integral_constant<bool, detail::has_push_back<T>::value>(), L, src);
|
||||
}
|
||||
|
||||
static int real_insert_call(lua_State*L) {
|
||||
using std::begin;
|
||||
auto& src = get_src(L);
|
||||
@ -197,14 +226,23 @@ namespace sol {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int push_back_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_length_call)>(L);
|
||||
static int real_clear_call(lua_State*L) {
|
||||
auto& src = get_src(L);
|
||||
src.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_add_call)>(L);
|
||||
}
|
||||
|
||||
static int insert_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_insert_call)>(L);
|
||||
}
|
||||
#endif // Sometime later, in a distant universe...
|
||||
|
||||
static int clear_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_clear_call)>(L);
|
||||
}
|
||||
|
||||
static int length_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_length_call)>(L);
|
||||
@ -254,9 +292,9 @@ namespace sol {
|
||||
}
|
||||
|
||||
static int real_index_call(lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
auto k = stack::check_get<K>(L, 2);
|
||||
if (k) {
|
||||
auto& src = get_src(L);
|
||||
using std::end;
|
||||
auto it = detail::find(src, *k);
|
||||
if (it != end(src)) {
|
||||
@ -264,6 +302,21 @@ namespace sol {
|
||||
return stack::push_reference(L, v.second);
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto maybename = stack::check_get<string_detail::string_shim>(L, 2);
|
||||
if (maybename) {
|
||||
auto& name = *maybename;
|
||||
if (name == "add") {
|
||||
return stack::push(L, &add_call);
|
||||
}
|
||||
else if (name == "insert") {
|
||||
return stack::push(L, &insert_call);
|
||||
}
|
||||
else if (name == "clear") {
|
||||
return stack::push(L, &clear_call);
|
||||
}
|
||||
}
|
||||
}
|
||||
return stack::push(L, nil);
|
||||
}
|
||||
|
||||
@ -298,11 +351,12 @@ namespace sol {
|
||||
iter& i = stack::get<user<iter>>(L, 1);
|
||||
auto& source = i.source;
|
||||
auto& it = i.it;
|
||||
std::advance(it, 1);
|
||||
if (it == end(source)) {
|
||||
return 0;
|
||||
}
|
||||
return stack::multi_push_reference(L, it->first, it->second);
|
||||
int p = stack::multi_push_reference(L, it->first, it->second);
|
||||
std::advance(it, 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
static int real_pairs_call(lua_State* L) {
|
||||
@ -319,6 +373,28 @@ namespace sol {
|
||||
return stack::push(L, src.size());
|
||||
}
|
||||
|
||||
static int real_insert_call(lua_State*L) {
|
||||
return real_new_index_call(L);
|
||||
}
|
||||
|
||||
static int real_clear_call(lua_State*L) {
|
||||
auto& src = get_src(L);
|
||||
src.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_insert_call)>(L);
|
||||
}
|
||||
|
||||
static int insert_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_insert_call)>(L);
|
||||
}
|
||||
|
||||
static int clear_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_clear_call)>(L);
|
||||
}
|
||||
|
||||
static int length_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_length_call)>(L);
|
||||
}
|
||||
@ -341,67 +417,80 @@ namespace sol {
|
||||
};
|
||||
|
||||
namespace stack {
|
||||
namespace stack_detail {
|
||||
template <typename T>
|
||||
inline auto container_metatable() {
|
||||
typedef container_usertype_metatable<std::remove_pointer_t<T>> meta_cumt;
|
||||
std::array<luaL_Reg, 10> reg = { {
|
||||
{ "__index", &meta_cumt::index_call },
|
||||
{ "__newindex", &meta_cumt::new_index_call },
|
||||
{ "__pairs", &meta_cumt::pairs_call },
|
||||
{ "__ipairs", &meta_cumt::pairs_call },
|
||||
{ "__len", &meta_cumt::length_call },
|
||||
{ "clear", &meta_cumt::clear_call },
|
||||
{ "insert", &meta_cumt::insert_call },
|
||||
{ "add", &meta_cumt::add_call },
|
||||
std::is_pointer<T>::value ? luaL_Reg{ nullptr, nullptr } : luaL_Reg{ "__gc", &detail::usertype_alloc_destroy<T> },
|
||||
{ nullptr, nullptr }
|
||||
} };
|
||||
return reg;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct pusher<T, std::enable_if_t<meta::all<meta::has_begin_end<T>, meta::neg<meta::any<std::is_base_of<reference, T>, std::is_base_of<stack_reference, T>>>>::value>> {
|
||||
typedef container_usertype_metatable<T> cumt;
|
||||
static int push(lua_State* L, const T& cont) {
|
||||
auto fx = [&L]() {
|
||||
const char* metakey = &usertype_traits<T>::metatable[0];
|
||||
template <typename T>
|
||||
inline auto container_metatable_behind() {
|
||||
typedef container_usertype_metatable<std::remove_pointer_t<T>> meta_cumt;
|
||||
std::array<luaL_Reg, 3> reg = { {
|
||||
{ "__index", &meta_cumt::index_call },
|
||||
{ "__newindex", &meta_cumt::new_index_call },
|
||||
{ nullptr, nullptr }
|
||||
} };
|
||||
return reg;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct metatable_setup {
|
||||
lua_State* L;
|
||||
|
||||
metatable_setup(lua_State* L) : L(L) {}
|
||||
|
||||
void operator()() {
|
||||
static const auto reg = container_metatable<T>();
|
||||
static const auto containerreg = container_metatable_behind<T>();
|
||||
static const char* metakey = &usertype_traits<T>::metatable()[0];
|
||||
|
||||
if (luaL_newmetatable(L, metakey) == 1) {
|
||||
luaL_Reg reg[] = {
|
||||
{ "__index", &cumt::index_call },
|
||||
{ "__newindex", &cumt::new_index_call },
|
||||
{ "__pairs", &cumt::pairs_call },
|
||||
{ "__len", &cumt::length_call },
|
||||
{ "__gc", &detail::usertype_alloc_destroy<T> },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
luaL_setfuncs(L, reg, 0);
|
||||
stack_reference metatable(L, -1);
|
||||
luaL_setfuncs(L, reg.data(), 0);
|
||||
|
||||
lua_createtable(L, 0, static_cast<int>(containerreg.size()));
|
||||
stack_reference metabehind(L, -1);
|
||||
luaL_setfuncs(L, containerreg.data(), 0);
|
||||
|
||||
stack::set_field(L, metatable_key, metabehind, metatable.stack_index());
|
||||
metabehind.pop();
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct pusher<T, std::enable_if_t<meta::all<is_container<T>, meta::neg<meta::any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>>>>::value>> {
|
||||
static int push(lua_State* L, const T& cont) {
|
||||
stack_detail::metatable_setup<T> fx(L);
|
||||
return pusher<detail::as_value_tag<T>>{}.push_fx(L, fx, cont);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, T&& cont) {
|
||||
auto fx = [&L]() {
|
||||
const char* metakey = &usertype_traits<T>::metatable[0];
|
||||
if (luaL_newmetatable(L, metakey) == 1) {
|
||||
luaL_Reg reg[] = {
|
||||
{ "__index", &cumt::index_call },
|
||||
{ "__newindex", &cumt::new_index_call },
|
||||
{ "__pairs", &cumt::pairs_call },
|
||||
{ "__len", &cumt::length_call },
|
||||
{ "__gc", &detail::usertype_alloc_destroy<T> },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
luaL_setfuncs(L, reg, 0);
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
};
|
||||
stack_detail::metatable_setup<T> fx(L);
|
||||
return pusher<detail::as_value_tag<T>>{}.push_fx(L, fx, std::move(cont));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct pusher<T*, std::enable_if_t<meta::all<meta::has_begin_end<meta::unqualified_t<T>>, meta::neg<meta::any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>>>>::value>> {
|
||||
typedef container_usertype_metatable<T> cumt;
|
||||
struct pusher<T*, std::enable_if_t<meta::all<is_container<T>, meta::neg<meta::any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>>>>::value>> {
|
||||
static int push(lua_State* L, T* cont) {
|
||||
auto fx = [&L]() {
|
||||
const char* metakey = &usertype_traits<meta::unqualified_t<T>*>::metatable[0];
|
||||
if (luaL_newmetatable(L, metakey) == 1) {
|
||||
luaL_Reg reg[] = {
|
||||
{ "__index", &cumt::index_call },
|
||||
{ "__newindex", &cumt::new_index_call },
|
||||
{ "__pairs", &cumt::pairs_call },
|
||||
{ "__len", &cumt::length_call },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
luaL_setfuncs(L, reg, 0);
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
};
|
||||
stack_detail::metatable_setup<T*> fx(L);
|
||||
return pusher<detail::as_pointer_tag<T>>{}.push_fx(L, fx, cont);
|
||||
}
|
||||
};
|
||||
|
1
3rdparty/sol2/sol/error.hpp
vendored
1
3rdparty/sol2/sol/error.hpp
vendored
@ -37,6 +37,7 @@ namespace sol {
|
||||
std::string w;
|
||||
public:
|
||||
error(const std::string& str) : error(detail::direct_error, "lua: error: " + str) {}
|
||||
error(std::string&& str) : error(detail::direct_error, "lua: error: " + std::move(str)) {}
|
||||
error(detail::direct_error_tag, const std::string& str) : std::runtime_error(""), w(str) {}
|
||||
error(detail::direct_error_tag, std::string&& str) : std::runtime_error(""), w(std::move(str)) {}
|
||||
|
||||
|
2
3rdparty/sol2/sol/load_result.hpp
vendored
2
3rdparty/sol2/sol/load_result.hpp
vendored
@ -119,7 +119,7 @@ namespace sol {
|
||||
|
||||
template<typename... Ret, typename... Args>
|
||||
decltype(auto) call(Args&&... args) {
|
||||
return get<function>().template call<Ret...>(std::forward<Args>(args)...);
|
||||
return get<protected_function>().template call<Ret...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
|
2
3rdparty/sol2/sol/object.hpp
vendored
2
3rdparty/sol2/sol/object.hpp
vendored
@ -22,11 +22,11 @@
|
||||
#ifndef SOL_OBJECT_HPP
|
||||
#define SOL_OBJECT_HPP
|
||||
|
||||
#include "optional.hpp"
|
||||
#include "reference.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "userdata.hpp"
|
||||
#include "variadic_args.hpp"
|
||||
#include "optional.hpp"
|
||||
|
||||
namespace sol {
|
||||
|
||||
|
3
3rdparty/sol2/sol/optional.hpp
vendored
3
3rdparty/sol2/sol/optional.hpp
vendored
@ -22,11 +22,12 @@
|
||||
#ifndef SOL_OPTIONAL_HPP
|
||||
#define SOL_OPTIONAL_HPP
|
||||
|
||||
#include "compatibility.hpp"
|
||||
#include "in_place.hpp"
|
||||
#if defined(SOL_USE_BOOST)
|
||||
#include <boost/optional.hpp>
|
||||
#else
|
||||
#include "../Optional/optional.hpp"
|
||||
#include "optional_implementation.hpp"
|
||||
#endif // Boost vs. Better optional
|
||||
|
||||
namespace sol {
|
||||
|
1127
3rdparty/sol2/sol/optional_implementation.hpp
vendored
Normal file
1127
3rdparty/sol2/sol/optional_implementation.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12
3rdparty/sol2/sol/proxy.hpp
vendored
12
3rdparty/sol2/sol/proxy.hpp
vendored
@ -123,22 +123,26 @@ namespace sol {
|
||||
|
||||
template<typename Table, typename Key, typename T>
|
||||
inline bool operator==(T&& left, const proxy<Table, Key>& right) {
|
||||
return left == right.template get<std::decay_t<T>>();
|
||||
typedef decltype(stack::get<T>(nullptr, 0)) U;
|
||||
return right.template get<optional<U>>() == left;
|
||||
}
|
||||
|
||||
template<typename Table, typename Key, typename T>
|
||||
inline bool operator==(const proxy<Table, Key>& right, T&& left) {
|
||||
return right.template get<std::decay_t<T>>() == left;
|
||||
typedef decltype(stack::get<T>(nullptr, 0)) U;
|
||||
return right.template get<optional<U>>() == left;
|
||||
}
|
||||
|
||||
template<typename Table, typename Key, typename T>
|
||||
inline bool operator!=(T&& left, const proxy<Table, Key>& right) {
|
||||
return right.template get<std::decay_t<T>>() != left;
|
||||
typedef decltype(stack::get<T>(nullptr, 0)) U;
|
||||
return right.template get<optional<U>>() == left;
|
||||
}
|
||||
|
||||
template<typename Table, typename Key, typename T>
|
||||
inline bool operator!=(const proxy<Table, Key>& right, T&& left) {
|
||||
return right.template get<std::decay_t<T>>() != left;
|
||||
typedef decltype(stack::get<T>(nullptr, 0)) U;
|
||||
return right.template get<optional<U>>() == left;
|
||||
}
|
||||
|
||||
template<typename Table, typename Key>
|
||||
|
163
3rdparty/sol2/sol/simple_usertype_metatable.hpp
vendored
163
3rdparty/sol2/sol/simple_usertype_metatable.hpp
vendored
@ -31,6 +31,8 @@
|
||||
namespace sol {
|
||||
|
||||
namespace usertype_detail {
|
||||
const lua_Integer toplevel_magic = static_cast<lua_Integer>(0x00000001);
|
||||
|
||||
struct variable_wrapper {
|
||||
virtual int index(lua_State* L) = 0;
|
||||
virtual int new_index(lua_State* L) = 0;
|
||||
@ -68,8 +70,31 @@ namespace sol {
|
||||
|
||||
template <typename T>
|
||||
inline int simple_metatable_newindex(lua_State* L) {
|
||||
if (stack::stack_detail::check_metatable<T, false>(L, 1)) {
|
||||
stack::set_field<false, true>(L, stack_reference(L, 2), stack_reference(L, 3), 1);
|
||||
int isnum = 0;
|
||||
lua_Integer magic = lua_tointegerx(L, lua_upvalueindex(4), &isnum);
|
||||
if (isnum != 0 && magic == toplevel_magic) {
|
||||
for (std::size_t i = 0; i < 3; lua_pop(L, 1), ++i) {
|
||||
// Pointer types, AKA "references" from C++
|
||||
const char* metakey = nullptr;
|
||||
switch (i) {
|
||||
case 0:
|
||||
metakey = &usertype_traits<T*>::metatable()[0];
|
||||
break;
|
||||
case 1:
|
||||
metakey = &usertype_traits<detail::unique_usertype<T>>::metatable()[0];
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
metakey = &usertype_traits<T>::metatable()[0];
|
||||
break;
|
||||
}
|
||||
luaL_getmetatable(L, metakey);
|
||||
int tableindex = lua_gettop(L);
|
||||
if (type_of(L, tableindex) == type::nil) {
|
||||
continue;
|
||||
}
|
||||
stack::set_field<false, true>(L, stack_reference(L, 2), stack_reference(L, 3), tableindex);
|
||||
}
|
||||
lua_settop(L, 0);
|
||||
return 0;
|
||||
}
|
||||
@ -259,15 +284,15 @@ namespace sol {
|
||||
|
||||
template <typename... Bases>
|
||||
void add(lua_State*, base_classes_tag, bases<Bases...>) {
|
||||
static_assert(sizeof(usertype_detail::base_walk) <= sizeof(void*), "size of function pointer is greater than sizeof(void*); cannot work on this platform");
|
||||
static_assert(sizeof(usertype_detail::base_walk) <= sizeof(void*), "size of function pointer is greater than sizeof(void*); cannot work on this platform. Please file a bug report.");
|
||||
if (sizeof...(Bases) < 1) {
|
||||
return;
|
||||
}
|
||||
mustindex = true;
|
||||
(void)detail::swallow{ 0, ((detail::has_derived<Bases>::value = true), 0)... };
|
||||
|
||||
static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
|
||||
static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
|
||||
static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function), "The size of this data pointer is too small to fit the inheritance checking function: Please file a bug report.");
|
||||
static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function), "The size of this data pointer is too small to fit the inheritance checking function: Please file a bug report.");
|
||||
baseclasscheck = (void*)&detail::inheritance<T, Bases...>::type_check;
|
||||
baseclasscast = (void*)&detail::inheritance<T, Bases...>::type_cast;
|
||||
indexbaseclasspropogation = usertype_detail::walk_all_bases<true, Bases...>;
|
||||
@ -278,11 +303,11 @@ namespace sol {
|
||||
template<std::size_t... I, typename Tuple>
|
||||
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
|
||||
: callconstructfunc(nil),
|
||||
indexfunc(&usertype_detail::indexing_fail<true>), newindexfunc(&usertype_detail::simple_metatable_newindex<T>),
|
||||
indexfunc(&usertype_detail::indexing_fail<true>), newindexfunc(&usertype_detail::indexing_fail<false>),
|
||||
indexbase(&usertype_detail::simple_core_indexing_call<true>), newindexbase(&usertype_detail::simple_core_indexing_call<false>),
|
||||
indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
|
||||
baseclasscheck(nullptr), baseclasscast(nullptr),
|
||||
mustindex(true), secondarymeta(true) {
|
||||
mustindex(false), secondarymeta(false) {
|
||||
(void)detail::swallow{ 0,
|
||||
(add(L, detail::forward_get<I * 2>(args), detail::forward_get<I * 2 + 1>(args)),0)...
|
||||
};
|
||||
@ -329,7 +354,7 @@ namespace sol {
|
||||
|
||||
static usertype_detail::simple_map& make_cleanup(lua_State* L, umt_t& umx) {
|
||||
static int uniqueness = 0;
|
||||
std::string uniquegcmetakey = usertype_traits<T>::user_gc_metatable;
|
||||
std::string uniquegcmetakey = usertype_traits<T>::user_gc_metatable();
|
||||
// std::to_string doesn't exist in android still, with NDK, so this bullshit
|
||||
// is necessary
|
||||
// thanks, Android :v
|
||||
@ -340,8 +365,11 @@ namespace sol {
|
||||
snprintf(uniquetarget, uniquegcmetakey.length(), "%d", uniqueness);
|
||||
++uniqueness;
|
||||
|
||||
const char* gcmetakey = &usertype_traits<T>::gc_table[0];
|
||||
stack::push<user<usertype_detail::simple_map>>(L, metatable_key, uniquegcmetakey, &usertype_traits<T>::metatable[0], umx.indexbaseclasspropogation, umx.newindexbaseclasspropogation, std::move(umx.varmap), std::move(umx.registrations));
|
||||
const char* gcmetakey = &usertype_traits<T>::gc_table()[0];
|
||||
stack::push<user<usertype_detail::simple_map>>(L, metatable_key, uniquegcmetakey, &usertype_traits<T>::metatable()[0],
|
||||
umx.indexbaseclasspropogation, umx.newindexbaseclasspropogation,
|
||||
std::move(umx.varmap), std::move(umx.registrations)
|
||||
);
|
||||
stack_reference stackvarmap(L, -1);
|
||||
stack::set_field<true>(L, gcmetakey, stackvarmap);
|
||||
stackvarmap.pop();
|
||||
@ -356,19 +384,53 @@ namespace sol {
|
||||
bool hasequals = false;
|
||||
bool hasless = false;
|
||||
bool haslessequals = false;
|
||||
auto register_kvp = [&](std::size_t i, stack_reference& t, const std::string& first, object& second) {
|
||||
if (first == name_of(meta_function::equal_to)) {
|
||||
hasequals = true;
|
||||
}
|
||||
else if (first == name_of(meta_function::less_than)) {
|
||||
hasless = true;
|
||||
}
|
||||
else if (first == name_of(meta_function::less_than_or_equal_to)) {
|
||||
haslessequals = true;
|
||||
}
|
||||
else if (first == name_of(meta_function::index)) {
|
||||
umx.indexfunc = second.template as<lua_CFunction>();
|
||||
}
|
||||
else if (first == name_of(meta_function::new_index)) {
|
||||
umx.newindexfunc = second.template as<lua_CFunction>();
|
||||
}
|
||||
switch (i) {
|
||||
case 0:
|
||||
if (first == name_of(meta_function::garbage_collect)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (first == name_of(meta_function::garbage_collect)) {
|
||||
stack::set_field(L, first, detail::unique_destruct<T>, t.stack_index());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
stack::set_field(L, first, second, t.stack_index());
|
||||
};
|
||||
for (std::size_t i = 0; i < 3; ++i) {
|
||||
// Pointer types, AKA "references" from C++
|
||||
const char* metakey = nullptr;
|
||||
switch (i) {
|
||||
case 0:
|
||||
metakey = &usertype_traits<T*>::metatable[0];
|
||||
metakey = &usertype_traits<T*>::metatable()[0];
|
||||
break;
|
||||
case 1:
|
||||
metakey = &usertype_traits<detail::unique_usertype<T>>::metatable[0];
|
||||
metakey = &usertype_traits<detail::unique_usertype<T>>::metatable()[0];
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
metakey = &usertype_traits<T>::metatable[0];
|
||||
metakey = &usertype_traits<T>::metatable()[0];
|
||||
break;
|
||||
}
|
||||
luaL_newmetatable(L, metakey);
|
||||
@ -376,38 +438,7 @@ namespace sol {
|
||||
for (auto& kvp : varmap.functions) {
|
||||
auto& first = std::get<0>(kvp);
|
||||
auto& second = std::get<1>(kvp);
|
||||
if (first == name_of(meta_function::equal_to)) {
|
||||
hasequals = true;
|
||||
}
|
||||
else if (first == name_of(meta_function::less_than)) {
|
||||
hasless = true;
|
||||
}
|
||||
else if (first == name_of(meta_function::less_than_or_equal_to)) {
|
||||
haslessequals = true;
|
||||
}
|
||||
else if (first == name_of(meta_function::index)) {
|
||||
umx.indexfunc = second.template as<lua_CFunction>();
|
||||
}
|
||||
else if (first == name_of(meta_function::new_index)) {
|
||||
umx.newindexfunc = second.template as<lua_CFunction>();
|
||||
}
|
||||
switch (i) {
|
||||
case 0:
|
||||
if (first == name_of(meta_function::garbage_collect)) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (first == name_of(meta_function::garbage_collect)) {
|
||||
stack::set_field(L, first, detail::unique_destruct<T>, t.stack_index());
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
stack::set_field(L, first, second, t.stack_index());
|
||||
register_kvp(i, t, first, second);
|
||||
}
|
||||
luaL_Reg opregs[4]{};
|
||||
int opregsindex = 0;
|
||||
@ -440,7 +471,6 @@ namespace sol {
|
||||
|
||||
if (umx.mustindex) {
|
||||
// use indexing function
|
||||
static_assert(sizeof(usertype_detail::base_walk) <= sizeof(void*), "The size of this data pointer is too small to fit the base class index propagation key: file a bug report.");
|
||||
stack::set_field(L, meta_function::index,
|
||||
make_closure(&usertype_detail::simple_index_call,
|
||||
make_light(varmap),
|
||||
@ -460,7 +490,7 @@ namespace sol {
|
||||
}
|
||||
// metatable on the metatable
|
||||
// for call constructor purposes and such
|
||||
lua_createtable(L, 0, 1);
|
||||
lua_createtable(L, 0, 2 * static_cast<int>(umx.secondarymeta) + static_cast<int>(umx.callconstructfunc.valid()));
|
||||
stack_reference metabehind(L, -1);
|
||||
if (umx.callconstructfunc.valid()) {
|
||||
stack::set_field(L, sol::meta_function::call_function, umx.callconstructfunc, metabehind.stack_index());
|
||||
@ -482,9 +512,44 @@ namespace sol {
|
||||
stack::set_field(L, metatable_key, metabehind, t.stack_index());
|
||||
metabehind.pop();
|
||||
|
||||
if (i < 2)
|
||||
t.pop();
|
||||
t.pop();
|
||||
}
|
||||
|
||||
// Now for the shim-table that actually gets pushed
|
||||
luaL_newmetatable(L, &usertype_traits<T>::user_metatable()[0]);
|
||||
stack_reference t(L, -1);
|
||||
for (auto& kvp : varmap.functions) {
|
||||
auto& first = std::get<0>(kvp);
|
||||
auto& second = std::get<1>(kvp);
|
||||
register_kvp(2, t, first, second);
|
||||
}
|
||||
{
|
||||
lua_createtable(L, 0, 2 + static_cast<int>(umx.callconstructfunc.valid()));
|
||||
stack_reference metabehind(L, -1);
|
||||
if (umx.callconstructfunc.valid()) {
|
||||
stack::set_field(L, sol::meta_function::call_function, umx.callconstructfunc, metabehind.stack_index());
|
||||
}
|
||||
// use indexing function
|
||||
stack::set_field(L, meta_function::index,
|
||||
make_closure(&usertype_detail::simple_index_call,
|
||||
make_light(varmap),
|
||||
&usertype_detail::simple_index_call,
|
||||
&usertype_detail::simple_metatable_newindex<T>,
|
||||
usertype_detail::toplevel_magic
|
||||
), metabehind.stack_index());
|
||||
stack::set_field(L, meta_function::new_index,
|
||||
make_closure(&usertype_detail::simple_new_index_call,
|
||||
make_light(varmap),
|
||||
&usertype_detail::simple_index_call,
|
||||
&usertype_detail::simple_metatable_newindex<T>,
|
||||
usertype_detail::toplevel_magic
|
||||
), metabehind.stack_index());
|
||||
stack::set_field(L, metatable_key, metabehind, t.stack_index());
|
||||
metabehind.pop();
|
||||
}
|
||||
|
||||
// Don't pop the table when we're done;
|
||||
// return it
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
65
3rdparty/sol2/sol/stack_check.hpp
vendored
65
3rdparty/sol2/sol/stack_check.hpp
vendored
@ -34,7 +34,7 @@ namespace sol {
|
||||
namespace stack_detail {
|
||||
template <typename T, bool poptable = true>
|
||||
inline bool check_metatable(lua_State* L, int index = -2) {
|
||||
const auto& metakey = usertype_traits<T>::metatable;
|
||||
const auto& metakey = usertype_traits<T>::metatable();
|
||||
luaL_getmetatable(L, &metakey[0]);
|
||||
const type expectedmetatabletype = static_cast<type>(lua_type(L, -1));
|
||||
if (expectedmetatabletype != type::nil) {
|
||||
@ -77,6 +77,34 @@ namespace sol {
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct checker<T, type::number, std::enable_if_t<std::is_integral<T>::value>> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
bool success = lua_isinteger(L, index) == 1;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
}
|
||||
return success;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct checker<T, type::number, std::enable_if_t<std::is_floating_point<T>::value>> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
bool success = lua_isnumber(L, index) == 1;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
}
|
||||
return success;
|
||||
}
|
||||
};
|
||||
|
||||
template <type expected, typename C>
|
||||
struct checker<nil_t, expected, C> {
|
||||
template <typename Handler>
|
||||
@ -239,21 +267,7 @@ namespace sol {
|
||||
};
|
||||
|
||||
template <typename T, typename C>
|
||||
struct checker<T*, type::userdata, C> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
const type indextype = type_of(L, index);
|
||||
// Allow nil to be transformed to nullptr
|
||||
if (indextype == type::nil) {
|
||||
tracking.use(1);
|
||||
return true;
|
||||
}
|
||||
return checker<meta::unqualified_t<T>, type::userdata, C>{}.check(types<meta::unqualified_t<T>>(), L, indextype, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename C>
|
||||
struct checker<T, type::userdata, C> {
|
||||
struct checker<detail::as_value_tag<T>, type::userdata, C> {
|
||||
template <typename U, typename Handler>
|
||||
static bool check(types<U>, lua_State* L, type indextype, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
@ -292,11 +306,28 @@ namespace sol {
|
||||
lua_pop(L, 1);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename C>
|
||||
struct checker<T, type::userdata, C> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
const type indextype = type_of(L, index);
|
||||
return check(types<T>(), L, indextype, index, std::forward<Handler>(handler), tracking);
|
||||
return checker<detail::as_value_tag<T>, type::userdata, C>{}.check(types<T>(), L, indextype, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename C>
|
||||
struct checker<T*, type::userdata, C> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
const type indextype = type_of(L, index);
|
||||
// Allow nil to be transformed to nullptr
|
||||
if (indextype == type::nil) {
|
||||
tracking.use(1);
|
||||
return true;
|
||||
}
|
||||
return checker<meta::unqualified_t<T>, type::userdata, C>{}.check(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
};
|
||||
|
||||
|
38
3rdparty/sol2/sol/stack_get.hpp
vendored
38
3rdparty/sol2/sol/stack_get.hpp
vendored
@ -41,7 +41,7 @@ namespace sol {
|
||||
template<typename T, typename>
|
||||
struct getter {
|
||||
static T& get(lua_State* L, int index, record& tracking) {
|
||||
return getter<T&>{}.get(L, index, tracking);
|
||||
return getter<sol::detail::as_value_tag<T>>{}.get(L, index, tracking);
|
||||
}
|
||||
};
|
||||
|
||||
@ -437,7 +437,7 @@ namespace sol {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<T*> {
|
||||
struct getter<detail::as_value_tag<T>> {
|
||||
static T* get_no_nil(lua_State* L, int index, record& tracking) {
|
||||
tracking.use(1);
|
||||
void** pudata = static_cast<void**>(lua_touserdata(L, index));
|
||||
@ -456,28 +456,49 @@ namespace sol {
|
||||
T* obj = static_cast<T*>(udata);
|
||||
return obj;
|
||||
}
|
||||
|
||||
static T& get(lua_State* L, int index, record& tracking) {
|
||||
return *get_no_nil(L, index, tracking);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<detail::as_pointer_tag<T>> {
|
||||
static T* get(lua_State* L, int index, record& tracking) {
|
||||
type t = type_of(L, index);
|
||||
if (t == type::nil) {
|
||||
tracking.use(1);
|
||||
return nullptr;
|
||||
}
|
||||
return get_no_nil(L, index, tracking);
|
||||
return getter<detail::as_value_tag<T>>::get_no_nil(L, index, tracking);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<non_null<T*>> {
|
||||
static T* get(lua_State* L, int index, record& tracking) {
|
||||
return getter<T*>::get_no_nil(L, index, tracking);
|
||||
return getter<detail::as_value_tag<T>>::get_no_nil(L, index, tracking);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<T&> {
|
||||
static T& get(lua_State* L, int index, record& tracking) {
|
||||
return *getter<T*>::get_no_nil(L, index, tracking);
|
||||
return getter<detail::as_value_tag<T>>::get(L, index, tracking);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<std::reference_wrapper<T>> {
|
||||
static T& get(lua_State* L, int index, record& tracking) {
|
||||
return getter<T&>{}.get(L, index, tracking);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<T*> {
|
||||
static T* get(lua_State* L, int index, record& tracking) {
|
||||
return getter<detail::as_pointer_tag<T>>::get(L, index, tracking);
|
||||
}
|
||||
};
|
||||
|
||||
@ -495,13 +516,6 @@ namespace sol {
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<std::reference_wrapper<T>> {
|
||||
static T& get(lua_State* L, int index, record& tracking) {
|
||||
return getter<T&>{}.get(L, index, tracking);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
struct getter<std::tuple<Args...>> {
|
||||
typedef std::tuple<decltype(stack::get<Args>(nullptr, 0))...> R;
|
||||
|
18
3rdparty/sol2/sol/stack_push.hpp
vendored
18
3rdparty/sol2/sol/stack_push.hpp
vendored
@ -62,7 +62,7 @@ namespace sol {
|
||||
|
||||
template <typename... Args>
|
||||
static int push(lua_State* L, Args&&... args) {
|
||||
return push_keyed(L, usertype_traits<T>::metatable, std::forward<Args>(args)...);
|
||||
return push_keyed(L, usertype_traits<T>::metatable(), std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
@ -87,7 +87,7 @@ namespace sol {
|
||||
}
|
||||
|
||||
static int push(lua_State* L, T* obj) {
|
||||
return push_keyed(L, usertype_traits<meta::unqualified_t<T>*>::metatable, obj);
|
||||
return push_keyed(L, usertype_traits<meta::unqualified_t<T>*>::metatable(), obj);
|
||||
}
|
||||
};
|
||||
|
||||
@ -140,7 +140,7 @@ namespace sol {
|
||||
*fx = detail::special_destruct<P, Real>;
|
||||
detail::default_construct::construct(mem, std::forward<Args>(args)...);
|
||||
*pref = unique_usertype_traits<T>::get(*mem);
|
||||
if (luaL_newmetatable(L, &usertype_traits<detail::unique_usertype<P>>::metatable[0]) == 1) {
|
||||
if (luaL_newmetatable(L, &usertype_traits<detail::unique_usertype<P>>::metatable()[0]) == 1) {
|
||||
set_field(L, "__gc", detail::unique_destruct<P>);
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
@ -362,13 +362,13 @@ namespace sol {
|
||||
|
||||
template <typename Arg, typename... Args, meta::disable<meta::any_same<meta::unqualified_t<Arg>, no_metatable_t, metatable_key_t>> = meta::enabler>
|
||||
static int push(lua_State* L, Arg&& arg, Args&&... args) {
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
|
||||
return push_with(L, name, std::forward<Arg>(arg), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static int push(lua_State* L, no_metatable_t, Args&&... args) {
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
|
||||
return push_with<false>(L, name, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
@ -379,22 +379,22 @@ namespace sol {
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const user<T>& u) {
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
|
||||
return push_with(L, name, u.value);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, user<T>&& u) {
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
|
||||
return push_with(L, name, std::move(u.value));
|
||||
}
|
||||
|
||||
static int push(lua_State* L, no_metatable_t, const user<T>& u) {
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
|
||||
return push_with<false>(L, name, u.value);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, no_metatable_t, user<T>&& u) {
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
|
||||
return push_with<false>(L, name, std::move(u.value));
|
||||
}
|
||||
};
|
||||
|
8
3rdparty/sol2/sol/state.hpp
vendored
8
3rdparty/sol2/sol/state.hpp
vendored
@ -31,8 +31,12 @@ namespace sol {
|
||||
return -1;
|
||||
#else
|
||||
const char* message = lua_tostring(L, -1);
|
||||
std::string err = message ? message : "An unexpected error occurred and forced the lua state to call atpanic";
|
||||
throw error(err);
|
||||
if (message) {
|
||||
std::string err = message;
|
||||
lua_pop(L, 1);
|
||||
throw error(err);
|
||||
}
|
||||
throw error(std::string("An unexpected error occurred and forced the lua state to call atpanic"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
30
3rdparty/sol2/sol/state_view.hpp
vendored
30
3rdparty/sol2/sol/state_view.hpp
vendored
@ -115,6 +115,10 @@ namespace sol {
|
||||
|
||||
}
|
||||
|
||||
state_view(this_state L) : state_view(L.L){
|
||||
|
||||
}
|
||||
|
||||
lua_State* lua_state() const {
|
||||
return L;
|
||||
}
|
||||
@ -222,18 +226,30 @@ namespace sol {
|
||||
return require_core(key, [this, &filename]() {stack::script_file(L, filename); }, create_global);
|
||||
}
|
||||
|
||||
protected_function_result do_string(const std::string& code) {
|
||||
sol::protected_function pf = load(code);
|
||||
return pf();
|
||||
}
|
||||
|
||||
protected_function_result do_file(const std::string& filename) {
|
||||
sol::protected_function pf = load_file(filename);
|
||||
return pf();
|
||||
}
|
||||
|
||||
function_result script(const std::string& code) {
|
||||
int index = (::std::max)(lua_gettop(L), 1);
|
||||
int index = lua_gettop(L);
|
||||
stack::script(L, code);
|
||||
int returns = lua_gettop(L) - (index - 1);
|
||||
return function_result(L, index, returns);
|
||||
int postindex = lua_gettop(L);
|
||||
int returns = postindex - index;
|
||||
return function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
|
||||
}
|
||||
|
||||
function_result script_file(const std::string& filename) {
|
||||
int index = (::std::max)(lua_gettop(L), 1);
|
||||
int index = lua_gettop(L);
|
||||
stack::script_file(L, filename);
|
||||
int returns = lua_gettop(L) - (index - 1);
|
||||
return function_result(L, index, returns);
|
||||
int postindex = lua_gettop(L);
|
||||
int returns = postindex - index;
|
||||
return function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
|
||||
}
|
||||
|
||||
load_result load(const std::string& code) {
|
||||
@ -317,7 +333,7 @@ namespace sol {
|
||||
|
||||
template<typename T>
|
||||
state_view& set_usertype(usertype<T>& user) {
|
||||
return set_usertype(usertype_traits<T>::name, user);
|
||||
return set_usertype(usertype_traits<T>::name(), user);
|
||||
}
|
||||
|
||||
template<typename Key, typename T>
|
||||
|
3
3rdparty/sol2/sol/table_core.hpp
vendored
3
3rdparty/sol2/sol/table_core.hpp
vendored
@ -244,7 +244,7 @@ namespace sol {
|
||||
|
||||
template<typename T>
|
||||
basic_table_core& set_usertype(usertype<T>& user) {
|
||||
return set_usertype(usertype_traits<T>::name, user);
|
||||
return set_usertype(usertype_traits<T>::name(), user);
|
||||
}
|
||||
|
||||
template<typename Key, typename T>
|
||||
@ -419,6 +419,7 @@ namespace sol {
|
||||
|
||||
template <typename... Args>
|
||||
static inline table create_with(lua_State* L, Args&&... args) {
|
||||
static_assert(sizeof...(Args) % 2 == 0, "You must have an even number of arguments for a key, value ... list.");
|
||||
static const int narr = static_cast<int>(meta::count_2_for_pack<std::is_integral, Args...>::value);
|
||||
return create(L, narr, static_cast<int>((sizeof...(Args) / 2) - narr), std::forward<Args>(args)...);
|
||||
}
|
||||
|
20
3rdparty/sol2/sol/types.hpp
vendored
20
3rdparty/sol2/sol/types.hpp
vendored
@ -361,6 +361,7 @@ namespace sol {
|
||||
new_index,
|
||||
mode,
|
||||
call,
|
||||
call_function = call,
|
||||
metatable,
|
||||
to_string,
|
||||
length,
|
||||
@ -377,7 +378,13 @@ namespace sol {
|
||||
less_than,
|
||||
less_than_or_equal_to,
|
||||
garbage_collect,
|
||||
call_function = call,
|
||||
floor_division,
|
||||
bitwise_left_shift,
|
||||
bitwise_right_shift,
|
||||
bitwise_not,
|
||||
bitwise_and,
|
||||
bitwise_or,
|
||||
bitwise_xor,
|
||||
};
|
||||
|
||||
typedef meta_function meta_method;
|
||||
@ -393,7 +400,7 @@ namespace sol {
|
||||
"__newindex",
|
||||
"__mode",
|
||||
"__call",
|
||||
"__metatable",
|
||||
"__mt",
|
||||
"__tostring",
|
||||
"__len",
|
||||
"__unm",
|
||||
@ -643,6 +650,12 @@ namespace sol {
|
||||
template <typename T>
|
||||
struct lua_type_of<T, std::enable_if_t<std::is_enum<T>::value>> : std::integral_constant<type, type::number> {};
|
||||
|
||||
template <typename T, typename C = void>
|
||||
struct is_container : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_container<T, std::enable_if_t<meta::has_begin_end<meta::unqualified_t<T>>::value>> : std::true_type {};
|
||||
|
||||
template <>
|
||||
struct lua_type_of<meta_function> : std::integral_constant<type, type::string> {};
|
||||
|
||||
@ -747,6 +760,9 @@ namespace sol {
|
||||
template <typename T>
|
||||
struct is_userdata<basic_userdata<T>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_container : detail::is_container<T>{};
|
||||
|
||||
template<typename T>
|
||||
inline type type_of() {
|
||||
return lua_type_of<meta::unqualified_t<T>>::value;
|
||||
|
37
3rdparty/sol2/sol/usertype_metatable.hpp
vendored
37
3rdparty/sol2/sol/usertype_metatable.hpp
vendored
@ -116,8 +116,8 @@ namespace sol {
|
||||
static void walk_single_base(lua_State* L, bool& found, int& ret, string_detail::string_shim&) {
|
||||
if (found)
|
||||
return;
|
||||
const char* metakey = &usertype_traits<Base>::metatable[0];
|
||||
const char* gcmetakey = &usertype_traits<Base>::gc_table[0];
|
||||
const char* metakey = &usertype_traits<Base>::metatable()[0];
|
||||
const char* gcmetakey = &usertype_traits<Base>::gc_table()[0];
|
||||
const char* basewalkkey = is_index ? detail::base_class_index_propogation_key() : detail::base_class_new_index_propogation_key();
|
||||
|
||||
luaL_getmetatable(L, metakey);
|
||||
@ -466,7 +466,7 @@ namespace sol {
|
||||
static umt_t& make_cleanup(lua_State* L, umt_t&& umx) {
|
||||
// ensure some sort of uniqueness
|
||||
static int uniqueness = 0;
|
||||
std::string uniquegcmetakey = usertype_traits<T>::user_gc_metatable;
|
||||
std::string uniquegcmetakey = usertype_traits<T>::user_gc_metatable();
|
||||
// std::to_string doesn't exist in android still, with NDK, so this bullshit
|
||||
// is necessary
|
||||
// thanks, Android :v
|
||||
@ -477,7 +477,7 @@ namespace sol {
|
||||
snprintf(uniquetarget, uniquegcmetakey.length(), "%d", uniqueness);
|
||||
++uniqueness;
|
||||
|
||||
const char* gcmetakey = &usertype_traits<T>::gc_table[0];
|
||||
const char* gcmetakey = &usertype_traits<T>::gc_table()[0];
|
||||
// Make sure userdata's memory is properly in lua first,
|
||||
// otherwise all the light userdata we make later will become invalid
|
||||
stack::push<user<umt_t>>(L, metatable_key, uniquegcmetakey, std::move(umx));
|
||||
@ -514,16 +514,16 @@ namespace sol {
|
||||
luaL_Reg* metaregs = nullptr;
|
||||
switch (i) {
|
||||
case 0:
|
||||
metakey = &usertype_traits<T*>::metatable[0];
|
||||
metakey = &usertype_traits<T*>::metatable()[0];
|
||||
metaregs = ref_table.data();
|
||||
break;
|
||||
case 1:
|
||||
metakey = &usertype_traits<detail::unique_usertype<T>>::metatable[0];
|
||||
metakey = &usertype_traits<detail::unique_usertype<T>>::metatable()[0];
|
||||
metaregs = unique_table.data();
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
metakey = &usertype_traits<T>::metatable[0];
|
||||
metakey = &usertype_traits<T>::metatable()[0];
|
||||
metaregs = value_table.data();
|
||||
break;
|
||||
}
|
||||
@ -554,7 +554,7 @@ namespace sol {
|
||||
}
|
||||
// metatable on the metatable
|
||||
// for call constructor purposes and such
|
||||
lua_createtable(L, 0, 1);
|
||||
lua_createtable(L, 0, 3);
|
||||
stack_reference metabehind(L, -1);
|
||||
if (um.callconstructfunc != nullptr) {
|
||||
stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, make_light(um)), metabehind.stack_index());
|
||||
@ -567,9 +567,26 @@ namespace sol {
|
||||
metabehind.pop();
|
||||
// We want to just leave the table
|
||||
// in the registry only, otherwise we return it
|
||||
if (i < 2) {
|
||||
t.pop();
|
||||
t.pop();
|
||||
}
|
||||
|
||||
// Now for the shim-table that actually gets assigned to the name
|
||||
luaL_newmetatable(L, &usertype_traits<T>::user_metatable()[0]);
|
||||
stack_reference t(L, -1);
|
||||
stack::push(L, make_light(um));
|
||||
luaL_setfuncs(L, value_table.data(), 1);
|
||||
{
|
||||
lua_createtable(L, 0, 3);
|
||||
stack_reference metabehind(L, -1);
|
||||
if (um.callconstructfunc != nullptr) {
|
||||
stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, make_light(um)), metabehind.stack_index());
|
||||
}
|
||||
if (um.secondarymeta) {
|
||||
stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um)), metabehind.stack_index());
|
||||
stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um)), metabehind.stack_index());
|
||||
}
|
||||
stack::set_field(L, metatable_key, metabehind, t.stack_index());
|
||||
metabehind.pop();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
44
3rdparty/sol2/sol/usertype_traits.hpp
vendored
44
3rdparty/sol2/sol/usertype_traits.hpp
vendored
@ -28,28 +28,32 @@ namespace sol {
|
||||
|
||||
template<typename T>
|
||||
struct usertype_traits {
|
||||
static const std::string name;
|
||||
static const std::string qualified_name;
|
||||
static const std::string metatable;
|
||||
static const std::string user_gc_metatable;
|
||||
static const std::string gc_table;
|
||||
static const std::string& name() {
|
||||
static const std::string n = detail::short_demangle<T>();
|
||||
return n;
|
||||
}
|
||||
static const std::string& qualified_name() {
|
||||
static const std::string q_n = detail::demangle<T>();
|
||||
return q_n;
|
||||
}
|
||||
static const std::string& metatable() {
|
||||
static const std::string m = std::string("sol.").append(detail::demangle<T>());
|
||||
return m;
|
||||
}
|
||||
static const std::string& user_metatable() {
|
||||
static const std::string u_m = std::string("sol.").append(detail::demangle<T>()).append(".user");
|
||||
return u_m;
|
||||
}
|
||||
static const std::string& user_gc_metatable() {
|
||||
static const std::string u_g_m = std::string("sol.").append(detail::demangle<T>()).append(".user\xE2\x99\xBB");
|
||||
return u_g_m;
|
||||
}
|
||||
static const std::string& gc_table() {
|
||||
static const std::string g_t = std::string("sol.").append(detail::demangle<T>().append(".\xE2\x99\xBB"));
|
||||
return g_t;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
const std::string usertype_traits<T>::name = detail::short_demangle<T>();
|
||||
|
||||
template<typename T>
|
||||
const std::string usertype_traits<T>::qualified_name = detail::demangle<T>();
|
||||
|
||||
template<typename T>
|
||||
const std::string usertype_traits<T>::metatable = std::string("sol.").append(detail::demangle<T>());
|
||||
|
||||
template<typename T>
|
||||
const std::string usertype_traits<T>::user_gc_metatable = std::string("sol.").append(detail::demangle<T>()).append(".user\xE2\x99\xBB");
|
||||
|
||||
template<typename T>
|
||||
const std::string usertype_traits<T>::gc_table = std::string("sol.").append(detail::demangle<T>().append(".\xE2\x99\xBB"));
|
||||
|
||||
}
|
||||
|
||||
#endif // SOL_USERTYPE_TRAITS_HPP
|
||||
|
51
3rdparty/sol2/test_containers.cpp
vendored
51
3rdparty/sol2/test_containers.cpp
vendored
@ -273,6 +273,57 @@ TEST_CASE("containers/arbitrary-creation", "userdata and tables should be usable
|
||||
REQUIRE(c.get<std::string>("project") == "sol");
|
||||
}
|
||||
|
||||
TEST_CASE("containers/extra-functions", "make sure the manipulation functions are present and usable and working across various container types") {
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.script(R"(
|
||||
function g (x)
|
||||
x:add(20)
|
||||
end
|
||||
|
||||
function h (x)
|
||||
x:add(20, 40)
|
||||
end
|
||||
|
||||
function i (x)
|
||||
x:clear()
|
||||
end
|
||||
)");
|
||||
|
||||
// Have the function we
|
||||
// just defined in Lua
|
||||
sol::function g = lua["g"];
|
||||
sol::function h = lua["h"];
|
||||
sol::function i = lua["i"];
|
||||
|
||||
// Set a global variable called
|
||||
// "arr" to be a vector of 5 lements
|
||||
lua["arr"] = std::vector<int>{ 2, 4, 6, 8, 10 };
|
||||
lua["map"] = std::map<int, int>{ { 1 , 2 },{ 2, 4 },{ 3, 6 },{ 4, 8 },{ 5, 10 } };
|
||||
lua["set"] = std::set<int>{ 2, 4, 6, 8, 10 };
|
||||
std::vector<int>& arr = lua["arr"];
|
||||
std::map<int, int>& map = lua["map"];
|
||||
std::set<int>& set = lua["set"];
|
||||
REQUIRE(arr.size() == 5);
|
||||
REQUIRE(map.size() == 5);
|
||||
REQUIRE(set.size() == 5);
|
||||
|
||||
g(lua["set"]);
|
||||
g(lua["arr"]);
|
||||
h(lua["map"]);
|
||||
REQUIRE(arr.size() == 6);
|
||||
REQUIRE(map.size() == 6);
|
||||
REQUIRE(set.size() == 6);
|
||||
|
||||
i(lua["arr"]);
|
||||
i(lua["map"]);
|
||||
i(lua["set"]);
|
||||
REQUIRE(arr.empty());
|
||||
REQUIRE(map.empty());
|
||||
REQUIRE(set.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("containers/usertype-transparency", "Make sure containers pass their arguments through transparently and push the results as references, not new values") {
|
||||
class A {
|
||||
public:
|
||||
|
6
3rdparty/sol2/test_simple_usertypes.cpp
vendored
6
3rdparty/sol2/test_simple_usertypes.cpp
vendored
@ -453,7 +453,11 @@ TEST_CASE("usertype/simple-table-append", "Ensure that appending to the meta tab
|
||||
table["func"] = &A::func;
|
||||
A a;
|
||||
lua.set("a", &a);
|
||||
lua.set("pa", &a);
|
||||
lua.set("ua", std::make_unique<A>());
|
||||
REQUIRE_NOTHROW(
|
||||
lua.script("assert(a:func() == 5000)")
|
||||
lua.script("assert(a:func() == 5000)");
|
||||
lua.script("assert(pa:func() == 5000)");
|
||||
lua.script("assert(ua:func() == 5000)");
|
||||
);
|
||||
}
|
||||
|
114
3rdparty/sol2/tests.cpp
vendored
114
3rdparty/sol2/tests.cpp
vendored
@ -664,6 +664,21 @@ TEST_CASE("proxy/proper-pushing", "allow proxies to reference other proxies and
|
||||
REQUIRE(b);
|
||||
}
|
||||
|
||||
TEST_CASE("proxy/equality", "check to make sure equality tests work") {
|
||||
sol::state lua;
|
||||
REQUIRE((lua["a"] == sol::nil));
|
||||
REQUIRE_FALSE((lua["a"] == nullptr));
|
||||
REQUIRE_FALSE((lua["a"] == 0));
|
||||
REQUIRE_FALSE((lua["a"] == 2));
|
||||
|
||||
lua["a"] = 2;
|
||||
|
||||
REQUIRE_FALSE((lua["a"] == sol::nil)); //0
|
||||
REQUIRE_FALSE((lua["a"] == nullptr)); //0
|
||||
REQUIRE_FALSE((lua["a"] == 0)); //0
|
||||
REQUIRE((lua["a"] == 2)); //1
|
||||
}
|
||||
|
||||
TEST_CASE("compilation/const-regression", "make sure constness in tables is respected all the way down") {
|
||||
struct State {
|
||||
public:
|
||||
@ -678,3 +693,102 @@ TEST_CASE("compilation/const-regression", "make sure constness in tables is resp
|
||||
State* s = state.state_.registry()["state"];
|
||||
REQUIRE(s == &state);
|
||||
}
|
||||
|
||||
TEST_CASE("numbers/integers", "make sure integers are detectable on most platforms") {
|
||||
sol::state lua;
|
||||
|
||||
lua["a"] = 50; // int
|
||||
lua["b"] = 50.5; // double
|
||||
|
||||
sol::object a = lua["a"];
|
||||
sol::object b = lua["b"];
|
||||
|
||||
bool a_is_int = a.is<int>();
|
||||
bool a_is_double = a.is<double>();
|
||||
|
||||
bool b_is_int = b.is<int>();
|
||||
bool b_is_double = b.is<double>();
|
||||
|
||||
REQUIRE(a_is_int);
|
||||
REQUIRE(a_is_double);
|
||||
|
||||
// TODO: will this fail on certain lower Lua versions?
|
||||
REQUIRE_FALSE(b_is_int);
|
||||
REQUIRE(b_is_double);
|
||||
}
|
||||
|
||||
TEST_CASE("state/script-returns", "make sure script returns are done properly") {
|
||||
std::string script =
|
||||
R"(
|
||||
local example =
|
||||
{
|
||||
str = "this is a string",
|
||||
num = 1234,
|
||||
|
||||
func = function(self)
|
||||
print(self.str)
|
||||
return "fstr"
|
||||
end
|
||||
}
|
||||
|
||||
return example;
|
||||
)";
|
||||
|
||||
auto bar = [&script](sol::this_state l) {
|
||||
sol::state_view lua = l;
|
||||
sol::table data = lua.script(script);
|
||||
|
||||
std::string str = data["str"];
|
||||
int num = data["num"];
|
||||
std::string fstr = data["func"](data);
|
||||
REQUIRE(str == "this is a string");
|
||||
REQUIRE(fstr == "fstr");
|
||||
REQUIRE(num == 1234);
|
||||
};
|
||||
|
||||
auto foo = [&script](int, sol::this_state l) {
|
||||
sol::state_view lua = l;
|
||||
sol::table data = lua.script(script);
|
||||
|
||||
std::string str = data["str"];
|
||||
int num = data["num"];
|
||||
std::string fstr = data["func"](data);
|
||||
REQUIRE(str == "this is a string");
|
||||
REQUIRE(fstr == "fstr");
|
||||
REQUIRE(num == 1234);
|
||||
};
|
||||
|
||||
auto bar2 = [&script](sol::this_state l) {
|
||||
sol::state_view lua = l;
|
||||
sol::table data = lua.do_string(script);
|
||||
|
||||
std::string str = data["str"];
|
||||
int num = data["num"];
|
||||
std::string fstr = data["func"](data);
|
||||
REQUIRE(str == "this is a string");
|
||||
REQUIRE(fstr == "fstr");
|
||||
REQUIRE(num == 1234);
|
||||
};
|
||||
|
||||
auto foo2 = [&script](int, sol::this_state l) {
|
||||
sol::state_view lua = l;
|
||||
sol::table data = lua.do_string(script);
|
||||
|
||||
std::string str = data["str"];
|
||||
int num = data["num"];
|
||||
std::string fstr = data["func"](data);
|
||||
REQUIRE(str == "this is a string");
|
||||
REQUIRE(fstr == "fstr");
|
||||
REQUIRE(num == 1234);
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.set_function("foo", foo);
|
||||
lua.set_function("foo2", foo2);
|
||||
lua.set_function("bar", bar);
|
||||
lua.set_function("bar2", bar2);
|
||||
|
||||
lua.script("bar() bar2() foo(1) foo2(1)");
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
#define __LUA_ENGINE_H__
|
||||
|
||||
#include <map>
|
||||
#define SOL_SAFE_USERTYPE
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#include "sol2/sol.hpp"
|
||||
|
||||
class cheat_manager;
|
||||
|
Loading…
Reference in New Issue
Block a user