Rewrite planemap and idalloc in pure C++
This commit is contained in:
@@ -222,6 +222,12 @@ inline LuaAcceptNilNumber &LuaAcceptNil(lua_Number &x) { return *(LuaAcceptNilNu
|
||||
inline LuaAcceptNilInteger &LuaAcceptNil(lua_Integer &x) { return *(LuaAcceptNilInteger *)(&x); }
|
||||
inline LuaAcceptNilString &LuaAcceptNil(std::string &x) { return *(LuaAcceptNilString *)(&x); }
|
||||
|
||||
using LuaDeleterFn = void (*)(void *);
|
||||
|
||||
using LuaTypeTag = lua_CFunction;
|
||||
template<typename T>
|
||||
int LuaTypeTagValue(lua_State *L) { return 0; }
|
||||
|
||||
class LuaStack {
|
||||
private:
|
||||
int narg_;
|
||||
@@ -296,6 +302,7 @@ private:
|
||||
void push_any_value(double s) const { lua_pushnumber(L_, s); }
|
||||
void push_any_value(int s) const { lua_pushinteger(L_, s); }
|
||||
void push_any_value(lua_Integer s) const { lua_pushinteger(L_, s); }
|
||||
void push_any_value(lua_CFunction s) const { lua_pushcfunction(L_, s); }
|
||||
void push_any_value(bool b) const { lua_pushboolean(L_, b ? 1:0); }
|
||||
|
||||
// Pop any value off the stack, by type.
|
||||
@@ -354,6 +361,23 @@ private:
|
||||
// original stack top, and number of declared return values.
|
||||
void check_nret(int xnret, int otop, int nret) const;
|
||||
|
||||
// Tagged pointers: we expect all userdata to be tagged pointers.
|
||||
// This starts with a void pointer, then a type tag that identifies the
|
||||
// underlying C++ type, then a deleter function. In addition, there will
|
||||
// be a metatable that contains the type name as a string and a collect
|
||||
// function.
|
||||
struct TaggedPointer {
|
||||
void *ptr;
|
||||
LuaTypeTag tag;
|
||||
LuaDeleterFn del;
|
||||
};
|
||||
static int collect_tagged_pointer(lua_State *L);
|
||||
void make_tagged_pointer(LuaSlot target, void *ptr, LuaTypeTag tag, LuaDeleterFn del);
|
||||
|
||||
template<typename T>
|
||||
static void delete_pointer(void *p) { delete (T*)p; }
|
||||
static void do_not_delete(void *p) { }
|
||||
|
||||
public:
|
||||
template<class... SS>
|
||||
LuaStack(lua_State *L, SS & ... stackslots) {
|
||||
@@ -401,6 +425,30 @@ public:
|
||||
void checknometa(LuaSlot index) const;
|
||||
|
||||
void newtable(LuaSlot target) const;
|
||||
void setlightuserdata(LuaSlot target, void *p) const;
|
||||
|
||||
template <typename T>
|
||||
void newpointer(LuaSlot target, T *ptr, bool autodel) {
|
||||
make_tagged_pointer(target, ptr, LuaTypeTagValue<T>, autodel ? delete_pointer<T> : do_not_delete);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *touserdata(LuaSlot target) {
|
||||
TaggedPointer *tp = (TaggedPointer*)lua_touserdata(L_, target);
|
||||
LuaTypeTag tag = LuaTypeTagValue<T>;
|
||||
if ((tp == 0) || (tp->tag != tag)) return 0;
|
||||
return (T*)(tp->ptr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *ckuserdata(LuaSlot target) {
|
||||
TaggedPointer *tp = (TaggedPointer*)lua_touserdata(L_, target);
|
||||
LuaTypeTag tag = LuaTypeTagValue<T>;
|
||||
if ((tp == 0) || (tp->tag != tag) || (tp->ptr==0)) {
|
||||
luaL_error(L_, "wrong userdata type");
|
||||
}
|
||||
return (T*)(tp->ptr);
|
||||
}
|
||||
|
||||
int next(LuaSlot tab, LuaSlot key, LuaSlot value) const;
|
||||
bool isemptytable(LuaSlot s) const;
|
||||
@@ -448,8 +496,11 @@ public:
|
||||
void call(T&... args) {
|
||||
call_cfunction<0>(lua_gettop(L_), args...);
|
||||
}
|
||||
|
||||
static void register_all_userdata(lua_State *L);
|
||||
};
|
||||
|
||||
|
||||
class LuaFunctionReg {
|
||||
private:
|
||||
const char *mode_;
|
||||
@@ -470,11 +521,15 @@ public:
|
||||
lua_CFunction get_func() const { return func_; }
|
||||
};
|
||||
|
||||
|
||||
#define LuaDefine(name, mode) \
|
||||
int name(lua_State *L); \
|
||||
LuaFunctionReg reg_##name(mode, #name, name); \
|
||||
int name(lua_State *L)
|
||||
|
||||
#define LuaDefineType(name) \
|
||||
LuaFunctionReg regt_##name("t", #name, LuaTypeTagValue<name>)
|
||||
|
||||
|
||||
|
||||
#endif // LUASTACK_HPP
|
||||
|
||||
Reference in New Issue
Block a user