Made Lua object custom fields allocate deterministically

This commit is contained in:
MysterD 2022-03-26 23:58:04 -07:00
parent 3f3936e874
commit 47d2fe30a7
2 changed files with 75 additions and 7 deletions

View file

@ -77,6 +77,50 @@ bool smlua_valid_lvt(u16 lvt) {
// obj behavior //
//////////////////
#define CUSTOM_FIELD_MAX 11
#define CUSTOM_FIELD_ITEM_LEN 48
struct CustomFieldItem {
char key[CUSTOM_FIELD_ITEM_LEN];
enum LuaValueType lvt;
struct CustomFieldItem* next;
};
static void smlua_add_custom_field_linked(struct CustomFieldItem** head, struct CustomFieldItem* item, const char* key, enum LuaValueType lvt) {
snprintf(item->key, CUSTOM_FIELD_ITEM_LEN, "%s", key);
item->lvt = lvt;
item->next = NULL;
if (*head == NULL) {
item->next = *head;
*head = item;
return;
}
struct CustomFieldItem* prev = NULL;
struct CustomFieldItem* node = *head;
while (node != NULL) {
if (strcmp(node->key, item->key) > 0) {
if (prev == NULL) {
item->next = *head;
*head = item;
return;
} else {
item->next = prev->next;
prev->next = item;
return;
}
}
prev = node;
node = node->next;
}
if (prev != NULL) {
item->next = prev->next;
prev->next = item;
}
}
static int smlua_func_define_custom_obj_fields(lua_State* L) {
LUA_STACK_CHECK_BEGIN();
if (!smlua_functions_valid_param_count(L, 1)) { return 0; }
@ -91,6 +135,10 @@ static int smlua_func_define_custom_obj_fields(lua_State* L) {
return 0;
}
struct CustomFieldItem* customFieldsHead = NULL;
struct CustomFieldItem customFields[CUSTOM_FIELD_MAX] = { 0 };
u16 customFieldCount = 0;
// get _custom_object_fields
lua_getglobal(L, "_G"); // get global table
lua_getfield(L, LUA_REGISTRYINDEX, gLuaLoadingMod->relativePath); // push file's "global" table
@ -100,8 +148,6 @@ static int smlua_func_define_custom_obj_fields(lua_State* L) {
lua_remove(L, -2); // remove global table
int customObjectFieldsIndex = lua_gettop(L);
u32 fieldIndex = 0x1B;
// table is in the stack at index 't'
lua_pushnil(L); // first key
int iterationTop = lua_gettop(L);
@ -127,6 +173,11 @@ static int smlua_func_define_custom_obj_fields(lua_State* L) {
lua_settop(L, iterationTop);
continue;
}
if (strlen(key) >= CUSTOM_FIELD_ITEM_LEN) {
LOG_LUA("Too long of key name for define_custom_obj_fields()");
lua_settop(L, iterationTop);
continue;
}
const char* value = smlua_to_string(L, valueIndex);
enum LuaValueType lvt = LVT_U32;
@ -138,6 +189,22 @@ static int smlua_func_define_custom_obj_fields(lua_State* L) {
return 0;
}
if (customFieldCount >= CUSTOM_FIELD_MAX) {
LOG_LUA("Ran out of custom fields!");
return 0;
}
smlua_add_custom_field_linked(&customFieldsHead, &customFields[customFieldCount], key, lvt);
customFieldCount++;
lua_settop(L, iterationTop);
}
lua_settop(L, iterationTop);
struct CustomFieldItem* node = customFieldsHead;
u32 fieldIndex = 0x1B;
while (node != NULL) {
// keep fieldIndex in range
if (fieldIndex < 0x1B) {
fieldIndex = 0x1B;
@ -149,7 +216,7 @@ static int smlua_func_define_custom_obj_fields(lua_State* L) {
}
lua_pushvalue(L, customObjectFieldsIndex);
lua_pushvalue(L, keyIndex);
lua_pushstring(L, node->key);
lua_newtable(L);
{
// set fieldIndex
@ -159,16 +226,17 @@ static int smlua_func_define_custom_obj_fields(lua_State* L) {
// set lvt
lua_pushstring(L, "_lvt");
lua_pushinteger(L, lvt);
lua_pushinteger(L, node->lvt);
lua_rawset(L, -3);
}
lua_settable(L, -3); // set _custom_object_fields
fieldIndex++;
node = node->next;
lua_settop(L, iterationTop);
}
lua_settop(L, iterationTop);
lua_pop(L, 1); // pop key
lua_pop(L, 1); // pop _custom_object_fields

View file

@ -84,7 +84,7 @@ void network_send_spawn_objects_to(u8 sendToLocalIndex, struct Object* objects[]
packet_write(&p, &model, sizeof(u32));
packet_write(&p, &behaviorId, sizeof(u32));
packet_write(&p, &o->activeFlags, sizeof(s16));
packet_write(&p, o->rawData.asU32, sizeof(s32) * 80);
packet_write(&p, o->rawData.asU32, sizeof(u32) * 0x50);
packet_write(&p, &o->header.gfx.scale[0], sizeof(f32));
packet_write(&p, &o->header.gfx.scale[1], sizeof(f32));
packet_write(&p, &o->header.gfx.scale[2], sizeof(f32));
@ -120,7 +120,7 @@ void network_receive_spawn_objects(struct Packet* p) {
packet_read(p, &data.model, sizeof(u32));
packet_read(p, &data.behaviorId, sizeof(u32));
packet_read(p, &data.activeFlags, sizeof(s16));
packet_read(p, &data.rawData, sizeof(s32) * 80);
packet_read(p, &data.rawData, sizeof(u32) * 0x50);
packet_read(p, &scale[0], sizeof(f32));
packet_read(p, &scale[1], sizeof(f32));
packet_read(p, &scale[2], sizeof(f32));