-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBreakpoints.lua
More file actions
149 lines (119 loc) · 3.33 KB
/
Breakpoints.lua
File metadata and controls
149 lines (119 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
local projectRoot = system.pathForFile("", system.ResourceDirectory)
local function getlocalsAtLevel(level, locals)
local i = 1
while true do
local name, value = debug.getlocal(level, i)
if not name then break end
if locals[name] == nil then
locals[name] = value
end
i = i + 1
end
end
local function getLocals(level)
local locals = {}
local success, l
repeat
success, l = pcall(getlocalsAtLevel, level, locals)
level = level + 1
until not success
return locals
end
local function getUpvalues(f)
local i = 1
local upvalues = {}
while true do
local name, value = debug.getupvalue(f, i)
if not name then break end
upvalues[name] = value
i = i + 1
end
return upvalues
end
local function getEnv(f)
-- lets save all the local values from the original function
local locals = getLocals(6)
local upvalues = getUpvalues(f)
local env = {}
-- let's set the globals
for k, v in pairs(_G) do
env[k] = v
end
-- let's set the locals
for k, v in pairs(locals) do
env[k] = v
end
-- let's set the upvalues
for k, v in pairs(upvalues) do
env[k] = v
end
return env
end
local s = "> "
local function consolePrint(...)
print(s, ...)
s = " "
end
function _G.breakpoint(n, f)
if not f then
f = n
n = nil
end
-- lets save all the local values from the original function
local env = getEnv(f)
local file = debug.getinfo(f, "S").source
:gsub(projectRoot, "")
:sub(2)
local absPath = system.pathForFile(file)
local function reload()
local f = io.open(absPath, "r")
local content = f:read("*all")
f:close()
local breakpointCall
if n then
breakpointCall = content:match("breakpoint%(%s*"..n.."%s*,%s*function%s*%(%s*%)(.-)end%s*%)")
else
breakpointCall = content:match("breakpoint%(%s*function%s*%(%s*%)(.-)end%s*%)")
end
if breakpointCall then
local f = loadstring(breakpointCall)
setfenv(f, env)
s = "> "
env.print = consolePrint
local success, msg = pcall(f)
if success then
print(" ")
return msg
else
print("Error in breakpoint: " .. msg)
end
end
end
local lfs = require("lfs")
local lastModified = lfs.attributes(absPath).modification
local function wasModified()
local attributes = lfs.attributes(absPath)
local modified = attributes.modification
if modified ~= lastModified then
lastModified = modified
return true
end
end
local function shouldResume()
if not wasModified() then
return false
end
return reload()
end
local trace = debug.traceback("", 2)
-- third line is the function call
local line = trace:match(":(%d+):")
-- let's add some emojis letting the user know we hit a breakpoint
-- with some clear indications
print(" ")
print(" ")
print("🔴 Breakpoint at: " .. file .. ":" .. line)
while not shouldResume() do
os.execute("sleep 0.01")
end
end