mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
HEAVILY improve the entire infrastructure and documentation along with all the examples
This commit is contained in:
parent
74a99d68ed
commit
f701fd2de7
|
@ -1,4 +1,4 @@
|
|||
# # # # sol2
|
||||
# # # # sol3
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## Contributing to Sol
|
||||
## Contributing to sol
|
||||
|
||||
Looking to contribute to Sol? Well, first thing I want to mention is thank you!
|
||||
Looking to contribute to sol? Well, first thing I want to mention is thank you!
|
||||
Second of all, this is probably where you should look :)
|
||||
|
||||
## Reporting Issues
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# 🎉 Donators! ♥ 🎉
|
||||
|
||||
Thank you to all patrons, donators and contributors who help keep sol2 amazing.
|
||||
Thank you to all patrons, donators and contributors who help keep sol3 amazing.
|
||||
|
||||
- Robert Salvet
|
||||
- Ορφέας Ζαφείρης - 2x Donations!
|
||||
|
@ -12,7 +12,7 @@ Thank you to all patrons, donators and contributors who help keep sol2 amazing.
|
|||
|
||||
# 🎉 Patrons! ♥ 🎉
|
||||
|
||||
Beyond just a one-time donation, patrons make a continued commitment to help keep sol2 supported and bug-free. Thank you for your patronage! Here are the supporters that wanted to be featured as sol2 contributors.
|
||||
Beyond just a one-time donation, patrons make a continued commitment to help keep sol3 supported and bug-free. Thank you for your patronage! Here are the supporters that wanted to be featured as sol3 contributors.
|
||||
|
||||
- Michael Caisse
|
||||
- Joshua Fisher
|
||||
|
@ -21,6 +21,6 @@ Beyond just a one-time donation, patrons make a continued commitment to help kee
|
|||
|
||||
# Company Patrons / Supporters #
|
||||
|
||||
Companies who sign up for a long-term support contract or patronage are listed here! They really push forward what's possible with sol2 (and the newer v3)! Please reach out to phdofthehouse@gmail.com if you are interested in a custom solution or a long-term support contract that goes beyond the current release's needs!
|
||||
Companies who sign up for a long-term support contract or patronage are listed here! They really push forward what's possible with sol3 (and the newer v3)! Please reach out to phdofthehouse@gmail.com if you are interested in a custom solution or a long-term support contract that goes beyond the current release's needs!
|
||||
|
||||
- Intrepid Control Systems [intrepidcs.com](https://www.intrepidcs.com/)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# # # # sol2
|
||||
# # # # sol3
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2017 Rapptz, ThePhD, and contributors
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
[![Support via Patreon](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.herokuapp.com%2FThePhD)](https://patreon.com/thephd)
|
||||
[![Liberapay patrons](https://img.shields.io/liberapay/patrons/ThePhD.svg)](https://liberapay.com/ThePhD/)
|
||||
|
||||
Sol is a C++ library binding to Lua. It currently supports all Lua versions 5.1+ (LuaJIT 2.x included). Sol aims to be easy to use and easy to add to a project.
|
||||
sol is a C++ library binding to Lua. It currently supports all Lua versions 5.1+ (LuaJIT 2.x included). sol aims to be easy to use and easy to add to a project.
|
||||
The library is header-only for easy integration with projects.
|
||||
|
||||
## Documentation
|
||||
|
@ -116,7 +116,7 @@ C++Now 2019 - Flug Auditorium, Aspen Physics Center, Aspen, Colorado
|
|||
|
||||
## Supported Compilers
|
||||
|
||||
Sol makes use of C++17 features. GCC 7.x.x and Clang 3.9.x (with `-std=c++1z` and appropriate standard library)
|
||||
sol makes use of C++17 features. GCC 7.x.x and Clang 3.9.x (with `-std=c++1z` and appropriate standard library)
|
||||
or higher should be able to compile without problems. However, the officially supported and CI-tested compilers are:
|
||||
|
||||
- GCC 7.x.x+ (MinGW 7.x.x+)
|
||||
|
@ -147,6 +147,6 @@ You will need any flavor of python3 and an available compiler. The testing suite
|
|||
|
||||
## License
|
||||
|
||||
Sol is distributed with an MIT License. You can see LICENSE.txt for more info.
|
||||
sol is distributed with an MIT License. You can see LICENSE.txt for more info.
|
||||
|
||||
If you need a custom solution, feel free to contact me.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# # # # sol2
|
||||
# # # # sol3
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# # # # sol2
|
||||
# # # # sol3
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# # # # sol2
|
||||
# # # # sol3
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# # # # sol2
|
||||
# # # # sol3
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors
|
||||
|
|
|
@ -94,9 +94,9 @@ qthelp:
|
|||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Sol.qhcp"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/sol.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Sol.qhc"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/sol.qhc"
|
||||
|
||||
.PHONY: applehelp
|
||||
applehelp:
|
||||
|
@ -113,8 +113,8 @@ devhelp:
|
|||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/Sol"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Sol"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/sol"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/sol"
|
||||
@echo "# devhelp"
|
||||
|
||||
.PHONY: epub
|
||||
|
|
|
@ -127,9 +127,9 @@ if "%1" == "qthelp" (
|
|||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Sol.qhcp
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\sol.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Sol.ghc
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\sol.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
api reference manual
|
||||
====================
|
||||
|
||||
Browse the various function and classes :doc:`Sol<../index>` utilizes to make your life easier when working with Lua.
|
||||
Browse the various function and classes :doc:`sol<../index>` utilizes to make your life easier when working with Lua.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:caption: Sol API
|
||||
:caption: sol API
|
||||
:name: apitoc
|
||||
:maxdepth: 2
|
||||
|
||||
state
|
||||
this_state
|
||||
lua_value
|
||||
reference
|
||||
stack_reference
|
||||
make_reference
|
||||
|
|
|
@ -19,6 +19,6 @@ as_args
|
|||
:caption: args_from_container.cpp
|
||||
:linenos:
|
||||
|
||||
It is basically implemented as a `one-way customization point`_. For more information about customization points, see the :doc:`tutorial on how to customize Sol to work with your types<../tutorial/customization>`.
|
||||
It is basically implemented as a `one-way customization point`_. For more information about customization points, see the :doc:`tutorial on how to customize sol to work with your types<../tutorial/customization>`.
|
||||
|
||||
.. _one-way customization point: https://github.com/ThePhD/sol2/blob/develop/sol/as_args.hpp
|
||||
|
|
|
@ -6,7 +6,11 @@ as_table
|
|||
.. code-block:: cpp
|
||||
|
||||
template <typename T>
|
||||
as_table_t { ... };
|
||||
as_table_t {
|
||||
T& value() &;
|
||||
const T& value() & const;
|
||||
T&& value() &&;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
as_table_t<T> as_function ( T&& container );
|
||||
|
@ -16,12 +20,14 @@ This function serves the purpose of ensuring that an object is pushed -- if poss
|
|||
.. literalinclude:: ../../../examples/source/docs/as_table_ipairs.cpp
|
||||
:linenos:
|
||||
|
||||
Note that any caveats with Lua tables apply the moment it is serialized, and the data cannot be gotten out back out in C++ as a C++ type. You can deserialize the Lua table into something explicitly using the ``sol::as_table_t`` marker for your get and conversion operations using Sol. At that point, the returned type is deserialized **from** a table, meaning you cannot reference any kind of C++ data directly as you do with regular userdata/usertypes. *All C++ type information is lost upon serialization into Lua.*
|
||||
Note that any caveats with Lua tables apply the moment it is serialized, and the data cannot be gotten out back out in C++ as a C++ type. You can deserialize the Lua table into something explicitly using the ``sol::as_table_t`` marker for your get and conversion operations using sol. At that point, the returned type is deserialized **from** a table, meaning you cannot reference any kind of C++ data directly as you do with regular userdata/usertypes. *All C++ type information is lost upon serialization into Lua.*
|
||||
|
||||
If you need this functionality with a member variable, use a :doc:`property on a getter function<property>` that returns the result of ``sol::as_table``.
|
||||
|
||||
This marker does NOT apply to :doc:`usertypes<usertype>`.
|
||||
|
||||
You can also use this to nest types and retrieve tables within tables as shown by `this example`_.
|
||||
You can also use this to nest types and retrieve tables within tables as shown by this example.
|
||||
|
||||
.. _this example: https://github.com/ThePhD/sol2/blob/develop/examples/containers_as_table.cpp
|
||||
.. literalinclude:: ../../../examples/source/containers_as_table.cpp
|
||||
:linenos:
|
||||
:lines: 1-8,31-60,62-68,70-
|
||||
|
|
|
@ -19,7 +19,7 @@ The goal of ``sol::c_call<...>`` is to provide a way to wrap a function and tran
|
|||
|
||||
This pushes a raw ``lua_CFunction`` into whatever you pass the resulting ``c_call`` function pointer into, whether it be a table or a userdata or whatever else using sol3's API. The resulting ``lua_CFunction`` can also be used directly with the lua API, just like many of sol3's types can be intermingled with Lua's API if you know what you're doing.
|
||||
|
||||
It is advisable for the user to consider making a macro to do the necessary ``decltype( &function_name, ), function_name``. Sol does not provide one because many codebases already have `one similar to this`_.
|
||||
It is advisable for the user to consider making a macro to do the necessary ``decltype( &function_name, ), function_name``. sol does not provide one because many codebases already have `one similar to this`_.
|
||||
|
||||
Here's an example below of various ways to use ``sol::c_call``:
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ compatibility.hpp
|
|||
|
||||
This is a detail header used to maintain compatability with the 5.2 and 5.3+ APIs. It contains code from the MIT-Licensed `Lua code`_ in some places and also from the `lua-compat`_ repository by KeplerProject.
|
||||
|
||||
It is not fully documented as this header's only purpose is for internal use to make sure Sol compiles across all platforms / distributions with no errors or missing Lua functionality. If you think there's some compatibility features we are missing or if you are running into redefinition errors, please make an `issue in the issue tracker`_.
|
||||
It is not fully documented as this header's only purpose is for internal use to make sure sol compiles across all platforms / distributions with no errors or missing Lua functionality. If you think there's some compatibility features we are missing or if you are running into redefinition errors, please make an `issue in the issue tracker`_.
|
||||
|
||||
If you have this already in your project or you have your own compatibility layer, then please ``#define SOL_NO_COMPAT 1`` before including ``sol.hpp`` or pass this flag on the command line to turn off the compatibility wrapper.
|
||||
|
||||
|
|
|
@ -16,6 +16,6 @@ error
|
|||
Please do not throw this error type yourself. It belongs to the library and we do some information appending at the front.
|
||||
|
||||
|
||||
If an eror is thrown by Sol, it is going to be of this type. We use this in a single place: the default ``at_panic`` function we bind on construction of a :ref:`sol::state<set-panic>`. If you turn :doc:`off exceptions<../exceptions>`, the chances of you seeing this error are nil unless you specifically use it to pull errors out of things such as :doc:`sol::protected_function<protected_function>`.
|
||||
If an eror is thrown by sol, it is going to be of this type. We use this in a single place: the default ``at_panic`` function we bind on construction of a :ref:`sol::state<set-panic>`. If you turn :doc:`off exceptions<../exceptions>`, the chances of you seeing this error are nil unless you specifically use it to pull errors out of things such as :doc:`sol::protected_function<protected_function>`.
|
||||
|
||||
As it derives from ``std::runtime_error``, which derives from ``std::exception``, you can catch it with a ``catch (const std::exception& )`` clause in your try/catch blocks. You can retrieve a string error from Lua (Lua pushes all its errors as string returns) by using this type with any of the get or lookup functions in Sol.
|
||||
As it derives from ``std::runtime_error``, which derives from ``std::exception``, you can catch it with a ``catch (const std::exception& )`` clause in your try/catch blocks. You can retrieve a string error from Lua (Lua pushes all its errors as string returns) by using this type with any of the get or lookup functions in sol.
|
||||
|
|
|
@ -12,7 +12,7 @@ function
|
|||
class unsafe_function : public reference;
|
||||
typedef unsafe_function function;
|
||||
|
||||
Function is a correct-assuming version of :doc:`protected_function<protected_function>`, omitting the need for typechecks and error handling (thus marginally increasing speed in some cases). It is the default function type of Sol. Grab a function directly off the stack using the constructor:
|
||||
Function is a correct-assuming version of :doc:`protected_function<protected_function>`, omitting the need for typechecks and error handling (thus marginally increasing speed in some cases). It is the default function type of sol. Grab a function directly off the stack using the constructor:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: constructor: unsafe_function
|
||||
|
|
16
docs/source/api/lua_value.rst
Normal file
16
docs/source/api/lua_value.rst
Normal file
|
@ -0,0 +1,16 @@
|
|||
lua_value
|
||||
=========
|
||||
*easy creation of Lua values and tables at the cost of some safety and speed*
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct lua_value;
|
||||
struct array_value;
|
||||
|
||||
|
||||
The goal of these types is to make it easy to describe tables and arrays in C++ code. It works by using a thread local ``lua_State*`` variable inside the class so that one can simply pass values. The thread local variable is initialized by creation of a `sol::state`, but can also `be done manually<state-automatic-handlers>` with ``sol::set_default_state``. An example of usage is below:
|
||||
|
||||
.. literalinclude:: ../../../examples/source/lua_value.cpp
|
||||
:caption: lua_value.cpp
|
||||
:name: lua-value-example
|
||||
:linenos:
|
|
@ -12,7 +12,7 @@ make_object/make_reference
|
|||
template <typename T, typename R = reference, bool should_pop = (R is base of sol::stack_index), typename... Args>
|
||||
R make_reference(lua_State* L, Args&&... args);
|
||||
|
||||
Makes an ``R`` out of the value. The first overload deduces the type from the passed in argument, the second allows you to specify a template parameter and forward any relevant arguments to ``sol::stack::push``. The type figured out for ``R`` is what is referenced from the stack. This allows you to request arbitrary pop-able types from Sol and have it constructed from ``R(lua_State* L, int stack_index)``. If the template boolean ``should_pop`` is ``true``, the value that was pushed will be popped off the stack. It defaults to popping, but if it encounters a type such as :doc:`sol::stack_reference<stack_reference>` (or any of its typically derived types in Sol), it will leave the pushed values on the stack.
|
||||
Makes an ``R`` out of the value. The first overload deduces the type from the passed in argument, the second allows you to specify a template parameter and forward any relevant arguments to ``sol::stack::push``. The type figured out for ``R`` is what is referenced from the stack. This allows you to request arbitrary pop-able types from sol and have it constructed from ``R(lua_State* L, int stack_index)``. If the template boolean ``should_pop`` is ``true``, the value that was pushed will be popped off the stack. It defaults to popping, but if it encounters a type such as :doc:`sol::stack_reference<stack_reference>` (or any of its typically derived types in sol), it will leave the pushed values on the stack.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: make_object
|
||||
|
|
|
@ -8,7 +8,7 @@ metatable_key
|
|||
struct metatable_key_t {};
|
||||
const metatable_key_t metatable_key;
|
||||
|
||||
You can use this in conjunction with :doc:`sol::table<table>` to set/get a metatable. Lua metatables are powerful ways to override default behavior of objects for various kinds of operators, among other things. Here is an entirely complete example, showing getting and working with a :doc:`usertype<usertype>`'s metatable defined by Sol:
|
||||
You can use this in conjunction with :doc:`sol::table<table>` to set/get a metatable. Lua metatables are powerful ways to override default behavior of objects for various kinds of operators, among other things. Here is an entirely complete example, showing getting and working with a :doc:`usertype<usertype>`'s metatable defined by sol:
|
||||
|
||||
.. literalinclude:: ../../../examples/source/metatable_key_low_level.cpp
|
||||
:caption: messing with metatables
|
||||
|
|
|
@ -6,14 +6,18 @@ nested
|
|||
|
||||
template <typename T>
|
||||
struct nested {
|
||||
T source;
|
||||
T& value() &;
|
||||
const T& value() & const;
|
||||
T&& value() &&;
|
||||
};
|
||||
|
||||
|
||||
``sol::nested<...>`` is a template class similar to :doc:`sol::as_table<as_table>`, but with the caveat that every :doc:`container type<../containers>` within the ``sol::nested`` type will be retrieved as a table from lua. This is helpful when you need to receive C++-style vectors, lists, and maps nested within each other: all of them will be deserialized from lua using table properties rather than anything else.
|
||||
|
||||
Note that any caveats with Lua tables apply the moment it is serialized, and the data cannot be gotten out back out in C++ as a C++ type. You can deserialize the Lua table into something explicitly using the ``sol::as_table_t`` marker for your get and conversion operations using Sol. At that point, the returned type is deserialized **from** a table, meaning you cannot reference any kind of C++ data directly as you do with regular userdata/usertypes. *All C++ type information is lost upon serialization into Lua.*
|
||||
Note that any caveats with Lua tables apply the moment it is serialized, and the data cannot be gotten out back out in C++ as a C++ type. You can deserialize the Lua table into something explicitly using the ``sol::as_table_t`` marker for your get and conversion operations using sol. At that point, the returned type is deserialized **from** a table, meaning you cannot reference any kind of C++ data directly as you do with regular userdata/usertypes. *All C++ type information is lost upon serialization into Lua.*
|
||||
|
||||
The `example`_ provides a very in-depth look at both ``sol::as_table<T>`` and ``sol::nested<T>``, and how the two are equivalent.
|
||||
The example provides a very in-depth look at both ``sol::as_table<T>`` and ``sol::nested<T>``, and how the two are equivalent.
|
||||
|
||||
.. _example: https://github.com/ThePhD/sol2/blob/develop/examples/containers_as_table.cpp
|
||||
.. literalinclude:: ../../../examples/source/containers_as_table.cpp
|
||||
:linenos:
|
||||
:lines: 1-30,56-61,63-68,70-
|
||||
|
|
|
@ -34,7 +34,7 @@ There are 4 kinds of constructors here. One allows construction of an object fro
|
|||
template<typename T>
|
||||
decltype(auto) as() const;
|
||||
|
||||
Performs a cast of the item this reference refers to into the type ``T`` and returns it. It obeys the same rules as :ref:`sol::stack::get\<T><getter>`.
|
||||
Performs a cast of the item this reference refers to into the type ``T`` and returns it. It obeys the same rules as :ref:`sol::stack::get\<T><stack-get>`.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: type check
|
||||
|
@ -42,7 +42,7 @@ Performs a cast of the item this reference refers to into the type ``T`` and ret
|
|||
template<typename T>
|
||||
bool is() const;
|
||||
|
||||
Performs a type check using the :ref:`sol::stack::check<checker>` api, after checking if the reference is valid.
|
||||
Performs a type check using the :ref:`sol::stack::check<stack-check>` api, after checking if the internally stored reference is valid.
|
||||
|
||||
|
||||
non-members
|
||||
|
@ -64,7 +64,5 @@ These allow a person to compare an ``sol::object`` against :ref:`nil<nil>`, whic
|
|||
// doesn't have anything...
|
||||
}
|
||||
|
||||
Use this to check objects.
|
||||
|
||||
|
||||
.. _any_return example: https://github.com/ThePhD/sol2/blob/develop/examples/any_return.cpp
|
||||
.. _any_return example: https://github.com/ThePhD/sol2/blob/develop/examples/any_return.cpp
|
||||
|
|
|
@ -56,7 +56,7 @@ Note that because of this system, you can use :doc:`sol::variadic_args<variadic_
|
|||
|
||||
.. note::
|
||||
|
||||
Please keep in mind that doing this bears a runtime cost to find the proper overload. The cost scales directly not exactly with the number of overloads, but the number of functions that have the same argument count as each other (Sol will early-eliminate any functions that do not match the argument count).
|
||||
Please keep in mind that doing this bears a runtime cost to find the proper overload. The cost scales directly not exactly with the number of overloads, but the number of functions that have the same argument count as each other (sol will early-eliminate any functions that do not match the argument count).
|
||||
|
||||
.. _luaL_check{number/udata/string}: http://www.Lua.org/manual/5.3/manual.html#luaL_checkinteger
|
||||
.. _This example shows how: https://github.com/ThePhD/sol2/blob/develop/examples/overloading_with_fallback.cpp
|
||||
|
|
|
@ -8,7 +8,7 @@ protect
|
|||
template <typename T>
|
||||
auto protect( T&& value );
|
||||
|
||||
``sol::protect( my_func )`` allows you to protect a function call or member variable call when it is being set to Lua. It can be used with usertypes or when just setting a function into Sol. Below is an example that demonstrates that a call that would normally not error without :doc:`Safety features turned on<../safety>` that instead errors and makes the Lua safety-call wrapper ``pcall`` fail:
|
||||
``sol::protect( my_func )`` allows you to protect a function call or member variable call when it is being set to Lua. It can be used with usertypes or when just setting a function into sol. Below is an example that demonstrates that a call that would normally not error without :doc:`Safety features turned on<../safety>` that instead errors and makes the Lua safety-call wrapper ``pcall`` fail:
|
||||
|
||||
.. literalinclude:: ../../../examples/source/protect.cpp
|
||||
:linenos:
|
||||
|
|
|
@ -107,7 +107,7 @@ Get and set the Lua entity that is used as the default error handler. The defaul
|
|||
|
||||
reference error_handler;
|
||||
|
||||
The error-handler that is called should a runtime error that Lua can detect occurs. The error handler function needs to take a single string argument (use type std::string if you want to use a C++ function bound to lua as the error handler) and return a single string argument (again, return a std::string or string-alike argument from the C++ function if you're using one as the error handler). If :doc:`exceptions<../exceptions>` are enabled, Sol will attempt to convert the ``.what()`` argument of the exception into a string and then call the error handling function. It is a :doc:`reference<reference>`, as it must refer to something that exists in the lua registry or on the Lua stack. This is automatically set to the default error handler when ``protected_function`` is constructed.
|
||||
The error-handler that is called should a runtime error that Lua can detect occurs. The error handler function needs to take a single string argument (use type std::string if you want to use a C++ function bound to lua as the error handler) and return a single string argument (again, return a std::string or string-alike argument from the C++ function if you're using one as the error handler). If :doc:`exceptions<../exceptions>` are enabled, sol will attempt to convert the ``.what()`` argument of the exception into a string and then call the error handling function. It is a :doc:`reference<reference>`, as it must refer to something that exists in the lua registry or on the Lua stack. This is automatically set to the default error handler when ``protected_function`` is constructed.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@ stack namespace
|
|||
|
||||
namespace stack
|
||||
|
||||
If you find that the higher level abstractions are not meeting your needs, you may want to delve into the ``stack`` namespace to try and get more out of Sol. ``stack.hpp`` and the ``stack`` namespace define several utilities to work with Lua, including pushing / popping utilities, getters, type checkers, Lua call helpers and more. This namespace is not thoroughly documented as the majority of its interface is mercurial and subject to change between releases to either heavily boost performance or improve the Sol :doc:`api<api-top>`.
|
||||
If you find that the higher level abstractions are not meeting your needs, you may want to delve into the ``stack`` namespace to try and get more out of sol. ``stack.hpp`` and the ``stack`` namespace define several utilities to work with Lua, including pushing / popping utilities, getters, type checkers, Lua call helpers and more. This namespace is not thoroughly documented as the majority of its interface is mercurial and subject to change between releases to either heavily boost performance or improve the sol :doc:`api<api-top>`.
|
||||
|
||||
Working at this level of the stack can be enhanced by understanding how the `Lua stack works in general`_ and then supplementing it with the objects and items here.
|
||||
|
||||
There are, however, a few :ref:`template customization points<extension_points>` that you may use for your purposes and a handful of potentially handy functions. These may help if you're trying to slim down the code you have to write, or if you want to make your types behave differently throughout the Sol stack. Note that overriding the defaults **can** throw out many of the safety guarantees Sol provides: therefore, modify the :ref:`extension points<extension_points>` at your own discretion.
|
||||
There are, however, a few :ref:`ADL customization points<extension_points>` that you may use for your purposes and a handful of potentially handy functions. These may help if you're trying to slim down the code you have to write, or if you want to make your types behave differently throughout the sol stack. Note that overriding the defaults **can** throw out many of the safety guarantees sol provides: therefore, modify the :ref:`extension points<extension_points>` at your own discretion.
|
||||
|
||||
structures
|
||||
----------
|
||||
|
@ -69,7 +69,7 @@ This function is helpful for when you bind to a raw C function but need sol's ab
|
|||
template <typename T>
|
||||
auto get( lua_State* L, int index, record& tracking )
|
||||
|
||||
Retrieves the value of the object at ``index`` in the stack. The return type varies based on ``T``: with primitive types, it is usually ``T``: for all unrecognized ``T``, it is generally a ``T&`` or whatever the extension point :ref:`stack::getter\<T><getter>` implementation returns. The type ``T`` has top-level ``const`` qualifiers and reference modifiers removed before being forwarded to the extension point :ref:`stack::getter\<T><getter>` struct. ``stack::get`` will default to forwarding all arguments to the :ref:`stack::check_get<stack-check-get>` function with a handler of ``type_panic`` to strongly alert for errors, if you ask for the :doc:`safety<../safety>`.
|
||||
Retrieves the value of the object at ``index`` in the stack. The return type varies based on ``T``: with primitive types, it is usually ``T``: for all unrecognized ``T``, it is generally a ``T&`` or whatever the extension point :ref:`sol_lua_get\<T><sol_lua_get>` implementation returns. The type ``T`` is tried once as it is (with ``const`` and reference qualifiers left alone) and then once more once it has top-level ``const`` qualifiers and reference modifiers removed before being forwarded to the extension point :ref:`sol_lua_get\<T><sol_lua_get>` function. ``stack::get`` will default to forwarding all arguments to the :ref:`stack::check_get<stack-check-get>` function with a handler of ``type_panic`` to strongly alert for errors, if you ask for the :doc:`safety<../safety>`.
|
||||
|
||||
You may also retrieve an :doc:`sol::optional\<T><optional>` from this as well, to have it attempt to not throw errors when performing the get and the type is not correct.
|
||||
|
||||
|
@ -123,7 +123,7 @@ Checks if the object at ``index`` is of type ``T`` and stored as a sol3 usertype
|
|||
template <typename T, typename Handler>
|
||||
auto check_get( lua_State* L, int index, Handler&& handler, record& tracking )
|
||||
|
||||
Retrieves the value of the object at ``index`` in the stack, but does so safely. It returns an ``optional<U>``, where ``U`` in this case is the return type deduced from ``stack::get<T>``. This allows a person to properly check if the type they're getting is what they actually want, and gracefully handle errors when working with the stack if they so choose to. You can define ``SOL_CHECK_ARGUMENTS`` to turn on additional :doc:`safety<../safety>`, in which ``stack::get`` will default to calling this version of the function with some variant on a handler of ``sol::type_panic_string`` to strongly alert for errors and help you track bugs if you suspect something might be going wrong in your system.
|
||||
Retrieves the value of the object at ``index`` in the stack, but does so safely. It returns an ``optional<U>``, where ``U`` in this case is the return type deduced from ``stack::get<T>``. This allows a person to properly check if the type they're getting is what they actually want, and gracefully handle errors when working with the stack if they so choose to. You can define ``SOL_ALL_SAFETIES_ON`` to turn on additional :doc:`safety<../safety>`, in which ``stack::get`` will default to calling this version of the function with some variant on a handler of ``sol::type_panic_string`` to strongly alert for errors and help you track bugs if you suspect something might be going wrong in your system.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: push
|
||||
|
@ -141,7 +141,7 @@ Retrieves the value of the object at ``index`` in the stack, but does so safely.
|
|||
template <typename... Args>
|
||||
int multi_push( lua_State* L, Args&&... args )
|
||||
|
||||
Based on how it is called, pushes a variable amount of objects onto the stack. in 99% of cases, returns for 1 object pushed onto the stack. For the case of a ``std::tuple<...>``, it recursively pushes each object contained inside the tuple, from left to right, resulting in a variable number of things pushed onto the stack (this enables multi-valued returns when binding a C++ function to a Lua). Can be called with ``sol::stack::push<T>( L, args... )`` to have arguments different from the type that wants to be pushed, or ``sol::stack::push( L, arg, args... )`` where ``T`` will be inferred from ``arg``. The final form of this function is ``sol::stack::multi_push``, which will call one ``sol::stack::push`` for each argument. The ``T`` that describes what to push is first sanitized by removing top-level ``const`` qualifiers and reference qualifiers before being forwarded to the extension point :ref:`stack::pusher\<T><pusher>` struct.
|
||||
Based on how it is called, pushes a variable amount of objects onto the stack. in 99% of cases, returns for 1 object pushed onto the stack. For the case of a ``std::tuple<...>``, it recursively pushes each object contained inside the tuple, from left to right, resulting in a variable number of things pushed onto the stack (this enables multi-valued returns when binding a C++ function to a Lua). Can be called with ``sol::stack::push<T>( L, args... )`` to have arguments different from the type that wants to be pushed, or ``sol::stack::push( L, arg, args... )`` where ``T`` will be inferred from ``arg``. The final form of this function is ``sol::stack::multi_push``, which will call one ``sol::stack::push`` for each argument. The ``T`` that describes what to push is first sanitized by removing top-level ``const`` qualifiers and reference qualifiers before being forwarded to the extension point :ref:`sol_lua_push\<T><sol_lua_push>`.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: push_reference
|
||||
|
@ -216,85 +216,81 @@ This function leaves the retrieved value on the stack.
|
|||
objects (extension points)
|
||||
--------------------------
|
||||
|
||||
You can customize the way Sol handles different structures and classes by following the information provided in the :doc:`adding your own types<../tutorial/customization>`.
|
||||
You can customize the way sol handles different structures and classes by following the information provided in the :doc:`adding your own types<../tutorial/customization>`.
|
||||
|
||||
Below is more extensive information for the curious.
|
||||
|
||||
The structs below are already overriden for a handful of types. If you try to mess with them for the types ``sol`` has already overriden them for, you're in for a world of thick template error traces and headaches. Overriding them for your own user defined types should be just fine, however.
|
||||
.. code-block:: cpp
|
||||
:caption: ADL Extension Point sol_lua_get
|
||||
:name: sol_lua_get
|
||||
|
||||
MyType sol_lua_get ( sol::types<MyType>, lua_State* L, int index, sol::stack::record& tracking ) {
|
||||
// do work
|
||||
// ...
|
||||
|
||||
return MyType{}; // return value
|
||||
}
|
||||
|
||||
This extension point is to ``get`` an object (or reference or pointer or whatever) of type ``T``, or something convertible to it. The default internal getter implementation assumes ``T`` is a usertype and pulls out a userdata from Lua before attempting to cast it to the desired ``T``.
|
||||
|
||||
Interally, there are implementations for getting numbers (``std::is_floating``, ``std::is_integral``-matching types), getting ``std::string`` and ``const char*`` plus wide string and unicode variants, getting raw userdata with :doc:`userdata_value<types>` and anything as upvalues with :doc:`upvalue_index<types>`, getting raw `lua_CFunction`_ s, and finally pulling out Lua functions into ``std::function<R(Args...)>``. It is also defined for anything that derives from :doc:`sol::reference<reference>`. It also has a special implementation for the 2 standard library smart pointers (see :doc:`usertype memory<usertype_memory>`) that can be more specifically extended.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: struct: getter
|
||||
:name: getter
|
||||
:caption: ADL Extension Point sol_lua_push
|
||||
:name: sol_lua_push
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct getter {
|
||||
static T get (lua_State* L, int index, record& tracking) {
|
||||
// ...
|
||||
return // T, or something related to T.
|
||||
}
|
||||
};
|
||||
int push ( sol::types<MyType>, lua_State* L, MyType&& value ) {
|
||||
// can optionally take more than just 1 argument
|
||||
// to "construct" in-place and similar
|
||||
// use them however you like!
|
||||
// ...
|
||||
return N; // number of things pushed onto the stack
|
||||
}
|
||||
|
||||
This is an SFINAE-friendly struct that is meant to expose static function ``get`` that returns a ``T``, or something convertible to it. The default implementation assumes ``T`` is a usertype and pulls out a userdata from Lua before attempting to cast it to the desired ``T``. There are implementations for getting numbers (``std::is_floating``, ``std::is_integral``-matching types), getting ``std::string`` and ``const char*``, getting raw userdata with :doc:`userdata_value<types>` and anything as upvalues with :doc:`upvalue_index<types>`, getting raw `lua_CFunction`_ s, and finally pulling out Lua functions into ``std::function<R(Args...)>``. It is also defined for anything that derives from :doc:`sol::reference<reference>`. It also has a special implementation for the 2 standard library smart pointers (see :doc:`usertype memory<usertype_memory>`).
|
||||
|
||||
This extension point is to ``push`` a value into Lua. It returns the number of things pushed onto the stack. The default implementation assumes ``T`` is a usertype and pushes a userdata into Lua with a class-specific, state-wide metatable associated with it. There are implementations for pushing numbers (``std::is_floating``, ``std::is_integral``-matching types), getting ``std::string`` and ``const char*``, getting raw userdata with :doc:`userdata<types>` and raw upvalues with :doc:`upvalue<types>`, getting raw `lua_CFunction`_ s, and finally pulling out Lua functions into ``sol::function``. It is also defined for anything that derives from :doc:`sol::reference<reference>`. It also has a special implementation for the 2 standard library smart pointers (see :doc:`usertype memory<usertype_memory>`).
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: struct: pusher
|
||||
:name: pusher
|
||||
:caption: ADL Extension Point sol_lua_check
|
||||
:name: sol_lua_check
|
||||
|
||||
template <typename X, typename = void>
|
||||
struct unqualified_pusher {
|
||||
template <typename T>
|
||||
static int push ( lua_State* L, T&&, ... ) {
|
||||
// can optionally take more than just 1 argument
|
||||
// ...
|
||||
return // number of things pushed onto the stack
|
||||
template <typename Handler>
|
||||
bool sol_lua_check ( sol::types<MyType>, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking ) {
|
||||
// if the object in the Lua stack at index is a T, return true
|
||||
if ( ... ) {
|
||||
tracking.use(1); // or however many you use
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// otherwise, call the handler function,
|
||||
// with the required 4/5 arguments, then return false
|
||||
//
|
||||
handler(L, index, expected, indextype, "message");
|
||||
return false;
|
||||
}
|
||||
|
||||
This is an SFINAE-friendly struct that is meant to expose static function ``push`` that returns the number of things pushed onto the stack. The default implementation assumes ``T`` is a usertype and pushes a userdata into Lua with a class-specific, state-wide metatable associated with it. There are implementations for pushing numbers (``std::is_floating``, ``std::is_integral``-matching types), getting ``std::string`` and ``const char*``, getting raw userdata with :doc:`userdata<types>` and raw upvalues with :doc:`upvalue<types>`, getting raw `lua_CFunction`_ s, and finally pulling out Lua functions into ``sol::function``. It is also defined for anything that derives from :doc:`sol::reference<reference>`. It also has a special implementation for the 2 standard library smart pointers (see :doc:`usertype memory<usertype_memory>`).
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: struct: checker
|
||||
:name: checker
|
||||
This extension point is to ``check`` whether or not a type at a given index is what its supposed to be. The default implementation simply checks whether the expected type passed in through the template is equal to the type of the object at the specified index in the Lua stack. The default implementation for types which are considered ``userdata`` go through a myriad of checks to support checking if a type is *actually* of type ``T`` or if its the base class of what it actually stored as a userdata in that index.
|
||||
|
||||
template <typename T, type expected = lua_type_of<T>, typename = void>
|
||||
struct checker {
|
||||
template <typename Handler>
|
||||
static bool check ( lua_State* L, int index, Handler&& handler, record& tracking ) {
|
||||
// if the object in the Lua stack at index is a T, return true
|
||||
if ( ... ) {
|
||||
tracking.use(1); // or however many you use
|
||||
return true;
|
||||
}
|
||||
// otherwise, call the handler function,
|
||||
// with the required 4/5 arguments, then return false
|
||||
//
|
||||
handler(L, index, expected, indextype, "optional message");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
This is an SFINAE-friendly struct that is meant to expose static function ``check`` that returns whether or not a type at a given index is what its supposed to be. The default implementation simply checks whether the expected type passed in through the template is equal to the type of the object at the specified index in the Lua stack. The default implementation for types which are considered ``userdata`` go through a myriad of checks to support checking if a type is *actually* of type ``T`` or if its the base class of what it actually stored as a userdata in that index. Down-casting from a base class to a more derived type is, unfortunately, impossible to do.
|
||||
Note that you may
|
||||
|
||||
.. _userdata-interop:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: struct: userdata_checker
|
||||
:name: userdata_checker
|
||||
:caption: ADL Extension Point sol_lua_interop_check
|
||||
:name: sol_lua_interop_check
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct userdata_checker {
|
||||
template <typename Handler>
|
||||
static bool check ( lua_State* L, int index, type indextype, Handler&& handler, record& tracking ) {
|
||||
// implement custom checking here for a userdata:
|
||||
// if it doesn't match, return "false" and regular
|
||||
// sol userdata checks will kick in
|
||||
return false;
|
||||
// returning true will skip sol's
|
||||
// default checks
|
||||
}
|
||||
};
|
||||
template <typename T, typename Handler>
|
||||
bool sol_lua_interop_check(sol::types<T>, lua_State* L, int relindex, sol::type index_type, Handler&& handler, sol::stack::record& tracking) {
|
||||
// implement custom checking here for a userdata:
|
||||
// if it doesn't match, return "false" and regular
|
||||
// sol userdata checks will kick in
|
||||
return false;
|
||||
// returning true will skip sol's
|
||||
// default checks
|
||||
}
|
||||
|
||||
This is an SFINAE-friendly struct that is meant to expose a function ``check=`` that returns ``true`` if a type meets some custom userdata specifiction, and ``false`` if it does not. The default implementation just returns ``false`` to let the original sol3 handlers take care of everything. If you want to implement your own usertype checking; e.g., for messing with ``toLua`` or ``OOLua`` or ``kaguya`` or some other libraries. Note that the library must have a with a :doc:`memory compatible layout<usertype_memory>` if you **want to specialize this checker method but not the subsequent getter method**. You can specialize it as shown in the `interop examples`_.
|
||||
|
||||
This extension point is to ``check`` a foreign userdata. It should return ``true`` if a type meets some custom userdata specifiction (from, say, another library or an internal framework), and ``false`` if it does not. The default implementation just returns ``false`` to let the original sol3 handlers take care of everything. If you want to implement your own usertype checking; e.g., for messing with ``toLua`` or ``OOLua`` or ``kaguya`` or some other libraries. Note that the library must have a with a :doc:`memory compatible layout<usertype_memory>` if you **want to specialize this checker method but not the subsequent getter method**. You can specialize it as shown in the `interop examples`_.
|
||||
|
||||
.. note::
|
||||
|
||||
|
@ -302,31 +298,30 @@ This is an SFINAE-friendly struct that is meant to expose a function ``check=``
|
|||
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: struct: userdata_getter
|
||||
:name: userdata_getter
|
||||
:caption: ADL Extension Point sol_lua_interop_get
|
||||
:name: sol_lua_interop_get
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct userdata_getter {
|
||||
static std::pair<bool, T*> get ( lua_State* L, int index, void* unadjusted_pointer, record& tracking ) {
|
||||
// implement custom getting here for non-sol3 userdatas:
|
||||
// if it doesn't match, return "false" and regular
|
||||
// sol userdata checks will kick in
|
||||
return { false, nullptr };
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
std::pair<bool, T*> sol_lua_interop_get(sol::types<T> t, lua_State* L, int relindex, void* unadjusted_pointer, sol::stack::record& tracking) {
|
||||
// implement custom getting here for non-sol3 userdatas:
|
||||
// if it doesn't match, return "false" and regular
|
||||
// sol userdata getters will kick in
|
||||
return { false, nullptr };
|
||||
}
|
||||
|
||||
This is an SFINAE-friendly struct that is meant to expose a function ``get`` that returns ``true`` and an adjusted pointer if a type meets some custom userdata specifiction (from, say, another library or an internal framework). The default implementation just returns ``{ false, nullptr }`` to let the original sol3 getter take care of everything. If you want to implement your own usertype getter; e.g., for messing with ``kaguya`` or some other libraries. You can specialize it as shown in the `interop examples`_.
|
||||
|
||||
.. note::
|
||||
|
||||
You do NOT need to use this method in particular if the :doc:`memory layout<usertype_memory>` is compatible. (For example, ``toLua`` stores userdata in a sol3-compatible way.)
|
||||
|
||||
This extension point is to ``get`` a foreign userdata. It should return both ``true`` and an adjusted pointer if a type meets some custom userdata specifiction (from, say, another library or an internal framework). The default implementation just returns ``{ false, nullptr }`` to let the default sol3 implementation take care of everything. You can use it to interop with other frameworks that are not sol3 but still include their power; e.g., for messing with ``kaguya`` or some other libraries. You can specialize it as shown in the `interop examples`_.
|
||||
|
||||
.. note::
|
||||
|
||||
You must turn it on with ``SOL_ENABLE_INTEROP``, as described in the :ref:`config and safety section<config>`.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
You do NOT need to use this method in particular if the :doc:`memory layout<usertype_memory>` is compatible. (For example, ``toLua`` stores userdata in a sol3-compatible way.)
|
||||
|
||||
|
||||
.. _lua_CFunction: http://www.Lua.org/manual/5.3/manual.html#lua_CFunction
|
||||
.. _Lua stack works in general: https://www.lua.org/pil/24.2.html
|
||||
.. _calling C functions works: https://www.lua.org/pil/26.html
|
||||
|
|
|
@ -11,11 +11,15 @@ table
|
|||
typedef table_core<false> table;
|
||||
typedef table_core<true> global_table;
|
||||
|
||||
``sol::table`` is an extremely efficient manipulator of state that brings most of the magic of the Sol abstraction. Capable of doing multiple sets at once, multiple gets into a ``std::tuple``, being indexed into using ``[key]`` syntax and setting keys with a similar syntax (see: :doc:`here<proxy>`), ``sol::table`` is the corner of the interaction between Lua and C++.
|
||||
class lua_table;
|
||||
|
||||
``sol::table`` is an extremely efficient manipulator of state that brings most of the magic of the sol abstraction. Capable of doing multiple sets at once, multiple gets into a ``std::tuple``, being indexed into using ``[key]`` syntax and setting keys with a similar syntax (see: :doc:`here<proxy>`), ``sol::table`` is the corner of the interaction between Lua and C++.
|
||||
|
||||
There are two kinds of tables: the global table and non-global tables: however, both have the exact same interface and all ``sol::global_table`` s are convertible to regular ``sol::table`` s.
|
||||
|
||||
Tables are the core of Lua, and they are very much the core of Sol.
|
||||
Tables are the core of Lua, and they are very much the core of sol.
|
||||
|
||||
``sol::lua_table`` is specifically useful for specifying you want **exactly** a Lua table, and not something that can masquerade like a table (e.g., a userdata with a metatable that has overriden `__index` and `__new_index` fields).
|
||||
|
||||
|
||||
members
|
||||
|
|
9
docs/source/api/table_traversal_keys.rst
Normal file
9
docs/source/api/table_traversal_keys.rst
Normal file
|
@ -0,0 +1,9 @@
|
|||
table traversal keys
|
||||
====================
|
||||
*the definitive way to get and set things easily*
|
||||
|
||||
|
||||
Objects ``sol::update_if_empty``, ``sol::create_if_nil``, and ``sol::override_value`` are special keys one can pass into a table traversal to enable creating tables as they go in ``nil``/empty spaces, optionally updating a value at the end of a chain of lookups if it is empty, or overriding the values and tables along a chain as they go. Each special key can be used in lookup and setting functionality on tables. It is primarily to enable easy use and creation of functionality like so:
|
||||
|
||||
.. literalinclude:: ../../../examples/source/table_create_if_nil.cpp
|
||||
:linenos:
|
|
@ -8,7 +8,7 @@ Sometimes in C++ it's useful to know where a Lua call is coming from and what :d
|
|||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_ALL_SAFETIES_ON
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
|
|
@ -3,7 +3,7 @@ tie
|
|||
*improved version of std::tie*
|
||||
|
||||
|
||||
`std::tie()`_ does not work well with :doc:`sol::function<function>`'s ``sol::function_result`` returns. Use ``sol::tie`` instead. Because they're both named `tie`, you'll need to be explicit when you use Sol's by naming it with the namespace (``sol::tie``), even with a ``using namespace sol;``. Here's an example:
|
||||
`std::tie()`_ does not work well with :doc:`sol::function<function>`'s ``sol::function_result`` returns. Use ``sol::tie`` instead. Because they're both named `tie`, you'll need to be explicit when you use sol's by naming it with the namespace (``sol::tie``), even with a ``using namespace sol;``. Here's an example:
|
||||
|
||||
.. literalinclude:: ../../../examples/source/tie.cpp
|
||||
:linenos:
|
||||
|
|
|
@ -2,7 +2,7 @@ types
|
|||
=====
|
||||
*nil, lua_primitive type traits, and other fundamentals*
|
||||
|
||||
The ``types.hpp`` header contains various fundamentals and utilities of Sol.
|
||||
The ``types.hpp`` header contains various fundamentals and utilities of sol.
|
||||
|
||||
|
||||
enumerations
|
||||
|
@ -83,7 +83,7 @@ This enumeration contains the status of a load operation from :ref:`state::load(
|
|||
table | boolean | function | userdata | lightuserdata
|
||||
};
|
||||
|
||||
The base types that Lua natively communicates in and understands. Note that "poly" isn't really a true type, it's just a symbol used in Sol for something whose type hasn't been checked (and you should almost never see it).
|
||||
The base types that Lua natively communicates in and understands. Note that "poly" isn't really a true type, it's just a symbol used in sol for something whose type hasn't been checked (and you should almost never see it).
|
||||
|
||||
|
||||
type traits
|
||||
|
@ -142,7 +142,7 @@ A tag type that, when used with :doc:`stack::get\<non_null\<T*>><stack>`, does n
|
|||
template <typename... Args>
|
||||
struct types;
|
||||
|
||||
A type list that, unlike ``std::tuple<Args...>``, does not actually contain anything. Used to indicate types and groups of types all over Sol.
|
||||
A type list that, unlike ``std::tuple<Args...>``, does not actually contain anything. Used to indicate types and groups of types all over sol.
|
||||
|
||||
|
||||
functions
|
||||
|
|
|
@ -39,7 +39,7 @@ This is a customization point for users who need to *work with special kinds of
|
|||
};
|
||||
}
|
||||
|
||||
This will allow the library to properly handle ``boost::shared_ptr<T>``, with ref-counting and all. The ``type`` is the type that lua and sol will interact with, and will allow you to pull out a non-owning reference / pointer to the data when you just ask for a plain ``T*`` or ``T&`` or ``T`` using the getter functions and properties of Sol. The ``actual_type`` is just the "real type" that controls the semantics (shared, unique, ``CComPtr``, ``ComPtr``, OpenGL handles, DirectX objects, the list goes on).
|
||||
This will allow the library to properly handle ``boost::shared_ptr<T>``, with ref-counting and all. The ``type`` is the type that lua and sol will interact with, and will allow you to pull out a non-owning reference / pointer to the data when you just ask for a plain ``T*`` or ``T&`` or ``T`` using the getter functions and properties of sol. The ``actual_type`` is just the "real type" that controls the semantics (shared, unique, ``CComPtr``, ``ComPtr``, OpenGL handles, DirectX objects, the list goes on).
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
@ -7,9 +7,16 @@ usertype<T>
|
|||
|
||||
``T`` refers to the type being turned into a usertype.
|
||||
|
||||
While other frameworks extend lua's syntax or create Data Structure Languages (DSLs) to create classes in Lua, :doc:`Sol<../index>` instead offers the ability to generate easy bindings that pile on performance. You can see a `small starter example here`_. These use metatables and userdata in Lua for their implementation. Usertypes are also `runtime extensible`_.
|
||||
.. code-block:: cpp
|
||||
|
||||
There are more advanced use cases for how to create and use a usertype, which are all based on how to use its constructor (see below).
|
||||
class metatable : public table;
|
||||
|
||||
template <typename T>
|
||||
class usertype : public metatable;
|
||||
|
||||
While other frameworks extend lua's syntax or create Data Structure Languages (DSLs) to create classes in Lua, :doc:`sol<../index>` instead offers the ability to generate easy bindings that pile on performance. You can see a `small starter example here`_. These use metatables and userdata in Lua for their implementation. Usertypes are also `runtime extensible`_.
|
||||
|
||||
There are more advanced use cases for how to create and use a usertype, which are all based on how to use its `.set()` function and its initial construction (see below).
|
||||
|
||||
enumerations
|
||||
------------
|
||||
|
@ -55,31 +62,55 @@ enumerations
|
|||
next,
|
||||
type,
|
||||
type_info,
|
||||
call_construct,
|
||||
storage,
|
||||
gc_names,
|
||||
static_index,
|
||||
static_new_index,
|
||||
};
|
||||
|
||||
typedef meta_function meta_method;
|
||||
|
||||
|
||||
Use this enumeration to specify names in a manner friendlier than memorizing the special lua metamethod names for each of these. Each binds to a specific operation indicated by the descriptive name of the enum. You can read more about `the metamethods in the Lua manual`_ and learn about how they work and are supposed to be implemented there. Each of the names here (except for the ones used as shortcuts to other names like ``meta_function::call_function`` and ``meta_function::involution`` and not including ``construct``, which just maps to the name ``new``) link directly to the Lua name for the operation. ``meta_function::pairs`` is only available in Lua 5.2 and above (does not include LuaJIT or Lua 5.1) and ``meta_function::ipairs`` is only available in Lua 5.2 exactly (disregarding compatibiltiy flags).
|
||||
|
||||
members
|
||||
Some are also sol2 specific, for example ``meta_function::type_info``, ``meta_function::call_construct``, ``meta_function::static_index`` and ``meta_function::static_new_index`` are sol2-specific and usable by users. The entries ``meta_function::storage`` and ``meta_function::gc_names`` are sol2-internal but still in the enumeration; **please** do not use them.
|
||||
|
||||
``meta_function::index`` and ``meta_function::new_index`` apply strictly to when an object in Lua is called with a key *it does not already know* (e.g., was not bound by the C++ programmer with ``.set(...)`` or ``.new_usertype<...>(...);``. ``meta_function::static_index`` and `meta_function::static_new_index`` functions get called when the the key is not found and the user is calling the new function from the named metatable itself.
|
||||
|
||||
structs
|
||||
-------
|
||||
|
||||
.. _automagic_enrollments:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: usertype<T> constructor
|
||||
:name: usertype-constructor
|
||||
:caption: automagic_enrollments for special members defined on a class
|
||||
:linenos:
|
||||
|
||||
template<typename... Args>
|
||||
usertype<T>(Args&&... args);
|
||||
struct automagic_enrollments {
|
||||
bool default_constructor = true;
|
||||
bool destructor = true;
|
||||
bool pairs_operator = true;
|
||||
bool to_string_operator = true;
|
||||
bool call_operator = true;
|
||||
bool less_than_operator = true;
|
||||
bool less_than_or_equal_to_operator = true;
|
||||
bool length_operator = true;
|
||||
bool equal_to_operator = true;
|
||||
};
|
||||
|
||||
This structure is used with ``new_usertype`` to specifically ordain certain special member functions to be bound to Lua, whether it is capable of them or not.
|
||||
|
||||
|
||||
The constructor of usertype takes a variable number of arguments. It takes an even number of arguments (except in the case where the very first argument is passed as the :ref:`constructor list type<constructor>`). Names can either be strings, :ref:`special meta_function enumerations<meta_function_enum>`, or one of the special indicators for initializers.
|
||||
new_usertype/set
|
||||
----------------
|
||||
|
||||
``sol::usertype<T>`` is a specialized version of ``sol::metatable``s, which are a specialized version of ``sol::table``. ``sol::metatable``s attempt to treat the table like either a Lua or a sol2 metatable. ``sol::usertype<T>`` demands that a usertype is a specific metatable for a specific class. Both of them are `sol::reference derived types<reference>`, meaning they take in the ``lua_State*``. For example...
|
||||
|
||||
|
||||
usertype constructor options
|
||||
++++++++++++++++++++++++++++
|
||||
new_usertype/set options
|
||||
++++++++++++++++++++++++
|
||||
|
||||
If you don't specify any constructor options at all and the type is `default_constructible`_, Sol will generate a ``new`` for you. Otherwise, the following are special ways to handle the construction of a usertype:
|
||||
If the type is `default_constructible`_, sol will generate a ``"new"`` member on the usertype for you. Otherwise, use ``my_table.new_usertype<MyType>("name", sol::no_constructor);`` to prevent the constructor or pass in a ``sol::automagic_enrollments enrollments; /* modify members here */;`` when calling ``.new_usertype<MyType>("name", enrollments);``. Otherwise, the following are special ways to handle the construction of a usertype:
|
||||
|
||||
.. _constructor:
|
||||
|
||||
|
@ -108,7 +139,11 @@ If you don't specify any constructor options at all and the type is `default_con
|
|||
- This is compatible with luabind, kaguya and other Lua library syntaxes and looks similar to C++ syntax, but the general consensus in Programming with Lua and other places is to use a function named ``new``
|
||||
- Note that with the ``sol::call_constructor`` key, a construct type above must be specified. A free function without it will pass in the metatable describing this object as the first argument without that distinction, which can cause strange runtime errors.
|
||||
* ``{anything}, sol::no_constructor``
|
||||
- Specifically tells Sol not to create a ``.new()`` if one is not specified and the type is default-constructible
|
||||
- Specifically tells sol not to create a ``.new()`` if one is not specified and the type is default-constructible
|
||||
- When the key ``{anything}`` is called on the table, it will result in an error. The error might be that the type is not-constructible.
|
||||
- *Use this plus some of the above to allow a factory function for your function type but prevent other types of constructor idioms in Lua*
|
||||
* ``{anything}, sol::no_constructor``
|
||||
- Specifically tells sol not to create a ``.new()`` if one is not specified and the type is default-constructible
|
||||
- When the key ``{anything}`` is called on the table, it will result in an error. The error might be that the type is not-constructible.
|
||||
- *Use this plus some of the above to allow a factory function for your function type but prevent other types of constructor idioms in Lua*
|
||||
|
||||
|
@ -129,8 +164,8 @@ If you don't specify anything at all and the type is `destructible`_, then a des
|
|||
|
||||
.. _automagical-registration:
|
||||
|
||||
usertype automatic meta functions
|
||||
+++++++++++++++++++++++++++++++++
|
||||
usertype automatic (automagic) meta functions
|
||||
+++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
If you don't specify a ``sol::meta_function`` name (or equivalent string metamethod name) and the type ``T`` supports certain operations, sol3 will generate the following operations provided it can find a good default implementation:
|
||||
|
||||
|
@ -194,6 +229,11 @@ Otherwise, the following is used to specify functions to bind on the specific us
|
|||
- Tells a usertype what its base classes are. You need this to have derived-to-base conversions work properly. See :ref:`inheritance<usertype-inheritance>`
|
||||
|
||||
|
||||
unregister
|
||||
----------
|
||||
|
||||
You can unlink and kill a usertype and its associated functionality by calling ``.unregister()`` on a ``sol::usertype<T>`` or ``sol::metatable`` pointed at a proper sol3 metatable. This will entirely unlink and clean out sol3's internal lookup structures and key information.
|
||||
|
||||
runtime functions
|
||||
-----------------
|
||||
|
||||
|
@ -220,7 +260,7 @@ Functions set on a usertype support overloading. See :doc:`here<overload>` for a
|
|||
inheritance
|
||||
-----------
|
||||
|
||||
Sol can adjust pointers from derived classes to base classes at runtime, but it has some caveats based on what you compile with:
|
||||
sol can adjust pointers from derived classes to base classes at runtime, but it has some caveats based on what you compile with:
|
||||
|
||||
If your class has no complicated™ virtual inheritance or multiple inheritance, than you can try to sneak away with a performance boost from not specifying any base classes and doing any casting checks. (What does "complicated™" mean? Ask your compiler's documentation, if you're in that deep.)
|
||||
|
||||
|
@ -230,7 +270,7 @@ Register the base classes explicitly.
|
|||
|
||||
.. note::
|
||||
|
||||
Always specify your bases if you plan to retrieve a base class using the Sol abstraction directly and not casting yourself.
|
||||
Always specify your bases if you plan to retrieve a base class using the sol abstraction directly and not casting yourself.
|
||||
|
||||
.. literalinclude:: ../../../examples/source/docs/inheritance.cpp
|
||||
:caption: inheritance.cpp
|
||||
|
@ -240,15 +280,15 @@ Register the base classes explicitly.
|
|||
|
||||
.. note::
|
||||
|
||||
You must list ALL base classes, including (if there were any) the base classes of A, and the base classes of those base classes, etc. if you want Sol/Lua to handle them automagically.
|
||||
You must list ALL base classes, including (if there were any) the base classes of A, and the base classes of those base classes, etc. if you want sol/Lua to handle them automagically.
|
||||
|
||||
.. note::
|
||||
|
||||
Sol does not support down-casting from a base class to a derived class at runtime.
|
||||
sol does not support down-casting from a base class to a derived class at runtime.
|
||||
|
||||
.. warning::
|
||||
|
||||
Specify all base class member variables and member functions to avoid current implementation caveats regarding automatic base member lookup. Sol currently attempts to link base class methods and variables with their derived classes with an undocumented, unsupported feature, provided you specify ``sol::bases<...>``. Unfortunately, this can come at the cost of performance, depending on how "far" the base is from the derived class in the bases lookup list. If you do not want to suffer the performance degradation while we iron out the kinks in the implementation (and want it to stay performant forever), please specify all the base methods on the derived class in the method listing you write. In the future, we hope that with reflection we will not have to worry about this.
|
||||
Specify all base class member variables and member functions to avoid current implementation caveats regarding automatic base member lookup. sol currently attempts to link base class methods and variables with their derived classes with an undocumented, unsupported feature, provided you specify ``sol::bases<...>``. Unfortunately, this can come at the cost of performance, depending on how "far" the base is from the derived class in the bases lookup list. If you do not want to suffer the performance degradation while we iron out the kinks in the implementation (and want it to stay performant forever), please specify all the base methods on the derived class in the method listing you write. In the future, we hope that with reflection we will not have to worry about this.
|
||||
|
||||
.. _automagical:
|
||||
|
||||
|
@ -269,7 +309,7 @@ Usertypes automatically register special functions, whether or not they're bound
|
|||
inheritance + overloading
|
||||
-------------------------
|
||||
|
||||
While overloading is supported regardless of inheritance caveats or not, the current version of Sol has a first-match, first-call style of overloading when it comes to inheritance. Put the functions with the most derived arguments first to get the kind of matching you expect or cast inside of an intermediary C++ function and call the function you desire.
|
||||
While overloading is supported regardless of inheritance caveats or not, the current version of sol has a first-match, first-call style of overloading when it comes to inheritance. Put the functions with the most derived arguments first to get the kind of matching you expect or cast inside of an intermediary C++ function and call the function you desire.
|
||||
|
||||
compilation speed
|
||||
-----------------
|
||||
|
@ -283,7 +323,7 @@ performance note
|
|||
|
||||
.. note::
|
||||
|
||||
Note that performance for member function calls goes down by a fixed overhead if you also bind variables as well as member functions. This is purely a limitation of the Lua implementation and there is, unfortunately, nothing that can be done about it. If you bind only functions and no variables, however, Sol will automatically optimize the Lua runtime and give you the maximum performance possible. *Please consider ease of use and maintenance of code before you make everything into functions.*
|
||||
Note that performance for member function calls goes down by a fixed overhead if you also bind variables as well as member functions. This is purely a limitation of the Lua implementation and there is, unfortunately, nothing that can be done about it. If you bind only functions and no variables, however, sol will automatically optimize the Lua runtime and give you the maximum performance possible. *Please consider ease of use and maintenance of code before you make everything into functions.*
|
||||
|
||||
.. _destructible: http://en.cppreference.com/w/cpp/types/is_destructible
|
||||
.. _default_constructible: http://en.cppreference.com/w/cpp/types/is_constructible
|
||||
|
|
|
@ -4,9 +4,9 @@ usertype memory
|
|||
|
||||
.. note::
|
||||
|
||||
Sol does not take ownership of raw pointers, returned from functions or set through the ``set`` functions. Return a value, a ``std::unique_ptr``, a ``std::shared_ptr`` of some kind, or hook up the :doc:`unique usertypes traits<unique_usertype_traits>` to work for some specific handle structure you use (AKA, for ``boost::shared_ptr``).
|
||||
sol does not take ownership of raw pointers, returned from functions or set through the ``set`` functions. Return a value, a ``std::unique_ptr``, a ``std::shared_ptr`` of some kind, or hook up the :doc:`unique usertypes traits<unique_usertype_traits>` to work for some specific handle structure you use (AKA, for ``boost::shared_ptr``).
|
||||
|
||||
The userdata generated by Sol has a specific layout, depending on how Sol recognizes userdata passed into it. All of the referred to metatable names are generated from the name of the class itself. Note that we use 1 metatable per the 3 styles listed below, plus 1 additional metatable that is used for the actual table that you bind with the name when calling ``table::new/set_(simple_)usertype``.
|
||||
The userdata generated by sol has a specific layout, depending on how sol recognizes userdata passed into it. All of the referred to metatable names are generated from the name of the class itself. Note that we use 1 metatable per the 3 styles listed below, plus 1 additional metatable that is used for the actual table that you bind with the name when calling ``table::new/set_(simple_)usertype``.
|
||||
|
||||
In general, we always insert a ``T*`` in the first ``sizeof(T*)`` bytes, so the any framework that pulls out those first bytes expecting a pointer will work. The rest of the data has some different alignments and contents based on what it's used for and how it's used.
|
||||
|
||||
|
@ -41,7 +41,7 @@ Lua will clean up the memory itself but does not know about any destruction sema
|
|||
For ``T*``
|
||||
----------
|
||||
|
||||
These are classified as a separate ``T*`` metatable, essentially the "reference" table. Things passed to Sol as a pointer or as a ``std::reference<T>`` are considered to be references, and thusly do not have a ``__gc`` (garbage collection) method by default. All raw pointers are non-owning pointers in C++. If you're working with a C API, provide a wrapper around pointers that are supposed to own data and use the constructor/destructor idioms (e.g., with an internal ``std::unique_ptr``) to keep things clean.
|
||||
These are classified as a separate ``T*`` metatable, essentially the "reference" table. Things passed to sol as a pointer or as a ``std::reference<T>`` are considered to be references, and thusly do not have a ``__gc`` (garbage collection) method by default. All raw pointers are non-owning pointers in C++. If you're working with a C API, provide a wrapper around pointers that are supposed to own data and use the constructor/destructor idioms (e.g., with an internal ``std::unique_ptr``) to keep things clean.
|
||||
|
||||
The data layout for data that only refers is as follows::
|
||||
|
||||
|
@ -60,4 +60,4 @@ The data layout for these kinds of types is as follows::
|
|||
| T* | void(*)(void*) function_pointer | T |
|
||||
^-sizeof(T*) bytes-^-sizeof(void(*)(void*)) bytes, deleter-^- sizeof(T) bytes, actal data -^
|
||||
|
||||
Note that we put a special deleter function before the actual data. This is because the custom deleter must know where the offset to the data is and where the special deleter is. In other words, fixed-size-fields come before any variably-sized data (T can be known at compile time, but when serialized into Lua in this manner it becomes a runtime entity). Sol just needs to know about ``T*`` and the userdata (and userdata metatable) to work, everything else is for preserving construction / destruction semantics.
|
||||
Note that we put a special deleter function before the actual data. This is because the custom deleter must know where the offset to the data is and where the special deleter is. In other words, fixed-size-fields come before any variably-sized data (T can be known at compile time, but when serialized into Lua in this manner it becomes a runtime entity). sol just needs to know about ``T*`` and the userdata (and userdata metatable) to work, everything else is for preserving construction / destruction semantics.
|
|
@ -90,7 +90,7 @@ Here are some notes on achieving better compile times without sacrificing too mu
|
|||
next steps
|
||||
----------
|
||||
|
||||
The next step for Sol from a developer standpoint is to formally make the library a C++17 one. This would mean using Fold Expressions and several other things which will reduce compilation time drastically. Unfortunately, that means also boosting compiler requirements. While most wouldn't care, others are very slow to upgrade: finding the balance is difficult, and often we have to opt for backwards compatibility and fixes for bad / older compilers (of which there are many in the codebase already).
|
||||
The next step for sol from a developer standpoint is to formally make the library a C++17 one. This would mean using Fold Expressions and several other things which will reduce compilation time drastically. Unfortunately, that means also boosting compiler requirements. While most wouldn't care, others are very slow to upgrade: finding the balance is difficult, and often we have to opt for backwards compatibility and fixes for bad / older compilers (of which there are many in the codebase already).
|
||||
|
||||
Hopefully, as things progress, we move things forward.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Sol documentation build configuration file, created by
|
||||
# sol documentation build configuration file, created by
|
||||
# sphinx-quickstart on Mon Feb 29 21:49:51 2016.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
|
@ -46,7 +46,7 @@ source_suffix = '.rst'
|
|||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'Sol'
|
||||
project = 'sol'
|
||||
copyright = '2019, ThePhD'
|
||||
author = 'ThePhD'
|
||||
|
||||
|
@ -226,7 +226,7 @@ latex_elements = {
|
|||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'Sol.tex', 'Sol Documentation', 'ThePhD', 'manual'),
|
||||
(master_doc, 'sol.tex', 'sol Documentation', 'ThePhD', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
|
@ -253,7 +253,7 @@ latex_documents = [
|
|||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [(master_doc, 'sol', 'Sol Documentation', [author], 1)]
|
||||
man_pages = [(master_doc, 'sol', 'sol Documentation', [author], 1)]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
@ -264,7 +264,7 @@ man_pages = [(master_doc, 'sol', 'Sol Documentation', [author], 1)]
|
|||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'Sol', 'Sol Documentation', author, 'Sol',
|
||||
(master_doc, 'sol', 'sol Documentation', author, 'sol',
|
||||
'One line description of project.', 'Miscellaneous'),
|
||||
]
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ Containers are objects that are meant to be inspected and iterated and whose job
|
|||
- If you need tables, consider using ``sol::as_table`` and ``sol::nested``
|
||||
- See `this table serialization example`_ for more details
|
||||
* Lua 5.1 has different semantics for ``pairs`` and ``ipairs``: be wary. See :ref:`examples down below<containers-pairs-example>` for more details
|
||||
* You can override container behavior by overriding :ref:`the detection trait<container-detection>` and :ref:`specializing the container_traits template<container-traits>`
|
||||
* You can override container behavior by overriding :ref:`the detection trait<container-detection>` and :ref:`specializing the usertype_container template<usertype-container>`
|
||||
* You can bind typical C-style arrays, but must follow :ref:`the rules<container-c-array>`
|
||||
|
||||
.. _container-c-array:
|
||||
|
@ -27,7 +27,7 @@ Containers are objects that are meant to be inspected and iterated and whose job
|
|||
container detection
|
||||
-------------------
|
||||
|
||||
containers are detected by the type trait ``sol::is_container<T>``. If that turns out to be true, sol3 will attempt to push a userdata into Lua for the specified type ``T``, and bestow it with some of the functions and properties listed below. These functions and properties are provided by a template struct ``sol::container_traits<T>``, which has a number of static Lua C functions bound to a safety metatable. If you want to override the behavior for a specific container, you must first specialize ``sol::is_container<T>`` to drive from ``std::true_type``, then override the functions you want to change. Any function you do not override will call the default implementation or equivalent. The default implementation for unrecognized containers is simply errors.
|
||||
containers are detected by the type trait ``sol::is_container<T>``. If that turns out to be true, sol3 will attempt to push a userdata into Lua for the specified type ``T``, and bestow it with some of the functions and properties listed below. These functions and properties are provided by a template struct ``sol::usertype_container<T>``, which has a number of static Lua C functions bound to a safety metatable. If you want to override the behavior for a specific container, you must first specialize ``sol::is_container<T>`` to drive from ``std::true_type``, then override the functions you want to change. Any function you do not override will call the default implementation or equivalent. The default implementation for unrecognized containers is simply errors.
|
||||
|
||||
You can also specialize ``sol::is_container<T>`` to turn off container detection, if you find it too eager for a type that just happens to have ``begin`` and ``end`` functions, like so:
|
||||
|
||||
|
@ -56,7 +56,7 @@ This will let the type be pushed as a regular userdata.
|
|||
Pushing a new :doc:`usertype<api/usertype>` will prevent a qualifying C++ container type from being treated like a container. To force a type that you've registered/bound as a usertype using ``new_usertype`` or ``new_simple_usertype`` to be treated like a container, use :doc:`sol::as_container<api/as_container>`.
|
||||
|
||||
|
||||
.. _container-traits:
|
||||
.. _usertype-container:
|
||||
|
||||
container overriding
|
||||
--------------------
|
||||
|
@ -75,7 +75,7 @@ If you need a type whose declaration and definition you do not have control over
|
|||
struct is_container<not_my_type> : std::true_type {};
|
||||
|
||||
template <>
|
||||
struct container_traits<not_my_type> {
|
||||
struct usertype_container<not_my_type> {
|
||||
|
||||
...
|
||||
// see below for implemetation details
|
||||
|
@ -83,7 +83,7 @@ If you need a type whose declaration and definition you do not have control over
|
|||
}
|
||||
|
||||
|
||||
The various operations provided by ``container_traits<T>`` are expected to be like so, below. Ability to override them requires familiarity with the Lua stack and how it operates, as well as knowledge of Lua's :ref:`raw C functions<raw-function-note>`. You can read up on raw C functions by looking at the "Programming in Lua" book. The `online version's information`_ about the stack and how to return information is still relevant, and you can combine that by also using sol's low-level :doc:`stack API<api/stack>` to achieve whatever behavior you need.
|
||||
The various operations provided by ``usertype_container<T>`` are expected to be like so, below. Ability to override them requires familiarity with the Lua stack and how it operates, as well as knowledge of Lua's :ref:`raw C functions<raw-function-note>`. You can read up on raw C functions by looking at the "Programming in Lua" book. The `online version's information`_ about the stack and how to return information is still relevant, and you can combine that by also using sol's low-level :doc:`stack API<api/stack>` to achieve whatever behavior you need.
|
||||
|
||||
.. warning::
|
||||
|
||||
|
@ -94,29 +94,29 @@ The various operations provided by ``container_traits<T>`` are expected to be li
|
|||
container operations
|
||||
-------------------------
|
||||
|
||||
Below are the many container operations and their override points for ``container_traits<T>``. Please use these to understand how to use any part of the implementation.
|
||||
Below are the many container operations and their override points for ``usertype_container<T>``. Please use these to understand how to use any part of the implementation.
|
||||
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| operation | lua syntax | container_traits<T> | stack argument order | notes/caveats |
|
||||
| operation | lua syntax | usertype_container<T> | stack argument order | notes/caveats |
|
||||
| | | extension point | | |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| set | ``c:set(key, value)`` | ``static int set(lua_State*);`` | 1 self | - if ``value`` is nil, it performs an erase in default implementation |
|
||||
| | | | 2 key | - if this is a sequence container and it support insertion and ``key``,is an index equal to the size of the container,+ 1, it will insert at,the end of the container (this is a Lua idiom) |
|
||||
| | | | 3 value | |
|
||||
| | | | 2 key | - if this is a container that supports insertion and``key`` is an index equal to the (size of the container) + 1, it will insert the value at the end of the container (this is a Lua idiom) |
|
||||
| | | | 3 value | - default implementation uses ``.insert`` or `operator[]` for c arrays |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| index_set | ``c[key] = value`` | ``static int index_set(lua_State*);`` | 1 self | - default implementation calls "set" |
|
||||
| index_set | ``c[key] = value`` | ``static int index_set(lua_State*);`` | 1 self | - default implementation defers work to "set" |
|
||||
| | | | 2 key | - if this is a sequence container and it support insertion and ``key`` is an index equal to the size of the container + 1, it will insert at the end of the container (this is a Lua idiom) |
|
||||
| | | | 3 value | |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| at | ``v = c:at(key)`` | ``static int at(lua_State*);`` | 1 self | - can return multiple values |
|
||||
| | | | 2 index | - default implementation increments iterators linearly for non-random-access |
|
||||
| | | | 2 index | - default implementation increments iterators linearly for non-random-access; uses ``.find()`` if available |
|
||||
| | | | | - if the type does not have random-access iterators, **do not use this in a for loop** ! |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| get | ``v = c:get(key)`` | ``static int get(lua_State*);`` | 1 self | - can return multiple values |
|
||||
| | | | 2 key | - default implementation increments iterators linearly for non-random-access |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| index_get | ``v = c[key]`` | ``static int index_get(lua_State*);`` | 1 self | - can only return 1 value |
|
||||
| | | | 2 key | - default implementation just calls "get" |
|
||||
| | | | 2 key | - default implementation defers work to "get" |
|
||||
| | | | | - if ``key`` is a string and ``key`` is one of the other member functions, it will return that member function rather than perform a lookup / index get |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| find | ``c:find(target)`` | ``static int find(lua_State*);`` | 1 self | - ``target`` is a value for non-lookup containers (fixed containers, sequence containers, non-associative and non-ordered containers) |
|
||||
|
@ -125,31 +125,31 @@ Below are the many container operations and their override points for ``containe
|
|||
| erase | ``c:erase(target)`` | ``static int erase(lua_State*);`` | 1 self | - for sequence containers, ``target`` is an index to erase |
|
||||
| | | | 2 target | - for lookup containers, ``target`` is the key type |
|
||||
| | | | | - uses linear incrementation to spot for sequence containers that do not have random access iterators (``std::list``, ``std::forward_list``, and similar) |
|
||||
| | | | | - invalidates iteration |
|
||||
| | | | | - can invalidates iteration |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| insert | ``c:insert(target, value)`` | | 1 self | - for sequence containers, ``target`` is an index, otherwise it is the key type |
|
||||
| | | | 2 target | - inserts into a container if possible at the specified location |
|
||||
| | | | 3 key | |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| add | ``c:add(key, value)`` or ``c:add(value)`` | ``static int add(lua_State*);`` | 1 self | - 2nd argument (3rd on stack) is provided for associative containers to add |
|
||||
| | | | 2 key/value | - ordered containers will insert into the appropriate spot, not necessarily at the end |
|
||||
| | | | 3 value | |
|
||||
| | | | 2 key/value | - ordered containers will insert into the appropriate spot, not necessarily at the end (uses ``.insert(...)`` or ``.find(...)`` with assignment |
|
||||
| | | | 3 value | - can invalidate iteratorion |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| size | ``#c`` | ``static int size(lua_State*);`` | 1 self | - default implementation calls ``.size()`` if present |
|
||||
| | | | | - otherwise, default implementation uses ``std::distance(begin(L, self), end(L, self))`` |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| clear | ``c:clear()`` | ``static int clear(lua_State*);`` | 1 self | - default implementation provides no fallback if there's no ``clear`` operation |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| offset | n/a | ``static int index_adjustment(lua_State*, T&);`` | n/a | - returns an index that adds to the passed-in numeric index for array acces (default implementation is ``return -1`` to simulate 1-based indexing from Lua) |
|
||||
| offset | n/a | ``static int index_adjustment(lua_State*, T&);`` | n/a | - returns an index that adds to the passed-in numeric index for array access (default implementation is ``return -1`` to simulate 1-based indexing from Lua) |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| begin | n/a | ``static iterator begin(lua_State*, T&);`` | n/a | - called by default implementation |
|
||||
| begin | n/a | ``static iterator begin(lua_State*, T&);`` | n/a | - called by default implementation in above functions |
|
||||
| | | | | - is not the regular raw function: must return an iterator from second "T&" argument, which is self |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| end | n/a | ``static iterator end(lua_State*, T&);`` | n/a | - called by default implementation |
|
||||
| end | n/a | ``static iterator end(lua_State*, T&);`` | n/a | - called by default implementation in above functions |
|
||||
| | | | | - is not the regular raw function: must return an iterator from second "T&" argument, which is self |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| next | | ``static int next(lua_State*);`` | 1 self | - implement if advanced user only that understands caveats |
|
||||
| | | | | - is used as 'iteration function' dispatched with pairs() call |
|
||||
| next | | ``static int next(lua_State*);`` | 1 self | - implement if advanced user only that understands caveats of writing a ``next`` function for Lua traversal |
|
||||
| | | | | - is used as the 'iteration function' dispatched with pairs() call |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
@ -189,7 +189,7 @@ When you serialize a container into sol3, the default container handler deals wi
|
|||
| | | std::forward_list | |
|
||||
+------------------------+----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------+
|
||||
| fixed | lacking ``push_back``/``insert`` | std::array<T, n> | - regular c-style arrays must be set with ``std::ref( arr )`` or ``&arr`` to be usable |
|
||||
| | lacking ``erase`` | T[n] (fixed arrays) | |
|
||||
| | lacking ``erase`` | T[n] (fixed arrays) | - C++ implementation inserts using operator[] |
|
||||
| | | | |
|
||||
+------------------------+----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------+
|
||||
| ordered | ``key_type`` typedef | std::set | - ``container[key] = stuff`` operation erases when ``stuff`` is nil, inserts/sets when not |
|
||||
|
|
|
@ -3,12 +3,12 @@ errors
|
|||
how to handle exceptions or other errors
|
||||
----------------------------------------
|
||||
|
||||
Here is some advice and some tricks for common errors about iteration, compile time / linker errors, and other pitfalls, especially when dealing with thrown exceptions, error conditions and the like in Sol.
|
||||
Here is some advice and some tricks for common errors about iteration, compile time / linker errors, and other pitfalls, especially when dealing with thrown exceptions, error conditions and the like in sol.
|
||||
|
||||
Running Scripts
|
||||
---------------
|
||||
|
||||
Scripts can have syntax errors, can load from the file system wrong, or have runtime issues. Knowing which one can be troublesome. There are various small building blocks to load and run code, but to check errors you can use the overloaded :ref:`script/script_file functions on sol::state/sol::state_view<state-script-function>`, specifically the ``safe_script`` variants. These also take an error callback that is called only when something goes wrong, and Sol comes with some default error handlers in the form of ``sol::script_default_on_error`` and ``sol::script_pass_on_error``.
|
||||
Scripts can have syntax errors, can load from the file system wrong, or have runtime issues. Knowing which one can be troublesome. There are various small building blocks to load and run code, but to check errors you can use the overloaded :ref:`script/script_file functions on sol::state/sol::state_view<state-script-function>`, specifically the ``safe_script`` variants. These also take an error callback that is called only when something goes wrong, and sol comes with some default error handlers in the form of ``sol::script_default_on_error`` and ``sol::script_pass_on_error``.
|
||||
|
||||
.. _compilation_errors_warnings:
|
||||
|
||||
|
@ -53,7 +53,7 @@ This should use the 64-bit tools by default, and increase your maximum heap spac
|
|||
Linker Errors
|
||||
-------------
|
||||
|
||||
There are lots of reasons for compiler linker errors. A common one is not knowing that you've compiled the Lua library as C++: when building with C++, it is important to note that every typical (static or dynamic) library expects the C calling convention to be used and that Sol includes the code using ``extern 'C'`` where applicable.
|
||||
There are lots of reasons for compiler linker errors. A common one is not knowing that you've compiled the Lua library as C++: when building with C++, it is important to note that every typical (static or dynamic) library expects the C calling convention to be used and that sol includes the code using ``extern 'C'`` where applicable.
|
||||
|
||||
However, when the target Lua library is compiled with C++, one must change the calling convention and name mangling scheme by getting rid of the ``extern 'C'`` block. This can be achieved by adding ``#define SOL_USING_CXX_LUA`` before including sol3, or by adding it to your compilation's command line. If you build LuaJIT in C++ mode (how you would even, is beyond me), then you need to ``#define SOL_USING_CXX_LUAJIT`` as well. Typically, there is never a need to use this last one.
|
||||
|
||||
|
@ -69,9 +69,9 @@ Please make sure to use the ``SOL_EXCEPTIONS_SAFE_PROPAGATION`` define before in
|
|||
Catch and CRASH!
|
||||
----------------
|
||||
|
||||
By default, Sol will add a ``default_at_panic`` handler to states opened by Sol (see :ref:`sol::state automatic handlers<state-automatic-handlers>` for more details). If exceptions are not turned off, this handler will throw to allow the user a chance to recover. However, in almost all cases, when Lua calls ``lua_atpanic`` and hits this function, it means that something *irreversibly wrong* occured in your code or the Lua code and the VM is in an unpredictable or dead state. Catching an error thrown from the default handler and then proceeding as if things are cleaned up or okay is NOT the best idea. Unexpected bugs in optimized and release mode builds can result, among other serious issues.
|
||||
By default, sol will add a ``default_at_panic`` handler to states opened by sol (see :ref:`sol::state automatic handlers<state-automatic-handlers>` for more details). If exceptions are not turned off, this handler will throw to allow the user a chance to recover. However, in almost all cases, when Lua calls ``lua_atpanic`` and hits this function, it means that something *irreversibly wrong* occured in your code or the Lua code and the VM is in an unpredictable or dead state. Catching an error thrown from the default handler and then proceeding as if things are cleaned up or okay is NOT the best idea. Unexpected bugs in optimized and release mode builds can result, among other serious issues.
|
||||
|
||||
It is preferred if you catch an error that you log what happened, terminate the Lua VM as soon as possible, and then crash if your application cannot handle spinning up a new Lua state. Catching can be done, but you should understand the risks of what you're doing when you do it. For more information about catching exceptions, the potentials, not turning off exceptions and other tricks and caveats, read about :doc:`exceptions in Sol here<exceptions>`.
|
||||
It is preferred if you catch an error that you log what happened, terminate the Lua VM as soon as possible, and then crash if your application cannot handle spinning up a new Lua state. Catching can be done, but you should understand the risks of what you're doing when you do it. For more information about catching exceptions, the potentials, not turning off exceptions and other tricks and caveats, read about :doc:`exceptions in sol here<exceptions>`.
|
||||
|
||||
Lua is a C API first and foremost: exceptions bubbling out of it is essentially last-ditch, terminal behavior that the VM does not expect. You can see an example of handling a panic on the exceptions page :ref:`here<typical-panic-function>`. This means that setting up a ``try { ... } catch (...) {}`` around an unprotected sol3 function or script call is **NOT** enough to keep the VM in a clean state. Lua does not understand exceptions and throwing them results in undefined behavior if they bubble through the C API once and then the state is used again. Please catch, and crash.
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ exceptions
|
|||
since somebody is going to ask about it...
|
||||
------------------------------------------
|
||||
|
||||
Yes, you can turn off exceptions in Sol with ``#define SOL_NO_EXCEPTIONS`` before including or by passing the command line argument that defines ``SOL_NO_EXCEPTIONS``. We don't recommend it unless you're playing with a Lua distro that also doesn't play nice with exceptions (like non-x64 versions of :ref:`LuaJIT<LuaJIT and exceptions>` ).
|
||||
Yes, you can turn off exceptions in sol with ``#define SOL_NO_EXCEPTIONS`` before including or by passing the command line argument that defines ``SOL_NO_EXCEPTIONS``. We don't recommend it unless you're playing with a Lua distro that also doesn't play nice with exceptions (like non-x64 versions of :ref:`LuaJIT<LuaJIT and exceptions>` ).
|
||||
|
||||
If you turn this off, the default `at_panic`_ function :doc:`state<api/state>` set for you will not throw (see :ref:`sol::state's automatic handlers<state-automatic-handlers>` for more details). Instead, the default Lua behavior of aborting will take place (and give you no chance of escape unless you implement your own at_panic function and decide to try ``longjmp`` out).
|
||||
|
||||
|
@ -15,7 +15,7 @@ To make this not be the case, you can set a panic function directly with ``lua_a
|
|||
:linenos:
|
||||
|
||||
|
||||
Note that ``SOL_NO_EXCEPTIONS`` will also disable :doc:`sol::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:`sol::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!
|
||||
|
||||
If there is a place where a throw statement is called or a try/catch is used and it is not hidden behind a ``#ifndef SOL_NO_EXCEPTIONS`` block, please file an issue at `issue`_ or submit your very own pull request so everyone can benefit!
|
||||
|
||||
|
@ -45,9 +45,9 @@ The other handler is specific to sol3. If you open a ``sol::state``, or open the
|
|||
LuaJIT and exceptions
|
||||
---------------------
|
||||
|
||||
It is important to note that a popular 5.1 distribution of Lua, LuaJIT, has some serious `caveats regarding exceptions`_. LuaJIT's exception promises are flaky at best on x64 (64-bit) platforms, and entirely terrible on non-x64 (32-bit, ARM, etc.) platforms. The trampolines we have in place for all functions bound through conventional means in Sol will catch exceptions and turn them into Lua errors so that LuaJIT remainds unperturbed, but if you link up a C function directly yourself and throw, chances are you might have screwed the pooch.
|
||||
It is important to note that a popular 5.1 distribution of Lua, LuaJIT, has some serious `caveats regarding exceptions`_. LuaJIT's exception promises are flaky at best on x64 (64-bit) platforms, and entirely terrible on non-x64 (32-bit, ARM, etc.) platforms. The trampolines we have in place for all functions bound through conventional means in sol will catch exceptions and turn them into Lua errors so that LuaJIT remainds unperturbed, but if you link up a C function directly yourself and throw, chances are you might have screwed the pooch.
|
||||
|
||||
Testing in `this closed issue`_ that it doesn't play nice on 64-bit Linux in many cases either, especially when it hits an error internal to the interpreter (and does not go through Sol). We do have tests, however, that compile for our continuous integration check-ins that check this functionality across several compilers and platforms to keep you protected and given hard, strong guarantees for what happens if you throw in a function bound by Sol. If you stray outside the realm of Sol's protection, however... Good luck.
|
||||
Testing in `this closed issue`_ that it doesn't play nice on 64-bit Linux in many cases either, especially when it hits an error internal to the interpreter (and does not go through sol). We do have tests, however, that compile for our continuous integration check-ins that check this functionality across several compilers and platforms to keep you protected and given hard, strong guarantees for what happens if you throw in a function bound by sol. If you stray outside the realm of sol's protection, however... Good luck.
|
||||
|
||||
|
||||
.. _exception-interop:
|
||||
|
@ -55,7 +55,7 @@ Testing in `this closed issue`_ that it doesn't play nice on 64-bit Linux in man
|
|||
Lua and LuaJIT C++ Exception Full Interoperability
|
||||
--------------------------------------------------
|
||||
|
||||
You can ``#define SOL_EXCEPTIONS_SAFE_PROPAGATION`` before including Sol or define ``SOL_EXCEPTIONS_SAFE_PROPAGATION`` on the command line if you know your implmentation of Lua has proper unwinding semantics that can be thrown through the version of the Lua API you have built / are using.
|
||||
You can ``#define SOL_EXCEPTIONS_SAFE_PROPAGATION`` before including sol or define ``SOL_EXCEPTIONS_SAFE_PROPAGATION`` on the command line if you know your implmentation of Lua has proper unwinding semantics that can be thrown through the version of the Lua API you have built / are using.
|
||||
|
||||
This will prevent sol from catching ``(...)`` errors in platforms and compilers that have full C++ exception interoperability. This means that Lua errors can be caught with ``catch (...)`` in the C++ end of your code after it goes through Lua, and exceptions can pass through the Lua API and Stack safely.
|
||||
|
||||
|
@ -63,7 +63,7 @@ Currently, the only known platform to do this is the listed "Full" `platforms fo
|
|||
|
||||
.. warning::
|
||||
|
||||
``SOL_EXCEPTIONS_SAFE_PROPAGATION`` is not defined automatically when Sol detects LuaJIT. *It is your job to define it if you know that your platform supports it*!
|
||||
``SOL_EXCEPTIONS_SAFE_PROPAGATION`` is not defined automatically when sol detects LuaJIT. *It is your job to define it if you know that your platform supports it*!
|
||||
|
||||
|
||||
.. _issue: https://github.com/ThePhD/sol2/issues/
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
features
|
||||
========
|
||||
*what does Sol (and other libraries) support?*
|
||||
*what does sol (and other libraries) support?*
|
||||
|
||||
|
||||
The goal of Sol is to provide an incredibly clean API that provides high performance (comparable or better than the C it was written on) and extreme ease of use. That is, users should be able to say: "this works pretty much how I expected it to."
|
||||
The goal of sol is to provide an incredibly clean API that provides high performance (comparable or better than the C it was written on) and extreme ease of use. That is, users should be able to say: "this works pretty much how I expected it to."
|
||||
|
||||
For the hard technical components of Lua and its ecosystem we support, here is the full rundown:
|
||||
|
||||
what Sol supports
|
||||
what sol supports
|
||||
-----------------
|
||||
|
||||
* Support for Lua 5.1, 5.2, and 5.3+ and LuaJIT 2.0.4 + 2.1.x-beta3+. We achieve this through our :doc:`compatibility<api/compatibility>` header.
|
||||
|
@ -75,7 +75,7 @@ Explanations for a few categories are below (rest are self-explanatory).
|
|||
|
||||
* optional: Support for getting an element, or potentially not (and not forcing the default construction of what amounts to a bogus/dead object). Usually comes with ``std(::experimental)::optional``. It's a fairly new class, so a hand-rolled class internal to the library with similar semantics is also acceptable
|
||||
* tables: Some sort of abstraction for dealing with tables. Ideal support is ``mytable["some_key"] = value``, and everything that the syntax implies.
|
||||
* table chaining: In conjunction with tables, having the ability to query deeply into tables ``mytable["key1"]["key2"]["key3"]``. Note that this becomes a tripping point for some libraries: crashing if ``"key1"`` doesn't exist while trying to access ``"key2"`` (Sol avoids this specifically when you use ``sol::optional``), and sometimes it's also a heavy performance bottleneck as expressions are not lazy-evaluated by a library.
|
||||
* table chaining: In conjunction with tables, having the ability to query deeply into tables ``mytable["key1"]["key2"]["key3"]``. Note that this becomes a tripping point for some libraries: crashing if ``"key1"`` doesn't exist while trying to access ``"key2"`` (sol avoids this specifically when you use ``sol::optional``), and sometimes it's also a heavy performance bottleneck as expressions are not lazy-evaluated by a library.
|
||||
* arbitrary keys: Letting C++ code use userdata, other tables, integers, etc. as keys for into a table.
|
||||
* user-defined types (udts): C++ types given form and function in Lua code.
|
||||
* udts - member functions: C++ member functions on a type, usually callable with ``my_object:foo(1)`` or similar in Lua.
|
||||
|
@ -162,13 +162,13 @@ kaguya -
|
|||
|
||||
* Table variables / member variables are automatically turned into ``obj:x( value )`` to set and ``obj:x()`` to get
|
||||
* Has optional support
|
||||
* Inspired coroutine support for Sol
|
||||
* Inspired coroutine support for sol
|
||||
* Library author (satoren) is a nice guy!
|
||||
* C++11/14, or boostified (which makes it C++03 compatible)
|
||||
* Class registration is a bit verbose, but not as offensive as OOLua or lua-intf or others
|
||||
* Constructor setting syntax is snazzy and good
|
||||
|
||||
Sol -
|
||||
sol -
|
||||
|
||||
* One of the few libraries with optional support!
|
||||
* Basically the fastest in almomst all respects: http://sol2.readthedocs.io/en/latest/benchmarks.html
|
||||
|
@ -260,7 +260,7 @@ luwra -
|
|||
* Cannot pull functions without first leaving them on the stack: manual cleanup becomes a thing
|
||||
* Doesn't understand ``std::function`` conversions and the like (but with some extra code can get it to work)
|
||||
* Recently improved by a lot: can chain tables and such, even if performance is a bit sad for that use case
|
||||
* When you do manage to set function calls with the macros they are fast (can a template solution do just as good? Sol is going to find out!)
|
||||
* 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
|
||||
|
|
|
@ -87,7 +87,7 @@ When you bind a function to Lua, please take any pointer arguments as ``T*``, un
|
|||
function call safety
|
||||
--------------------
|
||||
|
||||
You can have functions here and on usertypes check to definitely make sure that the types passed to C++ functions are what they're supposed to be by adding a ``#define SOL_CHECK_ARGUMENTS`` before including Sol, or passing it on the command line. Otherwise, for speed reasons, these checks are only used where absolutely necessary (like discriminating between :doc:`overloads<api/overload>`). See :doc:`safety<../safety>` for more information.
|
||||
You can have functions here and on usertypes check to definitely make sure that the types passed to C++ functions are what they're supposed to be by adding a ``#define SOL_ALL_SAFETIES_ON`` before including sol, or passing it on the command line. Otherwise, for speed reasons, these checks are only used where absolutely necessary (like discriminating between :doc:`overloads<api/overload>`). See :doc:`safety<../safety>` for more information.
|
||||
|
||||
|
||||
.. _raw-function-note:
|
||||
|
@ -95,7 +95,7 @@ You can have functions here and on usertypes check to definitely make sure that
|
|||
raw functions (``lua_CFunction``)
|
||||
---------------------------------
|
||||
|
||||
When you push a function into Lua using Sol using any methods and that function exactly matches the signature ``int( lua_State* );``, it will be treated as a *raw C function* (a ``lua_CFunction``). This means that the usual exception trampoline Sol wraps your other function calls in will not be present. You will be responsible for catching exceptions and handling them before they explode into the C API (and potentially destroy your code). Sol in all other cases adds an exception-handling trampoline that turns exceptions into Lua errors that can be caught by the above-mentioned protected functions and accessors.
|
||||
When you push a function into Lua using sol using any methods and that function exactly matches the signature ``int( lua_State* );``, it will be treated as a *raw C function* (a ``lua_CFunction``). This means that the usual exception trampoline sol wraps your other function calls in will not be present. You will be responsible for catching exceptions and handling them before they explode into the C API (and potentially destroy your code). sol in all other cases adds an exception-handling trampoline that turns exceptions into Lua errors that can be caught by the above-mentioned protected functions and accessors.
|
||||
|
||||
Note that stateless lambdas can be converted to a function pointer, so stateless lambdas similar to the form ``[](lua_State*) -> int { ... }`` will also be pushed as raw functions. If you need to get the Lua state that is calling a function, use :doc:`sol::this_state<api/this_state>`.
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
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.
|
||||
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:
|
||||
------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
|
|
@ -4,7 +4,7 @@ mentions
|
|||
|
||||
First off, feel free to `tell me about your uses!`_
|
||||
|
||||
Okay, so the features don't convince you, the documentation doesn't convince you, you want to see what *other* people think about Sol? Well, aside from the well-wishes that come through in the issue tracker, here's a few things floating around about sol3 that I occasionally get pinged about:
|
||||
Okay, so the features don't convince you, the documentation doesn't convince you, you want to see what *other* people think about sol? Well, aside from the well-wishes that come through in the issue tracker, here's a few things floating around about sol3 that I occasionally get pinged about:
|
||||
|
||||
`eevee`_ demonstrating the sheer code reduction by using sol3:
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ And lo, `Danny Y., Rapptz`_ did stand firm in the sea and cast his hands to the
|
|||
seriously
|
||||
---------
|
||||
|
||||
Sol was originally started by many moon cycles ago to interop with Lua and C++, by `Rapptz`_. It was very successful and many rejoiced at having an easy to use abstraction on top of the Lua API. Rapptz continued to make a number of great projects and has been busy with other things, so upon seeing the repository grow stagnant and tired in the last very long while (over a year), `ThePhD`_ forked it into Sol3 and rebooted the code with the hopes of reaching the Milestone and the documentation you have today.
|
||||
sol was originally started by many moon cycles ago to interop with Lua and C++, by `Rapptz`_. It was very successful and many rejoiced at having an easy to use abstraction on top of the Lua API. Rapptz continued to make a number of great projects and has been busy with other things, so upon seeing the repository grow stagnant and tired in the last very long while (over a year), `ThePhD`_ forked it into Sol3 and rebooted the code with the hopes of reaching the Milestone and the documentation you have today.
|
||||
|
||||
To get to the old repo, head over `here`_.
|
||||
|
||||
|
@ -21,7 +21,7 @@ To get to the old repo, head over `here`_.
|
|||
the name
|
||||
--------
|
||||
|
||||
Sol means sun. The moon (Lua) needs a sun, because without it only the bleak night of copy-paste programming and off-by-one errors would prevail. ... Or something.
|
||||
sol means sun. The moon (Lua) needs a sun, because without it only the bleak night of copy-paste programming and off-by-one errors would prevail. ... Or something.
|
||||
|
||||
|
||||
.. _here: https://github.com/Rapptz/sol
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
getting performance
|
||||
===================
|
||||
*things to make Sol as fast as possible*
|
||||
*things to make sol as fast as possible*
|
||||
|
||||
|
||||
As shown by the :doc:`benchmarks<benchmarks>`, Sol is very performant with its abstractions. However, in the case where you need every last drop of performance from Sol, a number of tips and API usage tricks will be documented here. PLEASE benchmark / profile your code before you start invoking these, as some of them trade in readability / clarity for performance.
|
||||
As shown by the :doc:`benchmarks<benchmarks>`, sol is very performant with its abstractions. However, in the case where you need every last drop of performance from sol, a number of tips and API usage tricks will be documented here. PLEASE benchmark / profile your code before you start invoking these, as some of them trade in readability / clarity for performance.
|
||||
|
||||
* If you have a bound function call / bound member function that you are going to call in a very tight, performance-heavy loop, considering using :doc:`sol::c_call<api/c_call>`
|
||||
* Be wary of passing by value / reference, and what it means by reading :ref:`this note<function-argument-handling>`.
|
||||
* It is currently undocumented that usertypes will "inherit" member function / member variables from bound classes, mostly because the semantics are unclear and it is not the most performant (although it is flexible: you can register base classes after / whenever you want in relation to the derived class, provided that derived class has its bases listed). Specifying all member functions / member variables for the usertype constructor / ``new_usertype`` function call and not relying on base lookup will boost performance of member lookup
|
||||
* Use the :doc:`sol::stack_{}<api/stack_reference>` versions of functions in order to achieve maximum performance benefits when doing things like calling a function from Lua and knowing that certain arguments of certain Lua types will be on the stack. This can save you a very small fraction of performance to not copy to the register (but is also more dangerous and usually not terribly worth it).
|
||||
* Specifying base classes can make getting the usertype out of Sol a bit slower since we have to check and cast; if you know the exact type wherever you're retrieving it, considering not specifying the bases, retrieving the exact type from Sol, and then casting to a base type yourself
|
||||
* Specifying base classes can make getting the usertype out of sol a bit slower since we have to check and cast; if you know the exact type wherever you're retrieving it, considering not specifying the bases, retrieving the exact type from sol, and then casting to a base type yourself
|
||||
* Member variables can sometimes cost an extra lookup to occur within the Lua system (as mentioned :doc:`bottom of the usertype page<api/usertype>`); until we find out a safe way around this, member variables will always incur that extra lookup cost
|
||||
|
||||
|
||||
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.
|
||||
|
|
|
@ -2,6 +2,6 @@ run-time type information (rtti)
|
|||
================================
|
||||
*because somebody's going to want to shut this off, too...*
|
||||
|
||||
Sol does not use RTTI.
|
||||
sol does not use RTTI.
|
||||
|
||||
.. _an issue: https://github.com/ThePhD/sol2/issues
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
config and safety
|
||||
=================
|
||||
|
||||
Sol was designed to be correct and fast, and in the pursuit of both uses the regular ``lua_to{x}`` functions of Lua rather than the checking versions (``lua_check{X}``) functions. The API defaults to paranoidly-safe alternatives if you have a ``#define SOL_CHECK_ARGUMENTS`` before you include Sol, or if you pass the ``SOL_CHECK_ARGUMENTS`` define on the build command for your build system. By default, it is off and remains off unless you define this, even in debug mode.
|
||||
sol was designed to be correct and fast, and in the pursuit of both uses the regular ``lua_to{x}`` functions of Lua rather than the checking versions (``lua_check{X}``) functions. The API defaults to paranoidly-safe alternatives if you have a ``#define SOL_ALL_SAFETIES_ON`` before you include sol, or if you pass the ``SOL_ALL_SAFETIES_ON`` define on the build command for your build system. By default, it is off and remains off unless you define this, even in debug mode.
|
||||
|
||||
.. _config:
|
||||
|
||||
|
@ -54,7 +54,7 @@ Safety Config
|
|||
* Don't turn this on unless you have an extremely good reason
|
||||
* *DON'T TURN THIS ON UNLESS YOU HAVE AN EXTREMELY GOOD REASON*
|
||||
|
||||
``SOL_CHECK_ARGUMENTS`` triggers the following changes:
|
||||
``SOL_ALL_SAFETIES_ON`` triggers the following changes:
|
||||
* If ``SOL_SAFE_USERTYPE``, ``SOL_SAFE_REFERENCES``, ``SOL_SAFE_FUNCTION``, ``SOL_SAFE_NUMERICS``, ``SOL_SAFE_GETTER``, and ``SOL_SAFE_FUNCTION_CALLS`` are not defined, they get defined and the effects described above kick in
|
||||
* **Not** turned on by default under any settings: *this MUST be turned on manually*
|
||||
|
||||
|
|
|
@ -11,10 +11,14 @@ These are all the things. Use your browser's search to find things you want.
|
|||
|
||||
All of the code below is available at the `sol3 tutorial examples`_.
|
||||
|
||||
.. note::
|
||||
|
||||
Make sure to add ``SOL_ALL_SAFETIES_ON`` preprocessor define to your build configuration to turn safety on.
|
||||
|
||||
asserts / prerequisites
|
||||
-----------------------
|
||||
|
||||
You'll need to ``#include <sol/sol.hpp>`` somewhere in your code. Sol is header-only, so you don't need to compile anything. However, **Lua must be compiled and available**. See the :doc:`getting started tutorial<getting-started>` for more details.
|
||||
You'll need to ``#include <sol/sol.hpp>`` somewhere in your code. sol is header-only, so you don't need to compile anything. However, **Lua must be compiled and available**. See the :doc:`getting started tutorial<getting-started>` for more details.
|
||||
|
||||
The implementation for ``assert.hpp`` with ``c_assert`` looks like so:
|
||||
|
||||
|
@ -57,6 +61,13 @@ To run Lua code but have an error handler in case things go wrong:
|
|||
:linenos:
|
||||
:lines: 28-39,47-
|
||||
|
||||
You can see more use of safety by employing the use of `.safe_script`_, which returns a protected result you can use to properly check for errors and similar.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
If you have the safety definitions on, `.script` will call into the `.safe_script` versions automatically. Otherwise, it will call into the `.unsafe_script` versions.
|
||||
|
||||
|
||||
running lua code (low-level)
|
||||
----------------------------
|
||||
|
@ -75,6 +86,24 @@ You can use the individual load and function call operator to load, check, and t
|
|||
You can also `develop custom loaders`_ that pull from things that are not strings or files.
|
||||
|
||||
|
||||
passing arguments to scripts
|
||||
----------------------------
|
||||
|
||||
Arguments to Lua scripts can be passed by first loading the file or script blob, and then calling it using sol's abstractions. Then, in the script, access the variables with a `...` on the left hand side of an assignment:
|
||||
|
||||
.. literalinclude:: ../../../examples/source/tutorials/quick_n_dirty/arguments_to_scripts.cpp
|
||||
:linenos:
|
||||
|
||||
|
||||
transferring functions (dumping bytecode)
|
||||
-----------------------------------------
|
||||
|
||||
You can dump the bytecode of a function, which allows you to transfer it to another state (or save it, or load it). Note that bytecode is *typically specific to the Lua version*!
|
||||
|
||||
.. literalinclude:: ../../../examples/source//dump.cpp
|
||||
:linenos:
|
||||
|
||||
|
||||
set and get variables
|
||||
---------------------
|
||||
|
||||
|
@ -254,14 +283,14 @@ You can emulate namespacing by having a table and giving it the namespace names
|
|||
:lines: 1-
|
||||
|
||||
|
||||
This technique can be used to register namespace-like functions and classes. It can be as deep as you want. Just make a table and name it appropriately, in either Lua script or using the equivalent Sol code. As long as the table FIRST exists (e.g., make it using a script or with one of Sol's methods or whatever you like), you can put anything you want specifically into that table using :doc:`sol::table's<../api/table>` abstractions.
|
||||
This technique can be used to register namespace-like functions and classes. It can be as deep as you want. Just make a table and name it appropriately, in either Lua script or using the equivalent sol code. As long as the table FIRST exists (e.g., make it using a script or with one of sol's methods or whatever you like), you can put anything you want specifically into that table using :doc:`sol::table's<../api/table>` abstractions.
|
||||
|
||||
there is a LOT more
|
||||
-------------------
|
||||
|
||||
Some more things you can do/read about:
|
||||
* :doc:`the usertypes page<../usertypes>` lists the huge amount of features for functions
|
||||
- :doc:`unique usertype traits<../api/unique_usertype_traits>` allows you to specialize handle/RAII types from other libraries frameworks, like boost and Unreal, to work with Sol. Allows custom smart pointers, custom handles and others
|
||||
- :doc:`unique usertype traits<../api/unique_usertype_traits>` allows you to specialize handle/RAII types from other libraries frameworks, like boost and Unreal, to work with sol. Allows custom smart pointers, custom handles and others
|
||||
* :doc:`the containers page<../containers>` gives full information about handling everything about container-like usertypes
|
||||
* :doc:`the functions page<../functions>` lists a myriad of features for functions
|
||||
- :doc:`variadic arguments<../api/variadic_args>` in functions with ``sol::variadic_args``.
|
||||
|
@ -271,11 +300,12 @@ Some more things you can do/read about:
|
|||
* :doc:`ownership semantics<ownership>` are described for how Lua deals with its own internal references and (raw) pointers.
|
||||
* :doc:`stack manipulation<../api/stack>` to safely play with the stack. You can also define customization points for ``stack::get``/``stack::check``/``stack::push`` for your type.
|
||||
* :doc:`make_reference/make_object convenience function<../api/make_reference>` to get the same benefits and conveniences as the low-level stack API but put into objects you can specify.
|
||||
* :doc:`stack references<../api/stack_reference>` to have zero-overhead Sol abstractions while not copying to the Lua registry.
|
||||
* :doc:`stack references<../api/stack_reference>` to have zero-overhead sol abstractions while not copying to the Lua registry.
|
||||
* :doc:`resolve<../api/resolve>` overloads in case you have overloaded functions; a cleaner casting utility. You must use this to emulate default parameters.
|
||||
|
||||
.. _.safe_script: https://github.com/ThePhD/sol2/tree/develop/examples/source/tutorials/quick_n_dirty/running_lua_code_safely.cpp
|
||||
.. _develop custom loaders: https://github.com/ThePhD/sol2/blob/develop/examples/custom_reader.cpp
|
||||
.. _basic example: https://github.com/ThePhD/sol2/blob/develop/examples/usertype.cpp
|
||||
.. _special functions example: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_special_functions.cpp
|
||||
.. _initializers example: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_initializers.cpp
|
||||
.. _sol3 tutorial examples: https://github.com/ThePhD/sol2/tree/develop/examples/tutorials/quick_n_dirty
|
||||
.. _sol3 tutorial examples: https://github.com/ThePhD/sol2/tree/develop/examples/source/tutorials/quick_n_dirty
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
adding your own types
|
||||
=====================
|
||||
|
||||
Sometimes, overriding Sol to make it handle certain ``struct``'s and ``class``'es as something other than just userdata is desirable. The way to do this is to take advantage of the 4 customization points for Sol. These are ``sol::lua_size<T>``, ``sol::stack::unqualified_pusher<T, C>``, ``sol::stack::getter<T, C>``, ``sol::stack::checker<T, sol::type t, C>``.
|
||||
Sometimes, overriding sol to make it handle certain ``struct``'s and ``class``'es as something other than just userdata is desirable. The way to do this is to take advantage of the 4 customization points for sol. These are ``sol_lua_check``, ``sol_lua_get``, ``sol_lua_push``, and ``sol_lua_check_get``.
|
||||
|
||||
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++:
|
||||
|
||||
|
@ -25,8 +25,8 @@ You can make something pushable into Lua, but not get-able in the same way if yo
|
|||
|
||||
.. note::
|
||||
|
||||
It is important to note here that the ``getter``, ``pusher`` and ``checker`` differentiate between a type ``T`` and a pointer to a type ``T*``. This means that if you want to work purely with, say, a ``T*`` handle that does not have the same semantics as just ``T``, you may need to specify checkers/getters/pushers for both ``T*`` and ``T``. The checkers for ``T*`` forward to the checkers for ``T``, but the getter for ``T*`` does not forward to the getter for ``T`` (e.g., because of ``int*`` not being quite the same as ``int``).
|
||||
It is important to note here that the ``gett``, ``push`` and ``check`` differentiate between a type ``T`` and a pointer to a type ``T*``. This means that if you want to work purely with, say, a ``T*`` handle that does not have the same semantics as just ``T``, you may need to specify checkers/getters/pushers for both ``T*`` and ``T``. The checkers for ``T*`` forward to the checkers for ``T``, but the getter for ``T*`` does not forward to the getter for ``T`` (e.g., because of ``int*`` not being quite the same as ``int``).
|
||||
|
||||
In general, this is fine since most getters/checkers only use 1 stack point. But, if you're doing more complex nested classes, it would be useful to use ``tracking.last`` to understand how many stack indices the last getter/checker operation did and increment it by ``index + tracking.last`` after using a ``stack::check<..>( L, index, tracking)`` call.
|
||||
In general, this is fine since most getters/checkers only use 1 stack point. But, if you're doing more complex nested classes, it would be useful to use ``tracking.last`` to understand how many stack indices the last gett/check operation did and increment it by ``index + tracking.last`` after using a ``stack::check<..>( L, index, tracking)`` call.
|
||||
|
||||
You can read more about the structs themselves :ref:`over on the API page for stack<extension_points>`, and if there's something that goes wrong or you have anymore questions, please feel free to drop a line on the Github Issues page or send an e-mail!
|
||||
You can read more about the extension points themselves :ref:`over on the API page for stack<extension_points>`, and if there's something that goes wrong or you have anymore questions, please feel free to drop a line on the Github Issues page or send an e-mail!
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
C++ in Lua
|
||||
==========
|
||||
|
||||
Using user defined types ("usertype"s, or just "udt"s) is simple with Sol. If you don't call any member variables or functions, then you don't even have to 'register' the usertype at all: just pass it through. But if you want variables and functions on your usertype inside of Lua, you need to register it. We're going to give a short example here that includes a bunch of information on how to work with things.
|
||||
Using user defined types ("usertype"s, or just "udt"s) is simple with sol. If you don't call any member variables or functions, then you don't even have to 'register' the usertype at all: just pass it through. But if you want variables and functions on your usertype inside of Lua, you need to register it. We're going to give a short example here that includes a bunch of information on how to work with things.
|
||||
|
||||
Take this ``player`` struct in C++ in a header file:
|
||||
|
||||
|
@ -133,7 +133,7 @@ To do this, you bind things using the ``new_usertype`` and ``set_usertype`` meth
|
|||
|
||||
That script should run fine now, and you can observe and play around with the values. Even more stuff :doc:`you can do<../api/usertype>` is described elsewhere, like initializer functions (private constructors / destructors support), "static" functions callable with ``name.my_function( ... )``, and overloaded member functions. You can even bind global variables (even by reference with ``std::ref``) with ``sol::var``. There's a lot to try out!
|
||||
|
||||
This is a powerful way to allow reuse of C++ code from Lua beyond just registering functions, and should get you on your way to having more complex classes and data structures! In the case that you need more customization than just usertypes, however, you can customize Sol to behave more fit to your desires by using the desired :doc:`customization and extension structures<customization>`.
|
||||
This is a powerful way to allow reuse of C++ code from Lua beyond just registering functions, and should get you on your way to having more complex classes and data structures! In the case that you need more customization than just usertypes, however, you can customize sol to behave more fit to your desires by using the desired :doc:`customization and extension structures<customization>`.
|
||||
|
||||
You can check out this code and more complicated code at the `examples directory`_ by looking at the ``usertype_``-prefixed examples.
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ If you're already using lua and you just want to use ``sol`` in some places, you
|
|||
:name: state-view-snippet
|
||||
|
||||
int something_in_my_system (lua_State* L) {
|
||||
// start using Sol with a pre-existing system
|
||||
// start using sol with a pre-existing system
|
||||
sol::state_view lua(L); // non-owning
|
||||
|
||||
lua.script("print('bark bark bark!')");
|
||||
|
@ -21,13 +21,13 @@ If you're already using lua and you just want to use ``sol`` in some places, you
|
|||
return 0; // or whatever you require of working with a raw function
|
||||
}
|
||||
|
||||
:doc:`sol::state_view<../api/state>` is exactly like ``sol::state``, but it doesn't manage the lifetime of a ``lua_State*``. Therefore, you get all the goodies that come with a ``sol::state`` without any of the ownership implications. Sol has no initialization components that need to deliberately remain alive for the duration of the program. It's entirely self-containing and uses lua's garbage collectors and various implementation techniques to require no state C++-side. After you do that, all of the power of `Sol` is available to you, and then some!
|
||||
:doc:`sol::state_view<../api/state>` is exactly like ``sol::state``, but it doesn't manage the lifetime of a ``lua_State*``. Therefore, you get all the goodies that come with a ``sol::state`` without any of the ownership implications. sol has no initialization components that need to deliberately remain alive for the duration of the program. It's entirely self-containing and uses lua's garbage collectors and various implementation techniques to require no state C++-side. After you do that, all of the power of `sol` is available to you, and then some!
|
||||
|
||||
``sol::state_view`` is also helpful when you want to `create a DLL that loads some Lua module`_ via requires.
|
||||
|
||||
You may also want to call ``require`` and supply a string of a script file or something that returns an object that you set equal to something in C++. For that, you can use the :ref:`require functionality<state-require-function>`.
|
||||
|
||||
Remember that Sol can be as lightweight as you want it: almost all of Sol's Lua types take the ``lua_State*`` argument and then a second ``int index`` stack index argument, meaning you can use :doc:`tables<../api/table>`, :doc:`lua functions<../api/function>`, :doc:`coroutines<../api/coroutine>`, and other reference-derived objects that expose the proper constructor for your use. You can also set :doc:`usertypes<../api/usertype>` and other things you need without changing your entire architecture in one go.
|
||||
Remember that sol can be as lightweight as you want it: almost all of sol's Lua types take the ``lua_State*`` argument and then a second ``int index`` stack index argument, meaning you can use :doc:`tables<../api/table>`, :doc:`lua functions<../api/function>`, :doc:`coroutines<../api/coroutine>`, and other reference-derived objects that expose the proper constructor for your use. You can also set :doc:`usertypes<../api/usertype>` and other things you need without changing your entire architecture in one go.
|
||||
|
||||
You can even customize it to `work with an external Lua wrapper/framework/library`_.
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
functions and You
|
||||
=================
|
||||
|
||||
Sol can register all kinds of functions. Many are shown in the :doc:`quick 'n' dirty<all-the-things>`, but here we will discuss many of the additional ways you can register functions into a sol-wrapped Lua system.
|
||||
sol can register all kinds of functions. Many are shown in the :doc:`quick 'n' dirty<all-the-things>`, but here we will discuss many of the additional ways you can register functions into a sol-wrapped Lua system.
|
||||
|
||||
Setting a new function
|
||||
----------------------
|
||||
|
||||
Given a C++ function, you can drop it into Sol in several equivalent ways, working similar to how :ref:`setting variables<writing-variables-demo>` works:
|
||||
Given a C++ function, you can drop it into sol in several equivalent ways, working similar to how :ref:`setting variables<writing-variables-demo>` works:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
@ -338,4 +338,4 @@ It can be used like so, inconjunction with ``sol::this_state``:
|
|||
}
|
||||
|
||||
|
||||
This covers almost everything you need to know about Functions and how they interact with Sol. For some advanced tricks and neat things, check out :doc:`sol::this_state<../api/this_state>` and :doc:`sol::variadic_args<../api/variadic_args>`. The next stop in this tutorial is about :doc:`C++ types (usertypes) in Lua<cxx-in-lua>`! If you need a bit more information about functions in the C++ side and how to best utilize arguments from C++, see :ref:`this note<function-argument-handling>`.
|
||||
This covers almost everything you need to know about Functions and how they interact with sol. For some advanced tricks and neat things, check out :doc:`sol::this_state<../api/this_state>` and :doc:`sol::variadic_args<../api/variadic_args>`. The next stop in this tutorial is about :doc:`C++ types (usertypes) in Lua<cxx-in-lua>`! If you need a bit more information about functions in the C++ side and how to best utilize arguments from C++, see :ref:`this note<function-argument-handling>`.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
getting started
|
||||
===============
|
||||
|
||||
Let's get you going with Sol! To start, you'll need to use a lua distribution of some sort. Sol doesn't provide that: it only wraps the API that comes with it, so you can pick whatever distribution you like for your application. There are lots, but the two popular ones are `vanilla Lua`_ and speedy `LuaJIT`_ . We recommend vanilla Lua if you're getting started, LuaJIT if you need speed and can handle some caveats: the interface for Sol doesn't change no matter what Lua version you're using.
|
||||
Let's get you going with sol! To start, you'll need to use a lua distribution of some sort. sol doesn't provide that: it only wraps the API that comes with it, so you can pick whatever distribution you like for your application. There are lots, but the two popular ones are `vanilla Lua`_ and speedy `LuaJIT`_ . We recommend vanilla Lua if you're getting started, LuaJIT if you need speed and can handle some caveats: the interface for sol doesn't change no matter what Lua version you're using.
|
||||
|
||||
If you need help getting or building Lua, check out the `Lua page on getting started`_. Note that for Visual Studio, one can simply download the sources, include all the Lua library files in that project, and then build for debug/release, x86/x64/ARM rather easily and with minimal interference. Just make sure to adjust the Project Property page to build as a static library (or a DLL with the proper define set in the ``Preprocessor`` step).
|
||||
|
||||
|
@ -59,7 +59,7 @@ The second line opens a single lua-provided library, "base". There are several o
|
|||
return 0;
|
||||
}
|
||||
|
||||
If you're interested in integrating Sol with a project that already uses some other library or Lua in the codebase, check out the :doc:`existing example<existing>` to see how to work with Sol when you add it to a project (the existing example covers ``require`` as well)!
|
||||
If you're interested in integrating sol with a project that already uses some other library or Lua in the codebase, check out the :doc:`existing example<existing>` to see how to work with sol when you add it to a project (the existing example covers ``require`` as well)!
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ You can take a reference to something that exists in Lua by pulling out a :doc:`
|
|||
lua["say"](keep_alive);
|
||||
|
||||
|
||||
Sol will not take ownership of raw pointers: raw pointers do not own anything. Sol will not delete raw pointers, because they do not (and are not supposed to) own anything:
|
||||
sol will not take ownership of raw pointers: raw pointers do not own anything. sol will not delete raw pointers, because they do not (and are not supposed to) own anything:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
|
@ -96,7 +96,7 @@ If you have something you know is going to last and you just want to give it to
|
|||
};
|
||||
|
||||
|
||||
Sol can detect ``nullptr``, so if you happen to return it there won't be any dangling because a ``sol::nil`` will be pushed.
|
||||
sol can detect ``nullptr``, so if you happen to return it there won't be any dangling because a ``sol::nil`` will be pushed.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ Take some time to learn the framework with these tutorials. But, if you need to
|
|||
|
||||
|
||||
.. toctree::
|
||||
:caption: Sol Tutorial
|
||||
:caption: sol Tutorial
|
||||
:name: tutorialtoc
|
||||
:maxdepth: 2
|
||||
|
||||
|
|
|
@ -58,8 +58,8 @@ Here are some other general advice and tips for understanding and dealing with u
|
|||
- Work on a copy by taking arguments or returning by value.
|
||||
- Do not use r-value references: they do not mean anything in Lua code.
|
||||
- Move-only types can only be taken by reference: sol3 cannot know if/when to move a value (except when serializing with perfect forwarding *into* Lua, but not calling a C++ function from Lua)
|
||||
* The actual metatable associated with the usertype has a long name and is defined to be opaque by the Sol implementation.
|
||||
* The actual metatable inner workings is opaque and defined by the Sol implementation, and there are no internal docs because optimizations on the operations are applied based on heuristics we discover from performance testing the system.
|
||||
* The actual metatable associated with the usertype has a long name and is defined to be opaque by the sol implementation.
|
||||
* The actual metatable inner workings is opaque and defined by the sol implementation, and there are no internal docs because optimizations on the operations are applied based on heuristics we discover from performance testing the system.
|
||||
|
||||
.. _here, that uses a few tricks: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_bitfields.cpp
|
||||
.. _Lua: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_advanced.cpp#L81
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# # # # sol2
|
||||
# # # # sol3
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors
|
||||
|
@ -20,7 +20,7 @@
|
|||
# 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.
|
||||
|
||||
# # # sol2 Examples
|
||||
# # # sol3 Examples
|
||||
|
||||
if (SOL2_DYNAMIC_LOADING_EXAMPLES OR SOL2_DYNAMIC_LOADING_EXAMPLES_SINGLE OR SOL2_DYNAMIC_LOADING_EXAMPLES_SINGLE_GENERATED)
|
||||
# # require_from_dll example
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# # # # sol2
|
||||
# # # # sol3
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors
|
||||
|
@ -20,7 +20,7 @@
|
|||
# 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.
|
||||
|
||||
# # # sol2 interop Examples - luabridge
|
||||
# # # sol3 interop Examples - luabridge
|
||||
|
||||
find_package(LuaBridgeBuild)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#define SOL_ENABLE_INTEROP 1 // MUST be defined to use interop features
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# # # # sol2
|
||||
# # # # sol3
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors
|
||||
|
@ -20,7 +20,7 @@
|
|||
# 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.
|
||||
|
||||
# # # sol2 interop Examples - kaguya
|
||||
# # # sol3 interop Examples - kaguya
|
||||
|
||||
find_package(KaguyaBuild)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <kaguya/kaguya.hpp>
|
||||
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#define SOL_ENABLE_INTEROP 1 // MUST be defined to use interop features
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# # # # sol2
|
||||
# # # # sol3
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors
|
||||
|
@ -20,7 +20,7 @@
|
|||
# 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.
|
||||
|
||||
# # # sol2 interop Examples - luwra
|
||||
# # # sol3 interop Examples - luwra
|
||||
|
||||
find_package(LuwraBuild)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#define SOL_ENABLE_INTEROP 1 // MUST be defined to use interop features
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
|
@ -55,7 +55,7 @@ inline bool sol_lua_interop_check(sol::types<T>, lua_State* L, int relindex, sol
|
|||
template <typename T>
|
||||
inline std::pair<bool, T*> sol_lua_interop_get(sol::types<T> t, lua_State* L, int relindex, void* unadjusted_pointer, sol::stack::record& tracking) {
|
||||
// you may not need to specialize this method every time:
|
||||
// some libraries are compatible with sol2's layout
|
||||
// some libraries are compatible with sol3's layout
|
||||
int index = lua_absindex(L, relindex);
|
||||
if (!sol_lua_interop_check(t, L, index, sol::type::userdata, sol::no_panic, tracking)) {
|
||||
return { false, nullptr };
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# # # # sol2
|
||||
# # # # sol3
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors
|
||||
|
@ -20,7 +20,7 @@
|
|||
# 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.
|
||||
|
||||
# # # sol2 interop Examples - tolua
|
||||
# # # sol3 interop Examples - tolua
|
||||
|
||||
find_package(ToLuappBuild REQUIRED)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#define SOL_ENABLE_INTEROP 1 // MUST be defined to use interop features
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# # # # sol2
|
||||
# # # # sol3
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors
|
||||
|
@ -20,7 +20,7 @@
|
|||
# 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.
|
||||
|
||||
# # # sol2 Examples - require_from_dll
|
||||
# # # sol3 Examples - require_from_dll
|
||||
|
||||
# # Reusable function to call for single target
|
||||
# # Also hides variables from directory/global scope
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <my_object/my_object.hpp>
|
||||
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
namespace my_object {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <my_object/my_object.hpp>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include "assert.hpp"
|
||||
|
||||
// Uses some of the fancier bits of sol2, including the "transparent argument",
|
||||
// Uses some of the fancier bits of sol3, including the "transparent argument",
|
||||
// sol::this_state, which gets the current state and does not increment
|
||||
// function arguments
|
||||
sol::object fancy_func(sol::object a, sol::object b, sol::this_state s) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include "assert.hpp"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include "assert.hpp"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include "assert.hpp"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include "assert.hpp"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include "assert.hpp"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <string>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include "assert.hpp"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include "assert.hpp"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -11,7 +11,7 @@ struct number_shim {
|
|||
|
||||
template <typename Handler>
|
||||
bool sol_lua_check(sol::types<number_shim>, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking) {
|
||||
// check_usertype is a backdoor for directly checking sol2 usertypes
|
||||
// check_usertype is a backdoor for directly checking sol3 usertypes
|
||||
if (!sol::stack::check_usertype<number_shim>(L, index)
|
||||
&& !sol::stack::check<double>(L, index)) {
|
||||
handler(L, index, sol::type_of(L, index), sol::type::userdata, "expected a number_shim or a number");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
// Something that can't be collided with
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
int main () {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
int main () {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
struct A {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
int main (int, char*[]) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <assert.hpp>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
|
||||
#include <sol/sol.hpp>
|
||||
#include <assert.hpp>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
|
||||
#include <sol/sol.hpp>
|
||||
#include <assert.hpp>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
|
|
42
examples/source/dump.cpp
Normal file
42
examples/source/dump.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include "assert.hpp"
|
||||
|
||||
|
||||
int main () {
|
||||
std::cout << "=== dump (serialize between states) ===" << std::endl;
|
||||
|
||||
// 2 states, transferring function from 1 to another
|
||||
sol::state lua;
|
||||
sol::state lua2;
|
||||
|
||||
// we're not going to run the code on the first
|
||||
// state, so we only actually need
|
||||
// the base lib on the second state
|
||||
// (where we will run the serialized bytecode)
|
||||
lua2.open_libraries(sol::lib::base);
|
||||
|
||||
// load this code (but do not run)
|
||||
sol::load_result lr = lua.load("a = function (v) print(v) return v end");
|
||||
// check if it's sucessfully loaded
|
||||
c_assert(lr.valid());
|
||||
|
||||
// turn it into a function, then dump the bytecode
|
||||
sol::protected_function target = lr;
|
||||
sol::bytecode target_bc = target.dump();
|
||||
|
||||
// reload the byte code
|
||||
// in the SECOND state
|
||||
auto result2 = lua2.safe_script(target_bc.as_string_view(), sol::script_pass_on_error);
|
||||
// check if it was done properly
|
||||
c_assert(result2.valid());
|
||||
|
||||
// check in the second state if it was valid
|
||||
sol::protected_function pf = lua2["a"];
|
||||
int v = pf(25557);
|
||||
c_assert(v == 25557);
|
||||
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user