Skip to content

Commit

Permalink
edict fields enum via ipairs() (wip)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexey-lysiuk committed Aug 17, 2023
1 parent 717d114 commit 94cc642
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 25 deletions.
37 changes: 27 additions & 10 deletions Quake/ls_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,24 +369,41 @@ static edict_t* LS_GetEdictFromUserData(lua_State* state)
// Pushes value of edict field by its name
static int LS_value_edict_index(lua_State* state)
{
luaL_checktype(state, 2, LUA_TSTRING);

edict_t* ed = LS_GetEdictFromUserData(state);
assert(ed);

if (ed->free)
lua_pushnil(state); // TODO: default value instead of nil
else
const char* name;
etype_t type;
const eval_t* value;

int indextype = lua_type(state, 2);

if (indextype == LUA_TSTRING)
{
if (ed->free)
lua_pushnil(state); // TODO: default value instead of nil
else
{
name = luaL_checkstring(state, 2);

if (ED_GetFieldByName(ed, name, &type, &value))
LS_PushEdictFieldValue(state, name, type, value);
else
lua_pushnil(state);
}
}
else if (indextype == LUA_TNUMBER)
{
const char* name = luaL_checkstring(state, 2);
etype_t type;
const eval_t* value;
int fieldindex = lua_tointeger(state, 2);

if (ED_GetFieldByName(ed, name, &type, &value))
if (ED_GetFieldByIndex(ed, fieldindex - 1, &name, &type, &value)) // on Lua side, indices start with one
// TODO: push name-value pair
LS_PushEdictFieldValue(state, name, type, value);
else
lua_pushnil(state); // TODO: default value instead of nil
lua_pushnil(state);
}
else
luaL_error(state, "Invalid type %d of edict index", indextype);

return 1;
}
Expand Down
39 changes: 24 additions & 15 deletions Quake/pr_edict.c
Original file line number Diff line number Diff line change
Expand Up @@ -1582,35 +1582,44 @@ qboolean ED_GetFieldByIndex(edict_t* ed, size_t fieldindex, const char** name, e
if (fieldindex >= (size_t)progs->numfielddefs)
return false;

static eval_t defaultvalue;

const ddef_t* fielddef = &pr_fielddefs[fieldindex];
const char* fieldname = PR_GetString(fielddef->s_name);

size_t namelen = strlen(fieldname);
if (namelen > 1 && fieldname[namelen - 2] == '_')
return false; // skip _x, _y, _z vars
// size_t namelen = strlen(fieldname);
// if (namelen > 1 && fieldname[namelen - 2] == '_')
// return false; // skip _x, _y, _z vars

const int* fieldvalue = (int*)((byte*)&ed->v + fielddef->ofs * 4);

// if the value is still all 0, skip the field
int fieldtype = fielddef->type & ~DEF_SAVEGLOBAL;

if (fieldtype >= NUM_TYPE_SIZES)
return false;

int tsi;

for (tsi = 0; tsi < type_size[fieldtype]; ++tsi)
{
if (fieldvalue[tsi])
break;
*name = "";
*type = ev_bad;
*value = &defaultvalue;
}
else
{
int tsi;

if (tsi == type_size[fieldtype])
return false;
for (tsi = 0; tsi < type_size[fieldtype]; ++tsi)
{
if (fieldvalue[tsi])
break;
}

*name = fieldname;
*type = fieldtype;
*value = (const eval_t*)fieldvalue;
if (tsi == type_size[fieldtype])
*value = &defaultvalue;
else
*value = (const eval_t*)fieldvalue;

*name = fieldname;
*type = fieldtype;
}

return true;
}
Expand Down

0 comments on commit 94cc642

Please sign in to comment.