summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/sol2/docs/source/tutorial/all-the-things.rst
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/sol2/docs/source/tutorial/all-the-things.rst')
-rw-r--r--3rdparty/sol2/docs/source/tutorial/all-the-things.rst628
1 files changed, 0 insertions, 628 deletions
diff --git a/3rdparty/sol2/docs/source/tutorial/all-the-things.rst b/3rdparty/sol2/docs/source/tutorial/all-the-things.rst
deleted file mode 100644
index 3b764b8d2e9..00000000000
--- a/3rdparty/sol2/docs/source/tutorial/all-the-things.rst
+++ /dev/null
@@ -1,628 +0,0 @@
-tutorial: quick 'n' dirty
-=========================
-
-These are all the things. Use your browser's search to find things you want.
-
-You'll need to ``#include <sol.hpp>``/``#include "sol.hpp"`` somewhere in your code. Sol is header-only, so you don't need to compile anything.
-
-opening a state
----------------
-
-.. code-block:: cpp
-
- 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*
-------------------------
-
-For your system/game that already has lua, but you'd like something nice:
-
-.. code-block:: cpp
-
- int pre_existing_system( lua_State* L ) {
- sol::state_view lua(L);
- lua.script( "print('bark bark bark!')" );
- return 0;
- }
-
-
-running lua code
-----------------
-
-.. code-block:: cpp
-
- sol::state lua;
- // load and execute from string
- lua.script("a = 'test'");
- // load and execute from file
- lua.script_file("path/to/luascript.lua");
-
- // run a script, get the result
- int value = lua.script("return 54");
- // value == 54
-
-To check the success of a loading operation:
-
-.. code-block:: cpp
-
- // load file without execute
- sol::load_result script1 = lua.load_file("path/to/luascript.lua");
- script1(); //execute
- // load string without execute
- sol::load_result script2 = lua.load("a = 'test'");
- script2(); //execute
-
- sol::load_result script3 = lua.load("return 24");
- int value2 = script3(); // execute, get return value
- // value2 == 24
-
-
-To check whether a script was successfully run or not (after loading is assumed to be successful):
-
-.. code-block:: cpp
-
- // execute and return result
- sol::protected_function_result result1 = lua.do_string("return 24");
- if (result1.valid()) {
- int value = result1;
- // value == 24
- // yay!
- }
- else {
- // ahhh :c
- }
-
-
-There is also ``lua.do_file("path/to/luascript.lua");``.
-
-set and get variables
----------------------
-
-You can set/get everything.
-
-.. code-block:: cpp
-
- sol::lua_state lua;
-
- lua.open_libraries(sol::lib::base);
-
- // integer types
- lua.set("number", 24);
-
- // floating point numbers
- lua["number2"] = 24.5;
-
- // string types
- lua["important_string"] = "woof woof";
-
- // non-recognized types is stored as userdata
- // is callable, therefore gets stored as a function
- lua["a_function"] = [](){ return 100; };
-
- // make a table
- lua["some_table"] = lua.create_table_wth("value", 24);
-
-
-Equivalent to loading a lua file with:
-
-.. code-block:: lua
-
- number = 24
- number2 = 24.5
- important_string = "woof woof"
- a_function = function () return 100 end
- some_table = { value = 24 }
-
-Retrieve these variables using this syntax:
-
-.. code-block:: cpp
-
- // implicit conversion
- int number = lua["number"];
-
- // explicit get
- auto number2 = lua.get<double>("number2");
-
- // strings too
- std::string important_string = lua["important_string"];
-
- // dig into a table
- int value = lua["some_table"]["value"];
-
- // get a function
- sol::function a_function = lua["a_function"];
- int value_is_100 = a_function();
-
- // get a std::function
- std::function<int()> a_std_function = lua["a_function"];
- int value_is_still_100 = a_std_function();
-
-Retrieve Lua types using ``object`` and other ``sol::`` types.
-
-.. code-block:: cpp
-
- sol::state lua;
-
- // ... everything from before
-
- sol::object number_obj = lua.get<sol::object>( "number" );
- // sol::type::number
- sol::type t1 = number_obj.get_type();
-
- sol::object function_obj = lua[ "a_function" ];
- // sol::type::function
- sol::type t2 = function_obj.get_type();
- bool is_it_really = function_obj.is<std::function<int()>>(); // true
-
- // will not contain data
- sol::optional<int> check_for_me = lua["a_function"];
-
-
-You can erase things by setting it to ``nullptr`` or ``sol::nil``.
-
-.. code-block:: cpp
-
- sol::state lua;
-
- lua.script("exists = 250");
-
- int first_try = lua.get_or( "exists", 322 );
- // first_try == 250
-
- lua.set("exists", sol::nil);
- int second_try = lua.get_or( "exists", 322 );
- // second_try == 322
-
-
-Note that if its a :doc:`userdata/usertype<../api/usertype>` for a C++ type, the destructor will run only when the garbage collector deems it appropriate to destroy the memory. If you are relying on the destructor being run when its set to ``sol::nil``, you're probably committing a mistake.
-
-tables
-------
-
-:doc:`sol::state<../api/state>` is a table too.
-
-.. code-block:: cpp
-
- sol::state lua;
-
- // Raw string literal for easy multiline
- lua.script( R"(
- abc = { [0] = 24 }
- def = {
- ghi = {
- bark = 50,
- woof = abc
- }
- }
- )"
- );
-
- sol::table abc = lua["abc"];
- sol::table def = lua["def"];
- sol::table ghi = lua["def"]["ghi"];
-
- int bark1 = def["ghi"]["bark"];
- int bark2 = lua["def"]["ghi"]["bark"];
- // bark1 == bark2 == 50
-
- int abcval1 = abc[0];
- int abcval2 = ghi["woof"][0];
- // abcval1 == abcval2 == 24
-
-If you're going deep, be safe:
-
-.. code-block:: cpp
-
- sol::state lua;
-
- sol::optional<int> will_not_error = lua["abc"]["DOESNOTEXIST"]["ghi"];
- // will_not_error == sol::nullopt
- int also_will_not_error = lua["abc"]["def"]["ghi"]["jklm"].get_or(25);
- // is 25
-
- // if you don't go safe,
- // will throw (or do at_panic if no exceptions)
- int aaaahhh = lua["boom"]["the_dynamite"];
-
-
-make tables
------------
-
-Make some:
-
-.. code-block:: cpp
-
- sol::state lua;
-
- lua["abc"] = lua.create_table_with(
- 0, 24
- );
-
- lua.create_named_table("def",
- "ghi", lua.create_table_with(
- "bark", 50,
- // can reference other existing stuff too
- "woof", lua["abc"]
- )
- );
-
-Equivalent Lua code:
-
-.. code-block:: lua
-
- abc = { [0] = 24 }
- def = {
- ghi = {
- bark = 50,
- woof = abc
- }
- }
-
-
-You can put anything you want in tables as values or keys, including strings, numbers, functions, other tables.
-
-Note that this idea that things can be nested is important and will help later when you get into :ref:`namespacing<namespacing>`.
-
-
-functions
----------
-
-They're great. Use them:
-
-.. code-block:: cpp
-
- sol::state lua;
-
- lua.script("function f (a, b, c, d) return 1 end");
- lua.script("function g (a, b) return a + b end");
-
- // fixed signature std::function<...>
- std::function<int(int, double, int, std::string)> stdfx = lua["f"];
- // sol::function is often easier:
- // takes a variable number/types of arguments...
- sol::function fx = lua["f"];
-
- int is_one = stdfx(1, 34.5, 3, "bark");
- int is_also_one = fx(1, "boop", 3, "bark");
-
- // call through operator[]
- int is_three = lua["g"](1, 2);
- // is_three == 3
- double is_4_8 = lua["g"](2.4, 2.4);
- // is_4_8 == 4.8
-
-If you need to protect against errors and parser problems and you're not ready to deal with Lua's `longjmp` problems (if you compiled with C), use :doc:`sol::protected_function<../api/protected_function>`.
-
-You can bind member variables as functions too, as well as all KINDS of function-like things:
-
-.. code-block:: cpp
-
- void some_function () {
- std::cout << "some function!" << std::endl;
- }
-
- void some_other_function () {
- std::cout << "some other function!" << std::endl;
- }
-
- struct some_class {
- int variable = 30;
-
- double member_function () {
- return 24.5;
- }
- };
-
- sol::state lua;
- lua.open_libraries(sol::lib::base);
-
- // put an instance of "some_class" into lua
- // (we'll go into more detail about this later
- // just know here that it works and is
- // put into lua as a userdata
- lua.set("sc", some_class());
-
- // binds a plain function
- lua["f1"] = some_function;
- lua.set_function("f2", &some_other_function);
-
- // binds just the member function
- lua["m1"] = &some_class::member_function;
-
- // binds the class to the type
- lua.set_function("m2", &some_class::member_function, some_class{});
-
- // binds just the member variable as a function
- lua["v1"] = &some_class::variable;
-
- // binds class with member variable as function
- lua.set_function("v2", &some_class::variable, some_class{});
-
-The lua code to call these things is:
-
-.. code-block:: lua
-
- f1() -- some function!
- f2() -- some other function!
-
- -- need class instance if you don't bind it with the function
- print(m1(sc)) -- 24.5
- -- does not need class instance: was bound to lua with one
- print(m2()) -- 24.5
-
- -- need class instance if you
- -- don't bind it with the function
- print(v1(sc)) -- 30
- -- does not need class instance:
- -- it was bound with one
- print(v2()) -- 30
-
- -- can set, still
- -- requires instance
- v1(sc, 212)
- -- can set, does not need
- -- class instance: was bound with one
- v2(254)
-
- print(v1(sc)) -- 212
- print(v2()) -- 254
-
-Can use ``sol::readonly( &some_class::variable )`` to make a variable readonly and error if someone tries to write to it.
-
-
-self call
----------
-
-You can pass the 'self' argument through C++ to emulate 'member function' calls in Lua.
-
-.. code-block:: cpp
-
- sol::state lua;
-
- lua.open_libraries(sol::lib::base, sol::lib::package, sol::lib::table);
-
- // a small script using 'self' syntax
- lua.script(R"(
- some_table = { some_val = 100 }
-
- function some_table:add_to_some_val(value)
- self.some_val = self.some_val + value
- end
-
- function print_some_val()
- print("some_table.some_val = " .. some_table.some_val)
- end
- )");
-
- // do some printing
- lua["print_some_val"]();
- // 100
-
- sol::table self = lua["some_table"];
- self["add_to_some_val"](self, 10);
- lua["print_some_val"]();
-
-
-
-multiple returns from lua
--------------------------
-
-.. code-block:: cpp
-
- sol::state lua;
-
- lua.script("function f (a, b, c) return a, b, c end");
-
- std::tuple<int, int, int> result;
- 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( a, b, c );
- };
-
- std::tuple<int, int, int> result = lua["f"](100, 200, 300);
- // result == { 100, 200, 300 }
-
- std::tuple<int, int, std::string> result2;
- result2 = lua["f"](100, 200, "BARK BARK BARK!");
- // result2 == { 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 from C++
---------------------
-
-Everything that is not a:
-
- * primitive type: ``bool``, ``char/short/int/long/long long``, ``float/double``
- * string type: ``std::string``, ``const char*``
- * function type: function pointers, ``lua_CFunction``, ``std::function``, :doc:`sol::function/sol::protected_function<../api/function>`, :doc:`sol::coroutine<../api/coroutine>`, member variable, member function
- * designated sol type: :doc:`sol::table<../api/table>`, :doc:`sol::thread<../api/thread>`, :doc:`sol::error<../api/error>`, :doc:`sol::object<../api/object>`
- * transparent argument type: :doc:`sol::variadic_arg<../api/variadic_args>`, :doc:`sol::this_state<../api/this_state>`
- * usertype<T> class: :doc:`sol::usertype<../api/usertype>`
-
-Is set as a :doc:`userdata + usertype<../api/usertype>`.
-
-.. code-block:: cpp
-
- struct Doge {
- int tailwag = 50;
- };
-
- Doge dog{};
-
- // Copy into lua: destroyed by Lua VM during garbage collection
- lua["dog"] = dog;
- // OR: move semantics - will call move constructor if present instead
- // Again, owned by Lua
- lua["dog"] = std::move( dog );
- lua["dog"] = Doge{};
- lua["dog"] = std::make_unique<Doge>();
- lua["dog"] = std::make_shared<Doge>();
- // Identical to above
-
- Doge dog2{};
-
- lua.set("dog", dog2);
- lua.set("dog", std::move(dog2));
- lua.set("dog", Doge{});
- lua.set("dog", std::unique_ptr<Doge>(new Doge()));
- lua.set("dog", std::shared_ptr<Doge>(new Doge()));
-
-``std::unique_ptr``/``std::shared_ptr``'s reference counts / deleters will :doc:`be respected<../api/unique_usertype_traits>`. If you want it to refer to something, whose memory you know won't die in C++, do the following:
-
-.. code-block:: cpp
-
- struct Doge {
- int tailwag = 50;
- };
-
- sol::state lua;
- lua.open_libraries(sol::lib::base);
-
- Doge dog{}; // Kept alive somehow
-
- // Later...
- // The following stores a reference, and does not copy/move
- // lifetime is same as dog in C++
- // (access after it is destroyed is bad)
- lua["dog"] = &dog;
- // Same as above: respects std::reference_wrapper
- lua["dog"] = std::ref(dog);
- // These two are identical to above
- lua.set( "dog", &dog );
- lua.set( "dog", std::ref( dog ) );
-
-Get userdata in the same way as everything else:
-
-.. code-block:: cpp
-
- struct Doge {
- int tailwag = 50;
- };
-
- sol::state lua;
- lua.open_libraries(sol::lib::base);
-
- Doge& dog = lua["dog"]; // References Lua memory
- Doge* dog_pointer = lua["dog"]; // References Lua memory
- Doge dog_copy = lua["dog"]; // Copies, will not affect lua
-
-Note that you can change the data of usertype variables and it will affect things in lua if you get a pointer or a reference from Sol:
-
-.. code-block:: cpp
-
- struct Doge {
- int tailwag = 50;
- };
-
- sol::state lua;
- lua.open_libraries(sol::lib::base);
-
- Doge& dog = lua["dog"]; // References Lua memory
- Doge* dog_pointer = lua["dog"]; // References Lua memory
- Doge dog_copy = lua["dog"]; // Copies, will not affect lua
-
- dog_copy.tailwag = 525;
- // Still 50
- lua.script("assert(dog.tailwag == 50)");
-
- dog.tailwag = 100;
- // Now 100
- lua.script("assert(dog.tailwag == 100)");
-
-
-C++ classes put into Lua
-------------------------
-
-See this :doc:`section here<cxx-in-lua>` and after perhaps see if :doc:`simple usertypes suit your needs<../api/simple_usertype>`. Also check out some `a basic example`_, `special functions`_ and `initializers`_,
-
-
-.. _namespacing:
-
-namespacing
------------
-
-You can emulate namespacing by having a table and giving it the namespace names you want before registering enums or usertypes:
-
-.. code-block:: cpp
-
- struct my_class {
- int b = 24;
-
- int f () const {
- return 24;
- }
-
- void g () {
- ++b;
- }
- };
-
- sol::state lua;
- lua.open_libraries();
-
- // set up table
- sol::table bark = lua.create_named_table("bark");
-
- bark.new_usertype<my_class>( "my_class",
- "f", &my_class::f,
- "g", &my_class::g
- ); // the usual
-
- // 'bark' namespace
- lua.script("obj = bark.my_class.new()" );
- lua.script("obj:g()");
- my_class& obj = lua["obj"];
- // obj.b == 25
-
-
-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.
-
-advanced
---------
-
-Some more advanced things you can do/read about:
- * :doc:`metatable manipulations<../api/metatable_key>` allow a user to change how indexing, function calls, and other things work on a single type.
- * :doc:`ownership semantics<ownership>` are described for how lua deals with (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:`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.
-
-.. _a basic example: https://github.com/ThePhD/sol2/blob/develop/examples/usertype.cpp
-.. _special functions: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_special_functions.cpp
-.. _initializers: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_initializers.cpp
-