summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/sol2/docs/source/api
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/sol2/docs/source/api')
-rw-r--r--3rdparty/sol2/docs/source/api/api-top.rst1
-rw-r--r--3rdparty/sol2/docs/source/api/as_table.rst6
-rw-r--r--3rdparty/sol2/docs/source/api/containers.rst93
-rw-r--r--3rdparty/sol2/docs/source/api/function.rst15
-rw-r--r--3rdparty/sol2/docs/source/api/protected_function.rst2
-rw-r--r--3rdparty/sol2/docs/source/api/readonly.rst61
-rw-r--r--3rdparty/sol2/docs/source/api/simple_usertype.rst25
-rw-r--r--3rdparty/sol2/docs/source/api/state.rst12
-rw-r--r--3rdparty/sol2/docs/source/api/usertype.rst2
-rw-r--r--3rdparty/sol2/docs/source/api/usertype_memory.rst6
10 files changed, 211 insertions, 12 deletions
diff --git a/3rdparty/sol2/docs/source/api/api-top.rst b/3rdparty/sol2/docs/source/api/api-top.rst
index f9b0378b30e..4dac922becf 100644
--- a/3rdparty/sol2/docs/source/api/api-top.rst
+++ b/3rdparty/sol2/docs/source/api/api-top.rst
@@ -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
diff --git a/3rdparty/sol2/docs/source/api/as_table.rst b/3rdparty/sol2/docs/source/api/as_table.rst
index 58870fa770f..e5b58b49fa4 100644
--- a/3rdparty/sol2/docs/source/api/as_table.rst
+++ b/3rdparty/sol2/docs/source/api/as_table.rst
@@ -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. \ No newline at end of file
+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>`. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/containers.rst b/3rdparty/sol2/docs/source/api/containers.rst
new file mode 100644
index 00000000000..dba03df8a58
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/containers.rst
@@ -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 {};
+ } \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/function.rst b/3rdparty/sol2/docs/source/api/function.rst
index 27946117a8c..93adedabe49 100644
--- a/3rdparty/sol2/docs/source/api/function.rst
+++ b/3rdparty/sol2/docs/source/api/function.rst
@@ -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
--------------------
diff --git a/3rdparty/sol2/docs/source/api/protected_function.rst b/3rdparty/sol2/docs/source/api/protected_function.rst
index 97d4e09f14f..c9fb9b4f425 100644
--- a/3rdparty/sol2/docs/source/api/protected_function.rst
+++ b/3rdparty/sol2/docs/source/api/protected_function.rst
@@ -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>`.
diff --git a/3rdparty/sol2/docs/source/api/readonly.rst b/3rdparty/sol2/docs/source/api/readonly.rst
index 3a9517f1058..e36db3358ff 100644
--- a/3rdparty/sol2/docs/source/api/readonly.rst
+++ b/3rdparty/sol2/docs/source/api/readonly.rst
@@ -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.
diff --git a/3rdparty/sol2/docs/source/api/simple_usertype.rst b/3rdparty/sol2/docs/source/api/simple_usertype.rst
index e030ed92985..0502e6b24ed 100644
--- a/3rdparty/sol2/docs/source/api/simple_usertype.rst
+++ b/3rdparty/sol2/docs/source/api/simple_usertype.rst
@@ -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 \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/state.rst b/3rdparty/sol2/docs/source/api/state.rst
index b593d5cc810..a0838fbf110 100644
--- a/3rdparty/sol2/docs/source/api/state.rst
+++ b/3rdparty/sol2/docs/source/api/state.rst
@@ -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);
@@ -83,6 +84,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
sol::global_table globals() const;
@@ -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
diff --git a/3rdparty/sol2/docs/source/api/usertype.rst b/3rdparty/sol2/docs/source/api/usertype.rst
index d3282cd5c64..2fa73a320a2 100644
--- a/3rdparty/sol2/docs/source/api/usertype.rst
+++ b/3rdparty/sol2/docs/source/api/usertype.rst
@@ -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:
diff --git a/3rdparty/sol2/docs/source/api/usertype_memory.rst b/3rdparty/sol2/docs/source/api/usertype_memory.rst
index 55734f7e543..e3a82ed120e 100644
--- a/3rdparty/sol2/docs/source/api/usertype_memory.rst
+++ b/3rdparty/sol2/docs/source/api/usertype_memory.rst
@@ -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. \ No newline at end of file
+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. \ No newline at end of file