diff options
author | 2016-11-06 10:05:36 +0100 | |
---|---|---|
committer | 2016-11-06 10:05:36 +0100 | |
commit | c2a75cb1799a31aa5687e576d1c0bdd50825fded (patch) | |
tree | 59144f444d666ae20ac8fb2bc4e4553d330945ca /3rdparty/sol2/docs/source | |
parent | fffd464d345a6368cda7d90945d3409151218a06 (diff) |
Updated sol2, made lua console not crash for nil data (nw)
Diffstat (limited to '3rdparty/sol2/docs/source')
23 files changed, 367 insertions, 53 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 diff --git a/3rdparty/sol2/docs/source/benchmarks.rst b/3rdparty/sol2/docs/source/benchmarks.rst index f85277b6df1..6fa3224ffda 100644 --- a/3rdparty/sol2/docs/source/benchmarks.rst +++ b/3rdparty/sol2/docs/source/benchmarks.rst @@ -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 diff --git a/3rdparty/sol2/docs/source/conf.py b/3rdparty/sol2/docs/source/conf.py index 63733022b90..9b78b5d59b6 100644 --- a/3rdparty/sol2/docs/source/conf.py +++ b/3rdparty/sol2/docs/source/conf.py @@ -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. diff --git a/3rdparty/sol2/docs/source/errors.rst b/3rdparty/sol2/docs/source/errors.rst new file mode 100644 index 00000000000..f017daad328 --- /dev/null +++ b/3rdparty/sol2/docs/source/errors.rst @@ -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! diff --git a/3rdparty/sol2/docs/source/features.rst b/3rdparty/sol2/docs/source/features.rst index 527398af374..6d52e317eeb 100644 --- a/3rdparty/sol2/docs/source/features.rst +++ b/3rdparty/sol2/docs/source/features.rst @@ -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 diff --git a/3rdparty/sol2/docs/source/index.rst b/3rdparty/sol2/docs/source/index.rst index b1ec3a4f276..ca5233398c7 100644 --- a/3rdparty/sol2/docs/source/index.rst +++ b/3rdparty/sol2/docs/source/index.rst @@ -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: diff --git a/3rdparty/sol2/docs/source/mentions.rst b/3rdparty/sol2/docs/source/mentions.rst index 7b920150181..72330a8a5a9 100644 --- a/3rdparty/sol2/docs/source/mentions.rst +++ b/3rdparty/sol2/docs/source/mentions.rst @@ -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
\ No newline at end of file +.. _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 diff --git a/3rdparty/sol2/docs/source/performance.rst b/3rdparty/sol2/docs/source/performance.rst index cdfaa9614e6..534ab7e5a3e 100644 --- a/3rdparty/sol2/docs/source/performance.rst +++ b/3rdparty/sol2/docs/source/performance.rst @@ -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 diff --git a/3rdparty/sol2/docs/source/traits.rst b/3rdparty/sol2/docs/source/traits.rst new file mode 100644 index 00000000000..b064223be08 --- /dev/null +++ b/3rdparty/sol2/docs/source/traits.rst @@ -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*``. diff --git a/3rdparty/sol2/docs/source/tutorial/all-the-things.rst b/3rdparty/sol2/docs/source/tutorial/all-the-things.rst index fa9e73ac6c0..3695ac77fe2 100644 --- a/3rdparty/sol2/docs/source/tutorial/all-the-things.rst +++ b/3rdparty/sol2/docs/source/tutorial/all-the-things.rst @@ -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 --------------------- diff --git a/3rdparty/sol2/docs/source/tutorial/customization.rst b/3rdparty/sol2/docs/source/tutorial/customization.rst index 31fcad46568..5479c804115 100644 --- a/3rdparty/sol2/docs/source/tutorial/customization.rst +++ b/3rdparty/sol2/docs/source/tutorial/customization.rst @@ -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. diff --git a/3rdparty/sol2/docs/source/tutorial/functions.rst b/3rdparty/sol2/docs/source/tutorial/functions.rst index 2b2f0e3ba61..5fa8d823fd3 100644 --- a/3rdparty/sol2/docs/source/tutorial/functions.rst +++ b/3rdparty/sol2/docs/source/tutorial/functions.rst @@ -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>`!
\ No newline at end of file +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>`.
\ No newline at end of file diff --git a/3rdparty/sol2/docs/source/tutorial/getting-started.rst b/3rdparty/sol2/docs/source/tutorial/getting-started.rst index fd83e4fcb93..02fc2daadf0 100644 --- a/3rdparty/sol2/docs/source/tutorial/getting-started.rst +++ b/3rdparty/sol2/docs/source/tutorial/getting-started.rst @@ -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: diff --git a/3rdparty/sol2/docs/source/usertypes.rst b/3rdparty/sol2/docs/source/usertypes.rst new file mode 100644 index 00000000000..89bf1d36a86 --- /dev/null +++ b/3rdparty/sol2/docs/source/usertypes.rst @@ -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>`.
\ No newline at end of file |