Rewrite planemap and idalloc in pure C++

This commit is contained in:
2021-01-06 15:10:21 -05:00
parent b03aada315
commit 78f8610eb8
18 changed files with 913 additions and 520 deletions

View File

@@ -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