mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 13:10:02 +01:00
Fixes a lua state null return related to the print wrapper, improves the lua editor ui formatting, and implements a stopgap lua lag fix (#68816)
This PR fixes this issue by making sure every proc called in the stack of /proc/wrap_lua_print which could sleep is called using INVOKE_ASYNC, and to prevent such problems in the future, marks all the wrappers as SHOULD_NOT_SLEEP(TRUE). I also figured out how to fix the dumb overflowing problem of the lua editor ui. Due to lag concerns regarding lua states with a large number of global variables (including fields within global tables), I have made it so the global table and state log are hidden by default - they can be shown using a toggle button in the editor ui.
This commit is contained in:
@@ -851,7 +851,8 @@
|
||||
if(value)
|
||||
to_add[new_key] = value
|
||||
ret += to_add
|
||||
CHECK_TICK
|
||||
if(i < target_list.len)
|
||||
CHECK_TICK
|
||||
return ret
|
||||
|
||||
/**
|
||||
@@ -874,7 +875,8 @@
|
||||
ret += list(list("key" = new_key, "value" = value))
|
||||
else
|
||||
ret += list(list("key" = i, "value" = new_key))
|
||||
CHECK_TICK
|
||||
if(i < target_list.len)
|
||||
CHECK_TICK
|
||||
return ret
|
||||
|
||||
/// Compares 2 lists, returns TRUE if they are the same
|
||||
@@ -927,5 +929,6 @@
|
||||
if(value)
|
||||
to_add[new_key] = value
|
||||
ret += to_add
|
||||
CHECK_TICK
|
||||
if(i < target_list.len)
|
||||
CHECK_TICK
|
||||
return ret
|
||||
|
||||
@@ -138,10 +138,7 @@ SUBSYSTEM_DEF(lua)
|
||||
break
|
||||
|
||||
// Update every lua editor TGUI open for each state that had a task awakened or resumed
|
||||
for(var/state in affected_states)
|
||||
var/list/editor_list = LAZYACCESS(editors, "\ref[state]")
|
||||
if(editor_list)
|
||||
for(var/datum/lua_editor/editor in editor_list)
|
||||
SStgui.update_uis(editor)
|
||||
for(var/datum/lua_state/state in affected_states)
|
||||
INVOKE_ASYNC(state, /datum/lua_state.proc/update_editors)
|
||||
|
||||
#undef SSLUA_INIT_FAILED
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/proc/wrap_lua_set_var(datum/thing_to_set, var_name, value)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
thing_to_set.vv_edit_var(var_name, value)
|
||||
|
||||
/proc/wrap_lua_datum_proc_call(datum/thing_to_call, proc_name, list/arguments)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
if(!usr)
|
||||
usr = GLOB.lua_usr
|
||||
var/ret
|
||||
@@ -16,6 +18,7 @@
|
||||
return ret
|
||||
|
||||
/proc/wrap_lua_global_proc_call(proc_name, list/arguments)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
if(!usr)
|
||||
usr = GLOB.lua_usr
|
||||
var/ret
|
||||
@@ -30,6 +33,7 @@
|
||||
return ret
|
||||
|
||||
/proc/wrap_lua_print(state_id, list/arguments)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
var/datum/lua_state/target_state
|
||||
for(var/datum/lua_state/state as anything in SSlua.states)
|
||||
if(state.internal_id == state_id)
|
||||
@@ -39,5 +43,5 @@
|
||||
return
|
||||
var/print_message = jointext(arguments, "\t")
|
||||
var/result = list("status" = "print", "param" = print_message)
|
||||
target_state.log_result(result, verbose = TRUE)
|
||||
INVOKE_ASYNC(target_state, /datum/lua_state.proc/log_result, result, TRUE)
|
||||
log_lua("[target_state]: [print_message]")
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
/// Arguments for a function call or coroutine resume
|
||||
var/list/arguments = list()
|
||||
|
||||
/// If set, the global table and the
|
||||
var/show_debug_info = FALSE
|
||||
|
||||
/datum/lua_editor/New(state, _quick_log_index)
|
||||
. = ..()
|
||||
if(state)
|
||||
@@ -36,12 +39,13 @@
|
||||
/datum/lua_editor/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["noStateYet"] = !current_state
|
||||
data["showDebugInfo"] = show_debug_info
|
||||
if(current_state)
|
||||
current_state.get_globals()
|
||||
if(current_state.log)
|
||||
if(current_state.log && show_debug_info)
|
||||
data["stateLog"] = kvpify_list(refify_list(current_state.log))
|
||||
data["tasks"] = current_state.get_tasks()
|
||||
if(current_state.globals)
|
||||
if(show_debug_info)
|
||||
current_state.get_globals()
|
||||
data["globals"] = kvpify_list(refify_list(current_state.globals))
|
||||
data["states"] = SSlua.states
|
||||
data["callArguments"] = kvpify_list(refify_list(arguments))
|
||||
@@ -187,6 +191,9 @@
|
||||
if("clearArgs")
|
||||
arguments.Cut()
|
||||
return TRUE
|
||||
if("toggleShowDebugInfo")
|
||||
show_debug_info = !show_debug_info
|
||||
return TRUE
|
||||
|
||||
/datum/lua_editor/ui_close(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -58,6 +58,7 @@ GLOBAL_PROTECT(lua_usr)
|
||||
break
|
||||
if(append_to_log)
|
||||
log += list(weakrefify_list(result))
|
||||
INVOKE_ASYNC(src, .proc/update_editors)
|
||||
|
||||
/datum/lua_state/proc/load_script(script)
|
||||
GLOB.IsLuaCall = TRUE
|
||||
@@ -68,6 +69,8 @@ GLOBAL_PROTECT(lua_usr)
|
||||
GLOB.lua_usr = tmp_usr
|
||||
|
||||
// Internal errors unrelated to the code being executed are returned as text rather than lists
|
||||
if(isnull(result))
|
||||
result = list("status" = "errored", "param" = "__lua_load returned null (it may have runtimed - check the runtime logs)", "name" = "input")
|
||||
if(istext(result))
|
||||
result = list("status" = "errored", "param" = result, "name" = "input")
|
||||
result["chunk"] = script
|
||||
@@ -90,13 +93,11 @@ GLOBAL_PROTECT(lua_usr)
|
||||
GLOB.IsLuaCall = FALSE
|
||||
GLOB.lua_usr = tmp_usr
|
||||
|
||||
if(isnull(result))
|
||||
result = list("status" = "errored", "param" = "__lua_call returned null (it may have runtimed - check the runtime logs)", "name" = "input")
|
||||
if(istext(result))
|
||||
result = list("status" = "errored", "param" = result, "name" = islist(function) ? jointext(function, ".") : function)
|
||||
check_if_slept(result)
|
||||
var/list/editor_list = LAZYACCESS(SSlua.editors, "\ref[src]")
|
||||
if(editor_list)
|
||||
for(var/datum/lua_editor/editor in editor_list)
|
||||
SStgui.update_uis(editor)
|
||||
return result
|
||||
|
||||
/datum/lua_state/proc/call_function_return_first(function, ...)
|
||||
@@ -111,6 +112,8 @@ GLOBAL_PROTECT(lua_usr)
|
||||
var/result = __lua_awaken(internal_id)
|
||||
GLOB.IsLuaCall = FALSE
|
||||
|
||||
if(isnull(result))
|
||||
result = list("status" = "errored", "param" = "__lua_awaken returned null (it may have runtimed - check the runtime logs)", "name" = "input")
|
||||
if(istext(result))
|
||||
result = list("status" = "errored", "param" = result, "name" = "An attempted awaken")
|
||||
check_if_slept(result)
|
||||
@@ -126,6 +129,8 @@ GLOBAL_PROTECT(lua_usr)
|
||||
var/result = __lua_resume(internal_id, index, call_args)
|
||||
GLOB.IsLuaCall = FALSE
|
||||
|
||||
if(isnull(result))
|
||||
result = list("status" = "errored", "param" = "__lua_resume returned null (it may have runtimed - check the runtime logs)", "name" = "input")
|
||||
if(istext(result))
|
||||
result = list("status" = "errored", "param" = result, "name" = "An attempted resume")
|
||||
check_if_slept(result)
|
||||
@@ -140,4 +145,10 @@ GLOBAL_PROTECT(lua_usr)
|
||||
/datum/lua_state/proc/kill_task(task_info)
|
||||
__lua_kill_task(internal_id, task_info)
|
||||
|
||||
/datum/lua_state/proc/update_editors()
|
||||
var/list/editor_list = LAZYACCESS(SSlua.editors, "\ref[src]")
|
||||
if(editor_list)
|
||||
for(var/datum/lua_editor/editor as anything in editor_list)
|
||||
SStgui.update_uis(editor)
|
||||
|
||||
#undef MAX_LOG_REPEAT_LOOKBACK
|
||||
|
||||
@@ -15,7 +15,7 @@ hljs.registerLanguage('lua', lua);
|
||||
|
||||
export const LuaEditor = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { noStateYet, globals, documentation, tasks } = data;
|
||||
const { noStateYet, globals, documentation, tasks, showDebugInfo } = data;
|
||||
const [modal, setModal] = useLocalState(
|
||||
context,
|
||||
'modal',
|
||||
@@ -24,7 +24,7 @@ export const LuaEditor = (props, context) => {
|
||||
const [activeTab, setActiveTab] = useLocalState(
|
||||
context,
|
||||
'activeTab',
|
||||
'globals'
|
||||
'tasks'
|
||||
);
|
||||
const [input, setInput] = useLocalState(context, 'scriptInput', '');
|
||||
let tabContent;
|
||||
@@ -81,10 +81,11 @@ export const LuaEditor = (props, context) => {
|
||||
<h1>Please select or create a lua state to get started.</h1>
|
||||
</Flex>
|
||||
) : (
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Stack height="calc(100% - 16px)">
|
||||
<Stack.Item grow shrink basis="55%">
|
||||
<Section
|
||||
fill
|
||||
pb="16px"
|
||||
title="Input"
|
||||
buttons={
|
||||
<>
|
||||
@@ -100,8 +101,8 @@ export const LuaEditor = (props, context) => {
|
||||
}>
|
||||
<TextArea
|
||||
fluid
|
||||
width="700px"
|
||||
height="590px"
|
||||
width="100%"
|
||||
height="100%"
|
||||
value={input}
|
||||
fontFamily="Consolas"
|
||||
onInput={(_, value) => setInput(value)}
|
||||
@@ -122,29 +123,51 @@ export const LuaEditor = (props, context) => {
|
||||
</Button>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<Section fill height="95%" width="100%">
|
||||
<Tabs>
|
||||
<Tabs.Tab
|
||||
selected={activeTab === 'globals'}
|
||||
onClick={() => {
|
||||
setActiveTab('globals');
|
||||
}}>
|
||||
Globals
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
selected={activeTab === 'tasks'}
|
||||
onClick={() => setActiveTab('tasks')}>
|
||||
Tasks
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
selected={activeTab === 'log'}
|
||||
onClick={() => {
|
||||
setActiveTab('log');
|
||||
}}>
|
||||
Log
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
<Stack.Item grow shrink basis="45%">
|
||||
<Section fill pb="24px" height="100%" width="100%" buttons>
|
||||
<Stack justify="space-between">
|
||||
<Stack.Item>
|
||||
<Tabs>
|
||||
{!!showDebugInfo && (
|
||||
<Tabs.Tab
|
||||
selected={activeTab === 'globals'}
|
||||
onClick={() => {
|
||||
setActiveTab('globals');
|
||||
}}>
|
||||
Globals
|
||||
</Tabs.Tab>
|
||||
)}
|
||||
<Tabs.Tab
|
||||
selected={activeTab === 'tasks'}
|
||||
onClick={() => setActiveTab('tasks')}>
|
||||
Tasks
|
||||
</Tabs.Tab>
|
||||
{!!showDebugInfo && (
|
||||
<Tabs.Tab
|
||||
selected={activeTab === 'log'}
|
||||
onClick={() => {
|
||||
setActiveTab('log');
|
||||
}}>
|
||||
Log
|
||||
</Tabs.Tab>
|
||||
)}
|
||||
</Tabs>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button.Checkbox
|
||||
inline
|
||||
checked={showDebugInfo}
|
||||
tooltip="WARNING: Enabling debug info can cause significant lag for the entire server, especially when there is a large number of global variables."
|
||||
onClick={() => {
|
||||
if (showDebugInfo && activeTab !== 'tasks') {
|
||||
setActiveTab('tasks');
|
||||
}
|
||||
act('toggleShowDebugInfo');
|
||||
}}>
|
||||
Show Debug Info
|
||||
</Button.Checkbox>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
<Section fill scrollable scrollableHorizontal width="100%">
|
||||
{tabContent}
|
||||
</Section>
|
||||
|
||||
Reference in New Issue
Block a user