mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
wew lad
This commit is contained in:
parent
97279aa68e
commit
908074e696
|
@ -47,7 +47,16 @@ Typical of Visual Studio, the compiler will complain that it is out of heap spac
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
This should use the 64-bit tools by default, and increase your maximum heap space to whatever a 64-bit windows machine can handle. If you do not have more than 4 GB of RAM, or you still encounter issues, you should look into using ``create_simple_usertype`` and adding functions 1 by 1 using ``.set( ... )``, as shown in `the simple usertype example here`_.
|
This should use the 64-bit tools by default, and increase your maximum heap space to whatever a 64-bit windows machine can handle. If you do not have more than 4 GB of RAM, or you still encounter issues, you should look into breaking up your usertype across C++ files. Also, it is imperative to not put all the functions inside single calls to the `new_usertype(...)` function directly: instead, use `my_usertype["func"] = func;` like so:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
auto my_usertype = lua.new_usertype<my_class>("my_class");
|
||||||
|
my_usertype["talkin"] = &about;
|
||||||
|
my_usertype["this"] = &my_class::that;
|
||||||
|
my_usertype["and_the"] = sol::property(&my_class::third);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Linker Errors
|
Linker Errors
|
||||||
|
|
|
@ -23,7 +23,7 @@ Okay, so the features don't convince you, the documentation doesn't convince you
|
||||||
| |before| | |after| |
|
| |before| | |after| |
|
||||||
+----------+---------+
|
+----------+---------+
|
||||||
|
|
||||||
* In `Perforce`_
|
* In `Perforce`_ (later versions of the code using sol2 more directly can be requested by e-mailing support@perforce.com !)
|
||||||
* In `High Performance Computing research`_
|
* In `High Performance Computing research`_
|
||||||
- `Published research, too!`_
|
- `Published research, too!`_
|
||||||
* The `Multiple Arcade Machine Emulator (MAME)`_ project switched from using LuaBridge to sol3!
|
* The `Multiple Arcade Machine Emulator (MAME)`_ project switched from using LuaBridge to sol3!
|
||||||
|
@ -42,7 +42,7 @@ Okay, so the features don't convince you, the documentation doesn't convince you
|
||||||
- Elias Daler: `"sol3 saved my life."`_
|
- Elias Daler: `"sol3 saved my life."`_
|
||||||
- Racod's Lair: `"from outdated LuaBridge to superior #sol3"`_
|
- Racod's Lair: `"from outdated LuaBridge to superior #sol3"`_
|
||||||
* (Reddit) Posts on reddit about it!
|
* (Reddit) Posts on reddit about it!
|
||||||
- `sol3's initial reddit release`_
|
- `sol2's initial reddit release`_
|
||||||
- `Benchmarking Discussing`_
|
- `Benchmarking Discussing`_
|
||||||
* Somehow landed on a Torque3D thread...
|
* Somehow landed on a Torque3D thread...
|
||||||
- http://forums.torque3d.org/viewtopic.php?f=32&t=629&p=5246&sid=8e759990ab1ce38a48e896fc9fd62653#p5241
|
- http://forums.torque3d.org/viewtopic.php?f=32&t=629&p=5246&sid=8e759990ab1ce38a48e896fc9fd62653#p5241
|
||||||
|
|
|
@ -13,4 +13,6 @@ As shown by the :doc:`benchmarks<benchmarks>`, sol is very performant with its a
|
||||||
* Member variables can sometimes cost an extra lookup to occur within the Lua system (as mentioned :doc:`bottom of the usertype page<api/usertype>`); until we find out a safe way around this, member variables will always incur that extra lookup cost
|
* Member variables can sometimes cost an extra lookup to occur within the Lua system (as mentioned :doc:`bottom of the usertype page<api/usertype>`); until we find out a safe way around this, member variables will always incur that extra lookup cost
|
||||||
|
|
||||||
|
|
||||||
That's it as far as different performance options are avilable to make sol run faster. Again, please make sure to invoke these only when you know sol is the bottleneck. If you find some form of the performance unacceptable to you, also feel free to open an issue at the github.
|
Working with things that are already on the stack can also boost performance. Last time regular, call overhead was measured, it was around 5-11 nanoseconds for a single C++ call on a recent (2015) machine. The range is for how slim you make the call, what kind of arguments, et cetera.
|
||||||
|
|
||||||
|
If you find some form of the performance unacceptable to you, also feel free to open an issue at the github.
|
||||||
|
|
|
@ -114,7 +114,7 @@ namespace sol {
|
||||||
template <typename... R>
|
template <typename... R>
|
||||||
static std::function<Signature> get_std_func(types<R...>, lua_State* L, int index) {
|
static std::function<Signature> get_std_func(types<R...>, lua_State* L, int index) {
|
||||||
detail::std_shim<R...> fx(unsafe_function(L, index));
|
detail::std_shim<R...> fx(unsafe_function(L, index));
|
||||||
return std::move(fx);
|
return fx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::function<Signature> get(lua_State* L, int index, record& tracking) {
|
static std::function<Signature> get(lua_State* L, int index, record& tracking) {
|
||||||
|
|
|
@ -109,7 +109,7 @@ namespace sol { namespace detail {
|
||||||
/// \exclude
|
/// \exclude
|
||||||
#define SOL_TL_OPTIONAL_11_CONSTEXPR
|
#define SOL_TL_OPTIONAL_11_CONSTEXPR
|
||||||
#else
|
#else
|
||||||
/// \exclude
|
/// \exclude
|
||||||
#define SOL_TL_OPTIONAL_11_CONSTEXPR constexpr
|
#define SOL_TL_OPTIONAL_11_CONSTEXPR constexpr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -448,10 +448,12 @@ namespace sol {
|
||||||
// This specialization is for when T is not trivially copy constructible
|
// This specialization is for when T is not trivially copy constructible
|
||||||
template <class T>
|
template <class T>
|
||||||
struct optional_copy_base<T, false> : optional_operations_base<T> {
|
struct optional_copy_base<T, false> : optional_operations_base<T> {
|
||||||
using optional_operations_base<T>::optional_operations_base;
|
using base_t = optional_operations_base<T>;
|
||||||
|
|
||||||
|
using base_t::base_t;
|
||||||
|
|
||||||
optional_copy_base() = default;
|
optional_copy_base() = default;
|
||||||
optional_copy_base(const optional_copy_base& rhs) {
|
optional_copy_base(const optional_copy_base& rhs) : base_t() {
|
||||||
if (rhs.has_value()) {
|
if (rhs.has_value()) {
|
||||||
this->construct(rhs.get());
|
this->construct(rhs.get());
|
||||||
}
|
}
|
||||||
|
@ -500,7 +502,8 @@ namespace sol {
|
||||||
|
|
||||||
// This class manages conditionally having a trivial copy assignment operator
|
// This class manages conditionally having a trivial copy assignment operator
|
||||||
template <class T,
|
template <class T,
|
||||||
bool = SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) && SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) && SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T)>
|
bool = SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) && SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)
|
||||||
|
&& SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T)>
|
||||||
struct optional_copy_assign_base : optional_move_base<T> {
|
struct optional_copy_assign_base : optional_move_base<T> {
|
||||||
using optional_move_base<T>::optional_move_base;
|
using optional_move_base<T>::optional_move_base;
|
||||||
};
|
};
|
||||||
|
@ -2259,12 +2262,12 @@ namespace sol {
|
||||||
namespace std {
|
namespace std {
|
||||||
// TODO SFINAE
|
// TODO SFINAE
|
||||||
template <class T>
|
template <class T>
|
||||||
struct hash< ::sol::optional<T> > {
|
struct hash<::sol::optional<T>> {
|
||||||
::std::size_t operator()(const ::sol::optional<T>& o) const {
|
::std::size_t operator()(const ::sol::optional<T>& o) const {
|
||||||
if (!o.has_value())
|
if (!o.has_value())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return ::std::hash< ::sol::detail::remove_const_t<T>>()(*o);
|
return ::std::hash<::sol::detail::remove_const_t<T>>()(*o);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
|
@ -95,8 +95,8 @@ namespace sol {
|
||||||
inline constexpr bool is_unique_usertype_v = is_unique_usertype<T>::value;
|
inline constexpr bool is_unique_usertype_v = is_unique_usertype<T>::value;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <typename T>
|
template <typename T, typename Rebind = void>
|
||||||
using is_base_rebindable_test = decltype(T::rebind_base);
|
using is_base_rebindable_test = typename T::template rebind_base<Rebind>;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -106,7 +106,7 @@ namespace sol {
|
||||||
inline constexpr bool is_base_rebindable_v = is_base_rebindable<T>::value;
|
inline constexpr bool is_base_rebindable_v = is_base_rebindable<T>::value;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <typename T, typename>
|
template <typename T, typename = void>
|
||||||
struct is_base_rebindable_non_void_sfinae : std::false_type {};
|
struct is_base_rebindable_non_void_sfinae : std::false_type {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -1258,14 +1258,24 @@ namespace sol {
|
||||||
}
|
}
|
||||||
|
|
||||||
static iterator begin(lua_State*, T& self) {
|
static iterator begin(lua_State*, T& self) {
|
||||||
|
if constexpr (meta::has_begin_end_v<T>) {
|
||||||
|
return self.begin();
|
||||||
|
}
|
||||||
|
else {
|
||||||
using std::begin;
|
using std::begin;
|
||||||
return begin(self);
|
return begin(self);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static iterator end(lua_State*, T& self) {
|
static iterator end(lua_State*, T& self) {
|
||||||
|
if constexpr (meta::has_begin_end_v<T>) {
|
||||||
|
return self.end();
|
||||||
|
}
|
||||||
|
else {
|
||||||
using std::end;
|
using std::end;
|
||||||
return end(self);
|
return end(self);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int size(lua_State* L) {
|
static int size(lua_State* L) {
|
||||||
auto& self = get_src(L);
|
auto& self = get_src(L);
|
||||||
|
|
|
@ -658,6 +658,7 @@ namespace sol { namespace u_detail {
|
||||||
this->named_index_table.pop();
|
this->named_index_table.pop();
|
||||||
}
|
}
|
||||||
else if constexpr (std::is_same_v<KeyU, base_classes_tag>) {
|
else if constexpr (std::is_same_v<KeyU, base_classes_tag>) {
|
||||||
|
(void)key;
|
||||||
this->update_bases<T>(L, std::forward<Value>(value));
|
this->update_bases<T>(L, std::forward<Value>(value));
|
||||||
}
|
}
|
||||||
else if constexpr ((meta::is_string_like_or_constructible<KeyU>::value || std::is_same_v<KeyU, meta_function>)) {
|
else if constexpr ((meta::is_string_like_or_constructible<KeyU>::value || std::is_same_v<KeyU, meta_function>)) {
|
||||||
|
|
|
@ -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 2019-09-15 04:36:38.687873 UTC
|
// Generated 2019-10-02 06:37:27.657219 UTC
|
||||||
// This header was generated with sol v3.0.3 (revision b2c22ea)
|
// This header was generated with sol v3.0.3 (revision 3768063)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
|
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
// beginning of sol/feature_test.hpp
|
// beginning of sol/feature_test.hpp
|
||||||
|
|
||||||
#if (defined(__cplusplus) && __cplusplus == 201703L) || (defined(_MSC_VER) && _MSC_VER > 1900 && ((defined(_HAS_CXX17) && _HAS_CXX17 == 1) || (defined(_MSVC_LANG) && (_MSVC_LANG > 201402L))))
|
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_MSC_VER) && _MSC_VER > 1900 && ((defined(_HAS_CXX17) && _HAS_CXX17 == 1) || (defined(_MSVC_LANG) && (_MSVC_LANG > 201402L))))
|
||||||
#ifndef SOL_CXX17_FEATURES
|
#ifndef SOL_CXX17_FEATURES
|
||||||
#define SOL_CXX17_FEATURES 1
|
#define SOL_CXX17_FEATURES 1
|
||||||
#endif // C++17 features macro
|
#endif // C++17 features macro
|
||||||
|
|
|
@ -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 2019-09-15 04:36:35.549872 UTC
|
// Generated 2019-10-02 06:37:26.989637 UTC
|
||||||
// This header was generated with sol v3.0.3 (revision b2c22ea)
|
// This header was generated with sol v3.0.3 (revision 3768063)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
|
|
||||||
// beginning of sol/feature_test.hpp
|
// beginning of sol/feature_test.hpp
|
||||||
|
|
||||||
#if (defined(__cplusplus) && __cplusplus == 201703L) || (defined(_MSC_VER) && _MSC_VER > 1900 && ((defined(_HAS_CXX17) && _HAS_CXX17 == 1) || (defined(_MSVC_LANG) && (_MSVC_LANG > 201402L))))
|
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_MSC_VER) && _MSC_VER > 1900 && ((defined(_HAS_CXX17) && _HAS_CXX17 == 1) || (defined(_MSVC_LANG) && (_MSVC_LANG > 201402L))))
|
||||||
#ifndef SOL_CXX17_FEATURES
|
#ifndef SOL_CXX17_FEATURES
|
||||||
#define SOL_CXX17_FEATURES 1
|
#define SOL_CXX17_FEATURES 1
|
||||||
#endif // C++17 features macro
|
#endif // C++17 features macro
|
||||||
|
@ -3752,6 +3752,7 @@ namespace sol { namespace detail {
|
||||||
#if (__cplusplus == 201103L || defined(SOL_TL_OPTIONAL_MSVC2015) || defined(SOL_TL_OPTIONAL_GCC49))
|
#if (__cplusplus == 201103L || defined(SOL_TL_OPTIONAL_MSVC2015) || defined(SOL_TL_OPTIONAL_GCC49))
|
||||||
#define SOL_TL_OPTIONAL_11_CONSTEXPR
|
#define SOL_TL_OPTIONAL_11_CONSTEXPR
|
||||||
#else
|
#else
|
||||||
|
/// \exclude
|
||||||
#define SOL_TL_OPTIONAL_11_CONSTEXPR constexpr
|
#define SOL_TL_OPTIONAL_11_CONSTEXPR constexpr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -4087,10 +4088,12 @@ namespace sol {
|
||||||
// This specialization is for when T is not trivially copy constructible
|
// This specialization is for when T is not trivially copy constructible
|
||||||
template <class T>
|
template <class T>
|
||||||
struct optional_copy_base<T, false> : optional_operations_base<T> {
|
struct optional_copy_base<T, false> : optional_operations_base<T> {
|
||||||
using optional_operations_base<T>::optional_operations_base;
|
using base_t = optional_operations_base<T>;
|
||||||
|
|
||||||
|
using base_t::base_t;
|
||||||
|
|
||||||
optional_copy_base() = default;
|
optional_copy_base() = default;
|
||||||
optional_copy_base(const optional_copy_base& rhs) {
|
optional_copy_base(const optional_copy_base& rhs) : base_t() {
|
||||||
if (rhs.has_value()) {
|
if (rhs.has_value()) {
|
||||||
this->construct(rhs.get());
|
this->construct(rhs.get());
|
||||||
}
|
}
|
||||||
|
@ -4134,7 +4137,8 @@ namespace sol {
|
||||||
|
|
||||||
// This class manages conditionally having a trivial copy assignment operator
|
// This class manages conditionally having a trivial copy assignment operator
|
||||||
template <class T,
|
template <class T,
|
||||||
bool = SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) && SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) && SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T)>
|
bool = SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) && SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)
|
||||||
|
&& SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T)>
|
||||||
struct optional_copy_assign_base : optional_move_base<T> {
|
struct optional_copy_assign_base : optional_move_base<T> {
|
||||||
using optional_move_base<T>::optional_move_base;
|
using optional_move_base<T>::optional_move_base;
|
||||||
};
|
};
|
||||||
|
@ -5880,12 +5884,12 @@ namespace sol {
|
||||||
namespace std {
|
namespace std {
|
||||||
// TODO SFINAE
|
// TODO SFINAE
|
||||||
template <class T>
|
template <class T>
|
||||||
struct hash< ::sol::optional<T> > {
|
struct hash<::sol::optional<T>> {
|
||||||
::std::size_t operator()(const ::sol::optional<T>& o) const {
|
::std::size_t operator()(const ::sol::optional<T>& o) const {
|
||||||
if (!o.has_value())
|
if (!o.has_value())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return ::std::hash< ::sol::detail::remove_const_t<T>>()(*o);
|
return ::std::hash<::sol::detail::remove_const_t<T>>()(*o);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
@ -8064,8 +8068,8 @@ namespace sol {
|
||||||
inline constexpr bool is_unique_usertype_v = is_unique_usertype<T>::value;
|
inline constexpr bool is_unique_usertype_v = is_unique_usertype<T>::value;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <typename T>
|
template <typename T, typename Rebind = void>
|
||||||
using is_base_rebindable_test = decltype(T::rebind_base);
|
using is_base_rebindable_test = typename T::template rebind_base<Rebind>;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -8075,7 +8079,7 @@ namespace sol {
|
||||||
inline constexpr bool is_base_rebindable_v = is_base_rebindable<T>::value;
|
inline constexpr bool is_base_rebindable_v = is_base_rebindable<T>::value;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <typename T, typename>
|
template <typename T, typename = void>
|
||||||
struct is_base_rebindable_non_void_sfinae : std::false_type {};
|
struct is_base_rebindable_non_void_sfinae : std::false_type {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -18973,7 +18977,7 @@ namespace sol {
|
||||||
template <typename... R>
|
template <typename... R>
|
||||||
static std::function<Signature> get_std_func(types<R...>, lua_State* L, int index) {
|
static std::function<Signature> get_std_func(types<R...>, lua_State* L, int index) {
|
||||||
detail::std_shim<R...> fx(unsafe_function(L, index));
|
detail::std_shim<R...> fx(unsafe_function(L, index));
|
||||||
return std::move(fx);
|
return fx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::function<Signature> get(lua_State* L, int index, record& tracking) {
|
static std::function<Signature> get(lua_State* L, int index, record& tracking) {
|
||||||
|
@ -20285,14 +20289,24 @@ namespace sol {
|
||||||
}
|
}
|
||||||
|
|
||||||
static iterator begin(lua_State*, T& self) {
|
static iterator begin(lua_State*, T& self) {
|
||||||
|
if constexpr (meta::has_begin_end_v<T>) {
|
||||||
|
return self.begin();
|
||||||
|
}
|
||||||
|
else {
|
||||||
using std::begin;
|
using std::begin;
|
||||||
return begin(self);
|
return begin(self);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static iterator end(lua_State*, T& self) {
|
static iterator end(lua_State*, T& self) {
|
||||||
|
if constexpr (meta::has_begin_end_v<T>) {
|
||||||
|
return self.end();
|
||||||
|
}
|
||||||
|
else {
|
||||||
using std::end;
|
using std::end;
|
||||||
return end(self);
|
return end(self);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int size(lua_State* L) {
|
static int size(lua_State* L) {
|
||||||
auto& self = get_src(L);
|
auto& self = get_src(L);
|
||||||
|
@ -21723,6 +21737,7 @@ namespace sol { namespace u_detail {
|
||||||
this->named_index_table.pop();
|
this->named_index_table.pop();
|
||||||
}
|
}
|
||||||
else if constexpr (std::is_same_v<KeyU, base_classes_tag>) {
|
else if constexpr (std::is_same_v<KeyU, base_classes_tag>) {
|
||||||
|
(void)key;
|
||||||
this->update_bases<T>(L, std::forward<Value>(value));
|
this->update_bases<T>(L, std::forward<Value>(value));
|
||||||
}
|
}
|
||||||
else if constexpr ((meta::is_string_like_or_constructible<KeyU>::value || std::is_same_v<KeyU, meta_function>)) {
|
else if constexpr ((meta::is_string_like_or_constructible<KeyU>::value || std::is_same_v<KeyU, meta_function>)) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user