Documentation update, get_or for proxies, and other goodies.

This commit is contained in:
ThePhD 2016-04-09 00:55:12 -04:00
parent eb91320652
commit 16007fa792
19 changed files with 414 additions and 128 deletions

View File

@ -61,6 +61,13 @@ The following are the members of ``sol::coroutine``:
members members
------- -------
.. code-block:: cpp
:caption: function: constructor
coroutine(lua_State* L, int index = -1);
Grabs the coroutine at the specified index given a ``lua_State*``.
.. code-block:: cpp .. code-block:: cpp
:caption: returning the coroutine's status :caption: returning the coroutine's status
:name: status :name: status

View File

@ -7,7 +7,15 @@ calling functions bound to Lua
class function : public reference; class function : public reference;
Function is a correct-assuming version of :doc:`protected_function<protected_function>`, omitting the need for typechecks and error handling. It is the default function type of Sol. When called without the return types being specified by either a ``sol::types<...>`` list or a ``call<Ret...>( ... )`` template type list, it generates a :ref:`function_result<function-result>` class that gets implicitly converted to the requested return type. For example: Function is a correct-assuming version of :doc:`protected_function<protected_function>`, omitting the need for typechecks and error handling. It is the default function type of Sol. Grab a function directly off the stack using the constructor:
.. code-block:: cpp
:caption: constructor: function
function(lua_State* L, int index = -1);
When called without the return types being specified by either a ``sol::types<...>`` list or a ``call<Ret...>( ... )`` template type list, it generates a :ref:`function_result<function-result>` class that gets implicitly converted to the requested return type. For example:
.. code-block:: lua .. code-block:: lua
:caption: func_barks.lua :caption: func_barks.lua

View File

@ -14,6 +14,13 @@ general-purpose safety reference to an existing object
members members
------- -------
.. code-block:: cpp
:caption: constructor: coroutine
coroutine(lua_State* L, int index = -1);
Create an object which references the specific element at the given index in the specified ``lua_State*``.
.. code-block:: cpp .. code-block:: cpp
:caption: function: type conversion :caption: function: type conversion

View File

@ -7,7 +7,15 @@ Lua function calls that trap errors and provide error handler
class protected_function : public reference; class protected_function : public reference;
Inspired by a request from `starwing<https://github.com/starwing>` in the old repository, this class provides the same interface as :doc:`function<function>` but with heavy protection and a potential error handler for any Lua errors and C++ exceptions. When called without the return types being specified by either a ``sol::types<...>`` list or a ``call<Ret...>( ... )`` template type list, it generates a :doc:`protected_function_result<proxy>` class that gets implicitly converted to the requested return type. For example: Inspired by a request from `starwing<https://github.com/starwing>` in the old repository, this class provides the same interface as :doc:`function<function>` but with heavy protection and a potential error handler for any Lua errors and C++ exceptions. Grab a function directly off the stack using the constructor:
.. code-block:: cpp
:caption: constructor: protected_function
protected_function(lua_State* L, int index = -1);
When called without the return types being specified by either a ``sol::types<...>`` list or a ``call<Ret...>( ... )`` template type list, it generates a :doc:`protected_function_result<proxy>` class that gets implicitly converted to the requested return type. For example:
.. code-block:: lua .. code-block:: lua
:caption: pfunc_barks.lua :caption: pfunc_barks.lua

View File

@ -14,6 +14,13 @@ This type keeps around a reference to something that was on the stack and places
members members
------- -------
.. code-block:: cpp
:caption: constructor: reference
reference(lua_State* L, int index = -1);
Creates a reference from the Lua stack at the specified index, saving it into the metatable registry. This constructor is exposed on all types that derive from ``sol::reference``.
.. code-block:: cpp .. code-block:: cpp
:caption: function: push referred-to element from the stack :caption: function: push referred-to element from the stack

View File

@ -7,7 +7,7 @@ the nitty-gritty core abstraction layer over Lua
namespace stack 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<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>`.
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:`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.

View File

@ -21,6 +21,13 @@ Tables are the core of Lua, and they are very much the core of Sol.
members members
------- -------
.. code-block:: cpp
:caption: constructor: table
table(lua_State* L, int index = -1);
Takes a table from the Lua stack at the specified index and allows a person to use all of the abstractions therein.
.. code-block:: cpp .. code-block:: cpp
:caption: function: get / traversing get :caption: function: get / traversing get
@ -30,6 +37,9 @@ members
template<typename T, typename... Keys> template<typename T, typename... Keys>
decltype(auto) traverse_get(Keys&&... keys) const; decltype(auto) traverse_get(Keys&&... keys) const;
template<typename T, typename Key>
decltype(auto) get_or(Key&& key, T&& otherwise) const;
template<typename T, typename Key, typename D> template<typename T, typename Key, typename D>
decltype(auto) get_or(Key&& key, D&& otherwise) const; decltype(auto) get_or(Key&& key, D&& otherwise) const;

View File

@ -12,6 +12,13 @@ a separate state that can contain and run functions
members members
------- -------
.. code-block:: cpp
:caption: constructor: thread
thread(lua_State* L, int index = -1);
Takes a thread from the Lua stack at the specified index and allows a person to use all of the abstractions therein.
.. code-block:: cpp .. code-block:: cpp
:caption: function: view into thread_state()'s state :caption: function: view into thread_state()'s state

View File

@ -52,59 +52,86 @@ The Feature Matrix™
The below feature table checks for the presence of something. It, however, does not actually account for any kind of laborious syntax. The below feature table checks for the presence of something. It, however, does not actually account for any kind of laborious syntax.
✔ full support ✔ full support: works as you'd expecte (operator[] on tables, etc...)
~ partial support / wonky support ~ partial support / wonky support: this means its either supported through some other fashion (not with the desired syntax, serious caveats, etc.). Sometimes means dropping down t use the plain C API.
✗ no support ✗ no support: feature doesn't work or, if it's there, it REALLY sucks to use
Implementation notes from using the libraries are below the tables.
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ category explanations
| | plain C | luawrapper | lua-intf | luabind | Selene | Sol | oolua | lua-api-pp | kaguya | ---------------------
| | | | | | | | | | |
+===========================+=============+============+==========+=========+==========+===========+===========+================+==========+ Explanations for a few categories are below (rest are self-explanatory).
| tables | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ * 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 framework with similar semantics is also acceptable
| table chaining | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | * 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 do nest 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 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | * arbitrary keys: Letting C++ code use userdata, other tables, integers, etc. as keys for into a table without dropping to the plain API.
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ * user-defined types (udts): C++ types given form and function in lua code.
| user-defined types (udts) | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | * udts - member functions: C++ member functions on a type, usually callable with ``my_object:foo(1)`` or similar in Lua.
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ * udts - variables: C++ member variables, manipulated by ``my_object.var = 24`` and friends
| udts: member functions | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | * function bindind:
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ * protected function:
| udts: variables | ~ | ~ | ~ | ~ | ~ | ✔ | ~ | ~ | ~ | * multi-return: returning multiple values from and to lua
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ * inheritance: allowing some degree of subtyping or inheritance on classes / userdata from lua
| stack abstractions | ~ | ✔ | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | * overloading: the ability to call overloaded functions, matched based on arity or type (``foo( 1 )`` from lua calls a different function then ``foo( "bark" )``).
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ * lua thread: basic wrapping of the lua thread API; ties in with coroutine.
| function binding | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | * coroutines: allowing a function to be called multiple times,
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
| protected function | ✔ | ✗ | ~ | ~ | ~ | ✔ | ~ | ✔ | ~ | +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ | | plain C | luawrapper | lua-intf | luabind | Selene | Sol | oolua | lua-api-pp | kaguya | SLB | SWIG | luacppinterface |
| multi-return | ~ | ✗ | ✗ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | | | | | | | | | | | | | | |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ +===========================+=============+============+==========+=========+==========+===========+===========+================+==========+==========+===========+=================+
| inheritance | ~ | ✗ | ✗ | ✔ | ✔ | ✔ | ~ | ~ | ✔ | | optional | ~ | ✗ | ✗ | ✗ | ✗ | ✔ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| overloading | ~ | ✗ | ✗ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | | tables | ~ | ~ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✗ | ✗ | ~ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| thread | ✔ | ✗ | ✗ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | | table chaining | ~ | ~ | ✔ | ✔ | ✔ | ✔ | ✗ | ✔ | ✔ | ✗ | ✗ | ~ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| coroutines | ✔ | ✗ | ✗ | ✔ | ✔ | ✔ | ✗ | ✗ | ✔ | | arbitrary keys | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✗ | ~ | ✔ | ✗ | ✗ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| no-rtti support | ✔ | ✗ | ~ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | | user-defined types (udts) | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✔ | ✔ | ✔ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| no-exception support | ✔ | ✗ | ~ | ~ | ✗ | ✔ | ✔ | ✗ | ✔ | | udts: member functions | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✔ | ✔ | ✔ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| Lua 5.1 | ✔ | ✔ | ~ | ✔ | ✗ | ✔ | ✔ | ✔ | ✔ | | udts: variables | ~ | ~ | ~ | ~ | ~ | ✔ | ~ | ~ | ~ | ✗ | ✔ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| Lua 5.2 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | stack abstractions | ~ | ✔ | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ✗ | ~ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| Lua 5.3 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | lua function from C(++) | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| luajit | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | function binding | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| distribution | compile | header | both | compile | header | header | compile | compile | header | | protected function | ~ | ✗ | ~ | ~ | ~ | ✔ | ~ | ✔ | ~ | ~ | ~ | ~ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+ +---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| multi-return | ~ | ✗ | ✗ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ~ | ✔ | ~ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| inheritance | ~ | ✗ | ✗ | ✔ | ✔ | ✔ | ~ | ~ | ✔ | ~ | ✔ | ~ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| overloading | ~ | ✗ | ✗ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✔ | ✔ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| lua thread | ~ | ✗ | ✗ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✗ | ✗ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| coroutines | ~ | ✗ | ✗ | ✔ | ✔ | ✔ | ✗ | ✗ | ✔ | ✗ | ✗ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| no-rtti support | ✔ | ✗ | ~ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| no-exception support | ✔ | ✗ | ~ | ~ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| Lua 5.1 | ✔ | ✔ | ~ | ✔ | ✗ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| Lua 5.2 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| Lua 5.3 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| luajit | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
| distribution | compile | header | both | compile | header | header | compile | compile | header | compile | generated | compile |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+
notes on implementations notes on implementations
------------------------ ------------------------
@ -113,15 +140,25 @@ Plain C -
* Obviously you can do anything you want with Plain C, but the effort involved is astronomical in comparison to what frameworks offer * Obviously you can do anything you want with Plain C, but the effort involved is astronomical in comparison to what frameworks offer
* Does not scale very well (in terms of developer ease of use) * Does not scale very well (in terms of developer ease of use)
* Compilation (or package manager use) is obviously required for your platform and required to use ANY of these libraries whatsoever * Compilation (or package manager use) is obviously required for your platform and required to use ANY of these libraries, but that's okay because all libraries need some version of Lua anyways, so you always have this!
luawrapper - kaguya -
* Takes the approach of writing and reading tables using ``readVariable`` and ``writeVariable`` functions * Probably the closest in implementation details and interface to Sol itself
* C++11 * Inspired coroutine support for Sol
* No macros * Library author (satoren) is a nice guy!
* The interface can be clunky (no table-like data structures: most things go though ``readVariable`` / ``writeVariable``) * C++11/14, or boostified (which makes it C++03 compatible)
* Clas registration is a bit verbose, but not as offensive as OOLua or lua-intf or others
* Deserves lots of love!
Sol -
* Only library with Optional support, hoorah!
* Prrreeettty fast (still working on being the ABSOLUTE FASTEST)!
* Overloading support can get messy with inheritance, see :doc:`here<api/overload>`
* C++14/"C++1y" (-std=c++14, -std=c++1y, =std=c++1z) flags are used (available since GCC 4.9 and Clang 3.5)
* Active issues, active individuals
* Deserves lots of love!
lua-intf - lua-intf -
@ -130,6 +167,37 @@ lua-intf -
* Macro-based registration (strange pseudo-language) * Macro-based registration (strange pseudo-language)
* Fairly fast in most regards * Fairly fast in most regards
* Registering classes/"modules" in using C++ code is extremely verbose * Registering classes/"modules" in using C++ code is extremely verbose
* Not too shabby!
Selene -
* member variables are automatically turned into ``obj:set_x( value )`` to set and ``obj:x()`` to get
* Registering classes/"modules" using C++ code is extremely verbose, similar to lua-intf's style
* Eats crap when it comes to performance, most of the time (see :doc:`benchmarks<benchmarks>`)
* Lots of users, but the Repository is kinda stagnant...
luawrapper -
* Takes the approach of writing and reading tables using ``readVariable`` and ``writeVariable`` functions
* C++11
* No macros!
* The interface can be clunky (no table-like data structures: most things go though ``readVariable`` / ``writeVariable``)
SWIG (3.0) -
* Very comprehensive for binding concepts of C++ (classes, variables, etc.) to lua
* Helps with literally nothing else (tables, threads, stack abstractions, etc.)
* Not really a good, full-featured Library...
* Requires preprocessing step (but it's not a... TERRIBLY complicated preprocessing step); some boilerplate in writing additional classes that you've already declared
luacppinterface -
* It seems like a decent library, until you try to get a function put into Lua using CreateFunction, and then getting it out again -- it fails miserably
* No member variable support
* Actually has tables (but no operator[])
* Does not support arbitrary keys
* Really has potential, but falls down on its face...
luabind - luabind -
@ -137,40 +205,36 @@ luabind -
* Strange in-lua keywords and parsing to allow for classes to be written in lua * Strange in-lua keywords and parsing to allow for classes to be written in lua
- not sure if good feature; vendor lock-in to that library to depend on this specific class syntax? - not sure if good feature; vendor lock-in to that library to depend on this specific class syntax?
Selene -
* member variables are automatically turned into ``obj:set_x( value )`` to set and ``obj:x()`` to get
* Registering classes/"modules" using C++ code is extremely verbose
Sol -
* Overloading support can get messy with inheritance, see :doc:`here<api/overload>`
* Only (?) library that supports table-like use of variables as shown in the :doc:`sneak peek<index>`
* C++14/"C++1y" (-std=c++14, -std=c++1y, =std=c++1z) flags are used (available since GCC 4.9 and Clang 3.5)
oolua -
* The syntax for this library is thicker than a brick. No, seriously. `Go read the docs.`_
* Supports not having exceptions or rtti turned on (shiny!)
.. _ fn1:
lua-api-pp - lua-api-pp -
* Compiled, but the recommendation is to add the source files directly to your project * Compiled, but the recommendation is to add the source files directly to your project
* Userdata registration with nice, thick macros: LUAPP_USERDATA( ... ) plus a bunch of free functions that take a ``T& self`` argument * Userdata registration with thick setup-macros: LUAPP_USERDATA( ... ) plus a bunch of free functions that take a ``T& self`` argument
- You can still bind member functions straight away in some cases, however
* You have to create a context and then call it to start accessing the lua state (adding more boilerplate... thanks)
- Thankfully, unlike many libraries, it actually has a Table type that can be used semi-easily. FINALLY.
* C++11-ish in some regards * C++11-ish in some regards
kaguya - SLB3 -
* Probably the closest in implementation details and interface to Sol itself * Old code exported to github from dying google code
* Inspired coroutine support for Sol * ".NET Style" - to override functionality, derive from class -- boilerplate (isn't that what we're trying to get rid of?)
* Library author (satoren) is a nice guy! * Pointers everywhere: ownership semantics unclear
* C++11/14, or boostified (which makes it C++03 compatible) * Piss-poor documentation, ugh!
* Least favorite to work with, for sure!
TODO: oolua -
* SWIG - http://www.swig.org/Doc1.3/Lua.html#Lua_nn2
* SLB3 - https://code.google.com/archive/p/slb/ * The syntax for this library is thicker than a brick. No, seriously. `Go read the docs`_
* The worst in terms of how to use it: may have docs, but the DSL (despite using C++11) is extraordinarily crappy with thick, hard-to-debug/hard-to-error-check macros (and seems not to compile on VS 2015 Update 2 properly for Userdata bindings?)
* Supports not having exceptions or rtti turned on (shiny!)
* Poor RAII support: default-construct-and-get style (requires some form of initalization to perform a ``get`` of an object, and it's hard to extend)
luwra -
* Mentioned here because... well, it's a thing
* Lightweight (read: feature-starved) wrapper library
* Can push/pop to the global namespace, but doing anymore more detailed is... harder
* Might as well go with luawrapper if you're going to bother
.. _Go read the docs.: https://oolua.org/docs/index.html .. _Go read the docs: https://oolua.org/docs/index.html

View File

@ -21,7 +21,8 @@ get going:
:maxdepth: 1 :maxdepth: 1
:name: mastertoc :name: mastertoc
api/top tutorial/tutorial-top
api/api-top
features features
benchmarks benchmarks
safety safety
@ -33,7 +34,7 @@ get going:
"I need feature X, maybe you have it?" "I need feature X, maybe you have it?"
-------------------------------------- --------------------------------------
Take a look at the :doc:`Features<features>` page: it links to much of the API. You can also just straight up browse the API. Don't see a feature you want? Send inquiries for support for a particular abstraction to the `issues`_ tracker. Take a look at the :doc:`Features<features>` page: it links to much of the API. You can also just straight up browse the :doc:`api<api/api-top>` or ease in with the :doc:`tutorials<tutorial/tutorial-top>`. Don't see a feature you want? Send inquiries for support for a particular abstraction to the `issues`_ tracker.
the basics: the basics:

View File

@ -0,0 +1,4 @@
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.

View File

@ -12,7 +12,12 @@ If you're already using lua and you just want to use ``sol`` in some places, you
// start using Sol with a pre-existing system // start using Sol with a pre-existing system
sol::state_view lua(L); // non-owning sol::state_view lua(L); // non-owning
lua.script("print('bark bark bark!')") lua.script("print('bark bark bark!')");
sol::table expected_table(L); // get the table off the top of the stack
// start using it...
} }
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. 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!
Remember that Sol can be as lightweight as you want it: almost all of Sol's 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:`tables<../api/table>`, and other reference-derived objects that expose the proper constructor for your use.

View File

@ -0,0 +1,4 @@
functions and You
=================
Sol can register all kinds of functions.

View File

@ -3,14 +3,20 @@ 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.
When you're ready: try compiling this short snippet: After that, make sure you grab either the `single header file release`_, or just perform a clone of the `github repository here`_ and set your include paths up so that you can get at ``sol.hpp`` somehow. We recommend the single-header-file release, since it's easier to move around, manage and update if you commit it with some form of version control.
.. note::
If you get an avalanche of errors (particularly referring to ``auto``), you may not have enabled C++14 / C++17 mode for your compiler. Add one of ``std=c++14``, ``std=c++1z`` OR ``std=c++1y`` to your compiler options. By default, this is always-on for VC++ compilers in Visual Studio and friends, but g++ and clang++ require a flag (unless you're on `GCC 6.0`_).
When you're ready, try compiling this short snippet:
.. code-block:: cpp .. code-block:: cpp
:linenos: :linenos:
:caption: the first snippet :caption: the first snippet
:name: the-first-snippet :name: the-first-snippet
#include "sol.hpp" // or #include <sol.hpp>, whichever suits your needs #include <sol.hpp> // or #include "sol.hpp", whichever suits your needs
int main (int argc, char* argv[]) { int main (int argc, char* argv[]) {
@ -22,7 +28,9 @@ When you're ready: try compiling this short snippet:
return 0; return 0;
} }
If this works, you're ready to start! The first line creates the ``lua_State`` and will hold onto it for the duration of the scope its declared in (e.g., from the opening ``{`` to the closing ``}``). It will automatically close / cleanup that lua state when it gets destructed. The second line opens a single lua-provided library, "base". There are several other libraries that come with lua that you can open by default, and those are included in the :ref:`sol::lib::base<lib-enum>` enumeration. If this works, you're ready to start! The first line creates the ``lua_State`` and will hold onto it for the duration of the scope its declared in (e.g., from the opening ``{`` to the closing ``}``). It will automatically close / cleanup that lua state when it gets destructed. The second line opens a single lua-provided library, "base". There are several other libraries that come with lua that you can open by default, and those are included in the :ref:`sol::lib<lib-enum>` enumeration.
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!
Next, let's start :doc:`reading/writing some variables<variables>` from Lua into C++, and vice-versa! Next, let's start :doc:`reading/writing some variables<variables>` from Lua into C++, and vice-versa!
@ -30,3 +38,9 @@ Next, let's start :doc:`reading/writing some variables<variables>` from Lua into
.. _vanilla Lua: https://www.lua.org/ .. _vanilla Lua: https://www.lua.org/
.. _LuaJIT: http://luajit.org/ .. _LuaJIT: http://luajit.org/
.. _GCC 6.0: https://gcc.gnu.org/gcc-6/changes.html
.. _single header file release: https://github.com/ThePhD/sol2/releases
.. _github repository here: https://github.com/ThePhD/sol2

View File

@ -0,0 +1,16 @@
get going FAST
==============
Ride into the speed lane by learning the all the ins-and-outs of Sol with these tutorials! You'll be up and running in minutes, maybe even faster if you're just That Good™.
.. toctree::
:caption: Sol Tutorial
:name: tutorialtoc
:maxdepth: 1
getting-started
existing
variables
functions
cxx-in-lua

View File

@ -18,6 +18,8 @@ reading
:caption: main.cpp :caption: main.cpp
:name: variables-main-cpp :name: variables-main-cpp
#include <sol.hpp>
int main () { int main () {
sol::state lua; sol::state lua;
@ -32,6 +34,8 @@ You can interact with the variables like this:
:caption: main.cpp extended :caption: main.cpp extended
:name: extended-variables-main-cpp :name: extended-variables-main-cpp
#include <sol.hpp>
#include <tuple>
#include <utility> // for std::pair #include <utility> // for std::pair
int main () { int main () {
@ -50,13 +54,13 @@ You can interact with the variables like this:
// table and state can have multiple things pulled out of it too // table and state can have multiple things pulled out of it too
std::pair<int, int> xyresolution = resolution.get<int, int>( "x", "y" ); std::pair<int, int> xyresolution = resolution.get<int, int>( "x", "y" );
// As an example, you can also pull out a tuple as well // As an example, you can also pull out a tuple as well
// std::tuple<int, int> xyresolution = resolution.get<int, int>( "x", "y" ); std::tuple<int, int> xyresolutiontuple = resolution.get<int, int>( "x", "y" );
return 0; return 0;
} }
From this example, you can see that there's many ways to pull out the varaibles you want. Some can be more safe than others. For example, to determine if a nested variable exists or not, you can use ``auto`` to capture the value of a ``table[key]`` lookup, and then use the ``.valid()`` method: From this example, you can see that there's many ways to pull out the varaibles you want. You can get For example, to determine if a nested variable exists or not, you can use ``auto`` to capture the value of a ``table[key]`` lookup, and then use the ``.valid()`` method:
.. code-block:: cpp .. code-block:: cpp
:caption: safe lookup :caption: safe lookup
@ -69,7 +73,7 @@ From this example, you can see that there's many ways to pull out the varaibles
// Branch taken: config is a not a variable // Branch taken: config is a not a variable
} }
This comes in handy when you want to check if a nested variable exists. You can also check if a toplevel variable is present or not by using ``sol::optional``, which also checks if the type you're trying to get is of a specific type: This comes in handy when you want to check if a nested variable exists. You can also check if a toplevel variable is present or not by using ``sol::optional``, which also checks if A) the keys you're going into exist and B) the type you're trying to get is of a specific type:
.. code-block:: cpp .. code-block:: cpp
:caption: optional lookup :caption: optional lookup
@ -89,3 +93,89 @@ This comes in handy when you want to check if a nested variable exists. You can
// Branch not taken: that variable is not present // Branch not taken: that variable is not present
} }
This can come in handy when, even in optimized or release modes, you still want the safety of checking. You can also use the `get_or` methods to, if a certain value may be present but you just want to default the value to something else:
.. code-block:: cpp
:caption: get_or lookup
// this will result in a value of '24'
int is_defaulted = lua["config"]["fullscreen"].get_or( 24 );
// This will result in the value of the config, which is 'false'
bool is_not_defaulted = lua["config"]["fullscreen"];
That's all it takes to read variables!
writing
-------
Writing gets a lot simpler. Even without scripting a file or a string, you can read and write variables into lua as you please:
.. code-block:: cpp
:caption: main.cpp
:name: writing-main-cpp
#include <sol.hpp>
#include <iostream>
int main () {
sol::state lua;
// open those basic lua libraries again, like print() etc.
lua.open_libs( sol::lib::base );
// value in the global table
lua["bark"] = 50;
// a table being created in the global table
lua["some_table"] = lua.create_table_with(
"key0", 24,
"key1", 25,
lua["bark"], "the key is 50 and this string is its value!"
);
// Run a plain ol' string
// Using a "Raw String Literal" to have multi-line goodness: http://en.cppreference.com/w/cpp/language/string_literal
lua.script(R"(
print(some_table[50])
print(some_table["key0"])
print(some_table["key1"])
-- a lua comment: access a global in a lua script with the _G table
print(_G["bark"])
)");
return 0;
}
This example pretty much sums up what can be done. Note that the syntax ``lua["non_existing_key_1"] = 1`` will make that variable, but if you tunnel too deep without first creating a table, the Lua API will panic (e.g., ``lua["does_not_exist"]["b"] = 20`` will trigger a panic). You can also be lazy with reading / writing values:
.. code-block:: cpp
:caption: main.cpp
:name: lazy-main-cpp
#include <sol.hpp>
#include <iostream>
int main () {
sol::state lua;
auto barkkey = lua["bark"];
if (barkkey.valid()) {
// Branch not taken: doesn't exist yet
std::cout << "How did you get in here, arf?!" << std::endl;
}
barkkey = 50;
if (barkkey.valid()) {
// Branch taken: value exists!
std::cout << "Bark Bjork Wan Wan Wan" << std::endl;
}
}
It's easy to see that there's a lot of options to do what you want here. But, these are just traditional numbers and strings. What if we want more power, more capabilities than what these limited types can offer us? Let's throw some :doc:`functions in there<functions>` :doc:`C++ classes into the mix<cxx-in-lua>`!

View File

@ -78,6 +78,25 @@ public:
return tuple_get<T>( std::make_index_sequence<std::tuple_size<meta::Unqualified<key_type>>::value>() ); return tuple_get<T>( std::make_index_sequence<std::tuple_size<meta::Unqualified<key_type>>::value>() );
} }
template<typename T>
decltype(auto) get_or(T&& otherwise) const {
typedef decltype(get<T>()) U;
sol::optional<U> option = get<sol::optional<U>>();
if (option) {
return static_cast<U>(option.value());
}
return static_cast<U>(std::forward<T>(otherwise));
}
template<typename T, typename D>
decltype(auto) get_or(D&& otherwise) const {
sol::optional<T> option = get<sol::optional<T>>();
if (option) {
return static_cast<T>(option.value());
}
return static_cast<T>(std::forward<D>(otherwise));
}
template <typename K> template <typename K>
decltype(auto) operator[](K&& k) const { decltype(auto) operator[](K&& k) const {
auto keys = meta::tuplefy(key, std::forward<K>(k)); auto keys = meta::tuplefy(key, std::forward<K>(k));

View File

@ -291,12 +291,10 @@ TEST_CASE("simple/get_or", "check if table.get_or works correctly") {
sol::state lua; sol::state lua;
auto bob_table = lua.create_table("bob"); auto bob_table = lua.create_table("bob");
int is_set=0;
int is_not_set=0;
bob_table.set("is_set", 42); bob_table.set("is_set", 42);
is_set = bob_table.get_or("is_set", 3); int is_set = bob_table.get_or("is_set", 3);
is_not_set = bob_table.get_or("is_not_set", 22); int is_not_set = bob_table.get_or("is_not_set", 22);
REQUIRE(is_set == 42); REQUIRE(is_set == 42);
REQUIRE(is_not_set == 22); REQUIRE(is_not_set == 22);
@ -306,6 +304,23 @@ TEST_CASE("simple/get_or", "check if table.get_or works correctly") {
REQUIRE(bark == 55.6); REQUIRE(bark == 55.6);
} }
TEST_CASE("simple/proxy_get_or", "check if proxy.get_or works correctly") {
sol::state lua;
auto bob_table = lua.create_table("bob");
bob_table.set("is_set", 42);
int is_set = bob_table["is_set"].get_or( 3 );
int is_not_set = bob_table[ "is_not_set" ].get_or( 22 );
REQUIRE(is_set == 42);
REQUIRE(is_not_set == 22);
lua["joe"] = 55.6;
double bark = lua["joe"].get_or<double>( 60 );
REQUIRE(bark == 55.6);
}
TEST_CASE("simple/addition", "check if addition works and can be gotten through lua.get and lua.set") { TEST_CASE("simple/addition", "check if addition works and can be gotten through lua.get and lua.set") {
sol::state lua; sol::state lua;