diff --git a/docs/source/api/api-top.rst b/docs/source/api/api-top.rst index 516a4050..d2951ea0 100644 --- a/docs/source/api/api-top.rst +++ b/docs/source/api/api-top.rst @@ -20,6 +20,7 @@ Browse the various function and classes :doc:`Sol<../index>` utilizes to make yo property proxy reference + stack_reference resolve stack optional diff --git a/docs/source/api/reference.rst b/docs/source/api/reference.rst index 9c0c247f..f79d529e 100644 --- a/docs/source/api/reference.rst +++ b/docs/source/api/reference.rst @@ -10,6 +10,8 @@ general purpose reference to Lua object in registry This type keeps around a reference to something that was on the stack and places it in the Lua registry. It is the backbone for all things that reference items on the stack and needs to keep them around beyond their appearance and lifetime on said Lua stack. Its progeny include :doc:`sol::coroutine`, :doc:`sol::function`, :doc:`sol::`, :doc:`sol::object`, :doc:`sol::table`/:doc:`sol::global_table
`, :doc:`sol::`, and :doc:`sol::userdata`. +For all of these types, there's also a ``stack_{x}`` version of them, such as ``stack_table`` + members ------- diff --git a/docs/source/api/stack_reference.rst b/docs/source/api/stack_reference.rst new file mode 100644 index 00000000..db5359d1 --- /dev/null +++ b/docs/source/api/stack_reference.rst @@ -0,0 +1,8 @@ +stack_reference +=============== +zero-overhead object on the stack +--------------------------------- + +When you work with a :doc:`sol::reference`, the object gotten from the stack has a reference to it made in the registry, keeping it alive. If you want to work with the Lua stack directly without having any additional references made, ``sol::stack_reference`` is for you. Its API is identical to ``sol::reference`` in every way, except it contains a ``int stack_index()`` member function that allows you to retrieve the stack index. + +All of the base types have ``stack`` versions of themselves, and the APIs are identical to their non-stack forms. This includes :doc:`sol::stack_table
`, :doc:`sol::stack_function`, :doc:`sol::stack_protected_function`, :doc:`sol::stack_(light\_)userdata` and :doc:`sol::stack_object`. \ No newline at end of file diff --git a/docs/source/tutorial/all-the-things.rst b/docs/source/tutorial/all-the-things.rst index 2ba53dc3..3a4d0fd1 100644 --- a/docs/source/tutorial/all-the-things.rst +++ b/docs/source/tutorial/all-the-things.rst @@ -8,14 +8,14 @@ You'll need to ``#include ``/``#include "sol.hpp"`` somewhere in your c opening a state --------------- -Do it. - .. code-block:: cpp - sol::state lua; - // open some common libraries - lua.open_libraries(sol::lib::base, sol::lib::package); - lua.script( "print('bark bark bark!')" ); + int main (int argc, char* argv[]) { + sol::state lua; + // open some common libraries + lua.open_libraries(sol::lib::base, sol::lib::package); + lua.script( "print('bark bark bark!')" ); + } sol::state on lua_State* @@ -127,50 +127,6 @@ You can erase things by setting it to ``nullptr`` or ``sol::nil``. // second_try == 322 -multiple returns from lua -------------------------- - -.. code-block:: cpp - - sol::state lua; - - lua.script("function f (a, b, c) return a, b, c end"); - - std::tuple result = lua["f"](100, 200, 300); - // result == { 100, 200, 300 } - int a, int b; - std::string c; - sol::tie( a, b, c ) = lua["f"](100, 200, "bark"); - // a == 100 - // b == 200 - // c == "bark" - - -multiple returns to lua ------------------------ - -.. code-block:: cpp - - sol::state lua; - - lua["f"] = [](int a, int b, sol::object c) { - // sol::object can be anything here: just pass it through - return std::make_tuple( 100, 200, c ); - }; - - std::tuple result = lua["f"](100, 200, 300); - // result == { 100, 200, 300 } - - lua[] - // result == { 100, 200, 300 } - int a, int b; - std::string c; - sol::tie( a, b, c ) = lua["f"](100, 200, "bark"); - // a == 100 - // b == 200 - // c == "bark" - - tables ------ @@ -353,8 +309,52 @@ You can bind member variables as functions too: Can use ``sol::readonly( &some_class::variable )`` to make a variable readonly and error if someone tries to write to it. -C++ classes in Lua ------------------- +multiple returns from lua +------------------------- + +.. code-block:: cpp + + sol::state lua; + + lua.script("function f (a, b, c) return a, b, c end"); + + std::tuple result = lua["f"](100, 200, 300); + // result == { 100, 200, 300 } + int a, int b; + std::string c; + sol::tie( a, b, c ) = lua["f"](100, 200, "bark"); + // a == 100 + // b == 200 + // c == "bark" + + +multiple returns to lua +----------------------- + +.. code-block:: cpp + + sol::state lua; + + lua["f"] = [](int a, int b, sol::object c) { + // sol::object can be anything here: just pass it through + return std::make_tuple( 100, 200, c ); + }; + + std::tuple result = lua["f"](100, 200, 300); + // result == { 100, 200, 300 } + + std::tuple resutl2 = lua["f"](100, 200, "BARK BARK BARK!") + // result == { 100, 200, "BARK BARK BARK!" } + int a, int b; + std::string c; + sol::tie( a, b, c ) = lua["f"](100, 200, "bark"); + // a == 100 + // b == 200 + // c == "bark" + + +C++ classes in from C++ +----------------------- Everything that is not a: @@ -627,6 +627,38 @@ Use/return a ``unique_ptr`` or ``shared_ptr`` instead or just return a value: auto my_unique = std::make_unique(); lua["other_thing"] = std::move(my_unique); +If you have something you know is going to last and you just want to give it to Lua as a reference, then it's fine too: + +.. code-block:: cpp + + // :ok: + lua["my_func"] = []() -> my_type* { + static my_type mt; + return &mt; + }; + + +Sol can detect ``nullptr``s, so if you happen to return it there won't be any dangling because a ``sol::nil`` will be pushed. + +.. code-block:: cpp + + struct my_type { + void stuff () {} + }; + + sol::state lua; + + // BUT THIS IS STILL BAD DON'T DO IT AAAHHH BAD + // return a unique_ptr still or something! + lua["my_func"] = []() -> my_type* { + return nullptr; + }; + + // Acceptable, it will set ``something`` to nil (and delete it on next GC if there's no more references) + lua.set("something", nullptr); + + // Also fine + lua["something_else"] = nullptr; advanced -------- @@ -634,6 +666,8 @@ advanced Some more advanced things you can do: * :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:`stack references<../api/stack_reference>` to have zero-overhead Sol abstractions while not copying to the Lua registry. + * :doc:`unique usertype traits<../api/unique_usertype_traits>` allows you to specialize handle/RAII types from other frameworks, like boost, and Unreal, to work with Sol. * :doc:`variadic arguments<../api/variadic_args>` in functions with ``sol::variadic_args``. * :doc:`this_state<../api/this_state>` to get the current ``lua_State*``. * :doc:`resolve<../api/resolve>` overloads in case you have overloaded functions; a cleaner casting utility. \ No newline at end of file