mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Update version numbers, fix tests, and change bond -> tie, since nobody understands what bond means
This commit is contained in:
parent
38d21827b1
commit
b19d1a0854
|
@ -27,6 +27,7 @@ Browse the various function and classes :doc:`Sol<../index>` utilizes to make yo
|
||||||
table
|
table
|
||||||
this_state
|
this_state
|
||||||
thread
|
thread
|
||||||
|
tie
|
||||||
types
|
types
|
||||||
usertype
|
usertype
|
||||||
userdata
|
userdata
|
||||||
|
|
26
docs/source/api/tie.rst
Normal file
26
docs/source/api/tie.rst
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
tie
|
||||||
|
===
|
||||||
|
An 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:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
lua.open_libraries(sol::lib::base);
|
||||||
|
|
||||||
|
const auto& code = R"(
|
||||||
|
function test()
|
||||||
|
return 1, 2, 3
|
||||||
|
end
|
||||||
|
)";
|
||||||
|
lua.script(code);
|
||||||
|
|
||||||
|
int a, b, c;
|
||||||
|
//std::tie(a, b, c) = lua["test"]();
|
||||||
|
// will error: use the line below
|
||||||
|
sol::tie(a, b, c) = lua["test"]();
|
||||||
|
|
||||||
|
|
||||||
|
.. _std::tie(): http://en.cppreference.com/w/cpp/utility/tuple/tie
|
|
@ -59,9 +59,9 @@ author = 'ThePhD'
|
||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '2.0'
|
version = '2.5'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '2.0.0'
|
release = '2.5.0'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
You can adapt this file completely to your liking, but it should at least
|
You can adapt this file completely to your liking, but it should at least
|
||||||
contain the root `toctree` directive.
|
contain the root `toctree` directive.
|
||||||
|
|
||||||
Sol 2.3
|
Sol 2.5
|
||||||
=======
|
=======
|
||||||
a fast, simple C++ and Lua Binding
|
a fast, simple C++ and Lua Binding
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
|
@ -28,6 +28,7 @@ For your system/game that already has lua, but you'd like something nice:
|
||||||
int pre_existing_system( lua_State* L ) {
|
int pre_existing_system( lua_State* L ) {
|
||||||
sol::state_view lua(L);
|
sol::state_view lua(L);
|
||||||
lua.script( "print('bark bark bark!')" );
|
lua.script( "print('bark bark bark!')" );
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,10 +58,6 @@ You can set/get everything.
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
|
||||||
struct some_class {
|
|
||||||
bool some_variable = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
sol::lua_state lua;
|
sol::lua_state lua;
|
||||||
|
|
||||||
lua.open_libraries(sol::lib::base);
|
lua.open_libraries(sol::lib::base);
|
||||||
|
@ -84,12 +81,6 @@ You can set/get everything.
|
||||||
// strings too
|
// strings too
|
||||||
std::string important_string = lua["important_string"];
|
std::string important_string = lua["important_string"];
|
||||||
|
|
||||||
// returns a plain reference
|
|
||||||
some_class& myuserdata = lua["myuserdata"];
|
|
||||||
// Modifies this in LUA VM AS WELL
|
|
||||||
// its a reference, not a copy!
|
|
||||||
myuserdata.some_variable = true;
|
|
||||||
|
|
||||||
// get a function
|
// get a function
|
||||||
sol::function a_function = lua["a_function"];
|
sol::function a_function = lua["a_function"];
|
||||||
int value_is_100 = a_function();
|
int value_is_100 = a_function();
|
||||||
|
@ -98,7 +89,6 @@ You can set/get everything.
|
||||||
std::function<int()> a_std_function = lua["a_function"];
|
std::function<int()> a_std_function = lua["a_function"];
|
||||||
int value_is_still_100 = a_std_function();
|
int value_is_still_100 = a_std_function();
|
||||||
|
|
||||||
|
|
||||||
Retrieve Lua types using ``object`` and other ``sol::`` types.
|
Retrieve Lua types using ``object`` and other ``sol::`` types.
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
@ -120,6 +110,158 @@ Retrieve Lua types using ``object`` and other ``sol::`` types.
|
||||||
sol::optional<int> check_for_me = lua["a_function"];
|
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<int>( 322 );
|
||||||
|
// first_try == 250
|
||||||
|
|
||||||
|
lua.set("exists", sol::nil);
|
||||||
|
|
||||||
|
int second_try = lua.get_or<int>( 322 );
|
||||||
|
// 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<int, int, int> 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<int, int, int> 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
|
||||||
|
------
|
||||||
|
|
||||||
|
: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::state def = lua["def"];
|
||||||
|
sol::table ghi = lua["def"]["ghi"];
|
||||||
|
|
||||||
|
int bark1 = def["ghi"]["bark"];
|
||||||
|
// bark1 == 50
|
||||||
|
int bark2 = lua["def"]["ghi"]["bark"];
|
||||||
|
// bark2 == 50
|
||||||
|
|
||||||
|
bool bark_equal = bark1 == bark2;
|
||||||
|
// true
|
||||||
|
|
||||||
|
int abcval1 = abc[0];
|
||||||
|
// abcval2 == 24
|
||||||
|
int abcval2 = ghi["woof"][0];
|
||||||
|
// abcval2 == 24
|
||||||
|
|
||||||
|
bool abcval_equal = abcval1 == abcval2;
|
||||||
|
// true
|
||||||
|
|
||||||
|
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 will_not_error2 = lua["abc"]["def"]["ghi"]["jklm"].get_or<int>(25);
|
||||||
|
// is 25
|
||||||
|
|
||||||
|
// if you don't go safe,
|
||||||
|
// will throw (or do at_panic if no exceptions)
|
||||||
|
int aaaahhh = lua["abc"]["hope_u_liek_crash"];
|
||||||
|
|
||||||
|
|
||||||
|
make tables
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Make some:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
lua["abc"] = lua.create_table_with(
|
||||||
|
0, 24
|
||||||
|
);
|
||||||
|
|
||||||
|
lua.create_named_table("def",
|
||||||
|
"ghi", lua.create_table_with(
|
||||||
|
"bark", 50,
|
||||||
|
"woof", lua["abc"] // can reference other existing stuff too
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
functions
|
functions
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
@ -143,8 +285,8 @@ They're great. Use them:
|
||||||
// call through operator[]
|
// call through operator[]
|
||||||
int is_three = lua["g"](1, 2);
|
int is_three = lua["g"](1, 2);
|
||||||
// is_three == 3
|
// is_three == 3
|
||||||
double is_2_8 = lua["g"](2.4, 2.4);
|
double is_4_8 = lua["g"](2.4, 2.4);
|
||||||
// is_2_8 == 2.8
|
// is_4_8 == 4.8
|
||||||
|
|
||||||
You can bind member variables as functions too:
|
You can bind member variables as functions too:
|
||||||
|
|
||||||
|
@ -211,159 +353,32 @@ 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.
|
Can use ``sol::readonly( &some_class::variable )`` to make a variable readonly and error if someone tries to write to it.
|
||||||
|
|
||||||
|
|
||||||
multiple returns from lua
|
C++ classes in 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 = lua["f"](100, 200, 300);
|
|
||||||
// result == { 100, 200, 300 }
|
|
||||||
int a, int b;
|
|
||||||
std::string c;
|
|
||||||
sol::bond( 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<int, int, int> result = lua["f"](100, 200, 300);
|
|
||||||
// result == { 100, 200, 300 }
|
|
||||||
|
|
||||||
lua[]
|
|
||||||
// result == { 100, 200, 300 }
|
|
||||||
int a, int b;
|
|
||||||
std::string c;
|
|
||||||
sol::bond( a, b, c ) = lua["f"](100, 200, "bark");
|
|
||||||
// a == 100
|
|
||||||
// b == 200
|
|
||||||
// c == "bark"
|
|
||||||
|
|
||||||
|
|
||||||
tables
|
|
||||||
------
|
|
||||||
|
|
||||||
:doc:`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::state def = lua["def"];
|
|
||||||
sol::table ghi = lua["def"]["ghi"];
|
|
||||||
|
|
||||||
int bark1 = def["ghi"]["bark"];
|
|
||||||
// bark1 == 50
|
|
||||||
int bark2 = lua["def"]["ghi"]["bark"];
|
|
||||||
// bark2 == 50
|
|
||||||
|
|
||||||
bool bark_equal = bark1 == bark2;
|
|
||||||
// true
|
|
||||||
|
|
||||||
int abcval1 = abc[0];
|
|
||||||
// abcval2 == 24
|
|
||||||
int abcval2 = ghi["woof"][0];
|
|
||||||
// abcval2 == 24
|
|
||||||
|
|
||||||
bool abcval_equal = abcval1 == abcval2;
|
|
||||||
// true
|
|
||||||
|
|
||||||
If you're going deep, be safe:
|
|
||||||
|
|
||||||
.. code-block:: cpp
|
|
||||||
|
|
||||||
sol::optional<int> will_not_error = lua["abc"]["DOESNOTEXIST"]["ghi"];
|
|
||||||
// will_not_error == sol::nullopt
|
|
||||||
int will_not_error2 = lua["abc"]["def"]["ghi"]["jklm"].get_or<int>(25);
|
|
||||||
// is 25
|
|
||||||
|
|
||||||
// if you don't go safe,
|
|
||||||
// will throw (or do at_panic if no exceptions)
|
|
||||||
int aaaahhh = lua["abc"]["hope_u_liek_crash"];
|
|
||||||
|
|
||||||
|
|
||||||
make tables
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Make some:
|
|
||||||
|
|
||||||
.. code-block:: cpp
|
|
||||||
|
|
||||||
lua["abc"] = lua.create_table_with(
|
|
||||||
0, 24
|
|
||||||
);
|
|
||||||
|
|
||||||
lua.create_named_table("def",
|
|
||||||
"ghi", lua.create_table_with(
|
|
||||||
"bark", 50,
|
|
||||||
"woof", lua["abc"] // can reference other existing stuff too
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Equivalent Lua code:
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
abc = { [0] = 24 }
|
|
||||||
def = {
|
|
||||||
ghi = {
|
|
||||||
bark = 50,
|
|
||||||
woof = abc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
userdata + usertypes (metatables)
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
Everything that is not a:
|
Everything that is not a:
|
||||||
|
|
||||||
* primitive type: ``bool``, ``char/short/int/long/long long``, ``float/double``
|
* primitive type: ``bool``, ``char/short/int/long/long long``, ``float/double``
|
||||||
* string type: ``std::string``, ``const char*``
|
* 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>`
|
* 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>`
|
* 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>`
|
* 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>`
|
* usertype<T> class: :doc:`sol::usertype<../api/usertype>`
|
||||||
|
|
||||||
Is set as a userdata.
|
Is set as a :doc:`userdata + usertype<../api/usertype>`.
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
|
||||||
struct Doge { int tailwag = 50; }
|
struct Doge {
|
||||||
|
int tailwag = 50;
|
||||||
|
}
|
||||||
|
|
||||||
Doge dog{};
|
Doge dog{};
|
||||||
|
|
||||||
// Copy into lua: destroyed when lua VM garbage collects
|
// Copy into lua: destroyed by Lua VM during garbage collection
|
||||||
lua["dog"] = dog;
|
lua["dog"] = dog;
|
||||||
// OR: move semantics - will call move constructor if present instead
|
// OR: move semantics - will call move constructor if present instead
|
||||||
|
// Again, owned by Lua
|
||||||
lua["dog"] = std::move( dog );
|
lua["dog"] = std::move( dog );
|
||||||
lua["dog"] = Doge{};
|
lua["dog"] = Doge{};
|
||||||
lua["dog"] = std::make_unique<Doge>();
|
lua["dog"] = std::make_unique<Doge>();
|
||||||
|
@ -375,10 +390,17 @@ Is set as a userdata.
|
||||||
lua.set("dog", std::unique_ptr<Doge>(new Doge()));
|
lua.set("dog", std::unique_ptr<Doge>(new Doge()));
|
||||||
lua.set("dog", std::shared_ptr<Doge>(new Doge()));
|
lua.set("dog", std::shared_ptr<Doge>(new Doge()));
|
||||||
|
|
||||||
``std::unique_ptr``/``std::shared_ptr``'s reference counts / deleters will be respected. If you want it to refer to something, whose memory you know won't die in C++, do the following:
|
``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
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
struct Doge {
|
||||||
|
int tailwag = 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
lua.open_libraries(sol::lib::base);
|
||||||
|
|
||||||
Doge dog{}; // Kept alive somehow
|
Doge dog{}; // Kept alive somehow
|
||||||
|
|
||||||
// Later...
|
// Later...
|
||||||
|
@ -396,6 +418,28 @@ Get userdata in the same way as everything else:
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. 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 = lua["dog"]; // References Lua memory
|
||||||
Doge* dog_pointer = lua["dog"]; // References Lua memory
|
Doge* dog_pointer = lua["dog"]; // References Lua memory
|
||||||
Doge dog_copy = lua["dog"]; // Copies, will not affect lua
|
Doge dog_copy = lua["dog"]; // Copies, will not affect lua
|
||||||
|
@ -409,8 +453,8 @@ Get userdata in the same way as everything else:
|
||||||
lua.script("assert(dog.tailwag == 100)");
|
lua.script("assert(dog.tailwag == 100)");
|
||||||
|
|
||||||
|
|
||||||
more userdata + usertypes
|
C++ classes in Lua
|
||||||
-------------------------
|
------------------
|
||||||
|
|
||||||
Because there's a LOT you can do with Sol:
|
Because there's a LOT you can do with Sol:
|
||||||
|
|
||||||
|
@ -470,9 +514,6 @@ Bind all the things:
|
||||||
// note that you can set a userdata before you register a usertype,
|
// note that you can set a userdata before you register a usertype,
|
||||||
// and it will still carry the right metatable if you register it later
|
// and it will still carry the right metatable if you register it later
|
||||||
|
|
||||||
lua.set("p2", player(0));
|
|
||||||
// p2 has no ammo
|
|
||||||
|
|
||||||
// make usertype metatable
|
// make usertype metatable
|
||||||
lua.new_usertype<player>( "player",
|
lua.new_usertype<player>( "player",
|
||||||
|
|
||||||
|
@ -532,20 +573,32 @@ And the script:
|
||||||
Even more stuff :doc:`you can do<../api/usertype>` described elsewhere, like initializer functions (private constructors / destructors support), "static" functions callable with ``name.my_function( ... )``, and overloaded member functions.
|
Even more stuff :doc:`you can do<../api/usertype>` described elsewhere, like initializer functions (private constructors / destructors support), "static" functions callable with ``name.my_function( ... )``, and overloaded member functions.
|
||||||
|
|
||||||
|
|
||||||
pointers
|
ownership
|
||||||
--------
|
---------
|
||||||
|
|
||||||
Sol will not take ownership of raw pointers: raw pointers do not own anything.
|
Sol will not take ownership of raw pointers: raw pointers do not own anything.
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
struct my_type {
|
||||||
|
void stuff () {}
|
||||||
|
};
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
|
||||||
// AAAHHH BAD
|
// AAAHHH BAD
|
||||||
// dangling pointer!
|
// dangling pointer!
|
||||||
lua["my_func"] = []() -> my_type* {
|
lua["my_func"] = []() -> my_type* {
|
||||||
return new my_type();
|
return new my_type();
|
||||||
};
|
};
|
||||||
|
|
||||||
Return a ``unique_ptr`` or ``shared_ptr`` instead or just return a value:
|
// AAAHHH!
|
||||||
|
lua.set("something", new my_type());
|
||||||
|
|
||||||
|
// AAAAAAHHH!!!
|
||||||
|
lua["something_else"] = new my_type();
|
||||||
|
|
||||||
|
Use/return a ``unique_ptr`` or ``shared_ptr`` instead or just return a value:
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
@ -564,6 +617,16 @@ Return a ``unique_ptr`` or ``shared_ptr`` instead or just return a value:
|
||||||
return my_type();
|
return my_type();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// :ok:
|
||||||
|
lua.set("something", std::unique_ptr<my_type>(new my_type()));
|
||||||
|
|
||||||
|
std::shared_ptr<my_type> my_shared = std::make_shared<my_type>();
|
||||||
|
// :ok:
|
||||||
|
lua.set("something_else", my_shared);
|
||||||
|
|
||||||
|
auto my_unique = std::make_unique<my_type>();
|
||||||
|
lua["other_thing"] = std::move(my_unique);
|
||||||
|
|
||||||
|
|
||||||
advanced
|
advanced
|
||||||
--------
|
--------
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include "userdata.hpp"
|
#include "userdata.hpp"
|
||||||
#include "tuple.hpp"
|
#include "tuple.hpp"
|
||||||
#include "traits.hpp"
|
#include "traits.hpp"
|
||||||
#include "bond.hpp"
|
#include "tie.hpp"
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
|
@ -78,7 +78,7 @@ struct pusher<stack_proxy> {
|
||||||
} // stack
|
} // stack
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct bond_size<function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
struct tie_size<function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
||||||
|
|
||||||
template <std::size_t I>
|
template <std::size_t I>
|
||||||
stack_proxy get(const function_result& fr) {
|
stack_proxy get(const function_result& fr) {
|
||||||
|
@ -86,7 +86,7 @@ stack_proxy get(const function_result& fr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct bond_size<protected_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
struct tie_size<protected_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
||||||
|
|
||||||
template <std::size_t I>
|
template <std::size_t I>
|
||||||
stack_proxy get(const protected_function_result& fr) {
|
stack_proxy get(const protected_function_result& fr) {
|
||||||
|
|
|
@ -19,21 +19,21 @@
|
||||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
// 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.
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
#ifndef SOL_BOND_HPP
|
#ifndef SOL_TIE_HPP
|
||||||
#define SOL_BOND_HPP
|
#define SOL_TIE_HPP
|
||||||
|
|
||||||
#include "traits.hpp"
|
#include "traits.hpp"
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct bond_size : std::tuple_size<T> {};
|
struct tie_size : std::tuple_size<T> {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_bondable : std::integral_constant<bool, (::sol::bond_size<T>::value > 0)> {};
|
struct is_tieable : std::integral_constant<bool, (::sol::tie_size<T>::value > 0)> {};
|
||||||
|
|
||||||
template <typename... Tn>
|
template <typename... Tn>
|
||||||
struct bond_t : public std::tuple<std::add_lvalue_reference_t<Tn>...> {
|
struct tie_t : public std::tuple<std::add_lvalue_reference_t<Tn>...> {
|
||||||
private:
|
private:
|
||||||
typedef std::tuple<std::add_lvalue_reference_t<Tn>...> base_t;
|
typedef std::tuple<std::add_lvalue_reference_t<Tn>...> base_t;
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ private:
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void set( std::true_type, T&& target ) {
|
void set( std::true_type, T&& target ) {
|
||||||
typedef bond_size<meta::Unqualified<T>> value_size;
|
typedef tie_size<meta::Unqualified<T>> value_size;
|
||||||
typedef bond_size<std::tuple<Tn...>> tie_size;
|
typedef tie_size<std::tuple<Tn...>> tie_size;
|
||||||
typedef std::conditional_t<(value_size::value < tie_size::value), value_size, tie_size> indices_size;
|
typedef std::conditional_t<(value_size::value < tie_size::value), value_size, tie_size> indices_size;
|
||||||
typedef std::make_index_sequence<indices_size::value> indices;
|
typedef std::make_index_sequence<indices_size::value> indices;
|
||||||
set( indices(), std::forward<T>( target ) );
|
set( indices(), std::forward<T>( target ) );
|
||||||
|
@ -63,8 +63,8 @@ public:
|
||||||
using base_t::base_t;
|
using base_t::base_t;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bond_t& operator= ( T&& value ) {
|
tie_t& operator= ( T&& value ) {
|
||||||
typedef is_bondable<meta::Unqualified<T>> bondable;
|
typedef is_tieable<meta::Unqualified<T>> bondable;
|
||||||
set( bondable(), std::forward<T>( value ) );
|
set( bondable(), std::forward<T>( value ) );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -72,13 +72,17 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename... Tn>
|
template <typename... Tn>
|
||||||
struct bond_size<::sol::bond_t<Tn...>> : ::std::tuple_size<::std::tuple<Tn...>> { };
|
struct tie_size<::sol::tie_t<Tn...>> : ::std::tuple_size<::std::tuple<Tn...>> { };
|
||||||
|
|
||||||
|
namespace adl_barrier_detail {
|
||||||
template <typename... Tn>
|
template <typename... Tn>
|
||||||
inline bond_t<std::remove_reference_t<Tn>...> bond( Tn&&... argn ) {
|
inline tie_t<std::remove_reference_t<Tn>...> tie(Tn&&... argn) {
|
||||||
return bond_t<std::remove_reference_t<Tn>...>( std::forward<Tn>( argn )... );
|
return tie_t<std::remove_reference_t<Tn>...>(std::forward<Tn>(argn)...);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace adl_barrier_detail;
|
||||||
|
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
#endif // SOL_BOND_HPP
|
#endif // SOL_TIE_HPP
|
|
@ -545,7 +545,7 @@ N = n(1, 2, 3)
|
||||||
|
|
||||||
REQUIRE( N == 13 );
|
REQUIRE( N == 13 );
|
||||||
|
|
||||||
sol::bond( ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N )
|
sol::tie( ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N )
|
||||||
= lua.get<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>(
|
= lua.get<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>(
|
||||||
"ob", "A", "B", "C", "D", "F", "G0", "G1", "H", "I", "J0", "J1", "K0", "K1", "L0", "L1", "M0", "M1", "N"
|
"ob", "A", "B", "C", "D", "F", "G0", "G1", "H", "I", "J0", "J1", "K0", "K1", "L0", "L1", "M0", "M1", "N"
|
||||||
);
|
);
|
||||||
|
@ -735,7 +735,7 @@ TEST_CASE("advanced/call-referenced_obj", "A C++ object is passed by pointer/ref
|
||||||
REQUIRE(y == 9);
|
REQUIRE(y == 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("functions/bond", "make sure advanced syntax with 'bond' works") {
|
TEST_CASE("functions/tie", "make sure advanced syntax with 'tie' works") {
|
||||||
sol::state lua;
|
sol::state lua;
|
||||||
|
|
||||||
lua.script(R"(function f ()
|
lua.script(R"(function f ()
|
||||||
|
@ -744,7 +744,7 @@ end)");
|
||||||
sol::function f = lua["f"];
|
sol::function f = lua["f"];
|
||||||
|
|
||||||
int a, b, c;
|
int a, b, c;
|
||||||
sol::bond(a, b, c) = f();
|
sol::tie(a, b, c) = f();
|
||||||
REQUIRE(a == 1);
|
REQUIRE(a == 1);
|
||||||
REQUIRE(b == 2);
|
REQUIRE(b == 2);
|
||||||
REQUIRE(c == 3);
|
REQUIRE(c == 3);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user