mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
update examples and documentation, proof typing for user
This commit is contained in:
parent
92a6fb8c11
commit
d98155cd22
|
@ -19,6 +19,7 @@ The examples folder also has a number of really great examples for you to see. T
|
||||||
- If you need dynamic callbacks or runtime overridable functions, have a ``std::function`` member variable and get/set it on the usertype object
|
- If you need dynamic callbacks or runtime overridable functions, have a ``std::function`` member variable and get/set it on the usertype object
|
||||||
- ``std::function`` works as a member variable or in passing as an argument / returning as a value (you can even use it with ``sol::property``)
|
- ``std::function`` works as a member variable or in passing as an argument / returning as a value (you can even use it with ``sol::property``)
|
||||||
- You can also create an entirely dynamic object: see the `dynamic_object example`_ for more details
|
- You can also create an entirely dynamic object: see the `dynamic_object example`_ for more details
|
||||||
|
* (Advanced) You can override the iteration function for Lua 5.2 and above (LuaJIT not included) `as shown in the pairs example`_
|
||||||
* You can use :doc:`filters<api/filters>` to control dependencies and streamline return values, as well as apply custom behavior to a functions return
|
* You can use :doc:`filters<api/filters>` to control dependencies and streamline return values, as well as apply custom behavior to a functions return
|
||||||
* Please note that the colon is necessary to "automatically" pass the ``this``/``self`` argument to Lua methods
|
* Please note that the colon is necessary to "automatically" pass the ``this``/``self`` argument to Lua methods
|
||||||
- ``obj:method_name()`` is how you call "member" methods in Lua
|
- ``obj:method_name()`` is how you call "member" methods in Lua
|
||||||
|
@ -52,3 +53,4 @@ The examples folder also has a number of really great examples for you to see. T
|
||||||
.. _C++: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_simple.cpp#L51
|
.. _C++: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_simple.cpp#L51
|
||||||
.. _Certain operators: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_automatic_operators.cpp
|
.. _Certain operators: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_automatic_operators.cpp
|
||||||
.. _dynamic_object example: https://github.com/ThePhD/sol2/blob/develop/examples/dynamic_object.cpp
|
.. _dynamic_object example: https://github.com/ThePhD/sol2/blob/develop/examples/dynamic_object.cpp
|
||||||
|
.. _as shown in this example: https://github.com/ThePhD/sol2/blob/develop/examples/pairs.cpp
|
||||||
|
|
|
@ -21,9 +21,8 @@ struct lua_iterator_state {
|
||||||
typedef std::map<std::string, int>::iterator it_t;
|
typedef std::map<std::string, int>::iterator it_t;
|
||||||
it_t it;
|
it_t it;
|
||||||
it_t last;
|
it_t last;
|
||||||
std::reference_wrapper<my_thing> source;
|
|
||||||
|
|
||||||
lua_iterator_state(my_thing& mt) : it(mt.m.begin()), last(mt.m.end()), source(mt) {}
|
lua_iterator_state(my_thing& mt) : it(mt.m.begin()), last(mt.m.end()) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::tuple<sol::object, sol::object> my_next(sol::user<lua_iterator_state&> user_it_state, sol::this_state l) {
|
std::tuple<sol::object, sol::object> my_next(sol::user<lua_iterator_state&> user_it_state, sol::this_state l) {
|
||||||
|
@ -35,7 +34,6 @@ std::tuple<sol::object, sol::object> my_next(sol::user<lua_iterator_state&> user
|
||||||
// the key value is argument 2, but we do not
|
// the key value is argument 2, but we do not
|
||||||
// care about the key value here
|
// care about the key value here
|
||||||
lua_iterator_state& it_state = user_it_state;
|
lua_iterator_state& it_state = user_it_state;
|
||||||
my_thing& source = it_state.source;
|
|
||||||
auto& it = it_state.it;
|
auto& it = it_state.it;
|
||||||
if (it == it_state.last) {
|
if (it == it_state.last) {
|
||||||
// return nil to signify that
|
// return nil to signify that
|
||||||
|
@ -53,7 +51,7 @@ std::tuple<sol::object, sol::object> my_next(sol::user<lua_iterator_state&> user
|
||||||
// the iterator must be moved forward one before we return
|
// the iterator must be moved forward one before we return
|
||||||
std::advance(it, 1);
|
std::advance(it, 1);
|
||||||
return r;
|
return r;
|
||||||
};
|
}
|
||||||
|
|
||||||
auto my_pairs(my_thing& mt) {
|
auto my_pairs(my_thing& mt) {
|
||||||
// pairs expects 3 returns:
|
// pairs expects 3 returns:
|
||||||
|
@ -67,11 +65,9 @@ auto my_pairs(my_thing& mt) {
|
||||||
// it's incompatible with regular usertypes and stores the type T directly in lua without any pretty setup
|
// it's incompatible with regular usertypes and stores the type T directly in lua without any pretty setup
|
||||||
// saves space allocation and a single dereference
|
// saves space allocation and a single dereference
|
||||||
return std::make_tuple(&my_next, sol::user<lua_iterator_state>(std::move(it_state)), sol::lua_nil);
|
return std::make_tuple(&my_next, sol::user<lua_iterator_state>(std::move(it_state)), sol::lua_nil);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
int main(int, char*[]) {
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
std::cout << "===== pairs (advanced) =====" << std::endl;
|
std::cout << "===== pairs (advanced) =====" << std::endl;
|
||||||
|
|
||||||
sol::state lua;
|
sol::state lua;
|
||||||
|
|
|
@ -21,9 +21,8 @@ struct lua_iterator_state {
|
||||||
typedef std::map<std::string, int>::iterator it_t;
|
typedef std::map<std::string, int>::iterator it_t;
|
||||||
it_t it;
|
it_t it;
|
||||||
it_t last;
|
it_t last;
|
||||||
std::reference_wrapper<my_thing> source;
|
|
||||||
|
|
||||||
lua_iterator_state(my_thing& mt) : it(mt.m.begin()), last(mt.m.end()), source(mt) {}
|
lua_iterator_state(my_thing& mt) : it(mt.m.begin()), last(mt.m.end()) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
int my_next(lua_State* L) {
|
int my_next(lua_State* L) {
|
||||||
|
@ -34,7 +33,6 @@ int my_next(lua_State* L) {
|
||||||
// the key value is argument 2
|
// the key value is argument 2
|
||||||
// we do not care about the key value here
|
// we do not care about the key value here
|
||||||
lua_iterator_state& it_state = sol::stack::get<sol::user<lua_iterator_state>>(L, 1);
|
lua_iterator_state& it_state = sol::stack::get<sol::user<lua_iterator_state>>(L, 1);
|
||||||
my_thing& source = it_state.source;
|
|
||||||
auto& it = it_state.it;
|
auto& it = it_state.it;
|
||||||
if (it == it_state.last) {
|
if (it == it_state.last) {
|
||||||
return sol::stack::push(L, sol::lua_nil);
|
return sol::stack::push(L, sol::lua_nil);
|
||||||
|
@ -47,16 +45,7 @@ int my_next(lua_State* L) {
|
||||||
pushed += sol::stack::push_reference(L, itderef.second);
|
pushed += sol::stack::push_reference(L, itderef.second);
|
||||||
std::advance(it, 1);
|
std::advance(it, 1);
|
||||||
return pushed;
|
return pushed;
|
||||||
};
|
}
|
||||||
|
|
||||||
auto my_pairs(my_thing& mt) {
|
|
||||||
// prepare our state
|
|
||||||
lua_iterator_state it_state(mt);
|
|
||||||
return std::make_tuple(&my_next, sol::user<lua_iterator_state>(std::move(it_state)), sol::lua_nil);
|
|
||||||
// sol::user above is a space/time optimization over regular usertypes,
|
|
||||||
// it's incompatible with regular usertypes and stores the type T directly in lua without any pretty setup
|
|
||||||
// saves space allocation and a single dereference
|
|
||||||
};
|
|
||||||
|
|
||||||
int my_pairs(lua_State* L) {
|
int my_pairs(lua_State* L) {
|
||||||
my_thing& mt = sol::stack::get<my_thing>(L, 1);
|
my_thing& mt = sol::stack::get<my_thing>(L, 1);
|
||||||
|
@ -71,16 +60,16 @@ int my_pairs(lua_State* L) {
|
||||||
pushed += sol::stack::push<sol::user<lua_iterator_state>>(L, std::move(it_state));
|
pushed += sol::stack::push<sol::user<lua_iterator_state>>(L, std::move(it_state));
|
||||||
pushed += sol::stack::push(L, sol::lua_nil);
|
pushed += sol::stack::push(L, sol::lua_nil);
|
||||||
return pushed;
|
return pushed;
|
||||||
};
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int, char*[]) {
|
||||||
std::cout << "===== pairs (using raw Lua C functions) (advanced) =====" << std::endl;
|
std::cout << "===== pairs (using raw Lua C functions) (advanced) =====" << std::endl;
|
||||||
|
|
||||||
sol::state lua;
|
sol::state lua;
|
||||||
lua.open_libraries(sol::lib::base);
|
lua.open_libraries(sol::lib::base);
|
||||||
|
|
||||||
lua.new_usertype<my_thing>("my_thing",
|
lua.new_usertype<my_thing>("my_thing",
|
||||||
sol::meta_function::pairs, my_pairs
|
sol::meta_function::pairs, &my_pairs
|
||||||
);
|
);
|
||||||
|
|
||||||
lua.safe_script(R"(
|
lua.safe_script(R"(
|
||||||
|
|
|
@ -79,10 +79,19 @@ print("obj1:", obj1)
|
||||||
print("obj2:", obj2)
|
print("obj2:", obj2)
|
||||||
print("obj3:", obj2)
|
print("obj3:", obj2)
|
||||||
|
|
||||||
|
print("#obj1:", #obj1)
|
||||||
|
print("#obj2:", #obj2)
|
||||||
|
print("#obj3:", #obj3)
|
||||||
|
|
||||||
obj1() obj1() obj1() obj1() obj1() obj1()
|
obj1() obj1() obj1() obj1() obj1() obj1()
|
||||||
obj2() obj2() obj2()
|
obj2() obj2() obj2()
|
||||||
obj3() obj3() obj3()
|
obj3() obj3() obj3()
|
||||||
|
|
||||||
|
print("after modifications using obj() operator")
|
||||||
|
print("obj1:", obj1)
|
||||||
|
print("obj2:", obj2)
|
||||||
|
print("obj3:", obj2)
|
||||||
|
|
||||||
print("#obj1:", #obj1)
|
print("#obj1:", #obj1)
|
||||||
print("#obj2:", #obj2)
|
print("#obj2:", #obj2)
|
||||||
print("#obj3:", #obj3)
|
print("#obj3:", #obj3)
|
||||||
|
@ -100,14 +109,15 @@ end
|
||||||
print("obj1 == obj2:", obj1 == obj2)
|
print("obj1 == obj2:", obj1 == obj2)
|
||||||
print("obj1 < obj2:", obj1 < obj2)
|
print("obj1 < obj2:", obj1 < obj2)
|
||||||
print("obj1 >= obj2:", obj1 >= obj2)
|
print("obj1 >= obj2:", obj1 >= obj2)
|
||||||
|
assert(obj1 ~= obj2)
|
||||||
|
assert(obj1 > obj2)
|
||||||
|
assert(obj1 >= obj2)
|
||||||
|
|
||||||
print("obj2 == obj3:", obj1 == obj2)
|
print("obj2 == obj3:", obj2 == obj3)
|
||||||
print("obj2 > obj3:", obj1 > obj2)
|
print("obj2 > obj3:", obj2 > obj3)
|
||||||
print("obj2 <= obj3:", obj1 <= obj2)
|
print("obj2 <= obj3:", obj2 <= obj3)
|
||||||
|
assert(obj2 == obj3)
|
||||||
print("obj1:", obj1)
|
assert(obj2 <= obj3)
|
||||||
print("obj2:", obj2)
|
|
||||||
print("obj3:", obj2)
|
|
||||||
)");
|
)");
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
// 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.
|
||||||
|
|
||||||
// This file was generated with a script.
|
// This file was generated with a script.
|
||||||
// Generated 2017-08-24 18:37:55.297938 UTC
|
// Generated 2017-08-24 18:56:19.661582 UTC
|
||||||
// This header was generated with sol v2.18.1 (revision a163ae7)
|
// This header was generated with sol v2.18.0 (revision 92a6fb8)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||||
|
@ -4225,10 +4225,10 @@ namespace sol {
|
||||||
struct user {
|
struct user {
|
||||||
U value;
|
U value;
|
||||||
|
|
||||||
user(U x) : value(std::move(x)) {}
|
user(U x) : value(std::forward<U>(x)) {}
|
||||||
operator std::remove_reference_t<U>* () { return std::addressof(value); }
|
operator std::add_pointer_t<std::remove_reference_t<U>> () { return std::addressof(value); }
|
||||||
operator U& () { return value; }
|
operator std::add_lvalue_reference_t<U> () { return value; }
|
||||||
operator const U& () const { return value; }
|
operator std::add_const_t<std::add_lvalue_reference_t<U>>& () const { return value; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -324,10 +324,10 @@ namespace sol {
|
||||||
struct user {
|
struct user {
|
||||||
U value;
|
U value;
|
||||||
|
|
||||||
user(U x) : value(std::move(x)) {}
|
user(U x) : value(std::forward<U>(x)) {}
|
||||||
operator std::remove_reference_t<U>* () { return std::addressof(value); }
|
operator std::add_pointer_t<std::remove_reference_t<U>> () { return std::addressof(value); }
|
||||||
operator U& () { return value; }
|
operator std::add_lvalue_reference_t<U> () { return value; }
|
||||||
operator const U& () const { return value; }
|
operator std::add_const_t<std::add_lvalue_reference_t<U>>& () const { return value; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user