Skip to content

Commit

Permalink
Revert "Revert "Garbage collection, asset delivery, icon2html revolut…
Browse files Browse the repository at this point in the history
…ion, and…" (#15816) (#15937)

This reverts commit f6d0f62.
  • Loading branch information
Heroman3003 authored Apr 21, 2024
1 parent 5ab2121 commit da8c2d7
Show file tree
Hide file tree
Showing 251 changed files with 2,360 additions and 1,625 deletions.
6 changes: 3 additions & 3 deletions _build_dependencies.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# This file has all the information on what versions of libraries are thrown into the code
# For dreamchecker
export SPACEMAN_DMM_VERSION=suite-1.7
export SPACEMAN_DMM_VERSION=suite-1.8
# For NanoUI + TGUI
export NODE_VERSION=16
# Byond Major
export BYOND_MAJOR=514
export BYOND_MAJOR=515
# Byond Minor
export BYOND_MINOR=1589
export BYOND_MINOR=1630
# Macro Count
export MACRO_COUNT=4
5 changes: 0 additions & 5 deletions code/__byond_version_compat.dm
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
#if DM_VERSION >= 515
#error PLEASE MAKE SURE THAT 515 IS PROPERLY TESTED AND WORKS. ESPECIALLY THE SAVE-FILES HAVE TO WORK.
#error Additionally: Make sure that the GitHub Workflow was updated to BYOND 515 as well.
#endif

// These defines are from __513_compatibility.dm -- Please Sort
#define CLAMP(CLVALUE, CLMIN, CLMAX) clamp(CLVALUE, CLMIN, CLMAX)
#define TAN(x) tan(x)
Expand Down
17 changes: 17 additions & 0 deletions code/__defines/dcs/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -779,3 +779,20 @@
#define ELEMENT_CONFLICT_FOUND (1<<0)
//From reagents touch_x.
#define COMSIG_REAGENTS_TOUCH "reagent_touch"


//Moved observer stuff to DCS
#define COMSIG_OBSERVER_MOVED "observer_move"
#define COMSIG_OBSERVER_DESTROYED "observer_destroyed"
#define COMSIG_OBSERVER_SHUTTLE_ADDED "observer_shuttle_added"
#define COMSIG_OBSERVER_SHUTTLE_PRE_MOVE "observer_shuttle_premove"
#define COMSIG_OBSERVER_SHUTTLE_MOVED "observer_shuttle_moved"
#define COMSIG_OBSERVER_TURF_ENTERED "observer_turf_entered"
#define COMSIG_OBSERVER_TURF_EXITED "observer_turf_exited"
#define COMSIG_OBSERVER_Z_MOVED "observer_z_moved"
#define COMSIG_OBSERVER_MOB_EQUIPPED "observer_mob_equipped"
#define COMSIG_OBSERVER_ITEM_EQUIPPED "observer_item_equipped"
#define COMSIG_OBSERVER_MOB_UNEQUIPPED "observer_mob_unequipped"
#define COMSIG_OBSERVER_ITEM_UNEQUIPPED "observer_item_unequipped"
#define COMSIG_OBSERVER_APC "observer_apc"
#define COMSIG_OBSERVER_GLOBALMOVED "observer_global_move"
41 changes: 29 additions & 12 deletions code/__defines/qdel.dm
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//defines that give qdel hints. these can be given as a return in destory() or by calling
//! Defines that give qdel hints.
//!
//! These can be given as a return in [/atom/proc/Destroy] or by calling [/proc/qdel].

/// `qdel` should queue the object for deletion.
#define QDEL_HINT_QUEUE 0
Expand All @@ -11,41 +13,56 @@
// Qdel should assume this object won't gc, and hard delete it posthaste.
#define QDEL_HINT_HARDDEL_NOW 4


#ifdef REFERENCE_TRACKING
/** If REFERENCE_TRACKING is enabled, qdel will call this object's find_references() verb.
*
* Functionally identical to [QDEL_HINT_QUEUE] if [GC_FAILURE_HARD_LOOKUP] is not enabled in _compiler_options.dm.
*/
#warn TG0001 qdel REFERENCE_TRACKING enabled
#define QDEL_HINT_FINDREFERENCE 5
/// Behavior as [QDEL_HINT_FINDREFERENCE], but only if the GC fails and a hard delete is forced.
#define QDEL_HINT_IFFAIL_FINDREFERENCE 6
#endif

#define GC_QUEUE_CHECK 1
#define GC_QUEUE_HARDDELETE 2
#define GC_QUEUE_COUNT 2 //increase this when adding more steps.
// Defines for the ssgarbage queues
#define GC_QUEUE_FILTER 1 //! short queue to filter out quick gc successes so they don't hang around in the main queue for 5 minutes
#define GC_QUEUE_CHECK 2 //! main queue that waits 5 minutes because thats the longest byond can hold a reference to our shit.
#define GC_QUEUE_HARDDELETE 3 //! short queue for things that hard delete instead of going thru the gc subsystem, this is purely so if they *can* softdelete, they will soft delete rather then wasting time with a hard delete.
#define GC_QUEUE_COUNT 3 //! Number of queues, used for allocating the nested lists. Don't forget to increase this if you add a new queue stage


// Defines for the ssgarbage queue items
#define GC_QUEUE_ITEM_QUEUE_TIME 1 //! Time this item entered the queue
#define GC_QUEUE_ITEM_REF 2 //! Ref to the item
#define GC_QUEUE_ITEM_GCD_DESTROYED 3 //! Item's gc_destroyed var value. Used to detect ref reuse.
#define GC_QUEUE_ITEM_INDEX_COUNT 3 //! Number of item indexes, used for allocating the nested lists. Don't forget to increase this if you add a new queue item index

// Defines for the time an item has to get its reference cleaned before it fails the queue and moves to the next.
#define GC_FILTER_QUEUE (1 SECONDS)
#define GC_CHECK_QUEUE (5 MINUTES)
#define GC_DEL_QUEUE (10 SECONDS)


#define QDEL_ITEM_ADMINS_WARNED (1<<0) //! Set when admins are told about lag causing qdels in this type.
#define QDEL_ITEM_SUSPENDED_FOR_LAG (1<<1) //! Set when a type can no longer be hard deleted on failure because of lag it causes while this happens.

// Defines for the [gc_destroyed][/datum/var/gc_destroyed] var.
#define GC_QUEUED_FOR_QUEUING -1
#define GC_CURRENTLY_BEING_QDELETED -2

#define QDELING(X) (X.gc_destroyed)
#define QDELETED(X) (!X || X.gc_destroyed)
#define QDELETED(X) (isnull(X) || QDELING(X))
#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)

//Qdel helper macros.
#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), item), time, TIMER_STOPPABLE)
// This is a bit hacky, we do it to avoid people relying on a return value for the macro
// If you need that you should use QDEL_IN_STOPPABLE instead
#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), (time) > GC_FILTER_QUEUE ? WEAKREF(item) : item), time);
#define QDEL_IN_STOPPABLE(item, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), (time) > GC_FILTER_QUEUE ? WEAKREF(item) : item), time, TIMER_STOPPABLE)
#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)
#define QDEL_NULL(item) if(item) {qdel(item); item = null}
#define QDEL_NULL(item) qdel(item); item = null
#define QDEL_NULL_LIST QDEL_LIST_NULL
#define QDEL_LIST_NULL(x) if(x) { for(var/y in x) { qdel(y) } ; x = null }
#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); }
#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(______qdel_list_wrapper), L), time, TIMER_STOPPABLE)
#define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); }
#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); }

/proc/______qdel_list_wrapper(list/L) //the underscores are to encourage people not to use this directly.
QDEL_LIST(L)
1 change: 1 addition & 0 deletions code/__defines/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define FIRE_PRIORITY_PING 10
#define FIRE_PRIORITY_AI 10
#define FIRE_PRIORITY_GARBAGE 15
#define FIRE_PRIORITY_ASSETS 20
#define FIRE_PRIORITY_ALARM 20
#define FIRE_PRIORITY_CHARSETUP 25
#define FIRE_PRIORITY_AIRFLOW 30
Expand Down
6 changes: 3 additions & 3 deletions code/_global_vars/misc.dm
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
GLOBAL_LIST_EMPTY(error_last_seen)
GLOBAL_LIST_EMPTY(error_cooldown)

GLOBAL_DATUM_INIT(all_observable_events, /datum/all_observable_events, new) // This is a datum. It is not a list.
GLOBAL_DATUM_INIT(destroyed_event, /decl/observ/destroyed, new())
//GLOBAL_DATUM_INIT(all_observable_events, /datum/all_observable_events, new) // This is a datum. It is not a list.
//GLOBAL_DATUM_INIT(destroyed_event, /decl/observ/destroyed, new())

GLOBAL_VAR_INIT(timezoneOffset, 0) // The difference betwen midnight (of the host computer) and 0 world.ticks.

GLOBAL_VAR_INIT(TAB, "&nbsp;&nbsp;&nbsp;&nbsp;")
GLOBAL_VAR_INIT(TAB, "&nbsp;&nbsp;&nbsp;&nbsp;")
2 changes: 1 addition & 1 deletion code/_helpers/_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
// atoms/items/objects can be pretty and whatnot
var/atom/A = item
if(output_icons && isicon(A.icon) && !ismob(A)) // mobs tend to have unusable icons
item_str += "\icon[A][bicon(A)]&nbsp;"
item_str += "[bicon(A)]&nbsp;"
switch(determiners)
if(DET_NONE) item_str += A.name
if(DET_DEFINITE) item_str += "\the [A]"
Expand Down
29 changes: 29 additions & 0 deletions code/_helpers/global_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,32 @@ GLOBAL_LIST_EMPTY(mannequins)
*/
//Hexidecimal numbers
var/global/list/hexNums = list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")

// Many global vars aren't GLOB type. This puts them there to be more easily inspected.
GLOBAL_LIST_EMPTY(legacy_globals)

/proc/populate_legacy_globals()
//Note: these lists cannot be changed to a new list anywhere in code!
//If they are, these will cause the old list to stay around!
//Check by searching for "<GLOBAL_NAME> =" in the entire codebase
GLOB.legacy_globals["player_list"] = player_list
GLOB.legacy_globals["mob_list"] = mob_list
GLOB.legacy_globals["human_mob_list"] = human_mob_list
GLOB.legacy_globals["silicon_mob_list"] = silicon_mob_list
GLOB.legacy_globals["ai_list"] = ai_list
GLOB.legacy_globals["living_mob_list"] = living_mob_list
GLOB.legacy_globals["dead_mob_list"] = dead_mob_list
GLOB.legacy_globals["observer_mob_list"] = observer_mob_list
GLOB.legacy_globals["listening_objects"] = listening_objects
GLOB.legacy_globals["cleanbot_reserved_turfs"] = cleanbot_reserved_turfs
GLOB.legacy_globals["cable_list"] = cable_list
GLOB.legacy_globals["landmarks_list"] = landmarks_list
GLOB.legacy_globals["event_triggers"] = event_triggers
GLOB.legacy_globals["side_effects"] = side_effects
GLOB.legacy_globals["mechas_list"] = mechas_list
GLOB.legacy_globals["mannequins_"] = mannequins_
//visual nets
GLOB.legacy_globals["visual_nets"] = visual_nets
GLOB.legacy_globals["cameranet"] = cameranet
GLOB.legacy_globals["cultnet"] = cultnet
GLOB.legacy_globals["existing_solargrubs"] = existing_solargrubs
23 changes: 15 additions & 8 deletions code/_helpers/icons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,13 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
CRASH("get_dummy_savefile failed to create a dummy savefile: '[error]'")
return get_dummy_savefile(from_failure = TRUE)


/// Generate a filename for this asset
/// The same asset will always lead to the same asset name
/// (Generated names do not include file extention.)
/proc/generate_asset_name(file)
return "asset.[md5(fcopy_rsc(file))]"

/**
* Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
* exporting it as text, and then parsing the base64 from that.
Expand Down Expand Up @@ -655,12 +662,12 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
//var/name = SANITIZE_FILENAME("[generate_asset_name(thing)].png")
var/name = "[generate_asset_name(thing)].png"
if (!SSassets.cache[name])
register_asset(name, thing)
SSassets.transport.register_asset(name, thing)
for (var/thing2 in targets)
send_asset(thing2, name)
SSassets.transport.send_assets(thing2, name)
if(sourceonly)
return get_asset_url(name)
return "<img class='[extra_classes] icon icon-misc' src='[get_asset_url(name)]'>"
return SSassets.transport.get_asset_url(name)
return "<img class='[extra_classes] icon icon-misc' src='[SSassets.transport.get_asset_url(name)]'>"

//its either an atom, image, or mutable_appearance, we want its icon var
icon2collapse = thing.icon
Expand Down Expand Up @@ -697,12 +704,12 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
key = "[name_and_ref[3]].png"

if(!SSassets.cache[key])
register_asset(key, rsc_ref, file_hash, icon_path)
SSassets.transport.register_asset(key, rsc_ref, file_hash, icon_path)
for (var/client_target in targets)
send_asset(client_target, key)
SSassets.transport.send_assets(client_target, key)
if(sourceonly)
return get_asset_url(key)
return "<img class='[extra_classes] icon icon-[icon_state]' src='[get_asset_url(key)]'>"
return SSassets.transport.get_asset_url(key)
return "<img class='[extra_classes] icon icon-[icon_state]' src='[SSassets.transport.get_asset_url(key)]'>"

/proc/icon2base64html(target, var/custom_classes = "")
if (!target)
Expand Down
12 changes: 8 additions & 4 deletions code/_helpers/sorts/TimSort.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
if(toIndex <= 0)
toIndex += L.len + 1

sortInstance.L = L
sortInstance.cmp = cmp
sortInstance.associative = associative
var/datum/sort_instance/SI = GLOB.sortInstance
if(!SI)
SI = new

sortInstance.timSort(fromIndex, toIndex)
SI.L = L
SI.cmp = cmp
SI.associative = associative

SI.timSort(fromIndex, toIndex)

return L
32 changes: 16 additions & 16 deletions code/_helpers/sorts/__main.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
#define MIN_GALLOP 7

//This is a global instance to allow much of this code to be reused. The interfaces are kept separately
var/datum/sortInstance/sortInstance = new()
/datum/sortInstance
GLOBAL_DATUM_INIT(sortInstance, /datum/sort_instance, new())
/datum/sort_instance
//The array being sorted.
var/list/L

//The comparator proc-reference
var/cmp = /proc/cmp_numeric_asc
var/cmp = GLOBAL_PROC_REF(cmp_numeric_asc)

//whether we are sorting list keys (0: L[i]) or associated values (1: L[L[i]])
var/associative = 0
Expand All @@ -32,7 +32,7 @@ var/datum/sortInstance/sortInstance = new()
var/list/runLens = list()


/datum/sortInstance/proc/timSort(start, end)
/datum/sort_instance/proc/timSort(start, end)
runBases.Cut()
runLens.Cut()

Expand Down Expand Up @@ -97,7 +97,7 @@ lo the index of the first element in the range to be sorted
hi the index after the last element in the range to be sorted
start the index of the first element in the range that is not already known to be sorted
*/
/datum/sortInstance/proc/binarySort(lo, hi, start)
/datum/sort_instance/proc/binarySort(lo, hi, start)
//ASSERT(lo <= start && start <= hi)
if(start <= lo)
start = lo + 1
Expand Down Expand Up @@ -135,7 +135,7 @@ For its intended use in a stable mergesort, the strictness of the
definition of "descending" is needed so that the call can safely
reverse a descending sequence without violating stability.
*/
/datum/sortInstance/proc/countRunAndMakeAscending(lo, hi)
/datum/sort_instance/proc/countRunAndMakeAscending(lo, hi)
//ASSERT(lo < hi)

var/runHi = lo + 1
Expand Down Expand Up @@ -165,7 +165,7 @@ reverse a descending sequence without violating stability.

//Returns the minimum acceptable run length for an array of the specified length.
//Natural runs shorter than this will be extended with binarySort
/datum/sortInstance/proc/minRunLength(n)
/datum/sort_instance/proc/minRunLength(n)
//ASSERT(n >= 0)
var/r = 0 //becomes 1 if any bits are shifted off
while(n >= MIN_MERGE)
Expand All @@ -178,7 +178,7 @@ reverse a descending sequence without violating stability.
// runLen[i-2] > runLen[i-1]
//This method is called each time a new run is pushed onto the stack.
//So the invariants are guaranteed to hold for i<stackSize upon entry to the method
/datum/sortInstance/proc/mergeCollapse()
/datum/sort_instance/proc/mergeCollapse()
while(runBases.len >= 2)
var/n = runBases.len - 1
if(n > 1 && runLens[n-1] <= runLens[n] + runLens[n+1])
Expand All @@ -193,7 +193,7 @@ reverse a descending sequence without violating stability.

//Merges all runs on the stack until only one remains.
//Called only once, to finalise the sort
/datum/sortInstance/proc/mergeForceCollapse()
/datum/sort_instance/proc/mergeForceCollapse()
while(runBases.len >= 2)
var/n = runBases.len - 1
if(n > 1 && runLens[n-1] < runLens[n+1])
Expand All @@ -204,7 +204,7 @@ reverse a descending sequence without violating stability.
//Merges the two consecutive runs at stack indices i and i+1
//Run i must be the penultimate or antepenultimate run on the stack
//In other words, i must be equal to stackSize-2 or stackSize-3
/datum/sortInstance/proc/mergeAt(i)
/datum/sort_instance/proc/mergeAt(i)
//ASSERT(runBases.len >= 2)
//ASSERT(i >= 1)
//ASSERT(i == runBases.len - 1 || i == runBases.len - 2)
Expand Down Expand Up @@ -258,7 +258,7 @@ reverse a descending sequence without violating stability.
Returns the index at which to insert element 'key'
*/
/datum/sortInstance/proc/gallopLeft(key, base, len, hint)
/datum/sort_instance/proc/gallopLeft(key, base, len, hint)
//ASSERT(len > 0 && hint >= 0 && hint < len)

var/lastOffset = 0
Expand Down Expand Up @@ -317,7 +317,7 @@ reverse a descending sequence without violating stability.
* @param c the comparator used to order the range, and to search
* @return the int k, 0 <= k <= n such that a[b + k - 1] <= key < a[b + k]
*/
/datum/sortInstance/proc/gallopRight(key, base, len, hint)
/datum/sort_instance/proc/gallopRight(key, base, len, hint)
//ASSERT(len > 0 && hint >= 0 && hint < len)

var/offset = 1
Expand Down Expand Up @@ -369,7 +369,7 @@ reverse a descending sequence without violating stability.

//Merges two adjacent runs in-place in a stable fashion.
//For performance this method should only be called when len1 <= len2!
/datum/sortInstance/proc/mergeLo(base1, len1, base2, len2)
/datum/sort_instance/proc/mergeLo(base1, len1, base2, len2)
//ASSERT(len1 > 0 && len2 > 0 && base1 + len1 == base2)

var/cursor1 = base1
Expand Down Expand Up @@ -471,7 +471,7 @@ reverse a descending sequence without violating stability.
//ASSERT(len1 > 1)


/datum/sortInstance/proc/mergeHi(base1, len1, base2, len2)
/datum/sort_instance/proc/mergeHi(base1, len1, base2, len2)
//ASSERT(len1 > 0 && len2 > 0 && base1 + len1 == base2)

var/cursor1 = base1 + len1 - 1 //start at end of sublists
Expand Down Expand Up @@ -571,7 +571,7 @@ reverse a descending sequence without violating stability.
//ASSERT(len2 > 0)


/datum/sortInstance/proc/mergeSort(start, end)
/datum/sort_instance/proc/mergeSort(start, end)
var/remaining = end - start

//If array is small, do an insertion sort
Expand Down Expand Up @@ -616,7 +616,7 @@ reverse a descending sequence without violating stability.

return L

/datum/sortInstance/proc/mergeAt2(i)
/datum/sort_instance/proc/mergeAt2(i)
var/cursor1 = runBases[i]
var/cursor2 = runBases[i+1]

Expand Down
4 changes: 2 additions & 2 deletions code/_helpers/text.dm
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,10 @@
return tagdesc
if(!text_tag_cache[tagname])
var/icon/tag = icon(text_tag_icons, tagname)
text_tag_cache[tagname] = bicon(tag, TRUE, "text_tag")
text_tag_cache[tagname] = tag
if(!C.tgui_panel.is_ready() || C.tgui_panel.oldchat)
return "<IMG src='\ref[text_tag_icons]' class='text_tag' iconstate='[tagname]'" + (tagdesc ? " alt='[tagdesc]'" : "") + ">"
return text_tag_cache[tagname]
return icon2html(text_tag_cache[tagname], C, extra_classes = "text_tag")

/proc/create_text_tag_old(var/tagname, var/tagdesc = tagname, var/client/C = null)
if(!(C && C.is_preference_enabled(/datum/client_preference/chat_tags)))
Expand Down
Loading

0 comments on commit da8c2d7

Please sign in to comment.