mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Update documentation, refactor examples out of docs, fix warning about static entry path
Still need help refactoring out more code from docs...
This commit is contained in:
parent
6b2e282ab0
commit
22c41d9482
|
@ -31,6 +31,7 @@ Browse the various function and classes :doc:`Sol<../index>` utilizes to make yo
|
||||||
function
|
function
|
||||||
protected_function
|
protected_function
|
||||||
coroutine
|
coroutine
|
||||||
|
yielding
|
||||||
error
|
error
|
||||||
object
|
object
|
||||||
thread
|
thread
|
||||||
|
@ -53,4 +54,4 @@ Browse the various function and classes :doc:`Sol<../index>` utilizes to make yo
|
||||||
compatibility
|
compatibility
|
||||||
types
|
types
|
||||||
metatable_key
|
metatable_key
|
||||||
new_table
|
new_table
|
||||||
|
|
|
@ -3,73 +3,4 @@ containers
|
||||||
*for handling ``std::vector/map/set`` and others*
|
*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 C++ container that they came from, as well as a small amount of indexing and other operations that behave properly given the table type.
|
See the full :doc:`containers documentation at the top level container page<../containers>`
|
||||||
|
|
||||||
An overview of these traits and additional information can be found :doc:`at the top level container page<../containers>`.
|
|
||||||
|
|
||||||
If you need to deal with these things from and in Lua to be **actual**, true-blue, Lua tables, please consider :doc:`sol::as_table<as_table>` and :doc:`sol::nested<nested>` for serialization and deserialization into and out of the VM with sol2 operations. You can also force something that is marked as not-a-container by using :doc:`sol::as_container<as_container>` for sol2 to push it as a userdata with the aforementioned special usertype metatable into Lua.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Overriding the detection traits and operation traits listed :doc:`on the top level container page<../containers>` and then trying to use ``sol::as_table`` or similar can result in compilation failures if you do not have a proper ``begin()`` or ``end()`` function on the type. If you want things to behave with special usertype considerations, please do not wrap the container in one of the special table-forcing abstractions.
|
|
||||||
|
|
||||||
|
|
||||||
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 Lua 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: ``lua["arr"] = as_table( std::vector<int>{ ... });``. For manual iteration in Lua code without using ``as_table`` for something with indices, try:
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
:caption: iteration.lua
|
|
||||||
|
|
||||||
for i = 1, #vec do
|
|
||||||
print(i, vec[i])
|
|
||||||
end
|
|
||||||
|
|
||||||
There are also other ways to iterate over key/values, but they can be difficult AND cost your performance due to not having proper support in Lua 5.1. We recommend that you upgrade to Lua 5.2 or 5.3 if this is integral to your infrastructure.
|
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,14 @@
|
||||||
codecvt + std::(w/u16/u32)string support
|
unicode transformation format handling
|
||||||
========================================
|
======================================
|
||||||
because this is surprisingly hard using standard C++
|
because this is surprisingly hard using standard C++
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
This header is no longer used and sol2 now converts utf8, utf16, and utf32 with internal routines. If you have a problem with the transcoding, please file an issue report.
|
|
||||||
|
|
||||||
|
|
||||||
Individuals using Visual Studio 2015, or on Windows with the VC++ and MinGW compilers (possibly Clang++ on Windows as well) have ``<codecvt>`` headers, and thusly Sol will attempt to include it. Individuals on GCC 4.9.x, Clang 3.5.x, Clang 3.6.x do not seem to have ``<codecvt>`` shipped with the standard library that comes with installation of these compilers. If you want ``std::wstring``, ``std::u16string``, ``std::u32string`` automatic handling then you need to make sure you have those headers and then define ``SOL_CODECVT_SUPPORT`` on unsupported compilers.
|
|
||||||
|
|
||||||
.. _codecvt-deprecation:
|
|
||||||
|
|
||||||
Visual C++, in Visual Studio versions 15.5+ (``_MSC_VER >= 1912``), introduced deprecation macros when you are in ``/std:c++latest``, or similar. In order to get rid of codecvt issues, you need to define the silencing macros they ask for (``_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING``).
|
|
||||||
|
|
||||||
It must be defined because despite the committee deprecating it, there is no useful standard alternative to perform these conversions (without, saying, including ``<Windows.h>`` on Windows machines, which is unacceptable).
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The `standard`_ states the following:
|
The ``<codecvt>`` header is no longer used and sol2 now converts utf8, utf16, and utf32 with internal routines. If you have a problem with the transcoding, please `file an issue report`_.
|
||||||
|
|
||||||
| “this library component should be retired to Annex D, along side ,
|
``std::(w)string(u16/u32)`` are assumed to be in the platform's native wide (for ``wstring``) or unicode format. Lua canonically stores its string literals as utf8 and embraces utf8, albeit its storage is simply a sequence of bytes that are also null-terminated (it is also counted and the size is kept around, so embedded nulls can be used in the string). Therefore, if you need to interact with the unicode or wide alternatives of strings, runtime conversions are performed from the (assumed) utf8 string data into other forms. These conversions check for well-formed UTF, and will error if they are not when converting.
|
||||||
| until a suitable replacement is standardized.”
|
|
||||||
|
|
||||||
|
Note that we cannot give you ``string_view``s to utf16 or utf32 strings: Lua does not hold them in memory this way. You can perhaps do your own customization to provide for this if need be. Remember that Lua stores a counted sequence of bytes: serializing your string as bytes and pushing a string type into Lua's stack will work, though do not except any complex string routines or printing to behave nicely with your code.
|
||||||
|
|
||||||
In other words, it is totally fine! Just define the silencing macro and leave it at that. sol2 keeps up with the standard, so the moment a suitable replacement is standardized it will be added to sol2 posthaste. For the time being, you will be okay.
|
.. _file an issue report: https://github.com/ThePhD/sol2/issues
|
||||||
|
|
||||||
.. _standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ We support:
|
||||||
* Lua 5.3+
|
* Lua 5.3+
|
||||||
* Lua 5.2
|
* Lua 5.2
|
||||||
* Lua 5.1
|
* Lua 5.1
|
||||||
* LuaJIT 2.0.4+
|
* LuaJIT 2.0.x+
|
||||||
* LuaJIT 2.1.x-beta3+
|
* LuaJIT 2.1.x-beta3+
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ html_theme_path = ["_themes", ]
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
html_static_path = ['_static']
|
html_static_path = []
|
||||||
|
|
||||||
# Add any extra paths that contain custom files (such as robots.txt or
|
# Add any extra paths that contain custom files (such as robots.txt or
|
||||||
# .htaccess) here, relative to this directory. These files are copied
|
# .htaccess) here, relative to this directory. These files are copied
|
||||||
|
|
|
@ -157,6 +157,11 @@ Below are the many container operations and their override points for ``containe
|
||||||
|
|
||||||
If your type does not adequately support ``begin()`` and ``end()`` and you cannot override it, use the ``sol::is_container`` trait override along with a custom implementation of ``pairs`` on your usertype to get it to work as you want it to. Note that a type not having proper ``begin()`` and ``end()`` will not work if you try to forcefully serialize it as a table (this means avoid using :doc:`sol::as_table<api/as_table>` and :doc:`sol::nested<api/nested>`, otherwise you will have compiler errors). Just set it or get it directly, as shown in the examples, to work with the C++ containers.
|
If your type does not adequately support ``begin()`` and ``end()`` and you cannot override it, use the ``sol::is_container`` trait override along with a custom implementation of ``pairs`` on your usertype to get it to work as you want it to. Note that a type not having proper ``begin()`` and ``end()`` will not work if you try to forcefully serialize it as a table (this means avoid using :doc:`sol::as_table<api/as_table>` and :doc:`sol::nested<api/nested>`, otherwise you will have compiler errors). Just set it or get it directly, as shown in the examples, to work with the C++ containers.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Overriding the detection traits and operation traits listed above and then trying to use ``sol::as_table`` or similar can result in compilation failures if you do not have a proper ``begin()`` or ``end()`` function on the type. If you want things to behave with special usertype considerations, please do not wrap the container in one of the special table-converting/forcing abstractions.
|
||||||
|
|
||||||
|
|
||||||
.. _container-classifications:
|
.. _container-classifications:
|
||||||
|
|
||||||
container classifications
|
container classifications
|
||||||
|
@ -196,6 +201,28 @@ When you serialize a container into sol2, the default container handler deals wi
|
||||||
+------------------------+----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------+
|
+------------------------+----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
.. literalinclude:: ../../examples/containers.cpp
|
||||||
|
:name: containers-example
|
||||||
|
:linenos:
|
||||||
|
|
||||||
|
|
||||||
|
Note that this will not work well in Lua 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<api/as_table>` when passing something to the library to get a table out of it: ``lua["arr"] = as_table( std::vector<int>{ ... });``. For manual iteration in Lua code without using ``as_table`` for something with indices, try:
|
||||||
|
|
||||||
|
.. code-block:: lua
|
||||||
|
:caption: iteration.lua
|
||||||
|
:linenos:
|
||||||
|
|
||||||
|
for i = 1, #vec do
|
||||||
|
print(i, vec[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
There are also other ways to iterate over key/values, but they can be difficult AND cost your performance due to not having proper support in Lua 5.1. We recommend that you upgrade to Lua 5.2 or 5.3 if this is integral to your infrastructure.
|
||||||
|
|
||||||
.. _online version's information: https://www.lua.org/pil/26.html
|
.. _online version's information: https://www.lua.org/pil/26.html
|
||||||
.. _reflect changes if you use a reference: https://github.com/ThePhD/sol2/blob/develop/examples/containers.cpp
|
.. _reflect changes if you use a reference: https://github.com/ThePhD/sol2/blob/develop/examples/containers.cpp
|
||||||
.. _this table serialization example: https://github.com/ThePhD/sol2/blob/develop/examples/containers_as_table.cpp
|
.. _this table serialization example: https://github.com/ThePhD/sol2/blob/develop/examples/containers_as_table.cpp
|
||||||
|
|
|
@ -25,7 +25,6 @@ A myriad of compiler errors can occur when something goes wrong. Here is some ba
|
||||||
* If you have a move-only type, that type may need to be made ``readonly`` if it is bound as a member variable on a usertype or bound using ``state_view::set_function``. See :doc:`sol::readonly<api/readonly>` for more details.
|
* If you have a move-only type, that type may need to be made ``readonly`` if it is bound as a member variable on a usertype or bound using ``state_view::set_function``. See :doc:`sol::readonly<api/readonly>` for more details.
|
||||||
* Assigning a ``std::string`` or a ``std::pair<T1, T2>`` using ``operator=`` after it's been constructed can result in compiler errors when working with ``sol::function`` and its results. See `this issue for fixes to this behavior`_.
|
* Assigning a ``std::string`` or a ``std::pair<T1, T2>`` using ``operator=`` after it's been constructed can result in compiler errors when working with ``sol::function`` and its results. See `this issue for fixes to this behavior`_.
|
||||||
* Sometimes, using ``__stdcall`` in a 32-bit (x86) environment on VC++ can cause problems binding functions because of a compiler bug. We have a prelimanry fix in, but if it doesn't work and there are still problems: put the function in a ``std::function`` to make the compiler errors and other problems go away. Also see `this __stdcall issue report`_ for more details.
|
* Sometimes, using ``__stdcall`` in a 32-bit (x86) environment on VC++ can cause problems binding functions because of a compiler bug. We have a prelimanry fix in, but if it doesn't work and there are still problems: put the function in a ``std::function`` to make the compiler errors and other problems go away. Also see `this __stdcall issue report`_ for more details.
|
||||||
* If you are using ``/std:c++latest`` on VC++ and get a number of deprecation errors for ``<codecvt>`` and others, please see :ref:`this note here<codecvt-deprecation>`.
|
|
||||||
* If you are using ``/std:c++latest`` on VC++ and get a number of errors for ``noexcept`` specifiers on functions, you may need to file an issue or wait for the next release of the VC++ compiler.
|
* If you are using ``/std:c++latest`` on VC++ and get a number of errors for ``noexcept`` specifiers on functions, you may need to file an issue or wait for the next release of the VC++ compiler.
|
||||||
|
|
||||||
Mac OSX Crashes
|
Mac OSX Crashes
|
||||||
|
|
|
@ -9,30 +9,10 @@ If you turn this off, the default `at_panic`_ function :doc:`state<api/state>` s
|
||||||
|
|
||||||
To make this not be the case, you can set a panic function directly with ``lua_atpanic( lua, my_panic_function );`` or when you create the ``sol::state`` with ``sol::state lua(my_panic_function);``. Here's an example ``my_panic_function`` you can have that prints out its errors:
|
To make this not be the case, you can set a panic function directly with ``lua_atpanic( lua, my_panic_function );`` or when you create the ``sol::state`` with ``sol::state lua(my_panic_function);``. Here's an example ``my_panic_function`` you can have that prints out its errors:
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. literalinclude:: ../../examples/docs/my_panic.cpp
|
||||||
:caption: regular panic function
|
:caption: regular panic function
|
||||||
:name: typical-panic-function
|
:name: typical-panic-function
|
||||||
|
:linenos:
|
||||||
#include <sol.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
inline void my_panic(sol::optional<std::string> maybe_msg) {
|
|
||||||
std::cerr << "Lua is in a panic state and will now abort() the application" << std::endl;
|
|
||||||
if (maybe_msg) {
|
|
||||||
const std::string& msg = maybe_msg.value();
|
|
||||||
std::cerr << "\terror message: " << msg << std::endl;
|
|
||||||
}
|
|
||||||
// When this function exits, Lua will exhibit default behavior and abort()
|
|
||||||
}
|
|
||||||
|
|
||||||
int main () {
|
|
||||||
sol::state lua(sol::c_call<decltype(&my_panic), &my_panic>);
|
|
||||||
// or, if you already have a lua_State* L
|
|
||||||
// lua_atpanic( L, sol::c_call<decltype(&my_panic)>, &my_panic> );
|
|
||||||
// or, with state/state_view:
|
|
||||||
// sol::state_view lua(L);
|
|
||||||
// lua.set_panic( sol::c_call<decltype(&my_panic)>, &my_panic> );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Note that ``SOL_NO_EXCEPTIONS`` will also disable :doc:`protected_function<api/protected_function>`'s ability to catch C++ errors you throw from C++ functions bound to Lua that you are calling through that API. So, only turn off exceptions in Sol if you're sure you're never going to use exceptions ever. Of course, if you are ALREADY not using Exceptions, you don't have to particularly worry about this and now you can use Sol!
|
Note that ``SOL_NO_EXCEPTIONS`` will also disable :doc:`protected_function<api/protected_function>`'s ability to catch C++ errors you throw from C++ functions bound to Lua that you are calling through that API. So, only turn off exceptions in Sol if you're sure you're never going to use exceptions ever. Of course, if you are ALREADY not using Exceptions, you don't have to particularly worry about this and now you can use Sol!
|
||||||
|
|
|
@ -18,6 +18,8 @@ what Sol supports
|
||||||
- Implicit conversion to the types you want
|
- Implicit conversion to the types you want
|
||||||
``double b = table["computed_value"];``
|
``double b = table["computed_value"];``
|
||||||
|
|
||||||
|
* :doc:`yielding<api/yielding>` support: tag a function as whose return is meant to yield into a coroutine
|
||||||
|
|
||||||
* :doc:`Optional<api/optional>` support: setting values, getting values of multiple (different) types
|
* :doc:`Optional<api/optional>` support: setting values, getting values of multiple (different) types
|
||||||
- :doc:`Lazy evaluation<api/proxy>` for nested/chained queries
|
- :doc:`Lazy evaluation<api/proxy>` for nested/chained queries
|
||||||
``optional<int> maybe_number = table["a"]["b"]["invalid_key"];``
|
``optional<int> maybe_number = table["a"]["b"]["invalid_key"];``
|
||||||
|
@ -34,7 +36,7 @@ what Sol supports
|
||||||
* User-Defined Type (:doc:`sol::usertype<api/usertype>` in the API) support:
|
* User-Defined Type (:doc:`sol::usertype<api/usertype>` in the API) support:
|
||||||
- Set member functions to be called
|
- Set member functions to be called
|
||||||
- Set member variables
|
- Set member variables
|
||||||
- Set variables on a class that are based on setter/getter functions
|
- Set variables on a class that are based on setter/getter functions using properties
|
||||||
- Use free-functions that take the Type as a first argument (pointer or reference)
|
- Use free-functions that take the Type as a first argument (pointer or reference)
|
||||||
- Support for "Factory" classes that do not expose constructor or destructor
|
- Support for "Factory" classes that do not expose constructor or destructor
|
||||||
- Modifying memory of userdata in C++ directly affects Lua without copying, and
|
- Modifying memory of userdata in C++ directly affects Lua without copying, and
|
||||||
|
@ -86,6 +88,7 @@ Explanations for a few categories are below (rest are self-explanatory).
|
||||||
* overloading: the ability to call overloaded functions, matched based on arity or type (``foo( 1 )`` from lua calls a different function then ``foo( "bark" )``).
|
* overloading: the ability to call overloaded functions, matched based on arity or type (``foo( 1 )`` from lua calls a different function then ``foo( "bark" )``).
|
||||||
* Lua thread: basic wrapping of the lua thread API; ties in with coroutine.
|
* Lua thread: basic wrapping of the lua thread API; ties in with coroutine.
|
||||||
* coroutines: allowing a function to be called multiple times, resuming the execution of a Lua coroutine each time
|
* coroutines: allowing a function to be called multiple times, resuming the execution of a Lua coroutine each time
|
||||||
|
* yielding C++ functions: allowing a function from C++ to be called multiple times, and yield any results it has back through the C API or into Lua
|
||||||
* environments: an abstraction for getting, setting and manipulating an environment, using table techniques, functions or otherwise. Typically for the purposes of sandboxing
|
* environments: an abstraction for getting, setting and manipulating an environment, using table techniques, functions or otherwise. Typically for the purposes of sandboxing
|
||||||
|
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
|
@ -128,6 +131,8 @@ Explanations for a few categories are below (rest are self-explanatory).
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
| coroutines | ~ | ✗ | ~ | ✔ | ✔ | ✔ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ |
|
| coroutines | ~ | ✗ | ~ | ✔ | ✔ | ✔ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ |
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
|
| yielding C++ functions | ~ | ✔ | ✔ | ✔ | ~ | ✔ | ~ | ✗ | ✔ | ✗ | ~ | ✔ | ~ |
|
||||||
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
| no-rtti support | ✔ | ✗ | ✔ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ | ✔ |
|
| no-rtti support | ✔ | ✗ | ✔ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ | ✔ |
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
| no-exception support | ✔ | ✗ | ✔ | ~ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ | ✔ |
|
| no-exception support | ✔ | ✗ | ✔ | ~ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ | ✔ |
|
||||||
|
@ -241,7 +246,7 @@ SLB3 -
|
||||||
|
|
||||||
oolua -
|
oolua -
|
||||||
|
|
||||||
* The syntax for this library. `Go read the docs`_
|
* The syntax for this library is not my favorite... `go read the docs`_, decide for yourself!
|
||||||
* 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
|
* 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
|
- 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!)
|
* Supports not having exceptions or rtti turned on (shiny!)
|
||||||
|
@ -258,5 +263,6 @@ luwra -
|
||||||
* 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!)
|
* 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 table 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)
|
* Table variables become class statics (surprising)
|
||||||
|
* Tanks in later MSVCs
|
||||||
|
|
||||||
.. _Go read the docs: https://oolua.org/docs/index.html
|
.. _Go read the docs: https://oolua.org/docs/index.html
|
||||||
|
|
|
@ -41,37 +41,12 @@ To be explicit about wanting a struct to be interpreted as a function, use ``myt
|
||||||
|
|
||||||
Note that this also applies to calling functions, for example: ``my_state["table"]["sort"]( some_table, sorting_object );``.
|
Note that this also applies to calling functions, for example: ``my_state["table"]["sort"]( some_table, sorting_object );``.
|
||||||
|
|
||||||
Furthermore, it is important to know that lambdas without a specified return type (and a non-const, non-reference-qualified ``auto``) will decay return values. To capture or return references explicitly, use ``decltype(auto)`` or specify the return type **exactly** as desired::
|
Furthermore, it is important to know that lambdas without a specified return type (and a non-const, non-reference-qualified ``auto``) will decay return values. To capture or return references explicitly, use ``decltype(auto)`` or specify the return type **exactly** as desired:
|
||||||
|
|
||||||
#define SOL_CHECK_ARGUMENTS 1
|
.. literalinclude:: ../../examples/docs/references_in_lambdas.cpp
|
||||||
#include <sol.hpp>
|
:name: refereces-in-lambdas-example
|
||||||
|
:linenos:
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
|
|
||||||
struct test {
|
|
||||||
int blah = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
test t;
|
|
||||||
sol::state lua;
|
|
||||||
lua.set_function("f", [&t]() {
|
|
||||||
return t;
|
|
||||||
});
|
|
||||||
lua.set_function("g", [&t]() -> test& {
|
|
||||||
return t;
|
|
||||||
});
|
|
||||||
|
|
||||||
lua.script("t1 = f()");
|
|
||||||
lua.script("t2 = g()");
|
|
||||||
|
|
||||||
test& lt1 = lua["t1"];
|
|
||||||
test& lt2 = lua["t2"];
|
|
||||||
|
|
||||||
assert(<1 != &t); // not the same: 'f' lambda copied
|
|
||||||
assert(<2 == &t); // the same: 'g' lambda returned reference
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.. _function-exception-handling:
|
.. _function-exception-handling:
|
||||||
|
|
||||||
|
|
|
@ -53,65 +53,16 @@ the basics:
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
More examples can be found in the `examples directory`_
|
The code below *and* more examples can be found in the `examples directory`_
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: c++
|
.. literalinclude:: ../../examples/docs/simple_functions.cpp
|
||||||
:caption: functions
|
:name: simple-functions-example
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
#include <sol.hpp>
|
.. literalinclude:: ../../examples/docs/simple_structs.cpp
|
||||||
#include <cassert>
|
:name: simple-structs-example
|
||||||
|
:linenos:
|
||||||
int main() {
|
|
||||||
sol::state lua;
|
|
||||||
int x = 0;
|
|
||||||
lua.set_function("beep", [&x]{ ++x; });
|
|
||||||
lua.script("beep()");
|
|
||||||
assert(x == 1);
|
|
||||||
|
|
||||||
sol::function beep = lua["beep"];
|
|
||||||
beep();
|
|
||||||
assert(x == 2);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: c++
|
|
||||||
:caption: linking C++ structures to Lua
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
#include <sol.hpp>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
struct vars {
|
|
||||||
int boop = 0;
|
|
||||||
|
|
||||||
int bop () const {
|
|
||||||
return boop + 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
sol::state lua;
|
|
||||||
lua.new_usertype<vars>("vars",
|
|
||||||
"boop", &vars::boop
|
|
||||||
"bop", &vars::bop);
|
|
||||||
lua.script("beep = vars.new()\n"
|
|
||||||
"beep.boop = 1\n"
|
|
||||||
"bopvalue = beep:bop()");
|
|
||||||
|
|
||||||
vars& beep = lua["beep"];
|
|
||||||
int bopvalue = lua["bopvalue"];
|
|
||||||
|
|
||||||
assert(beep.boop == 1);
|
|
||||||
assert(lua.get<vars>("beep").boop == 1);
|
|
||||||
assert(beep.bop() == 2);
|
|
||||||
assert(bopvalue == 2);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
helping out
|
helping out
|
||||||
|
|
|
@ -1,52 +1,93 @@
|
||||||
licenses
|
licenses
|
||||||
========
|
========
|
||||||
|
|
||||||
The following licenses cover all of the code in Sol. Spoiler: they're all `MIT`_ and it's safe to use in commercial code: feel free to copy/paste the below right into your own attributions / licenses file.
|
The following licenses cover all of the code in Sol. Spoiler: they're all `MIT`_ (and ``CC0``) and it's safe to use in commercial code: feel free to copy/paste the below right into your own attributions / licenses file.
|
||||||
|
|
||||||
Sol - ThePhD/sol2:
|
Sol - ThePhD/sol2:
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
The MIT License (MIT)
|
.. code-block:: none
|
||||||
|
|
||||||
Copyright (c) 2013-2016 Rapptz, ThePhD, and contributors
|
The MIT License (MIT)
|
||||||
|
|
||||||
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:
|
Copyright (c) 2013-2016 Rapptz, ThePhD, and contributors
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to
|
||||||
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.
|
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
|
||||||
Lua-compat-5.3 - keplerproject/Lua-compat-5.3:
|
furnished to do so, subject to the following conditions:
|
||||||
----------------------------------------------
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
The MIT License (MIT)
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
Copyright (c) 2015 Kepler Project.
|
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
|
||||||
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:
|
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
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN 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.
|
|
||||||
|
|
||||||
Lua - Lua.org:
|
Lua-compat-5.3 - keplerproject/Lua-compat-5.3:
|
||||||
--------------
|
----------------------------------------------
|
||||||
|
|
||||||
The MIT License (MIT)
|
.. code-block:: none
|
||||||
|
|
||||||
Copyright © 1994–2015 Lua.org, PUC-Rio.
|
The MIT License (MIT)
|
||||||
|
|
||||||
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:
|
Copyright (c) 2018 Kepler Project.
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to
|
||||||
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.
|
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
|
||||||
ogonek - libogonek/ogonek:
|
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.
|
||||||
|
|
||||||
|
Lua - Lua.org:
|
||||||
|
--------------
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright © 1994–2018 Lua.org, PUC-Rio.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
ogonek - libogonek/ogonek:
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
Creative Commons Legal Code
|
Creative Commons Legal Code
|
||||||
|
|
||||||
CC0 1.0 Universal
|
CC0 1.0 Universal
|
||||||
|
@ -167,7 +208,7 @@ ogonek - libogonek/ogonek:
|
||||||
Work.
|
Work.
|
||||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||||
party to this document and has no duty or obligation with respect to
|
party to this document and has no duty or obligation with respect to
|
||||||
this CC0 or use of the Work.
|
this CC0 or use of the Work.
|
||||||
|
|
||||||
|
|
||||||
.. _MIT: http://opensource.org/licenses/MIT
|
.. _MIT: http://opensource.org/licenses/MIT
|
||||||
|
|
|
@ -23,6 +23,7 @@ Okay, so the features don't convince you, the documentation doesn't convince you
|
||||||
| |before| | |after| |
|
| |before| | |after| |
|
||||||
+----------+---------+
|
+----------+---------+
|
||||||
|
|
||||||
|
* In `High Performance Computing research`_
|
||||||
* The `Multiple Arcade Machine Emulator (MAME)`_ project switched from using LuaBridge to sol2!
|
* The `Multiple Arcade Machine Emulator (MAME)`_ project switched from using LuaBridge to sol2!
|
||||||
- `The pull request`_ in which it was introduced to the master branch.
|
- `The pull request`_ in which it was introduced to the master branch.
|
||||||
* For scripting, in `OpenMPT`_
|
* For scripting, in `OpenMPT`_
|
||||||
|
@ -60,4 +61,5 @@ Are you using sol2 for something neat? Want it to be featured here or think it's
|
||||||
.. _"sol2 saved my life.": https://twitter.com/EliasDaler/status/739215685264494593
|
.. _"sol2 saved my life.": https://twitter.com/EliasDaler/status/739215685264494593
|
||||||
.. _Multiple Arcade Machine Emulator (MAME): http://www.mamedev.org/index.php
|
.. _Multiple Arcade Machine Emulator (MAME): http://www.mamedev.org/index.php
|
||||||
.. _The pull request: https://github.com/mamedev/mame/pull/1626
|
.. _The pull request: https://github.com/mamedev/mame/pull/1626
|
||||||
.. _OpenMPT: https://openmpt.org/
|
.. _OpenMPT: https://openmpt.org/
|
||||||
|
.. _High Performance Computing research: https://github.com/ThePhD/sol2/issues/568
|
||||||
|
|
|
@ -13,4 +13,4 @@ As shown by the :doc:`benchmarks<benchmarks>`, Sol is very performant with its a
|
||||||
* 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
|
* 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
|
||||||
|
|
||||||
|
|
||||||
That's it as far as different performance options are avilable to make Sol run faster. Again, please make sure to invoke these only when you know Sol is the bottleneck. If you find some form of the performance unacceptable to you, also feel free to open an issue at the github.
|
That's it as far as different performance options are avilable to make Sol run faster. Again, please make sure to invoke these only when you know Sol is the bottleneck. If you find some form of the performance unacceptable to you, also feel free to open an issue at the github.
|
||||||
|
|
|
@ -34,53 +34,6 @@ You can mitigate some of the pressure of using coroutines and threading by using
|
||||||
|
|
||||||
Here's an example of explicit state transferring below:
|
Here's an example of explicit state transferring below:
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. literalinclude:: ../../examples/docs/state_transfer.cpp
|
||||||
:caption: transfer from state function
|
|
||||||
:name: state-transfer
|
:name: state-transfer
|
||||||
|
:linenos:
|
||||||
#define SOL_CHECK_ARGUMENTS
|
|
||||||
#include <sol.hpp>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
int main (int, char*[]) {
|
|
||||||
|
|
||||||
sol::state lua;
|
|
||||||
lua.open_libraries();
|
|
||||||
sol::function transferred_into;
|
|
||||||
lua["f"] = [&lua, &transferred_into](sol::object t, sol::this_state this_L) {
|
|
||||||
std::cout << "state of main : " << (void*)lua.lua_state() << std::endl;
|
|
||||||
std::cout << "state of function : " << (void*)this_L.lua_state() << std::endl;
|
|
||||||
// pass original lua_State* (or sol::state/sol::state_view)
|
|
||||||
// transfers ownership from the state of "t",
|
|
||||||
// to the "lua" sol::state
|
|
||||||
transferred_into = sol::function(lua, t);
|
|
||||||
};
|
|
||||||
|
|
||||||
lua.script(R"(
|
|
||||||
i = 0
|
|
||||||
function test()
|
|
||||||
co = coroutine.create(
|
|
||||||
function()
|
|
||||||
local g = function() i = i + 1 end
|
|
||||||
f(g)
|
|
||||||
g = nil
|
|
||||||
collectgarbage()
|
|
||||||
end
|
|
||||||
)
|
|
||||||
coroutine.resume(co)
|
|
||||||
co = nil
|
|
||||||
collectgarbage()
|
|
||||||
end
|
|
||||||
)");
|
|
||||||
|
|
||||||
// give it a try
|
|
||||||
lua.safe_script("test()");
|
|
||||||
// should call 'g' from main thread, increment i by 1
|
|
||||||
transferred_into();
|
|
||||||
// check
|
|
||||||
int i = lua["i"];
|
|
||||||
assert(i == 1);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ The implementation for ``assert.hpp`` with ``c_assert`` looks like so:
|
||||||
|
|
||||||
.. literalinclude:: ../../../examples/assert.hpp
|
.. literalinclude:: ../../../examples/assert.hpp
|
||||||
:linenos:
|
:linenos:
|
||||||
:lines: 1-8, 19-
|
:lines: 1-3, 19-
|
||||||
|
|
||||||
This is the assert used in the quick code below.
|
This is the assert used in the quick code below.
|
||||||
|
|
||||||
|
|
|
@ -5,107 +5,17 @@ Sometimes, overriding Sol to make it handle certain ``struct``'s and ``class``'e
|
||||||
|
|
||||||
These are template class/structs, so you'll override them using a technique C++ calls *class/struct specialization*. Below is an example of a struct that gets broken apart into 2 pieces when going in the C++ --> Lua direction, and then pulled back into a struct when going in the Lua --> C++:
|
These are template class/structs, so you'll override them using a technique C++ calls *class/struct specialization*. Below is an example of a struct that gets broken apart into 2 pieces when going in the C++ --> Lua direction, and then pulled back into a struct when going in the Lua --> C++:
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. literalinclude:: ../../../examples/customization.cpp
|
||||||
:caption: two_things.hpp
|
|
||||||
:name: customization-overriding
|
:name: customization-overriding
|
||||||
|
:linenos:
|
||||||
#include <sol.hpp>
|
:lines: 1-72
|
||||||
|
|
||||||
struct two_things {
|
|
||||||
int a;
|
|
||||||
bool b;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace sol {
|
|
||||||
|
|
||||||
// First, the expected size
|
|
||||||
// Specialization of a struct
|
|
||||||
// We expect 2, so use 2
|
|
||||||
template <>
|
|
||||||
struct lua_size<two_things> : std::integral_constant<int, 2> {};
|
|
||||||
|
|
||||||
// Then, specialize the type to match:
|
|
||||||
// this has multiple types, so we consider it a "poly" type.
|
|
||||||
template <>
|
|
||||||
struct lua_type_of<two_things> : std::integral_constant<sol::type, sol::type::poly> {};
|
|
||||||
|
|
||||||
// Now, specialize various stack structures
|
|
||||||
namespace stack {
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct checker<two_things> {
|
|
||||||
template <typename Handler>
|
|
||||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
|
||||||
// indices can be negative to count backwards from the top of the stack,
|
|
||||||
// rather than the bottom up
|
|
||||||
// to deal with this, we adjust the index to
|
|
||||||
// its absolute position using the lua_absindex function
|
|
||||||
int absolute_index = lua_absindex(L, index);
|
|
||||||
// Check first and second second index for being the proper types
|
|
||||||
bool success = stack::check<int>(L, absolute_index - 1, handler)
|
|
||||||
&& stack::check<bool>(L, absolute_index, handler);
|
|
||||||
tracking.use(2);
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct getter<two_things> {
|
|
||||||
static two_things get(lua_State* L, int index, record& tracking) {
|
|
||||||
int absolute_index = lua_absindex(L, index);
|
|
||||||
// Get the first element
|
|
||||||
int a = stack::get<int>(L, absolute_index - 1);
|
|
||||||
// Get the second element,
|
|
||||||
// in the +1 position from the first
|
|
||||||
bool b = stack::get<bool>(L, absolute_index);
|
|
||||||
// we use 2 slots, each of the previous takes 1
|
|
||||||
tracking.use(2);
|
|
||||||
return two_things{ a, b };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct pusher<two_things> {
|
|
||||||
static int push(lua_State* L, const two_things& things) {
|
|
||||||
int amount = stack::push(L, things.a);
|
|
||||||
// amount will be 1: int pushes 1 item
|
|
||||||
amount += stack::push(L, things.b);
|
|
||||||
// amount 2 now, since bool pushes a single item
|
|
||||||
// Return 2 things
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
This is the base formula that you can follow to extend to your own classes. Using it in the rest of the library should then be seamless:
|
This is the base formula that you can follow to extend to your own classes. Using it in the rest of the library should then be seamless:
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. literalinclude:: ../../../examples/customization.cpp
|
||||||
:caption: customization: using it
|
:name: customization-overriding-use
|
||||||
:name: customization-using
|
:linenos:
|
||||||
|
:lines: 73-
|
||||||
#include <sol.hpp>
|
|
||||||
#include <two_things.hpp>
|
|
||||||
|
|
||||||
int main () {
|
|
||||||
|
|
||||||
sol::state lua;
|
|
||||||
|
|
||||||
// Create a pass-through style of function
|
|
||||||
lua.script("function f ( a, b ) return a, b end");
|
|
||||||
|
|
||||||
// get the function out of Lua
|
|
||||||
sol::function f = lua["f"];
|
|
||||||
|
|
||||||
two_things things = f(two_things{24, true});
|
|
||||||
// things.a == 24
|
|
||||||
// things.b == true
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
And that's it!
|
And that's it!
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ endif(INTEROP_EXAMPLES)
|
||||||
|
|
||||||
# # single-source compilable examples
|
# # single-source compilable examples
|
||||||
|
|
||||||
file(GLOB EXAMPLES_SRC *.cpp tutorials/quick_n_dirty/*.cpp)
|
file(GLOB EXAMPLES_SRC *.cpp tutorials/quick_n_dirty/*.cpp docs/*.cpp)
|
||||||
source_group(examples FILES ${EXAMPLES_SRC})
|
source_group(examples FILES ${EXAMPLES_SRC})
|
||||||
|
|
||||||
function (MAKE_EXAMPLE example_source_file is_single)
|
function (MAKE_EXAMPLE example_source_file is_single)
|
||||||
|
@ -100,4 +100,4 @@ if (EXAMPLES)
|
||||||
MAKE_EXAMPLE(${example_source_file} TRUE)
|
MAKE_EXAMPLE(${example_source_file} TRUE)
|
||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
27
examples/docs/my_panic.cpp
Normal file
27
examples/docs/my_panic.cpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
#define SOL_CHECK_ARGUMENTS 1
|
||||||
|
#include <sol.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
inline void my_panic(sol::optional<std::string> maybe_msg) {
|
||||||
|
std::cerr << "Lua is in a panic state and will now abort() the application" << std::endl;
|
||||||
|
if (maybe_msg) {
|
||||||
|
const std::string& msg = maybe_msg.value();
|
||||||
|
std::cerr << "\terror message: " << msg << std::endl;
|
||||||
|
}
|
||||||
|
// When this function exits, Lua will exhibit default behavior and abort()
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int, char*[]) {
|
||||||
|
sol::state lua(sol::c_call<decltype(&my_panic), &my_panic>);
|
||||||
|
// or, if you already have a lua_State* L
|
||||||
|
// lua_atpanic( L, sol::c_call<decltype(&my_panic)>, &my_panic> );
|
||||||
|
// or, with state/state_view:
|
||||||
|
// sol::state_view lua(L);
|
||||||
|
// lua.set_panic( sol::c_call<decltype(&my_panic)>, &my_panic> );
|
||||||
|
|
||||||
|
// uncomment the below to see
|
||||||
|
//lua.script("boom_goes.the_dynamite");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
33
examples/docs/references_in_lambdas.cpp
Normal file
33
examples/docs/references_in_lambdas.cpp
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#define SOL_CHECK_ARGUMENTS 1
|
||||||
|
#include <sol.hpp>
|
||||||
|
|
||||||
|
#include "../assert.hpp"
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
|
struct test {
|
||||||
|
int blah = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
test t;
|
||||||
|
sol::state lua;
|
||||||
|
lua.set_function("f", [&t]() {
|
||||||
|
return t;
|
||||||
|
});
|
||||||
|
lua.set_function("g", [&t]() -> test& {
|
||||||
|
return t;
|
||||||
|
});
|
||||||
|
|
||||||
|
lua.script("t1 = f()");
|
||||||
|
lua.script("t2 = g()");
|
||||||
|
|
||||||
|
test& from_lua_t1 = lua["t1"];
|
||||||
|
test& from_lua_t2 = lua["t2"];
|
||||||
|
|
||||||
|
// not the same: 'f' lambda copied
|
||||||
|
c_assert(&from_lua_t1 != &t);
|
||||||
|
// the same: 'g' lambda returned reference
|
||||||
|
c_assert(&from_lua_t2 == &t);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
18
examples/docs/simple_functions.cpp
Normal file
18
examples/docs/simple_functions.cpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#define SOL_CHECK_ARGUMENTS 1
|
||||||
|
|
||||||
|
#include <sol.hpp>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
sol::state lua;
|
||||||
|
int x = 0;
|
||||||
|
lua.set_function("beep", [&x]{ ++x; });
|
||||||
|
lua.script("beep()");
|
||||||
|
assert(x == 1);
|
||||||
|
|
||||||
|
sol::function beep = lua["beep"];
|
||||||
|
beep();
|
||||||
|
assert(x == 2);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
32
examples/docs/simple_structs.cpp
Normal file
32
examples/docs/simple_structs.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#define SOL_CHECK_ARGUMENTS 1
|
||||||
|
|
||||||
|
#include <sol.hpp>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
struct vars {
|
||||||
|
int boop = 0;
|
||||||
|
|
||||||
|
int bop () const {
|
||||||
|
return boop + 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
sol::state lua;
|
||||||
|
lua.new_usertype<vars>("vars",
|
||||||
|
"boop", &vars::boop,
|
||||||
|
"bop", &vars::bop);
|
||||||
|
lua.script("beep = vars.new()\n"
|
||||||
|
"beep.boop = 1\n"
|
||||||
|
"bopvalue = beep:bop()");
|
||||||
|
|
||||||
|
vars& beep = lua["beep"];
|
||||||
|
int bopvalue = lua["bopvalue"];
|
||||||
|
|
||||||
|
assert(beep.boop == 1);
|
||||||
|
assert(lua.get<vars>("beep").boop == 1);
|
||||||
|
assert(beep.bop() == 2);
|
||||||
|
assert(bopvalue == 2);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
47
examples/docs/state_transfer.cpp
Normal file
47
examples/docs/state_transfer.cpp
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#define SOL_CHECK_ARGUMENTS 1
|
||||||
|
#include <sol.hpp>
|
||||||
|
|
||||||
|
#include "../assert.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main (int, char*[]) {
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
lua.open_libraries();
|
||||||
|
sol::function transferred_into;
|
||||||
|
lua["f"] = [&lua, &transferred_into](sol::object t, sol::this_state this_L) {
|
||||||
|
std::cout << "state of main : " << (void*)lua.lua_state() << std::endl;
|
||||||
|
std::cout << "state of function : " << (void*)this_L.lua_state() << std::endl;
|
||||||
|
// pass original lua_State* (or sol::state/sol::state_view)
|
||||||
|
// transfers ownership from the state of "t",
|
||||||
|
// to the "lua" sol::state
|
||||||
|
transferred_into = sol::function(lua, t);
|
||||||
|
};
|
||||||
|
|
||||||
|
lua.script(R"(
|
||||||
|
i = 0
|
||||||
|
function test()
|
||||||
|
co = coroutine.create(
|
||||||
|
function()
|
||||||
|
local g = function() i = i + 1 end
|
||||||
|
f(g)
|
||||||
|
g = nil
|
||||||
|
collectgarbage()
|
||||||
|
end
|
||||||
|
)
|
||||||
|
coroutine.resume(co)
|
||||||
|
co = nil
|
||||||
|
collectgarbage()
|
||||||
|
end
|
||||||
|
)");
|
||||||
|
|
||||||
|
// give it a try
|
||||||
|
lua.safe_script("test()");
|
||||||
|
// should call 'g' from main thread, increment i by 1
|
||||||
|
transferred_into();
|
||||||
|
// check
|
||||||
|
int i = lua["i"];
|
||||||
|
c_assert(i == 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user