|
|
@ -1025,11 +1025,23 @@ static int meta_enum_attr_index(lua_State *state)
|
|
|
|
luaL_error(state, "Invalid index in enum.attrs[]");
|
|
|
|
luaL_error(state, "Invalid index in enum.attrs[]");
|
|
|
|
|
|
|
|
|
|
|
|
auto id = (enum_identity*)lua_touserdata(state, lua_upvalueindex(2));
|
|
|
|
auto id = (enum_identity*)lua_touserdata(state, lua_upvalueindex(2));
|
|
|
|
|
|
|
|
auto *complex = id->getComplex();
|
|
|
|
|
|
|
|
|
|
|
|
int64_t idx = lua_tonumber(state, 2);
|
|
|
|
int64_t idx = lua_tonumber(state, 2);
|
|
|
|
|
|
|
|
if (complex)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
auto it = complex->value_index_map.find(idx);
|
|
|
|
|
|
|
|
if (it != complex->value_index_map.end())
|
|
|
|
|
|
|
|
idx = int64_t(it->second);
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
idx = id->getLastItem() + 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
if (idx < id->getFirstItem() || idx > id->getLastItem())
|
|
|
|
if (idx < id->getFirstItem() || idx > id->getLastItem())
|
|
|
|
idx = id->getLastItem()+1;
|
|
|
|
idx = id->getLastItem()+1;
|
|
|
|
idx -= id->getFirstItem();
|
|
|
|
idx -= id->getFirstItem();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t *ptr = (uint8_t*)id->getAttrs();
|
|
|
|
uint8_t *ptr = (uint8_t*)id->getAttrs();
|
|
|
|
auto atype = id->getAttrType();
|
|
|
|
auto atype = id->getAttrType();
|
|
|
@ -1349,6 +1361,68 @@ static int wtype_next_item(lua_State *state)
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* Complex enums
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* upvalues for all of these:
|
|
|
|
|
|
|
|
* 1: key table? unsure, taken from wtype stuff
|
|
|
|
|
|
|
|
* 2: enum_identity::ComplexData
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool complex_enum_next_item_helper(lua_State *L, int64_t &item, bool wrap = false)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const auto *complex = (enum_identity::ComplexData*)lua_touserdata(L, lua_upvalueindex(2));
|
|
|
|
|
|
|
|
auto it = complex->value_index_map.find(item);
|
|
|
|
|
|
|
|
if (it != complex->value_index_map.end())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
size_t index = it->second;
|
|
|
|
|
|
|
|
if (!wrap && index >= complex->size() - 1)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
item = complex->index_value_map[(index + 1) % complex->size()];
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int complex_enum_inext(lua_State *L)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
bool is_first = lua_isuserdata(L, 2);
|
|
|
|
|
|
|
|
int64_t i = (is_first)
|
|
|
|
|
|
|
|
? ((enum_identity::ComplexData*)lua_touserdata(L, lua_upvalueindex(2)))->index_value_map[0]
|
|
|
|
|
|
|
|
: luaL_checkint(L, 2);
|
|
|
|
|
|
|
|
if (is_first || complex_enum_next_item_helper(L, i))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lua_pushinteger(L, i);
|
|
|
|
|
|
|
|
lua_rawgeti(L, lua_upvalueindex(1), i);
|
|
|
|
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lua_pushnil(L);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int complex_enum_next_item(lua_State *L)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int64_t cur = luaL_checkint(L, lua_gettop(L) > 1 ? 2 : 1); // 'self' optional
|
|
|
|
|
|
|
|
complex_enum_next_item_helper(L, cur, true);
|
|
|
|
|
|
|
|
lua_pushinteger(L, cur);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int complex_enum_ipairs(lua_State *L)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lua_pushvalue(L, lua_upvalueindex(1));
|
|
|
|
|
|
|
|
lua_pushvalue(L, lua_upvalueindex(2));
|
|
|
|
|
|
|
|
lua_pushcclosure(L, complex_enum_inext, 2);
|
|
|
|
|
|
|
|
lua_pushnil(L);
|
|
|
|
|
|
|
|
lua_pushlightuserdata(L, (void*)1);
|
|
|
|
|
|
|
|
return 3;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void RenderTypeChildren(lua_State *state, const std::vector<compound_identity*> &children);
|
|
|
|
static void RenderTypeChildren(lua_State *state, const std::vector<compound_identity*> &children);
|
|
|
|
|
|
|
|
|
|
|
|
void LuaWrapper::AssociateId(lua_State *state, int table, int val, const char *name)
|
|
|
|
void LuaWrapper::AssociateId(lua_State *state, int table, int val, const char *name)
|
|
|
@ -1371,13 +1445,49 @@ static void FillEnumKeys(lua_State *state, int ix_meta, int ftable, enum_identit
|
|
|
|
int base = lua_gettop(state);
|
|
|
|
int base = lua_gettop(state);
|
|
|
|
lua_newtable(state);
|
|
|
|
lua_newtable(state);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto *complex = eid->getComplex();
|
|
|
|
|
|
|
|
|
|
|
|
// For enums, set mapping between keys and values
|
|
|
|
// For enums, set mapping between keys and values
|
|
|
|
|
|
|
|
if (complex)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (size_t i = 0; i < complex->size(); i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (keys[i])
|
|
|
|
|
|
|
|
AssociateId(state, base+1, complex->index_value_map[i], keys[i]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
for (int64_t i = eid->getFirstItem(), j = 0; i <= eid->getLastItem(); i++, j++)
|
|
|
|
for (int64_t i = eid->getFirstItem(), j = 0; i <= eid->getLastItem(); i++, j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (keys[j])
|
|
|
|
if (keys[j])
|
|
|
|
AssociateId(state, base+1, i, keys[j]);
|
|
|
|
AssociateId(state, base+1, i, keys[j]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (complex)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lua_pushvalue(state, base + 1);
|
|
|
|
|
|
|
|
lua_pushlightuserdata(state, (void*)complex);
|
|
|
|
|
|
|
|
lua_pushcclosure(state, complex_enum_ipairs, 2);
|
|
|
|
|
|
|
|
lua_setfield(state, ix_meta, "__ipairs");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lua_pushinteger(state, 0); // unused; to align ComplexData
|
|
|
|
|
|
|
|
lua_pushlightuserdata(state, (void*)complex);
|
|
|
|
|
|
|
|
lua_pushcclosure(state, complex_enum_next_item, 2);
|
|
|
|
|
|
|
|
lua_setfield(state, ftable, "next_item");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lua_pushinteger(state, eid->getFirstItem());
|
|
|
|
|
|
|
|
lua_setfield(state, ftable, "_first_item");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lua_pushinteger(state, eid->getLastItem());
|
|
|
|
|
|
|
|
lua_setfield(state, ftable, "_last_item");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lua_pushboolean(state, true);
|
|
|
|
|
|
|
|
lua_setfield(state, ftable, "_complex");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
if (eid->getFirstItem() <= eid->getLastItem())
|
|
|
|
if (eid->getFirstItem() <= eid->getLastItem())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
lua_pushvalue(state, base + 1);
|
|
|
|
lua_pushvalue(state, base + 1);
|
|
|
@ -1396,6 +1506,10 @@ static void FillEnumKeys(lua_State *state, int ix_meta, int ftable, enum_identit
|
|
|
|
|
|
|
|
|
|
|
|
lua_pushinteger(state, eid->getLastItem());
|
|
|
|
lua_pushinteger(state, eid->getLastItem());
|
|
|
|
lua_setfield(state, ftable, "_last_item");
|
|
|
|
lua_setfield(state, ftable, "_last_item");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lua_pushboolean(state, false);
|
|
|
|
|
|
|
|
lua_setfield(state, ftable, "_complex");
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SaveInTable(state, eid, &DFHACK_ENUM_TABLE_TOKEN);
|
|
|
|
SaveInTable(state, eid, &DFHACK_ENUM_TABLE_TOKEN);
|
|
|
|