mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Change userdata
to usertype
names.
We don't need to make the function names `open_usertype` now, since `new_usertype` makes sense.
This commit is contained in:
parent
6121da334f
commit
0373dd4eb2
|
@ -26,7 +26,7 @@
|
|||
#include "tuple.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "function_types.hpp"
|
||||
#include "userdata_traits.hpp"
|
||||
#include "usertype_traits.hpp"
|
||||
#include "resolve.hpp"
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
@ -191,7 +191,7 @@ struct pusher<function_sig_t<Sigs...>> {
|
|||
|
||||
template<typename Fx>
|
||||
static void set_fx(lua_State* L, std::unique_ptr<base_function> luafunc) {
|
||||
auto&& metakey = userdata_traits<Unqualified<Fx>>::metatable;
|
||||
auto&& metakey = usertype_traits<Unqualified<Fx>>::metatable;
|
||||
const char* metatablename = std::addressof(metakey[0]);
|
||||
base_function* target = luafunc.release();
|
||||
void* userdata = reinterpret_cast<void*>(target);
|
||||
|
|
|
@ -248,7 +248,7 @@ struct base_function {
|
|||
}
|
||||
|
||||
template<std::size_t I>
|
||||
struct userdata {
|
||||
struct usertype {
|
||||
static int call(lua_State* L) {
|
||||
// Zero-based template parameter, but upvalues start at 1
|
||||
return base_call(L, stack::get<upvalue_t>(L, I + 1));
|
||||
|
@ -373,7 +373,7 @@ struct member_function : public base_function {
|
|||
};
|
||||
|
||||
template<typename Function, typename Tp>
|
||||
struct userdata_function_core : public base_function {
|
||||
struct usertype_function_core : public base_function {
|
||||
typedef typename std::remove_pointer<Tp>::type T;
|
||||
typedef typename std::remove_pointer<typename std::decay<Function>::type>::type function_type;
|
||||
typedef detail::functor<T, function_type> fx_t;
|
||||
|
@ -384,7 +384,7 @@ struct userdata_function_core : public base_function {
|
|||
fx_t fx;
|
||||
|
||||
template<typename... FxArgs>
|
||||
userdata_function_core(FxArgs&&... fxargs): fx(std::forward<FxArgs>(fxargs)...) {}
|
||||
usertype_function_core(FxArgs&&... fxargs): fx(std::forward<FxArgs>(fxargs)...) {}
|
||||
|
||||
template<typename Return, typename Raw = Unqualified<Return>>
|
||||
typename std::enable_if<std::is_same<T, Raw>::value, void>::type push(lua_State* L, Return&& r) {
|
||||
|
@ -432,15 +432,15 @@ struct userdata_function_core : public base_function {
|
|||
};
|
||||
|
||||
template<typename Function, typename Tp>
|
||||
struct userdata_function : public userdata_function_core<Function, Tp> {
|
||||
typedef userdata_function_core<Function, Tp> base_t;
|
||||
struct usertype_function : public usertype_function_core<Function, Tp> {
|
||||
typedef usertype_function_core<Function, Tp> base_t;
|
||||
typedef typename std::remove_pointer<Tp>::type T;
|
||||
typedef typename base_t::traits_type traits_type;
|
||||
typedef typename base_t::args_type args_type;
|
||||
typedef typename base_t::return_type return_type;
|
||||
|
||||
template<typename... FxArgs>
|
||||
userdata_function(FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...) {}
|
||||
usertype_function(FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...) {}
|
||||
|
||||
template<typename Tx>
|
||||
int fx_call(lua_State* L) {
|
||||
|
@ -461,15 +461,15 @@ struct userdata_function : public userdata_function_core<Function, Tp> {
|
|||
};
|
||||
|
||||
template<typename Function, typename Tp>
|
||||
struct userdata_variable_function : public userdata_function_core<Function, Tp> {
|
||||
typedef userdata_function_core<Function, Tp> base_t;
|
||||
struct usertype_variable_function : public usertype_function_core<Function, Tp> {
|
||||
typedef usertype_function_core<Function, Tp> base_t;
|
||||
typedef typename std::remove_pointer<Tp>::type T;
|
||||
typedef typename base_t::traits_type traits_type;
|
||||
typedef typename base_t::args_type args_type;
|
||||
typedef typename base_t::return_type return_type;
|
||||
|
||||
template<typename... FxArgs>
|
||||
userdata_variable_function(FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...) {}
|
||||
usertype_variable_function(FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...) {}
|
||||
|
||||
template<typename Tx>
|
||||
int fx_call(lua_State* L) {
|
||||
|
@ -500,8 +500,8 @@ struct userdata_variable_function : public userdata_function_core<Function, Tp>
|
|||
};
|
||||
|
||||
template<typename Function, typename Tp>
|
||||
struct userdata_indexing_function : public userdata_function_core<Function, Tp> {
|
||||
typedef userdata_function_core<Function, Tp> base_t;
|
||||
struct usertype_indexing_function : public usertype_function_core<Function, Tp> {
|
||||
typedef usertype_function_core<Function, Tp> base_t;
|
||||
typedef typename std::remove_pointer<Tp>::type T;
|
||||
typedef typename base_t::traits_type traits_type;
|
||||
typedef typename base_t::args_type args_type;
|
||||
|
@ -511,7 +511,7 @@ struct userdata_indexing_function : public userdata_function_core<Function, Tp>
|
|||
std::unordered_map<std::string, std::pair<std::unique_ptr<base_function>, bool>> functions;
|
||||
|
||||
template<typename... FxArgs>
|
||||
userdata_indexing_function(std::string name, FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...), name(std::move(name)) {}
|
||||
usertype_indexing_function(std::string name, FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...), name(std::move(name)) {}
|
||||
|
||||
template<typename Tx>
|
||||
int fx_call(lua_State* L) {
|
||||
|
@ -521,10 +521,10 @@ struct userdata_indexing_function : public userdata_function_core<Function, Tp>
|
|||
if(function->second.second) {
|
||||
stack::push<upvalue_t>(L, function->second.first.get());
|
||||
if(std::is_same<T*, Tx>::value) {
|
||||
stack::push(L, &base_function::userdata<0>::ref_call, 1);
|
||||
stack::push(L, &base_function::usertype<0>::ref_call, 1);
|
||||
}
|
||||
else {
|
||||
stack::push(L, &base_function::userdata<0>::call, 1);
|
||||
stack::push(L, &base_function::usertype<0>::call, 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "reference.hpp"
|
||||
#include "tuple.hpp"
|
||||
#include "traits.hpp"
|
||||
#include "userdata_traits.hpp"
|
||||
#include "usertype_traits.hpp"
|
||||
#include <utility>
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
|
@ -259,19 +259,19 @@ struct pusher {
|
|||
|
||||
template<typename U = Unqualified<T>, EnableIf<Not<has_begin_end<U>>, Not<std::is_base_of<reference, U>>, Not<std::is_integral<U>>, Not<std::is_floating_point<U>>> = 0>
|
||||
static void push(lua_State* L, T& t) {
|
||||
detail::push_userdata<U>(L, userdata_traits<T>::metatable, t);
|
||||
detail::push_userdata<U>(L, usertype_traits<T>::metatable, t);
|
||||
}
|
||||
|
||||
template<typename U = Unqualified<T>, EnableIf<Not<has_begin_end<U>>, Not<std::is_base_of<reference, U>>, Not<std::is_integral<U>>, Not<std::is_floating_point<U>>> = 0>
|
||||
static void push(lua_State* L, T&& t) {
|
||||
detail::push_userdata<U>(L, userdata_traits<T>::metatable, std::move(t));
|
||||
detail::push_userdata<U>(L, usertype_traits<T>::metatable, std::move(t));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct pusher<T*> {
|
||||
static void push(lua_State* L, T* obj) {
|
||||
detail::push_userdata<T*>(L, userdata_traits<T*>::metatable, obj);
|
||||
detail::push_userdata<T*>(L, usertype_traits<T*>::metatable, obj);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -148,26 +148,26 @@ public:
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
state& set_userdata(userdata<T>& user) {
|
||||
return set_userdata(user.name(), user);
|
||||
state& set_usertype(usertype<T>& user) {
|
||||
return set_usertype(usertype_traits<T>::name, user);
|
||||
}
|
||||
|
||||
template<typename Key, typename T>
|
||||
state& set_userdata(Key&& key, userdata<T>& user) {
|
||||
global.set_userdata(std::forward<Key>(key), user);
|
||||
state& set_usertype(Key&& key, usertype<T>& user) {
|
||||
global.set_usertype(std::forward<Key>(key), user);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Class, typename... CTor, typename... Args>
|
||||
state& new_userdata(const std::string& name, Args&&... args) {
|
||||
state& new_usertype(const std::string& name, Args&&... args) {
|
||||
constructors<types<CTor...>> ctor{};
|
||||
return new_userdata<Class>(name, ctor, std::forward<Args>(args)...);
|
||||
return new_usertype<Class>(name, ctor, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename Class, typename... CArgs, typename... Args>
|
||||
state& new_userdata(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
|
||||
userdata<Class> udata(name, ctor, std::forward<Args>(args)...);
|
||||
global.set_userdata(udata);
|
||||
state& new_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
|
||||
usertype<Class> utype(ctor, std::forward<Args>(args)...);
|
||||
set_usertype(name, utype);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "proxy.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "function_types.hpp"
|
||||
#include "userdata.hpp"
|
||||
#include "usertype.hpp"
|
||||
|
||||
namespace sol {
|
||||
class table : public reference {
|
||||
|
@ -84,12 +84,12 @@ public:
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
table& set_userdata(userdata<T>& user) {
|
||||
return set_userdata(user.name(), user);
|
||||
table& set_usertype(usertype<T>& user) {
|
||||
return set_userdata(usertype_traits<T>::name, user);
|
||||
}
|
||||
|
||||
template<typename Key, typename T>
|
||||
table& set_userdata(Key&& key, userdata<T>& user) {
|
||||
table& set_usertype(Key&& key, usertype<T>& user) {
|
||||
push();
|
||||
stack::push(state(), std::forward<Key>(key));
|
||||
stack::push(state(), user);
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_USERDATA_HPP
|
||||
#define SOL_USERDATA_HPP
|
||||
#define SOL_USERTYPE_HPP
|
||||
|
||||
#include "state.hpp"
|
||||
#include "function_types.hpp"
|
||||
#include "userdata_traits.hpp"
|
||||
#include "usertype_traits.hpp"
|
||||
#include "default_construct.hpp"
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
@ -88,7 +88,7 @@ enum class meta_function {
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
class userdata {
|
||||
class usertype {
|
||||
private:
|
||||
typedef std::unordered_map<std::string, std::pair<std::unique_ptr<base_function>, bool>> function_map_t;
|
||||
function_map_t indexmetafunctions, newindexmetafunctions;
|
||||
|
@ -97,7 +97,6 @@ private:
|
|||
std::vector<luaL_Reg> metafunctiontable;
|
||||
std::vector<luaL_Reg> ptrmetafunctiontable;
|
||||
lua_CFunction cleanup;
|
||||
std::string luaname;
|
||||
|
||||
template<typename... TTypes>
|
||||
struct constructor {
|
||||
|
@ -121,7 +120,7 @@ private:
|
|||
}
|
||||
|
||||
static int construct(lua_State* L) {
|
||||
auto&& meta = userdata_traits<T>::metatable;
|
||||
auto&& meta = usertype_traits<T>::metatable;
|
||||
call_syntax syntax = stack::get_call_syntax(L, meta);
|
||||
int argcount = lua_gettop(L);
|
||||
|
||||
|
@ -131,7 +130,7 @@ private:
|
|||
|
||||
if(luaL_newmetatable(L, std::addressof(meta[0])) == 1) {
|
||||
lua_pop(L, 1);
|
||||
std::string err = "Unable to get userdata metatable for ";
|
||||
std::string err = "Unable to get usertype metatable for ";
|
||||
err += meta;
|
||||
throw error(err);
|
||||
}
|
||||
|
@ -153,7 +152,7 @@ private:
|
|||
|
||||
template<std::size_t N>
|
||||
void build_cleanup() {
|
||||
cleanup = &base_function::userdata<N>::gc;
|
||||
cleanup = &base_function::usertype<N>::gc;
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
|
@ -161,13 +160,13 @@ private:
|
|||
int extracount = 0;
|
||||
if(!indexmetafunctions.empty()) {
|
||||
if(index == nullptr) {
|
||||
auto idxptr = detail::make_unique<userdata_indexing_function<void (T::*)(), T>>("__index", nullptr);
|
||||
auto idxptr = detail::make_unique<usertype_indexing_function<void (T::*)(), T>>("__index", nullptr);
|
||||
index = &(idxptr->functions);
|
||||
functionnames.emplace_back("__index");
|
||||
metafunctions.emplace_back(std::move(idxptr));
|
||||
std::string& name = functionnames.back();
|
||||
metafunctiontable.push_back({ name.c_str(), &base_function::userdata<N>::call });
|
||||
ptrmetafunctiontable.push_back({ name.c_str(), &base_function::userdata<N>::ref_call });
|
||||
metafunctiontable.push_back({ name.c_str(), &base_function::usertype<N>::call });
|
||||
ptrmetafunctiontable.push_back({ name.c_str(), &base_function::usertype<N>::ref_call });
|
||||
++extracount;
|
||||
}
|
||||
auto& idx = *index;
|
||||
|
@ -177,18 +176,18 @@ private:
|
|||
}
|
||||
if(!newindexmetafunctions.empty()) {
|
||||
if(newindex == nullptr) {
|
||||
auto idxptr = detail::make_unique<userdata_indexing_function<void (T::*)(), T>>("__newindex", nullptr);
|
||||
auto idxptr = detail::make_unique<usertype_indexing_function<void (T::*)(), T>>("__newindex", nullptr);
|
||||
newindex = &(idxptr->functions);
|
||||
functionnames.emplace_back("__newindex");
|
||||
metafunctions.emplace_back(std::move(idxptr));
|
||||
std::string& name = functionnames.back();
|
||||
if(extracount > 0) {
|
||||
metafunctiontable.push_back({ name.c_str(), &base_function::userdata<N + 1>::call });
|
||||
ptrmetafunctiontable.push_back({ name.c_str(), &base_function::userdata<N + 1>::ref_call });
|
||||
metafunctiontable.push_back({ name.c_str(), &base_function::usertype<N + 1>::call });
|
||||
ptrmetafunctiontable.push_back({ name.c_str(), &base_function::usertype<N + 1>::ref_call });
|
||||
}
|
||||
else {
|
||||
metafunctiontable.push_back({ name.c_str(), &base_function::userdata<N>::call });
|
||||
ptrmetafunctiontable.push_back({ name.c_str(), &base_function::userdata<N>::ref_call });
|
||||
metafunctiontable.push_back({ name.c_str(), &base_function::usertype<N>::call });
|
||||
ptrmetafunctiontable.push_back({ name.c_str(), &base_function::usertype<N>::ref_call });
|
||||
}
|
||||
++extracount;
|
||||
}
|
||||
|
@ -215,8 +214,8 @@ private:
|
|||
bool build_function(std::true_type, function_map_t*&, function_map_t*&, std::string funcname, Ret Base::* func) {
|
||||
static_assert(std::is_base_of<Base, T>::value, "Any registered function must be part of the class");
|
||||
typedef typename std::decay<decltype(func)>::type function_type;
|
||||
indexmetafunctions.emplace(funcname, std::make_pair(detail::make_unique<userdata_variable_function<function_type, T>>(func), false));
|
||||
newindexmetafunctions.emplace(funcname, std::make_pair(detail::make_unique<userdata_variable_function<function_type, T>>(func), false));
|
||||
indexmetafunctions.emplace(funcname, std::make_pair(detail::make_unique<usertype_variable_function<function_type, T>>(func), false));
|
||||
newindexmetafunctions.emplace(funcname, std::make_pair(detail::make_unique<usertype_variable_function<function_type, T>>(func), false));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -225,21 +224,21 @@ private:
|
|||
typedef Unqualified<Arg> Argu;
|
||||
static_assert(std::is_base_of<Argu, T>::value, "Any non-member-function must have a first argument which is covariant with the desired userdata type.");
|
||||
typedef typename std::decay<decltype(func)>::type function_type;
|
||||
return detail::make_unique<userdata_function<function_type, T>>(func);
|
||||
return detail::make_unique<usertype_function<function_type, T>>(func);
|
||||
}
|
||||
|
||||
template<typename Base, typename Ret>
|
||||
std::unique_ptr<base_function> make_variable_function(std::true_type, const std::string&, Ret Base::* func) {
|
||||
static_assert(std::is_base_of<Base, T>::value, "Any registered function must be part of the class");
|
||||
typedef typename std::decay<decltype(func)>::type function_type;
|
||||
return detail::make_unique<userdata_variable_function<function_type, T>>(func);
|
||||
return detail::make_unique<usertype_variable_function<function_type, T>>(func);
|
||||
}
|
||||
|
||||
template<typename Base, typename Ret>
|
||||
std::unique_ptr<base_function> make_variable_function(std::false_type, const std::string&, Ret Base::* func) {
|
||||
static_assert(std::is_base_of<Base, T>::value, "Any registered function must be part of the class");
|
||||
typedef typename std::decay<decltype(func)>::type function_type;
|
||||
return detail::make_unique<userdata_function<function_type, T>>(func);
|
||||
return detail::make_unique<usertype_function<function_type, T>>(func);
|
||||
}
|
||||
|
||||
template<typename Base, typename Ret>
|
||||
|
@ -255,7 +254,7 @@ private:
|
|||
typedef Unqualified<TArg> TArgu;
|
||||
static_assert(std::is_base_of<TArgu, T>::value, "Any non-member-function must have a first argument which is covariant with the desired userdata type.");
|
||||
typedef typename std::decay<decltype(func)>::type function_type;
|
||||
return detail::make_unique<userdata_function<function_type, T>>(func);
|
||||
return detail::make_unique<usertype_function<function_type, T>>(func);
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Fx>
|
||||
|
@ -268,7 +267,7 @@ private:
|
|||
auto indexmetamethod = std::find(meta_variable_names.begin(), meta_variable_names.end(), name);
|
||||
std::unique_ptr<base_function> ptr(nullptr);
|
||||
if(indexmetamethod != meta_variable_names.end()) {
|
||||
auto idxptr = detail::make_unique<userdata_indexing_function<function_type, T>>(name, func);
|
||||
auto idxptr = detail::make_unique<usertype_indexing_function<function_type, T>>(name, func);
|
||||
switch(std::distance(indexmetamethod, meta_variable_names.end())) {
|
||||
case 0:
|
||||
index = &(idxptr->functions);
|
||||
|
@ -285,8 +284,8 @@ private:
|
|||
ptr = make_function(funcname, std::forward<Fx>(func));
|
||||
}
|
||||
metafunctions.emplace_back(std::move(ptr));
|
||||
metafunctiontable.push_back( { name.c_str(), &base_function::userdata<N>::call } );
|
||||
ptrmetafunctiontable.push_back( { name.c_str(), &base_function::userdata<N>::ref_call } );
|
||||
metafunctiontable.push_back( { name.c_str(), &base_function::usertype<N>::call } );
|
||||
ptrmetafunctiontable.push_back( { name.c_str(), &base_function::usertype<N>::ref_call } );
|
||||
return true;
|
||||
}
|
||||
indexmetafunctions.emplace(funcname, std::make_pair(make_function(funcname, std::forward<Fx>(func)), true));
|
||||
|
@ -314,13 +313,10 @@ private:
|
|||
|
||||
public:
|
||||
template<typename... Args>
|
||||
userdata(Args&&... args): userdata(userdata_traits<T>::name, default_constructor, std::forward<Args>(args)...) {}
|
||||
usertype(Args&&... args): usertype(default_constructor, std::forward<Args>(args)...) {}
|
||||
|
||||
template<typename... Args, typename... CArgs>
|
||||
userdata(constructors<CArgs...> c, Args&&... args): userdata(userdata_traits<T>::name, std::move(c), std::forward<Args>(args)...) {}
|
||||
|
||||
template<typename... Args, typename... CArgs>
|
||||
userdata(std::string name, constructors<CArgs...>, Args&&... args): luaname(std::move(name)) {
|
||||
usertype(constructors<CArgs...>, Args&&... args) {
|
||||
functionnames.reserve(sizeof...(args) + 2);
|
||||
metafunctiontable.reserve(sizeof...(args));
|
||||
ptrmetafunctiontable.reserve(sizeof...(args));
|
||||
|
@ -343,23 +339,15 @@ public:
|
|||
ptrmetafunctiontable.push_back({ nullptr, nullptr });
|
||||
}
|
||||
|
||||
template<typename... Args, typename... CArgs>
|
||||
userdata(const char* name, constructors<CArgs...> c, Args&&... args) :
|
||||
userdata(std::string(name), std::move(c), std::forward<Args>(args)...) {}
|
||||
|
||||
const std::string& name() const {
|
||||
return luaname;
|
||||
}
|
||||
|
||||
void push(lua_State* L) {
|
||||
// push pointer tables first,
|
||||
// but leave the regular T table on last
|
||||
// so it can be linked to a type for usage with `.new(...)` or `:new(...)`
|
||||
push_metatable(L, userdata_traits<T*>::metatable,
|
||||
push_metatable(L, usertype_traits<T*>::metatable,
|
||||
metafunctions, ptrmetafunctiontable);
|
||||
lua_pop(L, 1);
|
||||
|
||||
push_metatable(L, userdata_traits<T>::metatable,
|
||||
push_metatable(L, usertype_traits<T>::metatable,
|
||||
metafunctions, metafunctiontable);
|
||||
set_global_deleter(L);
|
||||
}
|
||||
|
@ -386,7 +374,7 @@ private:
|
|||
lua_setfield(L, -2, "__gc");
|
||||
lua_setmetatable(L, -2);
|
||||
// gctable name by default has ♻ part of it
|
||||
lua_setglobal(L, std::addressof(userdata_traits<T>::gctable[0]));
|
||||
lua_setglobal(L, std::addressof(usertype_traits<T>::gctable[0]));
|
||||
}
|
||||
|
||||
template<bool release = false, typename TCont>
|
||||
|
@ -407,12 +395,12 @@ private:
|
|||
|
||||
namespace stack {
|
||||
template<typename T>
|
||||
struct pusher<userdata<T>> {
|
||||
static void push(lua_State* L, userdata<T>& user) {
|
||||
struct pusher<usertype<T>> {
|
||||
static void push(lua_State* L, usertype<T>& user) {
|
||||
user.push(L);
|
||||
}
|
||||
};
|
||||
} // stack
|
||||
} // sol
|
||||
|
||||
#endif // SOL_USERDATA_HPP
|
||||
#endif // SOL_USERTYPE_HPP
|
|
@ -19,29 +19,29 @@
|
|||
// 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.
|
||||
|
||||
#ifndef SOL_USERDATA_TRAITS_HPP
|
||||
#define SOL_USERDATA_TRAITS_HPP
|
||||
#ifndef SOL_USERTYPE_TRAITS_HPP
|
||||
#define SOL_USERTYPE_TRAITS_HPP
|
||||
|
||||
#include "demangle.hpp"
|
||||
|
||||
namespace sol {
|
||||
|
||||
template<typename T>
|
||||
struct userdata_traits {
|
||||
struct usertype_traits {
|
||||
static const std::string name;
|
||||
static const std::string metatable;
|
||||
static const std::string gctable;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
const std::string userdata_traits<T>::name = detail::demangle(typeid(T));
|
||||
const std::string usertype_traits<T>::name = detail::demangle(typeid(T));
|
||||
|
||||
template<typename T>
|
||||
const std::string userdata_traits<T>::metatable = std::string("sol.").append(detail::demangle(typeid(T)));
|
||||
const std::string usertype_traits<T>::metatable = std::string("sol.").append(detail::demangle(typeid(T)));
|
||||
|
||||
template<typename T>
|
||||
const std::string userdata_traits<T>::gctable = std::string("sol.").append(detail::demangle(typeid(T))).append(".\xE2\x99\xBB");
|
||||
const std::string usertype_traits<T>::gctable = std::string("sol.").append(detail::demangle(typeid(T))).append(".\xE2\x99\xBB");
|
||||
|
||||
}
|
||||
|
||||
#endif // SOL_USERDATA_TRAITS_HPP
|
||||
#endif // SOL_USERTYPE_TRAITS_HPP
|
75
tests.cpp
75
tests.cpp
|
@ -568,12 +568,12 @@ TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works
|
|||
REQUIRE_NOTHROW(assert1(lua.global_table()));
|
||||
}
|
||||
|
||||
TEST_CASE("tables/userdata", "Show that we can create classes from userdata and use them") {
|
||||
TEST_CASE("tables/usertype", "Show that we can create classes from usertype and use them") {
|
||||
|
||||
sol::state lua;
|
||||
|
||||
sol::userdata<fuser> lc{ "add", &fuser::add, "add2", &fuser::add2 };
|
||||
lua.set_userdata(lc);
|
||||
sol::usertype<fuser> lc{ "add", &fuser::add, "add2", &fuser::add2 };
|
||||
lua.set_usertype(lc);
|
||||
|
||||
lua.script("a = fuser:new()\n"
|
||||
"b = a:add(1)\n"
|
||||
|
@ -595,13 +595,13 @@ TEST_CASE("tables/userdata", "Show that we can create classes from userdata and
|
|||
REQUIRE(cresult == 3);
|
||||
}
|
||||
|
||||
TEST_CASE("tables/userdata constructors", "Show that we can create classes from userdata and use them with multiple destructors") {
|
||||
TEST_CASE("tables/usertype constructors", "Show that we can create classes from usertype and use them with multiple destructors") {
|
||||
|
||||
sol::state lua;
|
||||
|
||||
sol::constructors<sol::types<>, sol::types<int>, sol::types<int, int>> con;
|
||||
sol::userdata<crapola::fuser> lc("crapola_fuser", con, "add", &crapola::fuser::add, "add2", &crapola::fuser::add2);
|
||||
lua.set_userdata(lc);
|
||||
sol::usertype<crapola::fuser> lc(con, "add", &crapola::fuser::add, "add2", &crapola::fuser::add2);
|
||||
lua.set_usertype(lc);
|
||||
|
||||
lua.script(
|
||||
"a = crapola_fuser.new(2)\n"
|
||||
|
@ -638,10 +638,10 @@ TEST_CASE("tables/userdata constructors", "Show that we can create classes from
|
|||
REQUIRE((z.as<int>() == 9));
|
||||
}
|
||||
|
||||
TEST_CASE("tables/userdata utility", "Show internal management of classes registered through new_userdata") {
|
||||
TEST_CASE("tables/usertype utility", "Show internal management of classes registered through new_usertype") {
|
||||
sol::state lua;
|
||||
|
||||
lua.new_userdata<fuser>("fuser", "add", &fuser::add, "add2", &fuser::add2);
|
||||
lua.new_usertype<fuser>("fuser", "add", &fuser::add, "add2", &fuser::add2);
|
||||
|
||||
lua.script("a = fuser.new()\n"
|
||||
"b = a:add(1)\n"
|
||||
|
@ -663,21 +663,21 @@ TEST_CASE("tables/userdata utility", "Show internal management of classes regist
|
|||
REQUIRE(cresult == 3);
|
||||
}
|
||||
|
||||
TEST_CASE("tables/userdata utility derived", "userdata classes must play nice when a derived class does not overload a publically visible base function") {
|
||||
TEST_CASE("tables/usertype utility derived", "usertype classes must play nice when a derived class does not overload a publically visible base function") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
sol::constructors<sol::types<int>> basector;
|
||||
sol::userdata<Base> baseuserdata("Base", basector, "get_num", &Base::get_num);
|
||||
sol::usertype<Base> baseusertype(basector, "get_num", &Base::get_num);
|
||||
|
||||
lua.set_userdata(baseuserdata);
|
||||
lua.set_usertype(baseusertype);
|
||||
|
||||
lua.script("base = Base.new(5)");
|
||||
lua.script("print(base:get_num())");
|
||||
|
||||
sol::constructors<sol::types<int>> derivedctor;
|
||||
sol::userdata<Derived> deriveduserdata("Derived", derivedctor, "get_num", &Derived::get_num, "get_num_10", &Derived::get_num_10);
|
||||
sol::usertype<Derived> derivedusertype(derivedctor, "get_num", &Derived::get_num, "get_num_10", &Derived::get_num_10);
|
||||
|
||||
lua.set_userdata(deriveduserdata);
|
||||
lua.set_usertype(derivedusertype);
|
||||
|
||||
lua.script("derived = Derived.new(7)");
|
||||
lua.script("dgn10 = derived:get_num_10()\nprint(dgn10)");
|
||||
|
@ -687,11 +687,11 @@ TEST_CASE("tables/userdata utility derived", "userdata classes must play nice wh
|
|||
REQUIRE((lua.get<int>("dgn") == 7));
|
||||
}
|
||||
|
||||
TEST_CASE("tables/self-referential userdata", "userdata classes must play nice when C++ object types are requested for C++ code") {
|
||||
TEST_CASE("tables/self-referential usertype", "usertype classes must play nice when C++ object types are requested for C++ code") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.new_userdata<self_test>("test", "g", &self_test::g, "f", &self_test::f);
|
||||
lua.new_usertype<self_test>("test", "g", &self_test::g, "f", &self_test::f);
|
||||
|
||||
lua.script(
|
||||
"local a = test.new()\n"
|
||||
|
@ -757,7 +757,7 @@ TEST_CASE("tables/issue-number-twenty-five", "Using pointers and references from
|
|||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
lua.new_userdata<test>("test", "set", &test::set, "get", &test::get, "pointer_get", &test::pget, "fun", &test::fun, "create_get", &test::create_get);
|
||||
lua.new_usertype<test>("test", "set", &test::set, "get", &test::get, "pointer_get", &test::pget, "fun", &test::fun, "create_get", &test::create_get);
|
||||
REQUIRE_NOTHROW(lua.script("x = test.new()\n"
|
||||
"x:set():get()"));
|
||||
REQUIRE_NOTHROW(lua.script("y = x:pointer_get()"));
|
||||
|
@ -770,7 +770,7 @@ TEST_CASE("tables/issue-number-twenty-five", "Using pointers and references from
|
|||
REQUIRE_NOTHROW(lua.script("assert(y:set():get() == 10, '...')"));
|
||||
}
|
||||
|
||||
TEST_CASE("userdata/issue-number-thirty-five", "using value types created from lua-called C++ code, fixing user-defined types with constructors") {
|
||||
TEST_CASE("usertype/issue-number-thirty-five", "using value types created from lua-called C++ code, fixing user-defined types with constructors") {
|
||||
struct Line {
|
||||
Vec p1, p2;
|
||||
Line() : p1{0, 0, 0}, p2{0, 0, 0} {}
|
||||
|
@ -783,13 +783,13 @@ TEST_CASE("userdata/issue-number-thirty-five", "using value types created from l
|
|||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
sol::constructors<sol::types<>, sol::types<Vec>, sol::types<Vec, Vec>> lctor;
|
||||
sol::userdata<Line> ludata("Line", lctor);
|
||||
lua.set_userdata(ludata);
|
||||
sol::usertype<Line> ludata(lctor);
|
||||
lua.set_usertype("Line", ludata);
|
||||
|
||||
sol::constructors<sol::types<float, float, float>> ctor;
|
||||
sol::userdata<Vec> udata("Vec", ctor, "normalized", &Vec::normalized, "length", &Vec::length);
|
||||
sol::usertype<Vec> udata(ctor, "normalized", &Vec::normalized, "length", &Vec::length);
|
||||
|
||||
lua.set_userdata(udata);
|
||||
lua.set_usertype(udata);
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("v = Vec.new(1, 2, 3)\n"
|
||||
"print(v:length())"));
|
||||
|
@ -797,18 +797,18 @@ TEST_CASE("userdata/issue-number-thirty-five", "using value types created from l
|
|||
"print(v:normalized():length())" ));
|
||||
}
|
||||
|
||||
TEST_CASE("userdata/lua-stored-userdata", "ensure userdata values can be stored without keeping userdata object alive") {
|
||||
TEST_CASE("usertype/lua-stored-usertype", "ensure usertype values can be stored without keeping usertype object alive") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
{
|
||||
sol::constructors<sol::types<float, float, float>> ctor;
|
||||
sol::userdata<Vec> udata("Vec", ctor,
|
||||
sol::usertype<Vec> udata(ctor,
|
||||
"normalized", &Vec::normalized,
|
||||
"length", &Vec::length);
|
||||
|
||||
lua.set_userdata(udata);
|
||||
// userdata dies, but still usable in lua!
|
||||
lua.set_usertype(udata);
|
||||
// usertype dies, but still usable in lua!
|
||||
}
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("collectgarbage()\n"
|
||||
|
@ -819,17 +819,17 @@ TEST_CASE("userdata/lua-stored-userdata", "ensure userdata values can be stored
|
|||
"print(v:normalized():length())" ));
|
||||
}
|
||||
|
||||
TEST_CASE("userdata/member-variables", "allow table-like accessors to behave as member variables for userdata") {
|
||||
TEST_CASE("usertype/member-variables", "allow table-like accessors to behave as member variables for usertype") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
sol::constructors<sol::types<float, float, float>> ctor;
|
||||
sol::userdata<Vec> udata("Vec", ctor,
|
||||
sol::usertype<Vec> udata(ctor,
|
||||
"x", &Vec::x,
|
||||
"y", &Vec::y,
|
||||
"z", &Vec::z,
|
||||
"normalized", &Vec::normalized,
|
||||
"length", &Vec::length);
|
||||
lua.set_userdata(udata);
|
||||
lua.set_usertype(udata);
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("v = Vec.new(1, 2, 3)\n"
|
||||
"v2 = Vec.new(0, 1, 0)\n"
|
||||
|
@ -847,16 +847,16 @@ TEST_CASE("userdata/member-variables", "allow table-like accessors to behave as
|
|||
));
|
||||
}
|
||||
|
||||
TEST_CASE("userdata/nonmember functions implement functionality", "let users set non-member functions that take unqualified T as first parameter to userdata") {
|
||||
TEST_CASE("usertype/nonmember functions implement functionality", "let users set non-member functions that take unqualified T as first parameter to usertype") {
|
||||
sol::state lua;
|
||||
lua.open_libraries( sol::lib::base );
|
||||
|
||||
lua.new_userdata<giver>( "giver",
|
||||
"gief_stuff", giver::gief_stuff,
|
||||
"gief", &giver::gief,
|
||||
"__tostring", [](const giver& t) {
|
||||
return std::to_string(t.a) + ": giving value";
|
||||
}
|
||||
lua.new_usertype<giver>( "giver",
|
||||
"gief_stuff", giver::gief_stuff,
|
||||
"gief", &giver::gief,
|
||||
"__tostring", [](const giver& t) {
|
||||
return std::to_string(t.a) + ": giving value";
|
||||
}
|
||||
).get<sol::table>( "giver" )
|
||||
.set_function( "stuff", giver::stuff );
|
||||
|
||||
|
@ -870,7 +870,8 @@ TEST_CASE("userdata/nonmember functions implement functionality", "let users set
|
|||
|
||||
TEST_CASE("regressions/one", "issue number 48") {
|
||||
sol::state lua;
|
||||
lua.new_userdata<vars>("vars", "boop", &vars::boop);
|
||||
lua.new_usertype<vars>("vars",
|
||||
"boop", &vars::boop);
|
||||
REQUIRE_NOTHROW(lua.script("beep = vars.new()\n"
|
||||
"beep.boop = 1"));
|
||||
// test for segfault
|
||||
|
@ -883,7 +884,7 @@ TEST_CASE("regressions/one", "issue number 48") {
|
|||
TEST_CASE("references/get-set", "properly get and set with std::ref semantics. Note that to get, we must not use Unqualified<T> on the type...") {
|
||||
sol::state lua;
|
||||
|
||||
lua.new_userdata<vars>("vars",
|
||||
lua.new_usertype<vars>("vars",
|
||||
"boop", &vars::boop);
|
||||
|
||||
vars var{};
|
||||
|
|
Loading…
Reference in New Issue
Block a user