diff --git a/docs/source/api/api-top.rst b/docs/source/api/api-top.rst index 7fc1b896..d388a5d0 100644 --- a/docs/source/api/api-top.rst +++ b/docs/source/api/api-top.rst @@ -31,6 +31,7 @@ Browse the various function and classes :doc:`Sol<../index>` utilizes to make yo function protected_function coroutine + yielding error object thread @@ -53,4 +54,4 @@ Browse the various function and classes :doc:`Sol<../index>` utilizes to make yo compatibility types metatable_key - new_table \ No newline at end of file + new_table diff --git a/docs/source/api/containers.rst b/docs/source/api/containers.rst index 52d2fd4b..19d35b00 100644 --- a/docs/source/api/containers.rst +++ b/docs/source/api/containers.rst @@ -3,73 +3,4 @@ containers *for handling ``std::vector/map/set`` and others* -Sol2 automatically converts containers (detected using the ``sol::is_container`` 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. - -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` and :doc:`sol::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` 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 - - 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{ 2, 4, 6, 8, 10 }; - - // Call it, see 5 elements - // printed out - f(lua["arr"]); - - // Mess with it in C++ - std::vector& 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` when passing something to the library to get a table out of it: ``lua["arr"] = as_table( std::vector{ ... });``. 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. - +See the full :doc:`containers documentation at the top level container page<../containers>` diff --git a/docs/source/codecvt.rst b/docs/source/codecvt.rst index 5bcfeb5d..e1fb8702 100644 --- a/docs/source/codecvt.rst +++ b/docs/source/codecvt.rst @@ -1,29 +1,14 @@ -codecvt + std::(w/u16/u32)string support -======================================== +unicode transformation format handling +====================================== 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 ```` 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 ```` 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 ```` on Windows machines, which is unacceptable). - .. note:: - The `standard`_ states the following: + The ```` 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 , - | until a suitable replacement is standardized.” +``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. +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. - -.. _standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html +.. _file an issue report: https://github.com/ThePhD/sol2/issues diff --git a/docs/source/compilation.rst b/docs/source/compilation.rst index e078b727..9f3fe047 100644 --- a/docs/source/compilation.rst +++ b/docs/source/compilation.rst @@ -63,7 +63,7 @@ We support: * Lua 5.3+ * Lua 5.2 * Lua 5.1 -* LuaJIT 2.0.4+ +* LuaJIT 2.0.x+ * LuaJIT 2.1.x-beta3+ diff --git a/docs/source/conf.py b/docs/source/conf.py index 3aae4b13..3c5c4906 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -144,7 +144,7 @@ html_theme_path = ["_themes", ] # 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, # 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 # .htaccess) here, relative to this directory. These files are copied diff --git a/docs/source/containers.rst b/docs/source/containers.rst index b21de36d..d51ee2a1 100644 --- a/docs/source/containers.rst +++ b/docs/source/containers.rst @@ -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` and :doc:`sol::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 @@ -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` when passing something to the library to get a table out of it: ``lua["arr"] = as_table( std::vector{ ... });``. 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 .. _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 diff --git a/docs/source/errors.rst b/docs/source/errors.rst index 980ed7b2..031c1f30 100644 --- a/docs/source/errors.rst +++ b/docs/source/errors.rst @@ -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` for more details. * Assigning a ``std::string`` or a ``std::pair`` 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. -* If you are using ``/std:c++latest`` on VC++ and get a number of deprecation errors for ```` and others, please see :ref:`this note here`. * 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 diff --git a/docs/source/exceptions.rst b/docs/source/exceptions.rst index 2eddbbfb..4978dbda 100644 --- a/docs/source/exceptions.rst +++ b/docs/source/exceptions.rst @@ -9,30 +9,10 @@ If you turn this off, the default `at_panic`_ function :doc:`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: -.. code-block:: cpp +.. literalinclude:: ../../examples/docs/my_panic.cpp :caption: regular panic function :name: typical-panic-function - - #include - #include - - inline void my_panic(sol::optional 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); - // or, if you already have a lua_State* L - // lua_atpanic( L, sol::c_call, &my_panic> ); - // or, with state/state_view: - // sol::state_view lua(L); - // lua.set_panic( sol::c_call, &my_panic> ); - } + :linenos: Note that ``SOL_NO_EXCEPTIONS`` will also disable :doc:`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! diff --git a/docs/source/features.rst b/docs/source/features.rst index e3bfb77c..40cdb956 100644 --- a/docs/source/features.rst +++ b/docs/source/features.rst @@ -18,6 +18,8 @@ what Sol supports - Implicit conversion to the types you want ``double b = table["computed_value"];`` +* :doc:`yielding` support: tag a function as whose return is meant to yield into a coroutine + * :doc:`Optional` support: setting values, getting values of multiple (different) types - :doc:`Lazy evaluation` for nested/chained queries ``optional maybe_number = table["a"]["b"]["invalid_key"];`` @@ -34,7 +36,7 @@ what Sol supports * User-Defined Type (:doc:`sol::usertype` in the API) support: - Set member functions to be called - 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) - Support for "Factory" classes that do not expose constructor or destructor - 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" )``). * 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 +* 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 +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+ @@ -128,6 +131,8 @@ Explanations for a few categories are below (rest are self-explanatory). +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+ | coroutines | ~ | ✗ | ~ | ✔ | ✔ | ✔ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ | +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+ +| yielding C++ functions | ~ | ✔ | ✔ | ✔ | ~ | ✔ | ~ | ✗ | ✔ | ✗ | ~ | ✔ | ~ | ++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+ | no-rtti support | ✔ | ✗ | ✔ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ | ✔ | +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+ | no-exception support | ✔ | ✗ | ✔ | ~ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ | ✔ | @@ -241,7 +246,7 @@ SLB3 - 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 - 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!) @@ -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!) * No table variable support - get turned into getter/setter functions, similar to kaguya * Table variables become class statics (surprising) +* Tanks in later MSVCs .. _Go read the docs: https://oolua.org/docs/index.html diff --git a/docs/source/functions.rst b/docs/source/functions.rst index ec4a60fd..6aaac76a 100644 --- a/docs/source/functions.rst +++ b/docs/source/functions.rst @@ -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 );``. -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 - #include - - 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; - } +.. literalinclude:: ../../examples/docs/references_in_lambdas.cpp + :name: refereces-in-lambdas-example + :linenos: + .. _function-exception-handling: diff --git a/docs/source/index.rst b/docs/source/index.rst index e2671914..03eb563b 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -53,65 +53,16 @@ the basics: ----------- .. 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++ - :caption: functions +.. literalinclude:: ../../examples/docs/simple_functions.cpp + :name: simple-functions-example :linenos: - #include - #include - - 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 - #include - - struct vars { - int boop = 0; - - int bop () const { - return boop + 1; - } - }; - - int main() { - sol::state lua; - lua.new_usertype("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("beep").boop == 1); - assert(beep.bop() == 2); - assert(bopvalue == 2); - - return 0; - } +.. literalinclude:: ../../examples/docs/simple_structs.cpp + :name: simple-structs-example + :linenos: helping out diff --git a/docs/source/licenses.rst b/docs/source/licenses.rst index 50be8f03..3860c91f 100644 --- a/docs/source/licenses.rst +++ b/docs/source/licenses.rst @@ -1,52 +1,93 @@ -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. - -Sol - ThePhD/sol2: ------------------- - - The MIT License (MIT) - - Copyright (c) 2013-2016 Rapptz, ThePhD, and contributors - - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -Lua-compat-5.3 - keplerproject/Lua-compat-5.3: ----------------------------------------------- - - The MIT License (MIT) - - Copyright (c) 2015 Kepler Project. - - 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. - -Lua - Lua.org: --------------- - - The MIT License (MIT) - - Copyright © 1994–2015 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: --------------------------- - +licenses +======== + +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: +------------------ + +.. code-block:: none + + The MIT License (MIT) + + Copyright (c) 2013-2016 Rapptz, ThePhD, and contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Lua-compat-5.3 - keplerproject/Lua-compat-5.3: +---------------------------------------------- + +.. code-block:: none + + The MIT License (MIT) + + Copyright (c) 2018 Kepler Project. + + 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. + +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 CC0 1.0 Universal @@ -167,7 +208,7 @@ ogonek - libogonek/ogonek: Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. - - -.. _MIT: http://opensource.org/licenses/MIT + this CC0 or use of the Work. + + +.. _MIT: http://opensource.org/licenses/MIT diff --git a/docs/source/mentions.rst b/docs/source/mentions.rst index 705b60c5..2d1a163a 100644 --- a/docs/source/mentions.rst +++ b/docs/source/mentions.rst @@ -23,6 +23,7 @@ Okay, so the features don't convince you, the documentation doesn't convince you | |before| | |after| | +----------+---------+ +* In `High Performance Computing research`_ * 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. * 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 .. _Multiple Arcade Machine Emulator (MAME): http://www.mamedev.org/index.php .. _The pull request: https://github.com/mamedev/mame/pull/1626 -.. _OpenMPT: https://openmpt.org/ \ No newline at end of file +.. _OpenMPT: https://openmpt.org/ +.. _High Performance Computing research: https://github.com/ThePhD/sol2/issues/568 diff --git a/docs/source/performance.rst b/docs/source/performance.rst index 93543b71..5e346784 100644 --- a/docs/source/performance.rst +++ b/docs/source/performance.rst @@ -13,4 +13,4 @@ As shown by the :doc:`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`); 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. \ No newline at end of file +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. diff --git a/docs/source/threading.rst b/docs/source/threading.rst index a409f41b..4b898fdd 100644 --- a/docs/source/threading.rst +++ b/docs/source/threading.rst @@ -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: -.. code-block:: cpp - :caption: transfer from state function +.. literalinclude:: ../../examples/docs/state_transfer.cpp :name: state-transfer - - #define SOL_CHECK_ARGUMENTS - #include - - #include - - 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; - } + :linenos: diff --git a/docs/source/tutorial/all-the-things.rst b/docs/source/tutorial/all-the-things.rst index 760827eb..43bdc092 100644 --- a/docs/source/tutorial/all-the-things.rst +++ b/docs/source/tutorial/all-the-things.rst @@ -20,7 +20,7 @@ The implementation for ``assert.hpp`` with ``c_assert`` looks like so: .. literalinclude:: ../../../examples/assert.hpp :linenos: - :lines: 1-8, 19- + :lines: 1-3, 19- This is the assert used in the quick code below. diff --git a/docs/source/tutorial/customization.rst b/docs/source/tutorial/customization.rst index 4643c2ba..5140cedd 100644 --- a/docs/source/tutorial/customization.rst +++ b/docs/source/tutorial/customization.rst @@ -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++: -.. code-block:: cpp - :caption: two_things.hpp +.. literalinclude:: ../../../examples/customization.cpp :name: customization-overriding - - #include - - 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 : std::integral_constant {}; - - // Then, specialize the type to match: - // this has multiple types, so we consider it a "poly" type. - template <> - struct lua_type_of : std::integral_constant {}; - - // Now, specialize various stack structures - namespace stack { - - template <> - struct checker { - template - 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(L, absolute_index - 1, handler) - && stack::check(L, absolute_index, handler); - tracking.use(2); - return success; - } - }; - - template <> - struct getter { - 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(L, absolute_index - 1); - // Get the second element, - // in the +1 position from the first - bool b = stack::get(L, absolute_index); - // we use 2 slots, each of the previous takes 1 - tracking.use(2); - return two_things{ a, b }; - } - }; - - template <> - struct pusher { - 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; - } - }; - - } - } - + :linenos: + :lines: 1-72 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 - :caption: customization: using it - :name: customization-using - - #include - #include - - 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; - } - +.. literalinclude:: ../../../examples/customization.cpp + :name: customization-overriding-use + :linenos: + :lines: 73- And that's it! diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c8971450..54068f85 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -38,7 +38,7 @@ endif(INTEROP_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}) function (MAKE_EXAMPLE example_source_file is_single) @@ -100,4 +100,4 @@ if (EXAMPLES) MAKE_EXAMPLE(${example_source_file} TRUE) endforeach() endif() -endif() \ No newline at end of file +endif() diff --git a/examples/docs/my_panic.cpp b/examples/docs/my_panic.cpp new file mode 100644 index 00000000..764cfe05 --- /dev/null +++ b/examples/docs/my_panic.cpp @@ -0,0 +1,27 @@ + +#define SOL_CHECK_ARGUMENTS 1 +#include +#include + +inline void my_panic(sol::optional 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); + // or, if you already have a lua_State* L + // lua_atpanic( L, sol::c_call, &my_panic> ); + // or, with state/state_view: + // sol::state_view lua(L); + // lua.set_panic( sol::c_call, &my_panic> ); + + // uncomment the below to see + //lua.script("boom_goes.the_dynamite"); + + return 0; +} diff --git a/examples/docs/references_in_lambdas.cpp b/examples/docs/references_in_lambdas.cpp new file mode 100644 index 00000000..f59452e5 --- /dev/null +++ b/examples/docs/references_in_lambdas.cpp @@ -0,0 +1,33 @@ +#define SOL_CHECK_ARGUMENTS 1 +#include + +#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; +} diff --git a/examples/docs/simple_functions.cpp b/examples/docs/simple_functions.cpp new file mode 100644 index 00000000..a298c273 --- /dev/null +++ b/examples/docs/simple_functions.cpp @@ -0,0 +1,18 @@ +#define SOL_CHECK_ARGUMENTS 1 + +#include +#include + +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; +} diff --git a/examples/docs/simple_structs.cpp b/examples/docs/simple_structs.cpp new file mode 100644 index 00000000..a2dd5c0d --- /dev/null +++ b/examples/docs/simple_structs.cpp @@ -0,0 +1,32 @@ +#define SOL_CHECK_ARGUMENTS 1 + +#include +#include + +struct vars { + int boop = 0; + + int bop () const { + return boop + 1; + } +}; + +int main() { + sol::state lua; + lua.new_usertype("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("beep").boop == 1); + assert(beep.bop() == 2); + assert(bopvalue == 2); + + return 0; +} diff --git a/examples/docs/state_transfer.cpp b/examples/docs/state_transfer.cpp new file mode 100644 index 00000000..2bdc9240 --- /dev/null +++ b/examples/docs/state_transfer.cpp @@ -0,0 +1,47 @@ +#define SOL_CHECK_ARGUMENTS 1 +#include + +#include "../assert.hpp" +#include + +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; +}