MCPcopy Create free account
hub / github.com/DFHack/dfhack / AddFieldInfoTable

Function AddFieldInfoTable

library/LuaTypes.cpp:1488–1548  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1486}
1487
1488static void AddFieldInfoTable(lua_State *state, int ftable_idx, struct_identity *pstruct)
1489{
1490 Lua::StackUnwinder base{state};
1491
1492 // metatable
1493 lua_newtable(state);
1494 int ix_meta = lua_gettop(state);
1495
1496 // field info table (name -> struct_field_info*)
1497 lua_newtable(state);
1498 int ix_fieldinfo = lua_gettop(state);
1499
1500 // field iter table (int <-> name)
1501 lua_newtable(state);
1502 int ix_fielditer = lua_gettop(state);
1503 IndexFields(state, base, pstruct, IndexFieldsFlags::RAW);
1504
1505 PushStructMethod(state, ix_meta, ix_fielditer, meta_fieldinfo_next);
1506 // change upvalue 1 to the field info table since we don't need the original
1507 lua_pushvalue(state, ix_fieldinfo);
1508 lua_setupvalue(state, -2, 1);
1509 SetPairsMethod(state, ix_meta, "__pairs");
1510
1511 // field table (name -> table representation of struct_field_info)
1512 lua_newtable(state);
1513 int ix_fields = lua_gettop(state);
1514
1515 // wrapper table (empty, indexes into field table with metamethods)
1516 lua_newtable(state);
1517 int ix_wrapper = lua_gettop(state);
1518
1519 // set up metatable for the wrapper
1520 // use field table for __index
1521 lua_pushstring(state, "__index");
1522 lua_pushvalue(state, ix_fieldinfo);
1523 lua_pushcclosure(state, meta_fieldinfo_index, 1);
1524 lua_settable(state, ix_meta);
1525
1526 // use change_error() for __newindex
1527 lua_pushstring(state, "__newindex");
1528 lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_CHANGEERROR_NAME);
1529 lua_settable(state, ix_meta);
1530
1531 lua_pushvalue(state, ix_meta);
1532 lua_setmetatable(state, ix_wrapper);
1533
1534 // convert field info table (struct_field_info) to field table (lua tables)
1535 lua_pushnil(state); // initial key for next()
1536 while (lua_next(state, ix_fieldinfo)) {
1537 auto field = static_cast<const struct_field_info*>(lua_touserdata(state, -1));
1538 lua_pushvalue(state, -2); // field name
1539 PushFieldInfoSubTable(state, field);
1540 lua_settable(state, ix_fields);
1541 lua_pop(state, 1); // struct_field_info
1542 }
1543
1544 // lua_pushvalue(state, ix_fields);
1545 // freeze_table(state); // TODO: figure out why this creates an __index cycle for nonexistent fields

Callers 1

IndexStaticsMethod · 0.85

Calls 14

lua_gettopFunction · 0.85
IndexFieldsFunction · 0.85
lua_pushvalueFunction · 0.85
lua_setupvalueFunction · 0.85
lua_pushstringFunction · 0.85
lua_pushcclosureFunction · 0.85
lua_settableFunction · 0.85
lua_getfieldFunction · 0.85
lua_setmetatableFunction · 0.85
lua_pushnilFunction · 0.85
lua_nextFunction · 0.85
lua_touserdataFunction · 0.85

Tested by

no test coverage detected