Skip to content

Commit 40fd9ba

Browse files
committed
feat(log): ts before and after for each log entry and refactoring
1 parent 2cb183d commit 40fd9ba

File tree

1 file changed

+52
-56
lines changed

1 file changed

+52
-56
lines changed

src/lua/log.lua

Lines changed: 52 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ LOG = {
55
mod_path = nil,
66
current_run_file = nil,
77
pending_logs = {},
8-
previous_game_state = nil,
8+
game_state_before = {},
99
}
1010

1111
-- =============================================================================
1212
-- Utility Functions
1313
-- =============================================================================
1414

1515
---Writes a log entry to the JSONL file
16-
---@param log_entry table The log entry to write
17-
local function write_log_entry(log_entry)
16+
---@param log_entry LogEntry The log entry to write
17+
function LOG.write(log_entry)
1818
if LOG.current_run_file then
1919
local log_line = json.encode(log_entry) .. "\n"
2020
local file = io.open(LOG.current_run_file, "a")
@@ -31,44 +31,36 @@ end
3131
function LOG.update()
3232
for key, pending_log in pairs(LOG.pending_logs) do
3333
if pending_log.condition() then
34+
-- Update the log entry with after function call info
35+
pending_log.log_entry["timestamp_ms_after"] = math.floor(socket.gettime() * 1000)
3436
pending_log.log_entry["game_state_after"] = utils.get_game_state()
35-
write_log_entry(pending_log.log_entry)
36-
LOG.previous_game_state = pending_log.log_entry.game_state_after
37+
LOG.write(pending_log.log_entry)
38+
-- Prepare for the next log entry
39+
LOG.game_state_before = pending_log.log_entry.game_state_after
3740
LOG.pending_logs[key] = nil
3841
end
3942
end
4043
end
4144

42-
---Logs a function call to the JSONL file with completion waiting
43-
---@param original_function function The original function being called
45+
--- Schedules a log entry to be written when the condition is met
4446
---@param function_call FunctionCall The function call to log
45-
function LOG.write(original_function, function_call, ...)
47+
function LOG.schedule_write(function_call)
48+
sendInfoMessage(function_call.name .. "(" .. json.encode(function_call.arguments) .. ")", "LOG")
49+
4650
local log_entry = {
47-
timestamp_ms = math.floor(socket.gettime() * 1000),
4851
["function"] = function_call,
49-
game_state_before = LOG.previous_game_state,
52+
-- before function call
53+
timestamp_ms_before = math.floor(socket.gettime() * 1000),
54+
game_state_before = LOG.game_state_before,
55+
-- after function call (will be filled in by LOG.write)
56+
timestamp_ms_after = nil,
57+
game_state_after = nil,
58+
}
59+
local pending_key = function_call.name .. "_" .. tostring(socket.gettime())
60+
LOG.pending_logs[pending_key] = {
61+
log_entry = log_entry,
62+
condition = utils.COMPLETION_CONDITIONS[function_call.name],
5063
}
51-
52-
local result = original_function(...)
53-
sendInfoMessage(function_call.name .. "(" .. json.encode(function_call.arguments) .. ")", "LOG")
54-
55-
-- Get completion condition by function name
56-
local condition = utils.COMPLETION_CONDITIONS[function_call.name]
57-
if condition then
58-
-- Create a unique key for the pending log
59-
local pending_key = function_call.name .. "_" .. tostring(socket.gettime())
60-
LOG.pending_logs[pending_key] = {
61-
log_entry = log_entry,
62-
condition = condition,
63-
}
64-
else
65-
-- Immediate logging if no condition found
66-
log_entry["game_state_after"] = utils.get_game_state()
67-
write_log_entry(log_entry)
68-
LOG.previous_game_state = log_entry.game_state_after
69-
end
70-
71-
return result
7264
end
7365

7466
-- =============================================================================
@@ -87,7 +79,8 @@ function hook_go_to_menu()
8779
name = "go_to_menu",
8880
arguments = {},
8981
}
90-
return LOG.write(original_function, function_call, ...)
82+
LOG.schedule_write(function_call)
83+
return original_function(...)
9184
end
9285
sendDebugMessage("Hooked into G.FUNCS.go_to_menu for logging", "LOG")
9386
end
@@ -124,7 +117,8 @@ function hook_start_run()
124117
challenge = args.challenge and args.challenge.name,
125118
},
126119
}
127-
return LOG.write(original_function, function_call, game_state, args)
120+
LOG.schedule_write(function_call)
121+
return original_function(game_state, args)
128122
end
129123
sendDebugMessage("Hooked into G.FUNCS.start_run for logging", "LOG")
130124
end
@@ -138,7 +132,8 @@ function hook_select_blind()
138132
local original_function = G.FUNCS.select_blind
139133
G.FUNCS.select_blind = function(args)
140134
local function_call = { name = "skip_or_select_blind", arguments = { action = "select" } }
141-
return LOG.write(original_function, function_call, args)
135+
LOG.schedule_write(function_call)
136+
return original_function(args)
142137
end
143138
sendDebugMessage("Hooked into G.FUNCS.select_blind for logging", "LOG")
144139
end
@@ -148,7 +143,8 @@ function hook_skip_blind()
148143
local original_function = G.FUNCS.skip_blind
149144
G.FUNCS.skip_blind = function(args)
150145
local function_call = { name = "skip_or_select_blind", arguments = { action = "skip" } }
151-
return LOG.write(original_function, function_call, args)
146+
LOG.schedule_write(function_call)
147+
return original_function(args)
152148
end
153149
sendDebugMessage("Hooked into G.FUNCS.skip_blind for logging", "LOG")
154150
end
@@ -168,7 +164,8 @@ function hook_play_cards_from_highlighted()
168164
end
169165
end
170166
local function_call = { name = "play_hand_or_discard", arguments = { action = "play_hand", cards = cards } }
171-
return LOG.write(original_function, function_call, ...)
167+
LOG.schedule_write(function_call)
168+
return original_function(...)
172169
end
173170
sendDebugMessage("Hooked into G.FUNCS.play_cards_from_highlighted for logging", "LOG")
174171
end
@@ -184,7 +181,8 @@ function hook_discard_cards_from_highlighted()
184181
end
185182
end
186183
local function_call = { name = "play_hand_or_discard", arguments = { action = "discard", cards = cards } }
187-
return LOG.write(original_function, function_call, ...)
184+
LOG.schedule_write(function_call)
185+
return original_function(...)
188186
end
189187
sendDebugMessage("Hooked into G.FUNCS.discard_cards_from_highlighted for logging", "LOG")
190188
end
@@ -198,7 +196,8 @@ function hook_cash_out()
198196
local original_function = G.FUNCS.cash_out
199197
G.FUNCS.cash_out = function(...)
200198
local function_call = { name = "cash_out", arguments = {} }
201-
return LOG.write(original_function, function_call, ...)
199+
LOG.schedule_write(function_call)
200+
return original_function(...)
202201
end
203202
sendDebugMessage("Hooked into G.FUNCS.cash_out for logging", "LOG")
204203
end
@@ -212,7 +211,8 @@ function hook_toggle_shop()
212211
local original_function = G.FUNCS.toggle_shop
213212
G.FUNCS.toggle_shop = function(...)
214213
local function_call = { name = "shop", arguments = { action = "next_round" } }
215-
return LOG.write(original_function, function_call, ...)
214+
LOG.schedule_write(function_call)
215+
return original_function(...)
216216
end
217217
sendDebugMessage("Hooked into G.FUNCS.toggle_shop for logging", "LOG")
218218
end
@@ -273,34 +273,30 @@ function hook_hand_rearrange()
273273
arguments = { cards = cards },
274274
}
275275

276-
--- NOTE: we cannot use LOG.write because we do not have access to game_state_before. We need to recreate it.
277-
--- The following lines corresponds to LOG.write
276+
-- NOTE: we cannot schedule a log write because we don't have access to the
277+
-- state before the function call. We need to recreate it.
278+
279+
-- HACK: we cannot compute the timestamp before in the right way the function
280+
-- call because because this hook run with the game loop. So we use the
281+
-- timestamp for after and before
282+
283+
local timestamp_ms = math.floor(socket.gettime() * 1000)
278284

279285
local log_entry = {
280-
timestamp_ms = math.floor(socket.gettime() * 1000),
281286
["function"] = function_call,
282-
game_state_before = previous_game_state,
287+
timestamp_ms_before = timestamp_ms,
288+
game_state_before = LOG.game_state_before,
289+
timestamp_ms_after = timestamp_ms,
283290
game_state_after = utils.get_game_state(),
284291
}
285-
LOG.previous_game_state = log_entry.game_state_after
286292

287293
sendInfoMessage(function_call.name .. "(" .. json.encode(function_call.arguments) .. ")", "LOG")
288-
289-
if LOG.current_run_file then
290-
local log_line = json.encode(log_entry) .. "\n"
291-
local file = io.open(LOG.current_run_file, "a")
292-
if file then
293-
file:write(log_line)
294-
file:close()
295-
else
296-
sendErrorMessage("Failed to open log file for writing: " .. LOG.current_run_file, "LOG")
297-
end
298-
end
294+
LOG.write(log_entry)
295+
LOG.game_state_before = log_entry.game_state_after
299296
end
300297
end
301298

302299
previous_order = current_order
303-
previous_game_state = utils.get_game_state()
304300
return result
305301
else
306302
-- For non-hand card areas, just call the original function

0 commit comments

Comments
 (0)