policy.hpp
来自「这是整套横扫千军3D版游戏的源码」· HPP 代码 · 共 1,303 行 · 第 1/3 页
HPP
1,303 行
static int match(lua_State* L, T, int index)
{
using namespace converters;
return match_lua_to_cpp(L, T(), index);
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
template<>
struct user_defined_converter<cpp_to_lua>
{
typedef boost::mpl::bool_<false> is_value_converter;
typedef user_defined_converter type;
template<class T>
void apply(lua_State* L, const T& v)
{
using namespace converters;
convert_cpp_to_lua(L, v);
}
};
// ********** pointer converter ***********
template<class Direction> struct pointer_converter;
template<>
struct pointer_converter<cpp_to_lua>
{
typedef boost::mpl::bool_<false> is_value_converter;
typedef pointer_converter type;
template<class T>
void apply(lua_State* L, T* ptr)
{
if (ptr == 0)
{
lua_pushnil(L);
return;
}
if (luabind::get_back_reference(L, ptr))
return;
class_rep* crep = get_class_rep<T>(L);
// if you get caught in this assert you are
// trying to use an unregistered type
assert(crep && "you are trying to use an unregistered type");
// create the struct to hold the object
void* obj = lua_newuserdata(L, sizeof(object_rep));
//new(obj) object_rep(ptr, crep, object_rep::owner, destructor_s<T>::apply);
new(obj) object_rep(ptr, crep, 0, 0);
// set the meta table
detail::getref(L, crep->metatable_ref());
lua_setmetatable(L, -2);
}
};
template<class T> struct make_pointer { typedef T* type; };
template<>
struct pointer_converter<lua_to_cpp>
{
typedef boost::mpl::bool_<false> is_value_converter;
typedef pointer_converter type;
// TODO: does the pointer converter need this?!
char target[32];
void (*destructor)(void *);
pointer_converter(): destructor(0) {}
template<class T>
typename make_pointer<T>::type apply(lua_State* L, by_pointer<T>, int index)
{
// preconditions:
// lua_isuserdata(L, index);
// getmetatable().__lua_class is true
// object_rep->flags() & object_rep::constant == 0
if (lua_isnil(L, index)) return 0;
object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
assert((obj != 0) && "internal error, please report"); // internal error
const class_rep* crep = obj->crep();
T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
if ((void*)ptr == (char*)target) destructor = detail::destruct_only_s<T>::apply;
assert(!destructor || sizeof(T) <= 32);
return ptr;
}
template<class T>
static int match(lua_State* L, by_pointer<T>, int index)
{
if (lua_isnil(L, index)) return 0;
object_rep* obj = is_class_object(L, index);
if (obj == 0) return -1;
// cannot cast a constant object to nonconst
if (obj->flags() & object_rep::constant) return -1;
if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
return (obj->flags() & object_rep::constant)?-1:0;
if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
return (obj->flags() & object_rep::constant)?0:-1;
int d;
return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
}
~pointer_converter()
{
if (destructor) destructor(target);
}
template<class T>
void converter_postcall(lua_State*, by_pointer<T>, int)
{}
};
// ******* value converter *******
template<class Direction> struct value_converter;
template<>
struct value_converter<cpp_to_lua>
{
typedef boost::mpl::bool_<true> is_value_converter;
typedef value_converter type;
template<class T>
void apply(lua_State* L, const T& ref)
{
if (luabind::get_back_reference(L, ref))
return;
class_rep* crep = get_class_rep<T>(L);
// if you get caught in this assert you are
// trying to use an unregistered type
assert(crep && "you are trying to use an unregistered type");
void* obj_rep;
void* held;
boost::tie(obj_rep,held) = crep->allocate(L);
void* object_ptr;
void(*destructor)(void*);
destructor = crep->destructor();
int flags = object_rep::owner;
if (crep->has_holder())
{
new(held) T(ref);
object_ptr = held;
if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
{
flags |= object_rep::constant;
destructor = crep->const_holder_destructor();
}
}
else
{
object_ptr = new T(ref);
}
new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
// set the meta table
detail::getref(L, crep->metatable_ref());
lua_setmetatable(L, -2);
}
};
template<class T> struct make_const_reference { typedef const T& type; };
template<class T>
struct destruct_guard
{
T* ptr;
bool dismiss;
destruct_guard(T* p): ptr(p), dismiss(false) {}
~destruct_guard()
{
if (!dismiss)
ptr->~T();
}
};
template<>
struct value_converter<lua_to_cpp>
{
typedef boost::mpl::bool_<true> is_value_converter;
typedef value_converter type;
template<class T>
T apply(lua_State* L, by_value<T>, int index)
{
// preconditions:
// lua_isuserdata(L, index);
// getmetatable().__lua_class is true
// object_rep->flags() & object_rep::constant == 0
object_rep* obj = 0;
const class_rep* crep = 0;
// special case if we get nil in, try to convert the holder type
if (lua_isnil(L, index))
{
crep = get_class_rep<T>(L);
assert(crep);
}
else
{
obj = static_cast<object_rep*>(lua_touserdata(L, index));
assert((obj != 0) && "internal error, please report"); // internal error
crep = obj->crep();
}
assert(crep);
// TODO: align!
char target[sizeof(T)];
T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
destruct_guard<T> guard(ptr);
if ((void*)ptr != (void*)target) guard.dismiss = true;
return *ptr;
}
template<class T>
static int match(lua_State* L, by_value<T>, int index)
{
// special case if we get nil in, try to match the holder type
if (lua_isnil(L, index))
{
class_rep* crep = get_class_rep<T>(L);
if (crep == 0) return -1;
if ((LUABIND_TYPE_INFO_EQUAL(crep->holder_type(), LUABIND_TYPEID(T))))
return 0;
if ((LUABIND_TYPE_INFO_EQUAL(crep->const_holder_type(), LUABIND_TYPEID(T))))
return 0;
return -1;
}
object_rep* obj = is_class_object(L, index);
if (obj == 0) return -1;
int d;
if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
return (obj->flags() & object_rep::constant)?-1:0;
if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
return (obj->flags() & object_rep::constant)?0:1;
return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
// ******* const pointer converter *******
template<class Direction> struct const_pointer_converter;
template<>
struct const_pointer_converter<cpp_to_lua>
{
typedef boost::mpl::bool_<false> is_value_converter;
typedef const_pointer_converter type;
template<class T>
void apply(lua_State* L, const T* ptr)
{
if (ptr == 0)
{
lua_pushnil(L);
return;
}
if (luabind::get_back_reference(L, ptr))
return;
class_rep* crep = get_class_rep<T>(L);
// if you get caught in this assert you are
// trying to use an unregistered type
assert(crep && "you are trying to use an unregistered type");
// create the struct to hold the object
void* obj = lua_newuserdata(L, sizeof(object_rep));
assert(obj && "internal error, please report");
// we send 0 as destructor since we know it will never be called
new(obj) object_rep(const_cast<T*>(ptr), crep, object_rep::constant, 0);
// set the meta table
detail::getref(L, crep->metatable_ref());
lua_setmetatable(L, -2);
}
};
template<class T> struct make_const_pointer { typedef const T* type; };
template<>
struct const_pointer_converter<lua_to_cpp>
: private pointer_converter<lua_to_cpp>
{
typedef boost::mpl::bool_<false> is_value_converter;
typedef const_pointer_converter type;
template<class T>
typename make_const_pointer<T>::type apply(lua_State* L, by_const_pointer<T>, int index)
{
return pointer_converter<lua_to_cpp>::apply(L, by_pointer<T>(), index);
}
template<class T>
static int match(lua_State* L, by_const_pointer<T>, int index)
{
if (lua_isnil(L, index)) return 0;
object_rep* obj = is_class_object(L, index);
if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
return (obj->flags() & object_rep::constant)?-1:0;
if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
return (obj->flags() & object_rep::constant)?0:1;
bool const_ = obj->flags() & object_rep::constant;
int d;
int points = implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
return points == -1 ? -1 : points + !const_;
}
template<class T>
void converter_postcall(lua_State* L, by_const_pointer<T>, int index)
{
pointer_converter<lua_to_cpp>::converter_postcall(L, by_pointer<T>(), index);
}
};
// ******* reference converter *******
template<class Direction> struct ref_converter;
template<>
struct ref_converter<cpp_to_lua>
{
typedef boost::mpl::bool_<false> is_value_converter;
typedef ref_converter type;
template<class T>
void apply(lua_State* L, T& ref)
{
if (luabind::get_back_reference(L, ref))
return;
class_rep* crep = get_class_rep<T>(L);
// if you get caught in this assert you are
// trying to use an unregistered type
assert(crep && "you are trying to use an unregistered type");
T* ptr = &ref;
// create the struct to hold the object
void* obj = lua_newuserdata(L, sizeof(object_rep));
assert(obj && "internal error, please report");
new(obj) object_rep(ptr, crep, 0, 0);
// set the meta table
detail::getref(L, crep->metatable_ref());
lua_setmetatable(L, -2);
}
};
template<class T> struct make_reference { typedef T& type; };
template<>
struct ref_converter<lua_to_cpp>
{
typedef boost::mpl::bool_<false> is_value_converter;
typedef ref_converter type;
template<class T>
typename make_reference<T>::type apply(lua_State* L, by_reference<T>, int index)
{
assert(!lua_isnil(L, index));
return *pointer_converter<lua_to_cpp>().apply(L, by_pointer<T>(), index);
}
template<class T>
static int match(lua_State* L, by_reference<T>, int index)
{
if (lua_isnil(L, index)) return -1;
return pointer_converter<lua_to_cpp>::match(L, by_pointer<T>(), index);
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
// ******** const reference converter *********
template<class Direction> struct const_ref_converter;
template<>
struct const_ref_converter<cpp_to_lua>
{
typedef boost::mpl::bool_<false> is_value_converter;
typedef const_ref_converter type;
template<class T>
void apply(lua_State* L, T const& ref)
{
if (luabind::get_back_reference(L, ref))
return;
class_rep* crep = get_class_rep<T>(L);
// if you get caught in this assert you are
// trying to use an unregistered type
assert(crep && "you are trying to use an unregistered type");
T const* ptr = &ref;
// create the struct to hold the object
void* obj = lua_newuserdata(L, sizeof(object_rep));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?