mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-11 18:22:14 +00:00
## About The Pull Request Signals don't get removed on turfs when they're deleted. This fixes that so that it is reflected in lua as well. ## Why It's Good For The Game Lua bugfixes ## Changelog 🆑 fix: Fixed lua scripts breaking when turfs with registered signals get deleted. /🆑 --------- Co-authored-by: Watermelon914 <3052169-Watermelon914@users.noreply.gitlab.com>
190 lines
5.3 KiB
Lua
190 lines
5.3 KiB
Lua
local timer = require("timer")
|
|
local state = require("state")
|
|
|
|
local SS13 = {}
|
|
|
|
__SS13_signal_handlers = __SS13_signal_handlers or {}
|
|
|
|
SS13.SSlua = dm.global_vars.vars.SSlua
|
|
|
|
SS13.global_proc = "some_magic_bullshit"
|
|
|
|
SS13.state = state.state
|
|
|
|
function SS13.get_runner_ckey()
|
|
return SS13.state:get_var("ckey_last_runner")
|
|
end
|
|
|
|
function SS13.get_runner_client()
|
|
return dm.global_vars:get_var("GLOB"):get_var("directory"):get(SS13.get_runner_ckey())
|
|
end
|
|
|
|
function SS13.istype(thing, type)
|
|
return dm.global_proc("_istype", thing, dm.global_proc("_text2path", type)) == 1
|
|
end
|
|
|
|
function SS13.start_tracking(datum)
|
|
local references = SS13.state.vars.references
|
|
references:add(datum)
|
|
SS13.state:call_proc("clear_on_delete", datum)
|
|
end
|
|
|
|
function SS13.new(type, ...)
|
|
local datum = SS13.new_untracked(type, ...)
|
|
if datum then
|
|
SS13.start_tracking(datum)
|
|
return datum
|
|
end
|
|
end
|
|
|
|
function SS13.type(string_type)
|
|
return dm.global_proc("_text2path", string_type)
|
|
end
|
|
|
|
function SS13.qdel(datum)
|
|
if SS13.is_valid(datum) then
|
|
dm.global_proc("qdel", datum)
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function SS13.new_untracked(type, ...)
|
|
return dm.global_proc("_new", type, { ... })
|
|
end
|
|
|
|
function SS13.is_valid(datum)
|
|
if datum and not datum:is_null() and not datum:get_var("gc_destroyed") then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function SS13.await(thing_to_call, proc_to_call, ...)
|
|
if not SS13.istype(thing_to_call, "/datum") then
|
|
thing_to_call = SS13.global_proc
|
|
end
|
|
if thing_to_call == SS13.global_proc then
|
|
proc_to_call = "/proc/" .. proc_to_call
|
|
end
|
|
local promise = SS13.new("/datum/auxtools_promise", thing_to_call, proc_to_call, ...)
|
|
local promise_vars = promise.vars
|
|
while promise_vars.status == 0 do
|
|
sleep()
|
|
end
|
|
local return_value, runtime_message = promise_vars.return_value, promise_vars.runtime_message
|
|
SS13.stop_tracking(promise)
|
|
return return_value, runtime_message
|
|
end
|
|
|
|
function SS13.register_signal(datum, signal, func)
|
|
if not SS13.istype(datum, "/datum") then
|
|
return
|
|
end
|
|
if not SS13.is_valid(datum) then
|
|
error("Tried to register a signal on a deleted datum!", 2)
|
|
return
|
|
end
|
|
local datumWeakRef = dm.global_proc("WEAKREF", datum)
|
|
if not __SS13_signal_handlers[datumWeakRef] then
|
|
__SS13_signal_handlers[datumWeakRef] = {}
|
|
end
|
|
if signal == "_cleanup" then
|
|
return
|
|
end
|
|
if not __SS13_signal_handlers[datumWeakRef][signal] then
|
|
__SS13_signal_handlers[datumWeakRef][signal] = {}
|
|
end
|
|
local callback = SS13.new("/datum/callback", SS13.state, "call_function_return_first")
|
|
local callbackWeakRef = dm.global_proc("WEAKREF", callback)
|
|
callback:call_proc("RegisterSignal", datum, signal, "Invoke")
|
|
local path = { "__SS13_signal_handlers", datumWeakRef, signal, callbackWeakRef, "func" }
|
|
callback.vars.arguments = { path }
|
|
-- Turfs don't remove their signals on deletion.
|
|
if not __SS13_signal_handlers[datumWeakRef]._cleanup and not SS13.istype(datum, "/turf") then
|
|
local cleanupCallback = SS13.new("/datum/callback", SS13.state, "call_function_return_first")
|
|
local cleanupPath = { "__SS13_signal_handlers", datumWeakRef, "_cleanup"}
|
|
cleanupCallback.vars.arguments = { cleanupPath }
|
|
cleanupCallback:call_proc("RegisterSignal", datum, "parent_qdeleting", "Invoke")
|
|
__SS13_signal_handlers[datumWeakRef]._cleanup = function(datum)
|
|
SS13.start_tracking(datumWeakRef)
|
|
timer.set_timeout(0, function()
|
|
SS13.signal_handler_cleanup(datumWeakRef)
|
|
SS13.stop_tracking(cleanupCallback)
|
|
SS13.stop_tracking(datumWeakRef)
|
|
end)
|
|
end
|
|
end
|
|
__SS13_signal_handlers[datumWeakRef][signal][callbackWeakRef] = { func = func, callback = callback }
|
|
return callback
|
|
end
|
|
|
|
function SS13.stop_tracking(datum)
|
|
SS13.state:call_proc("let_soft_delete", datum)
|
|
end
|
|
|
|
function SS13.unregister_signal(datum, signal, callback)
|
|
local function clear_handler(handler_info)
|
|
if not handler_info then
|
|
return
|
|
end
|
|
if not handler_info.callback then
|
|
return
|
|
end
|
|
local handler_callback = handler_info.callback
|
|
local callbackWeakRef = dm.global_proc("WEAKREF", handler_callback)
|
|
if not SS13.istype(datum, "/datum/weakref") then
|
|
handler_callback:call_proc("UnregisterSignal", datum, signal)
|
|
else
|
|
local actualDatum = datum:call_proc("hard_resolve")
|
|
if SS13.is_valid(actualDatum) then
|
|
handler_callback:call_proc("UnregisterSignal", actualDatum, signal)
|
|
end
|
|
end
|
|
SS13.stop_tracking(handler_callback)
|
|
end
|
|
|
|
local datumWeakRef = datum
|
|
if not SS13.istype(datum, "/datum/weakref") then
|
|
datumWeakRef = dm.global_proc("WEAKREF", datum)
|
|
end
|
|
if not __SS13_signal_handlers[datumWeakRef] then
|
|
return
|
|
end
|
|
|
|
if signal == "_cleanup" then
|
|
return
|
|
end
|
|
|
|
if not __SS13_signal_handlers[datumWeakRef][signal] then
|
|
return
|
|
end
|
|
|
|
if not callback then
|
|
for handler_key, handler_info in __SS13_signal_handlers[datumWeakRef][signal] do
|
|
clear_handler(handler_info)
|
|
end
|
|
__SS13_signal_handlers[datumWeakRef][signal] = nil
|
|
else
|
|
if not SS13.istype(callback, "/datum/callback") then
|
|
return
|
|
end
|
|
local callbackWeakRef = dm.global_proc("WEAKREF", callback)
|
|
clear_handler(__SS13_signal_handlers[datumWeakRef][signal][callbackWeakRef])
|
|
__SS13_signal_handlers[datumWeakRef][signal][callbackWeakRef] = nil
|
|
end
|
|
end
|
|
|
|
function SS13.signal_handler_cleanup(datumWeakRef)
|
|
if not __SS13_signal_handlers[datumWeakRef] then
|
|
return
|
|
end
|
|
|
|
for signal, _ in __SS13_signal_handlers[datumWeakRef] do
|
|
SS13.unregister_signal(datumWeakRef, signal)
|
|
end
|
|
__SS13_signal_handlers[datumWeakRef] = nil
|
|
end
|
|
|
|
return SS13
|