mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
add more explicit readme notes for things we support
add examples about shared/unique update documentation
This commit is contained in:
parent
8e8dd379ff
commit
c464888c3e
|
@ -73,7 +73,13 @@ If you use CMake, you can also configure and generate a project that will genera
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- [Fastest in the land](http://sol2.readthedocs.io/en/latest/benchmarks.html) (see: sol bar in graph).
|
- [Fastest in the land](http://sol2.readthedocs.io/en/latest/benchmarks.html) (see: sol bar in graph).
|
||||||
- Supports retrieval and setting of multiple types including `std::string` and `std::map/unordered_map`.
|
- Supports retrieval and setting of multiple types including:
|
||||||
|
* `std::string`, `std::wstring`, `std::u16string` and `std::u32string` support (and for views).
|
||||||
|
* understands and works with containers such as `std::map/unordered_map`, c-style arrays, vectors, non-standard custom containers and more.
|
||||||
|
* user-defined types, with or **without** registering that type
|
||||||
|
* `std::unique_ptr`, `std::shared_ptr`, and optional support of other pointer types like `boost::shared_ptr`.
|
||||||
|
* custom `optional<T>` that works with references.
|
||||||
|
* C++17 support for variants and similar new types.
|
||||||
- Lambda, function, and member function bindings are supported.
|
- Lambda, function, and member function bindings are supported.
|
||||||
- Intermediate type for checking if a variable exists.
|
- Intermediate type for checking if a variable exists.
|
||||||
- Simple API that completely abstracts away the C stack API, including `protected_function` with the ability to use an error-handling function.
|
- Simple API that completely abstracts away the C stack API, including `protected_function` with the ability to use an error-handling function.
|
||||||
|
@ -82,6 +88,7 @@ If you use CMake, you can also configure and generate a project that will genera
|
||||||
- Customization points to allow your C++ objects to be pushed and retrieved from Lua as multiple consecutive objects, or anything else you desire!
|
- Customization points to allow your C++ objects to be pushed and retrieved from Lua as multiple consecutive objects, or anything else you desire!
|
||||||
- Overloaded function calls: `my_function(1); my_function("Hello")` in the same lua script route to different function calls based on parameters
|
- Overloaded function calls: `my_function(1); my_function("Hello")` in the same lua script route to different function calls based on parameters
|
||||||
- Support for tables, nested tables, table iteration with `table.for_each` / `begin()` and `end()` iterators.
|
- Support for tables, nested tables, table iteration with `table.for_each` / `begin()` and `end()` iterators.
|
||||||
|
- Zero overhead for usertype function call lookup when using `SOL_USE_BOOST`, safe for critical applications
|
||||||
|
|
||||||
## Supported Compilers
|
## Supported Compilers
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ unique_usertype_traits<T>
|
||||||
static type* get (const actual_type&) {...}
|
static type* get (const actual_type&) {...}
|
||||||
};
|
};
|
||||||
|
|
||||||
This is a customization point for users who need to *work with special kinds of pointers/handles*. The traits type alerts the library that a certain type is to be pushed as a special userdata with special deletion / destruction semantics, like many smart pointers / custom smart pointers / handles It is already defined for ``std::unique_ptr<T, D>`` and ``std::shared_ptr<T>``. You can specialize this to get ``unique_usertype_traits`` semantics with your code. For example, here is how ``boost::shared_ptr<T>`` would look:
|
This is a customization point for users who need to *work with special kinds of pointers/handles*. The traits type alerts the library that a certain type is to be pushed as a special userdata with special deletion / destruction semantics, like many smart pointers / custom smart pointers / handles. It is already defined for ``std::unique_ptr<T, D>`` and ``std::shared_ptr<T>`` and works properly with those types (see `shared_ptr here`_ and `unique_ptr here`_ for examples). You can specialize this to get ``unique_usertype_traits`` semantics with your code. For example, here is how ``boost::shared_ptr<T>`` would look:
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
@ -44,3 +44,7 @@ This will allow the library to properly handle ``boost::shared_ptr<T>``, with re
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
If ``is_null`` triggers (returns ``true``), a ``nil`` value will be pushed into Lua rather than an empty structure.
|
If ``is_null`` triggers (returns ``true``), a ``nil`` value will be pushed into Lua rather than an empty structure.
|
||||||
|
|
||||||
|
|
||||||
|
.. _shared_ptr here: https://github.com/ThePhD/sol2/blob/develop/examples/shared_ptr.cpp
|
||||||
|
.. _unique_ptr here: https://github.com/ThePhD/sol2/blob/develop/examples/unique_ptr.cpp
|
||||||
|
|
95
examples/shared_ptr.cpp
Normal file
95
examples/shared_ptr.cpp
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
#define SOL_CHECK_ARGUMENTS 1
|
||||||
|
#include <sol.hpp>
|
||||||
|
|
||||||
|
#include "assert.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
struct my_type {
|
||||||
|
int value = 10;
|
||||||
|
|
||||||
|
my_type() {
|
||||||
|
std::cout << "my_type at " << static_cast<void*>(this) << " being default constructed!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_type(const my_type& other) : value(other.value) {
|
||||||
|
std::cout << "my_type at " << static_cast<void*>(this) << " being copy constructed!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_type(my_type&& other) : value(other.value) {
|
||||||
|
std::cout << "my_type at " << static_cast<void*>(this) << " being move-constructed!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_type& operator=(const my_type& other) {
|
||||||
|
value = other.value;
|
||||||
|
std::cout << "my_type at " << static_cast<void*>(this) << " being copy-assigned to!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_type& operator=(my_type&& other) {
|
||||||
|
value = other.value;
|
||||||
|
std::cout << "my_type at " << static_cast<void*>(this) << " being move-assigned to!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
~my_type() {
|
||||||
|
std::cout << "my_type at " << static_cast<void*>(this) << " being destructed!" << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
std::cout << "=== shared_ptr support ===" << std::endl;
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
lua.new_usertype<my_type>("my_type",
|
||||||
|
"value", &my_type::value
|
||||||
|
);
|
||||||
|
{
|
||||||
|
std::shared_ptr<my_type> shared = std::make_shared<my_type>();
|
||||||
|
lua["shared"] = std::move(shared);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::cout << "getting reference to shared_ptr..." << std::endl;
|
||||||
|
std::shared_ptr<my_type>& ref_to_shared_ptr = lua["shared"];
|
||||||
|
std::cout << "\tshared.use_count(): " << ref_to_shared_ptr.use_count() << std::endl;
|
||||||
|
my_type& ref_to_my_type = lua["shared"];
|
||||||
|
std::cout << "\tafter getting reference to my_type: " << ref_to_shared_ptr.use_count() << std::endl;
|
||||||
|
my_type* ptr_to_my_type = lua["shared"];
|
||||||
|
std::cout << "\tafter getting pointer to my_type: " << ref_to_shared_ptr.use_count() << std::endl;
|
||||||
|
|
||||||
|
c_assert(ptr_to_my_type == ref_to_shared_ptr.get());
|
||||||
|
c_assert(&ref_to_my_type == ref_to_shared_ptr.get());
|
||||||
|
c_assert(ref_to_shared_ptr->value == 10);
|
||||||
|
|
||||||
|
// script affects all of them equally
|
||||||
|
lua.script("shared.value = 20");
|
||||||
|
|
||||||
|
c_assert(ptr_to_my_type->value == 20);
|
||||||
|
c_assert(ref_to_my_type.value == 20);
|
||||||
|
c_assert(ref_to_shared_ptr->value == 20);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::cout << "getting copy of shared_ptr..." << std::endl;
|
||||||
|
std::shared_ptr<my_type> copy_of_shared_ptr = lua["shared"];
|
||||||
|
std::cout << "\tshared.use_count(): " << copy_of_shared_ptr.use_count() << std::endl;
|
||||||
|
my_type copy_of_value = lua["shared"];
|
||||||
|
std::cout << "\tafter getting value copy of my_type: " << copy_of_shared_ptr.use_count() << std::endl;
|
||||||
|
|
||||||
|
c_assert(copy_of_shared_ptr->value == 20);
|
||||||
|
c_assert(copy_of_value.value == 20);
|
||||||
|
|
||||||
|
// script still affects pointer, but does not affect copy of `my_type`
|
||||||
|
lua.script("shared.value = 30");
|
||||||
|
|
||||||
|
c_assert(copy_of_shared_ptr->value == 30);
|
||||||
|
c_assert(copy_of_value.value == 20);
|
||||||
|
}
|
||||||
|
// set to nil and collect garbage to destroy it
|
||||||
|
lua.script("shared = nil");
|
||||||
|
lua.collect_garbage();
|
||||||
|
lua.collect_garbage();
|
||||||
|
|
||||||
|
std::cout << "garbage has been collected" << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
87
examples/unique_ptr.cpp
Normal file
87
examples/unique_ptr.cpp
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
#define SOL_CHECK_ARGUMENTS 1
|
||||||
|
#include <sol.hpp>
|
||||||
|
|
||||||
|
#include "assert.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
struct my_type {
|
||||||
|
int value = 10;
|
||||||
|
|
||||||
|
my_type() {
|
||||||
|
std::cout << "my_type at " << static_cast<void*>(this) << " being default constructed!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_type(const my_type& other) : value(other.value) {
|
||||||
|
std::cout << "my_type at " << static_cast<void*>(this) << " being copy constructed!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_type(my_type&& other) : value(other.value) {
|
||||||
|
std::cout << "my_type at " << static_cast<void*>(this) << " being move-constructed!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_type& operator=(const my_type& other) {
|
||||||
|
value = other.value;
|
||||||
|
std::cout << "my_type at " << static_cast<void*>(this) << " being copy-assigned to!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_type& operator=(my_type&& other) {
|
||||||
|
value = other.value;
|
||||||
|
std::cout << "my_type at " << static_cast<void*>(this) << " being move-assigned to!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
~my_type() {
|
||||||
|
std::cout << "my_type at " << static_cast<void*>(this) << " being destructed!" << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
std::cout << "=== unique_ptr support ===" << std::endl;
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
lua.new_usertype<my_type>("my_type",
|
||||||
|
"value", &my_type::value
|
||||||
|
);
|
||||||
|
{
|
||||||
|
std::unique_ptr<my_type> unique = std::make_unique<my_type>();
|
||||||
|
lua["unique"] = std::move(unique);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::cout << "getting reference to unique_ptr..." << std::endl;
|
||||||
|
std::unique_ptr<my_type>& ref_to_unique_ptr = lua["unique"];
|
||||||
|
my_type& ref_to_my_type = lua["unique"];
|
||||||
|
my_type* ptr_to_my_type = lua["unique"];
|
||||||
|
|
||||||
|
c_assert(ptr_to_my_type == ref_to_unique_ptr.get());
|
||||||
|
c_assert(&ref_to_my_type == ref_to_unique_ptr.get());
|
||||||
|
c_assert(ref_to_unique_ptr->value == 10);
|
||||||
|
|
||||||
|
// script affects all of them equally
|
||||||
|
lua.script("unique.value = 20");
|
||||||
|
|
||||||
|
c_assert(ptr_to_my_type->value == 20);
|
||||||
|
c_assert(ref_to_my_type.value == 20);
|
||||||
|
c_assert(ref_to_unique_ptr->value == 20);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::cout << "getting copy of unique_ptr..." << std::endl;
|
||||||
|
my_type copy_of_value = lua["unique"];
|
||||||
|
|
||||||
|
c_assert(copy_of_value.value == 20);
|
||||||
|
|
||||||
|
// script still affects pointer, but does not affect copy of `my_type`
|
||||||
|
lua.script("unique.value = 30");
|
||||||
|
|
||||||
|
c_assert(copy_of_value.value == 20);
|
||||||
|
}
|
||||||
|
// set to nil and collect garbage to destroy it
|
||||||
|
lua.script("unique = nil");
|
||||||
|
lua.collect_garbage();
|
||||||
|
lua.collect_garbage();
|
||||||
|
|
||||||
|
std::cout << "garbage has been collected" << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user