Files
Bubberstation/lua/SS13_base.lua
Y0SH1M4S73R d1ccb530b2 Replaces Auxlua with the byondapi-based Dreamluau (#84810)
## About The Pull Request

Ever since byondapi went stable, I've been meaning to create a
replacement lua library that uses it instead of the auxtools-based
auxlua. After so many months, I've finally got the code just about into
a position where it's ready for a PR.

[Click here](https://hackmd.io/@aloZJicNQrmfYgykhfFwAQ/BySAS18u0) for a
guide to rewriting auxlua scripts for dreamluau syntax.

## Why It's Good For The Game

Code that runs on production servers should not depend on memory hacks
that are liable to break any time Dream Daemon updates.

## Changelog

🆑
admin: Admin lua scripting uses a new library that (probably) will not
break when BYOND updates.
/🆑

## TODO:
- [x] Convert the lua editor ui to TS
- [x] Include a guide for converting scripts from auxlua syntax to
dreamluau syntax
2024-07-28 18:45:49 +00:00

153 lines
3.9 KiB
Lua

local timer = require("timer")
local state = require("state")
local SS13 = {}
__SS13_signal_handlers = __SS13_signal_handlers or {}
SS13.SSlua = dm.global_vars.SSlua
SS13.global_proc = "some_magic_bullshit"
SS13.state = state.state
function SS13.get_runner_ckey()
return SS13.state.ckey_last_runner
end
function SS13.get_runner_client()
return dm.global_vars.GLOB.directory[SS13.get_runner_ckey()]
end
SS13.type = dm.global_procs._text2path
function SS13.istype(thing, type)
return dm.global_procs._istype(thing, SS13.type(type)) == 1
end
SS13.new = dm.new
function SS13.qdel(datum)
if SS13.is_valid(datum) then
dm.global_procs.qdel(datum)
return true
end
return false
end
function SS13.is_valid(datum)
return dm.is_valid_ref(datum) and not datum.gc_destroyed
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/promise", thing_to_call, proc_to_call, ...)
while promise.status == 0 do
sleep()
end
return promise.return_value, promise.runtime_message
end
local function signal_handler(data, ...)
local output = 0
for func, _ in data.functions do
output = bit32.bor(output, func(...))
end
return output
end
local function create_qdeleting_callback(datum)
local callback = SS13.new("/datum/callback", SS13.state, "call_function_return_first")
callback:RegisterSignal(datum, "parent_qdeleting", "Invoke")
local path = {
"__SS13_signal_handlers",
dm.global_procs.WEAKREF(datum),
"parent_qdeleting",
"handler",
}
callback.arguments = { path }
local handler_data = { callback = callback, functions = {} }
handler_data.handler = function(source, ...)
local result = signal_handler(handler_data, source, ...)
for signal, signal_data in __SS13_signal_handlers[source] do
signal_data.callback:UnregisterSignal(source, signal)
end
__SS13_signal_handlers[source] = nil
return result
end
__SS13_signal_handlers[datum]["parent_qdeleting"] = handler_data
end
function SS13.register_signal(datum, signal, func)
if not type(func) == "function" then
return
end
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)
end
if not __SS13_signal_handlers[datum] then
__SS13_signal_handlers[datum] = {}
-- Turfs don't remove their signals on deletion.
if not SS13.istype(datum, "/turf") then
create_qdeleting_callback(datum)
end
end
local handler_data = __SS13_signal_handlers[datum][signal]
if not handler_data then
handler_data = { callback = nil, functions = {} }
local callback = SS13.new("/datum/callback", SS13.state, "call_function_return_first")
callback:RegisterSignal(datum, signal, "Invoke")
local path = {
"__SS13_signal_handlers",
dm.global_procs.WEAKREF(datum),
signal,
"handler",
}
callback.arguments = { path }
handler_data.callback = callback
handler_data.handler = function(...)
return signal_handler(handler_data, ...)
end
__SS13_signal_handlers[datum][signal] = handler_data
end
handler_data.functions[func] = true
return true
end
function SS13.unregister_signal(datum, signal, func)
if not (func == nil or type(func) == "function") then
return
end
if not __SS13_signal_handlers[datum] then
return
end
local handler_data = __SS13_signal_handlers[datum][signal]
if not handler_data then
return
end
if func == nil then
if signal == "parent_qdeleting" then
handler_data.functions = {}
else
handler_data.callback:UnregisterSignal(datum, signal)
__SS13_signal_handlers[datum][signal] = nil
end
else
handler_data.functions[func] = nil
if not (#handler_data.functions or (signal == "parent_qdeleting")) then
handler_data.callback:UnregisterSignal(datum, signal)
__SS13_signal_handlers[datum][signal] = nil
end
end
end
return SS13