Skip to content

Commit 95e6a5a

Browse files
authored
runcode: add "watch variables" feature (#186)
* runcode: add watch variables feature * runcode: fix inaccessible watch function * runcode: fix some stuff now that I have finally tested
1 parent fb9862a commit 95e6a5a

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

[admin]/runcode/client.lua

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
me = localPlayer
22

3+
-- Primary functionality
34
local function runString (commandstring)
45
outputChatBoxR("Executing client-side command: "..commandstring)
56
local notReturned
@@ -47,3 +48,94 @@ end
4748

4849
addEvent("doCrun", true)
4950
addEventHandler("doCrun", root, runString)
51+
52+
-- Variable watching feature
53+
local watchFuncs = {}
54+
local watchKeys = {}
55+
local watchFunc_G = function(k)
56+
return _G[k]
57+
end
58+
59+
local function watchRender()
60+
local sw, y = guiGetScreenSize()
61+
local strings = {}
62+
local maxWidth = 0
63+
64+
-- Offset bottom by some more
65+
y = y - 20
66+
67+
for _, key in ipairs(watchKeys) do
68+
local results = { pcall(watchFuncs[key], key) }
69+
for i, v in ipairs(results) do
70+
results[i] = tostring(v)
71+
end
72+
73+
local text = table.concat(results, ", ")
74+
table.insert(strings, key .. ": " .. text)
75+
76+
local textWidth = dxGetTextWidth(text)
77+
if textWidth > maxWidth then
78+
maxWidth = textWidth
79+
end
80+
end
81+
82+
for _, text in ipairs(strings) do
83+
y = y - 20
84+
dxDrawText(text, sw - 100 - maxWidth, y)
85+
end
86+
end
87+
88+
local function watch(key, v)
89+
-- Error checking
90+
if type(v) ~= "string" and type(v) ~= "function" and type(v) ~= "nil" then
91+
error("Unexpected watch value of type " .. type(v) .. " for key " .. key)
92+
return
93+
end
94+
95+
-- Remove if missing value
96+
if not v then
97+
-- Don't do anything if key doesn't exist
98+
if not watchFuncs[key] then
99+
return false
100+
end
101+
102+
watchFuncs[key] = nil
103+
104+
table.remove(watchKeys, table.find(watchKeys, key))
105+
table.sort(watchKeys)
106+
107+
-- Remove event handler if we have no keys left
108+
if #watchKeys == 0 then
109+
removeEventHandler("onClientRender", root, watchRender)
110+
end
111+
112+
return true
113+
end
114+
115+
-- Only insert key if it doesn't already exist
116+
if not watchFuncs[key] then
117+
table.insert(watchKeys, key)
118+
table.sort(watchKeys)
119+
120+
-- Add event handler if this is our first key
121+
if #watchKeys == 1 then
122+
addEventHandler("onClientRender", root, watchRender)
123+
end
124+
end
125+
126+
-- Set watchFunc as global watcher, if v is string
127+
if type(v) == "string" then
128+
watchFuncs[key] = watchFunc_G
129+
elseif type(v) == "function" then
130+
watchFuncs[key] = v
131+
else
132+
assert(false, "never reached")
133+
end
134+
135+
return true
136+
end
137+
138+
runcode = {
139+
me = localPlayer,
140+
watch = watch
141+
}

[admin]/runcode/shared_util.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,11 @@ _players = setmetatable({}, {
88
-- Disable setting of items in _players
99
__newindex = function() end,
1010
})
11+
12+
function table.find(t, needle)
13+
for i, val in pairs(t) do
14+
if val == needle then
15+
return i
16+
end
17+
end
18+
end

0 commit comments

Comments
 (0)