Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qdel optimize #3558

Merged
merged 17 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions code/__DEFINES/dcs/signals/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#define COMSIG_COMPONENT_REMOVING "component_removing"
/// before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation
#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted"
#define COMSIG_PREQDELETED "parent_preqdeleted"
/// just before a datum's Destroy() is called: (force), at this point none of the other components chose to interrupt qdel and Destroy will be called
#define COMSIG_PARENT_QDELETING "parent_qdeleting"
/// generic topic handler (usr, href_list)
Expand Down
300 changes: 300 additions & 0 deletions code/__HELPERS/_dreamluau.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
/* This comment bypasses grep checks */ /var/__dreamluau

/* This comment also bypasses grep checks */ /var/__dreamluau_exists

#define DREAMLUAU_EXISTS (__dreamluau_exists ||= fexists(DREAMLUAU))

#define DREAMLUAU (world.system_type == MS_WINDOWS ? "dreamluau.dll" : (__dreamluau ||= __detect_auxtools("dreamluau")))

#define DREAMLUAU_CALL(func) (!DREAMLUAU_EXISTS) ? null : call_ext(DREAMLUAU, "byond:[#func]")

/**
* All of the following functions will return a string if the underlying rust code returns an error or a wrapped panic.
* The return values specified for each function are what they will return if successful.
*/

/**
* As of 515.1631, byondapi does not provide direct access to `usr`.
* Use this function to pass `usr` into the dreamluau binary so that luau scripts can retrieve it.
*
* @return null on success
*/
#define DREAMLUAU_SET_USR DREAMLUAU_CALL(set_usr)(usr)


/**
* Sets the execution limit, in milliseconds.
*
* @param limit the new execution limit
*
* @return null on success
*/
#define DREAMLUAU_SET_EXECUTION_LIMIT_MILLIS(limit) DREAMLUAU_CALL(set_execution_limit_millis)((limit))

/**
* Sets the execution limit, in seconds.
*
* @param limit the new execution limit
*
* @return null on success
*/
#define DREAMLUAU_SET_EXECUTION_LIMIT_SECS(limit) DREAMLUAU_CALL(set_execution_limit_secs)((limit))

/**
* Clears the execution limit, allowing scripts to run as long as they need to.
*
* WARNING: This allows infinite loops to block Dream Daemon indefinitely, with no safety checks.
* Do not use this if you have no reason for scripts to run arbitrarily long.
*
* @return null on success
*/
#define DREAMLUAU_CLEAR_EXECUTION_LIMIT DREAMLUAU_CALL(clear_execution_limit)

//Wrapper setters/clearers

/**
* Set the wrapper for instancing new datums with `dm.new`.
* Clears it if the argument is null.
* If unset, the object will be instantiated using the default `new` instruction.
*
* The wrapper must be a proc with the signature `(type as path, list/arguments)`.
*
* @param wrapper the path to the proc to use as the new wrapper
*
* @return null on success
*/
#define DREAMLUAU_SET_NEW_WRAPPER(wrapper) DREAMLUAU_CALL(set_new_wrapper)((wrapper))

/**
* Set the wrapper for reading the vars of an object.
* Clears it if the argument is null.
* If unset, the var will be read directly, without any safety checks.
*
* The wrapper must be a proc with the signature `(target, var)`.
*
* @param wrapper the path to the proc to use as the new wrapper
*
* @return null on success
*/
#define DREAMLUAU_SET_VAR_GET_WRAPPER(wrapper) DREAMLUAU_CALL(set_var_get_wrapper)((wrapper))

/**
* Set the wrapper for writing the vars of an object.
* Clears it if the argument is null.
* If unset, the var will be modified directly, without any safety checks.
*
* The wrapper must be a proc with the signature `(target, var, value)`.
*
* @param wrapper the path to the proc to use as the new wrapper
*
* @return null on success
*/
#define DREAMLUAU_SET_VAR_SET_WRAPPER(wrapper) DREAMLUAU_CALL(set_var_set_wrapper)((wrapper))

/**
* Set the wrapper for calling a proc on an object.
* Clears it if the argument is null.
* If unset, the proc will be called directly, without any safety checks.
*
* The wrapper must be a proc with the signature `(target, procname as text, list/arguments)`.
*
* @param wrapper the path to the proc to use as the new wrapper
*
* @return null on success
*/
#define DREAMLUAU_SET_OBJECT_CALL_WRAPPER(wrapper) DREAMLUAU_CALL(set_object_call_wrapper)((wrapper))

/**
* Set the wrapper for calling a global proc.
* Clears it if the argument is null.
* If unset, the proc will be called directly, without any safety checks.
*
* The wrapper must be a proc with the signature `(procname as text, list/arguments)`.
*
* @param wrapper the path to the proc to use as the new wrapper
*
* @return null on success
*/
#define DREAMLUAU_SET_GLOBAL_CALL_WRAPPER(wrapper) DREAMLUAU_CALL(set_global_call_wrapper)((wrapper))

/**
* Set the wrapper for printing with the `print` function.
* Clears it if the argument is null.
* If unset, `print` will raise an error.
*
* The wrapper must be a proc with the signature `(list/arguments)`.
*
* @param wrapper the path to the proc to use as the new wrapper
*
* @return null on success
*/
#define DREAMLUAU_SET_PRINT_WRAPPER(wrapper) DREAMLUAU_CALL(set_print_wrapper)((wrapper))



/**
* Create a new luau state.
*
* @return a handle to the created state.
*/
#define DREAMLUAU_NEW_STATE DREAMLUAU_CALL(new_state)

/**
* Some of the following functions return values that cannot be cleanly converted from luau to DM.
* To account for this, these functions also return a list of variant specifiers, equivalent to
* an array of objects of the type described beloe:
* ```
* type Variants = {
* key?: "error"|Array<Variants?>
* value?: "error"|Array<Variants?>
* }
* ```
*/

/**
* The following 4 functions execute luau code and return
* an associative list containing information about the result.
* This list has the following params.
*
* - "status": either "finished", "sleep", "yield", or "error"
* - "return_values": if "status" is "finished" or "yield", contains a list of the return values
* - "variants": a list of variant specifiers for the "return_values" param
* - "message": if "status" is "error", contains the error message
* - "name": the name of the executed code, according to the `what` field of `debug.getinfo`
*/

/**
* Load and execute a luau script.
*
* @param state the handle to the state
* @param code the source code of the script to run
* @param name an optional name to give to the script, for debugging purposes
*
* @return an associative list containing result information as specified above
*/
#define DREAMLUAU_LOAD DREAMLUAU_CALL(load)

/**
* Awaken the thread at the front of the specified state's sleeping thread queue.
*
* @param state the handle to the state
*
* @return an associative list containing result information as specified above
*/
#define DREAMLUAU_AWAKEN(state) DREAMLUAU_CALL(awaken)((state))

/**
* Resume one of the state's yielded threads.
*
* @param state the handle to the state
* @param index the index of the thread in the state's yielded threads list
* @param ...arguments arguments that will be returned by the `coroutine.yield` that yielded the thread
*
* @return an associative list containing result information as specified above
*/
#define DREAMLUAU_RESUME DREAMLUAU_CALL(resume)

/**
* Call a function accessible from the global table.
*
* @param state the handle to the state
* @param function a list of nested indices from the global table to the specified function
* @param ...arguments arguments to pass to the function
*
* @return an associative list containing result information as specified above
*/
#define DREAMLUAU_CALL_FUNCTION DREAMLUAU_CALL(call_function)

// State information collection functions

/**
* Obtain a copy of the state's global table, converted to DM.
*
* @param state the handle to the state
*
* @return an associative list with the follwing entries:
* - "values": The actual values of the global table
* - "variants": Variant specifiers for "values"
*/
#define DREAMLUAU_GET_GLOBALS(state) DREAMLUAU_CALL(get_globals)((state))

/**
* List the names of all sleeping or yielded threads for the state.
*
* @param state the handle to the state
*
* @return an associative list with the following entries:
* - "sleeps": A list of sleeping threads
* - "yields": A list of yielded threads
*/
#define DREAMLUAU_LIST_THREADS(state) DREAMLUAU_CALL(list_threads)((state))

// Cleanup functions

/**
* Run garbage collection on the state.
*
* This may be necessary to prevent hanging references, as some
* hard references may persist in unreachable luau objects that
* would be collected after a garbage collection cycle or two.
*
* @param state the handle to the state
*
* @return null on success
*/
#define DREAMLUAU_COLLECT_GARBAGE(state) DREAMLUAU_CALL(collect_garbage)((state))

/**
* Remove a sleeping thread from the sleep queue, without executing it.
*
* @param state the handle to the state
* @param thread the index in the sleep queue to the target thread
*
* @return null on success
*/
#define DREAMLUAU_KILL_SLEEPING_THREAD(state, thread) DREAMLUAU_CALL(kill_sleeping_thread)((state), (thread))

/**
* Remove a yielded thread from the yield table, without executing it.
*
* @param state the handle to the state
* @param thread the index in the yield table to the target thread
*
* @return null on success
*/
#define DREAMLUAU_KILL_YIELDED_THREAD(state, thread) DREAMLUAU_CALL(kill_yielded_thread)((state), (thread))

/**
* Delete a state. The state's handle will be freed for any new states created afterwards.
*
* @param state the handle to the state
*
* @return null on success
*/
#define DREAMLUAU_KILL_STATE(state) DREAMLUAU_CALL(kill_state)((state))

/**
* Retrieve lua traceback info, containing every lua stack frame between the lua entrypoint and the re-entry to dm code.
*
* @param level the level of lua execution to get the traceback for,
* with 1 being the lua code that executed the dm code that called this function,
* 2 being the lua code that executed the dm code that executed the lua code
* that executed the dm code that called this function, etc.
*
* @return the callstack of the specified lua level if valid, null if invalid
*/
#define DREAMLUAU_GET_TRACEBACK(index) DREAMLUAU_CALL(get_traceback)((index))

/**
* Luau userdata corresponding to a ref-counted DM type counts as a hard reference for BYOND's garbage collector.
* If you need to delete a DM object, and you cannot be certain that there are no references to it in any luau state,
* call this function before deleting that object to disassociate it from any userdata in any luau state.
*
* Hard deleting an object without clearing userdata corresponding to it leaves the userdata to become associated with
* the next DM object to receive the old object's reference ID, which may be undesirable behavior.
*
* @param object the object to disassociate from userdata.
*
* @return null on success
*/
#define DREAMLUAU_CLEAR_REF_USERDATA(object) DREAMLUAU_CALL(clear_ref_userdata)((object))
12 changes: 12 additions & 0 deletions code/__HELPERS/auxtools.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/// Macro for getting the auxtools library file
#define AUXLUA (world.system_type == MS_WINDOWS ? "auxlua.dll" : __detect_auxtools("auxlua"))

/proc/__detect_auxtools(library)
if(IsAdminAdvancedProcCall())
return
if (fexists("./lib[library].so"))
return "./lib[library].so"
else if (fexists("[world.GetConfig("env", "HOME")]/.byond/bin/lib[library].so"))
return "[world.GetConfig("env", "HOME")]/.byond/bin/lib[library].so"
else
CRASH("Could not find lib[library].so")

Check failure on line 12 in code/__HELPERS/auxtools.dm

View workflow job for this annotation

GitHub Actions / Integration Tests (CREATE_AND_DESTROY_TEST) / run_integration_tests

/datum/unit_test/create_and_destroy: /datum/unit_test/create_and_destroy

[2024-10-14 16:08:29] Runtime in code/__HELPERS/auxtools.dm,12: Could not find libdreamluau.so proc name: detect auxtools (/proc/__detect_auxtools) src: null call stack: detect auxtools("dreamluau") qdel(null, 0) /datum/cogbar (/datum/cogbar): Destroy(0) qdel(/datum/cogbar (/datum/cogbar), 0) /datum/callback (/datum/callback): InvokeAsync() Timer (/datum/controller/subsystem/timer): fire(0) Timer (/datum/controller/subsystem/timer): ignite(0) Master (/datum/controller/master): RunQueue() Master (/datum/controller/master): Loop(2) Master (/datum/controller/master): StartProcessing(0)

Check failure on line 12 in code/__HELPERS/auxtools.dm

View workflow job for this annotation

GitHub Actions / Integration Tests (CREATE_AND_DESTROY_TEST) / run_integration_tests

/datum/unit_test/create_and_destroy: /datum/unit_test/create_and_destroy

[2024-10-14 16:08:37] Runtime in code/__HELPERS/auxtools.dm,12: Could not find libdreamluau.so proc name: detect auxtools (/proc/__detect_auxtools) src: null call stack: detect auxtools("dreamluau") qdel(null, 0) /datum/cogbar (/datum/cogbar): Destroy(0) qdel(/datum/cogbar (/datum/cogbar), 0) /datum/callback (/datum/callback): InvokeAsync() Timer (/datum/controller/subsystem/timer): fire(0) Timer (/datum/controller/subsystem/timer): ignite(0) Master (/datum/controller/master): RunQueue() Master (/datum/controller/master): Loop(2) Master (/datum/controller/master): StartProcessing(0)

Check failure on line 12 in code/__HELPERS/auxtools.dm

View workflow job for this annotation

GitHub Actions / Integration Tests (CREATE_AND_DESTROY_TEST) / run_integration_tests

/datum/unit_test/create_and_destroy: /datum/unit_test/create_and_destroy

[2024-10-14 16:09:21] Runtime in code/__HELPERS/auxtools.dm,12: Could not find libdreamluau.so proc name: detect auxtools (/proc/__detect_auxtools) src: null call stack: detect auxtools("dreamluau") qdel(null, 0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) qdel(the sparks (/obj/effect/particle_effect/sparks), 0) /datum/weakref (/datum/weakref): Destroy(0) qdel(/datum/weakref (/datum/weakref), 0) /datum/callback (/datum/callback): InvokeAsync() Timer (/datum/controller/subsystem/timer): fire(0) Timer (/datum/controller/subsystem/timer): ignite(0) Master (/datum/controller/master): RunQueue() Master (/datum/controller/master): Loop(2) Master (/datum/controller/master): StartProcessing(0)

Check failure on line 12 in code/__HELPERS/auxtools.dm

View workflow job for this annotation

GitHub Actions / Integration Tests (CREATE_AND_DESTROY_TEST) / run_integration_tests

/datum/unit_test/create_and_destroy: /datum/unit_test/create_and_destroy

[2024-10-14 16:09:21] Runtime in code/__HELPERS/auxtools.dm,12: Could not find libdreamluau.so proc name: detect auxtools (/proc/__detect_auxtools) src: null call stack: detect auxtools("dreamluau") qdel(null, 0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) qdel(the sparks (/obj/effect/particle_effect/sparks), 0) /datum/weakref (/datum/weakref): Destroy(0) qdel(/datum/weakref (/datum/weakref), 0) /datum/callback (/datum/callback): InvokeAsync() Timer (/datum/controller/subsystem/timer): fire(0) Timer (/datum/controller/subsystem/timer): ignite(0) Master (/datum/controller/master): RunQueue() Master (/datum/controller/master): Loop(2) Master (/datum/controller/master): StartProcessing(0)

Check failure on line 12 in code/__HELPERS/auxtools.dm

View workflow job for this annotation

GitHub Actions / Integration Tests (CREATE_AND_DESTROY_TEST) / run_integration_tests

/datum/unit_test/create_and_destroy: /datum/unit_test/create_and_destroy

[2024-10-14 16:09:21] Runtime in code/__HELPERS/auxtools.dm,12: Could not find libdreamluau.so proc name: detect auxtools (/proc/__detect_auxtools) src: null call stack: detect auxtools("dreamluau") qdel(null, 0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) qdel(the sparks (/obj/effect/particle_effect/sparks), 0) /datum/weakref (/datum/weakref): Destroy(0) qdel(/datum/weakref (/datum/weakref), 0) /datum/callback (/datum/callback): InvokeAsync() Timer (/datum/controller/subsystem/timer): fire(0) Timer (/datum/controller/subsystem/timer): ignite(0) Master (/datum/controller/master): RunQueue() Master (/datum/controller/master): Loop(2) Master (/datum/controller/master): StartProcessing(0)

Check failure on line 12 in code/__HELPERS/auxtools.dm

View workflow job for this annotation

GitHub Actions / Integration Tests (CREATE_AND_DESTROY_TEST) / run_integration_tests

/datum/unit_test/create_and_destroy: /datum/unit_test/create_and_destroy

[2024-10-14 16:09:21] Runtime in code/__HELPERS/auxtools.dm,12: Could not find libdreamluau.so proc name: detect auxtools (/proc/__detect_auxtools) src: null call stack: detect auxtools("dreamluau") qdel(null, 0) (/obj/effect/overlay/light_visible): Destroy(0) (/obj/effect/overlay/light_visible): Destroy(0) qdel( (/obj/effect/overlay/light_visible), 0) /datum/component/overlay_light... (/datum/component/overlay_lighting): Destroy(0) qdel(/datum/component/overlay_light... (/datum/component/overlay_lighting), 0, 1) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) ... the sparks (/obj/effect/particle_effect/sparks): Destroy(0) qdel(the sparks (/obj/effect/particle_effect/sparks), 0) /datum/weakref (/datum/weakref): Destroy(0) qdel(/datum/weakref (/datum/weakref), 0) /datum/callback (/datum/callback): InvokeAsync() Timer (/datum/controller/subsystem/timer): fire(0) Timer (/datum/controller/subsystem/timer): ignite(0) Master (/datum/controller/master): RunQueue() Master (/datum/controller/master): StartProcessing(0)

Check failure on line 12 in code/__HELPERS/auxtools.dm

View workflow job for this annotation

GitHub Actions / Integration Tests (CREATE_AND_DESTROY_TEST) / run_integration_tests

/datum/unit_test/create_and_destroy: /datum/unit_test/create_and_destroy

[2024-10-14 16:09:21] Runtime in code/__HELPERS/auxtools.dm,12: Could not find libdreamluau.so proc name: detect auxtools (/proc/__detect_auxtools) src: null call stack: detect auxtools("dreamluau") qdel(null, 0) (/obj/effect/overlay/light_visible): Destroy(0) (/obj/effect/overlay/light_visible): Destroy(0) qdel( (/obj/effect/overlay/light_visible), 0) /datum/component/overlay_light... (/datum/component/overlay_lighting): Destroy(0) qdel(/datum/component/overlay_light... (/datum/component/overlay_lighting), 0, 1) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) ... the sparks (/obj/effect/particle_effect/sparks): Destroy(0) qdel(the sparks (/obj/effect/particle_effect/sparks), 0) /datum/weakref (/datum/weakref): Destroy(0) qdel(/datum/weakref (/datum/weakref), 0) /datum/callback (/datum/callback): InvokeAsync() Timer (/datum/controller/subsystem/timer): fire(0) Timer (/datum/controller/subsystem/timer): ignite(0) Master (/datum/controller/master): RunQueue() Master (/datum/controller/master): StartProcessing(0)

Check failure on line 12 in code/__HELPERS/auxtools.dm

View workflow job for this annotation

GitHub Actions / Integration Tests (CREATE_AND_DESTROY_TEST) / run_integration_tests

/datum/unit_test/create_and_destroy: /datum/unit_test/create_and_destroy

[2024-10-14 16:09:21] Runtime in code/__HELPERS/auxtools.dm,12: Could not find libdreamluau.so proc name: detect auxtools (/proc/__detect_auxtools) src: null call stack: detect auxtools("dreamluau") qdel(null, 0) (/obj/effect/overlay/light_visible): Destroy(0) (/obj/effect/overlay/light_visible): Destroy(0) (/obj/effect/overlay/light_visible): Destroy(0) qdel( (/obj/effect/overlay/light_visible), 0) /datum/component/overlay_light... (/datum/component/overlay_lighting): Destroy(0) qdel(/datum/component/overlay_light... (/datum/component/overlay_lighting), 0, 1) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) ... the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) qdel(the sparks (/obj/effect/particle_effect/sparks), 0) /datum/weakref (/datum/weakref): Destroy(0) qdel(/datum/weakref (/datum/weakref), 0) /datum/callback (/datum/callback): InvokeAsync() Timer (/datum/controller/subsystem/timer): fire(0) Timer (/datum/controller/subsystem/timer): ignite(0) Master (/datum/controller/master): Loop(2) Master (/datum/controller/master): StartProcessing(0)

Check failure on line 12 in code/__HELPERS/auxtools.dm

View workflow job for this annotation

GitHub Actions / Integration Tests (CREATE_AND_DESTROY_TEST) / run_integration_tests

/datum/unit_test/create_and_destroy: /datum/unit_test/create_and_destroy

[2024-10-14 16:09:21] Runtime in code/__HELPERS/auxtools.dm,12: Could not find libdreamluau.so proc name: detect auxtools (/proc/__detect_auxtools) src: null call stack: detect auxtools("dreamluau") qdel(null, 0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) qdel(the sparks (/obj/effect/particle_effect/sparks), 0) /datum/weakref (/datum/weakref): Destroy(0) qdel(/datum/weakref (/datum/weakref), 0) /datum/callback (/datum/callback): InvokeAsync() Timer (/datum/controller/subsystem/timer): fire(0) Timer (/datum/controller/subsystem/timer): ignite(0) Master (/datum/controller/master): RunQueue() Master (/datum/controller/master): Loop(2) Master (/datum/controller/master): StartProcessing(0)

Check failure on line 12 in code/__HELPERS/auxtools.dm

View workflow job for this annotation

GitHub Actions / Integration Tests (CREATE_AND_DESTROY_TEST) / run_integration_tests

/datum/unit_test/create_and_destroy: /datum/unit_test/create_and_destroy

[2024-10-14 16:09:21] Runtime in code/__HELPERS/auxtools.dm,12: Could not find libdreamluau.so proc name: detect auxtools (/proc/__detect_auxtools) src: null call stack: detect auxtools("dreamluau") qdel(null, 0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) the sparks (/obj/effect/particle_effect/sparks): Destroy(0) qdel(the sparks (/obj/effect/particle_effect/sparks), 0) /datum/weakref (/datum/weakref): Destroy(0) qdel(/datum/weakref (/datum/weakref), 0) /datum/callback (/datum/callback): InvokeAsync() Timer (/datum/controller/subsystem/timer): fire(0) Timer (/datum/controller/subsystem/timer): ignite(0) Master (/datum/controller/master): RunQueue() Master (/datum/controller/master): Loop(2) Master (/datum/controller/master): StartProcessing(0)
Loading
Loading