Skip to content

Commit

Permalink
Bumps up qdel, garbage cleaning and MC from TG. (#750)
Browse files Browse the repository at this point in the history
* 56171

* 70729

* revert 56171 as it's already coded in

* 79568

early returns and cleaning

* 79134 partly

* 72797

* 80443

* Update garbage.dm

* 59813

* Update _attachable.dm

* Update dropship_equipment.dm

* master_gun

* Update xeno_towers.dm

* Update camera.dm

* Update _attachable.dm

* Update camera.dm

* Update attachments.dm

* Update _attachable.dm

* Update dropship_equipment.dm

* Update dropship_equipment.dm

* hmm

* Update _attachable.dm

* Update bracers.dm

* why do we use isdatum here?

* will this work?

* Revert "will this work?"

This reverts commit 59d6924.

* Revert "why do we use isdatum here?"

This reverts commit 71a6c0f.

* missing destroys?

* hmmmmmmmmmm

* Update armored_weapons.dm

* doubt it even does something

* tgstation/tgstation#79988

* tgstation/tgstation#76179

* tgstation/tgstation#76241

* tgstation/tgstation#81526

* tgstation/tgstation#69742

* Update atoms.dm

* will this even work

* Revert "will this even work"

This reverts commit ef08eaf.

* maybe this?

* Revert "maybe this?"

This reverts commit 987cde8.

* Update vehicle.dm

* Update _interior.dm
  • Loading branch information
Helg2 authored Dec 15, 2024
1 parent 440e31e commit 2176e2b
Show file tree
Hide file tree
Showing 25 changed files with 434 additions and 289 deletions.
5 changes: 0 additions & 5 deletions code/__DEFINES/rust_g.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,7 @@
#define RUST_G (__rust_g || __detect_rust_g())
#endif

// Handle 515 call() -> call_ext() changes
#if DM_VERSION >= 515
#define RUSTG_CALL call_ext
#else
#define RUSTG_CALL call
#endif

/// Gets the version of rust_g
/proc/rustg_get_version() return RUSTG_CALL(RUST_G, "get_version")()
Expand Down
6 changes: 3 additions & 3 deletions code/__HELPERS/icons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,7 @@ ColorTone(rgb, tone)
if(isicon(icon) && isfile(icon))
//icons compiled in from 'icons/path/to/dmi_file.dmi' at compile time are weird and arent really /icon objects,
///but they pass both isicon() and isfile() checks. theyre the easiest case since stringifying them gives us the path we want
var/icon_ref = "\ref[icon]"
var/icon_ref = text_ref(icon)
var/locate_icon_string = "[locate(icon_ref)]"

icon_path = locate_icon_string
Expand All @@ -999,7 +999,7 @@ ColorTone(rgb, tone)
// the rsc reference returned by fcopy_rsc() will be stringifiable to "icons/path/to/dmi_file.dmi"
var/rsc_ref = fcopy_rsc(icon)

var/icon_ref = "\ref[rsc_ref]"
var/icon_ref = text_ref(rsc_ref)

var/icon_path_string = "[locate(icon_ref)]"

Expand All @@ -1009,7 +1009,7 @@ ColorTone(rgb, tone)
var/rsc_ref = fcopy_rsc(icon)
//if its the text path of an existing dmi file, the rsc reference returned by fcopy_rsc() will be stringifiable to a dmi path

var/rsc_ref_ref = "\ref[rsc_ref]"
var/rsc_ref_ref = text_ref(rsc_ref)
var/rsc_ref_string = "[locate(rsc_ref_ref)]"

icon_path = rsc_ref_string
Expand Down
15 changes: 6 additions & 9 deletions code/controllers/master.dm
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,10 @@ GLOBAL_REAL(Master, /datum/controller/master)
continue
if ((SS_flags & (SS_TICKER|SS_KEEP_TIMING)) == SS_KEEP_TIMING && SS.last_fire + (SS.wait * 0.75) > world.time)
continue
if (SS.postponed_fires >= 1)
SS.postponed_fires--
SS.update_nextfire()
continue
SS.enqueue()
. = 1

Expand Down Expand Up @@ -709,15 +713,8 @@ GLOBAL_REAL(Master, /datum/controller/master)
queue_node.last_fire = world.time
queue_node.times_fired++

if (queue_node_flags & SS_TICKER)
queue_node.next_fire = world.time + (world.tick_lag * queue_node.wait)
else if (queue_node_flags & SS_POST_FIRE_TIMING)
queue_node.next_fire = world.time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun * 0.01))
else if (queue_node_flags & SS_KEEP_TIMING)
queue_node.next_fire += queue_node.wait
else
queue_node.next_fire = queue_node.queued_time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun * 0.01))

queue_node.update_nextfire()

queue_node.queued_time = 0

//remove from queue
Expand Down
31 changes: 28 additions & 3 deletions code/controllers/subsystem.dm
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
var/ticks = 1
///number of times we have called fire()
var/times_fired = 0
/// How many fires have we been requested to postpone
var/postponed_fires = 0
///time we entered the queue, (for timing and priority reasons)
var/queued_time = 0
///we keep a running total to make the math easier, if priority changes mid-fire that would break our running total, so we store it here
Expand Down Expand Up @@ -111,6 +113,29 @@
Master.subsystems -= src
return ..()

/** Update next_fire for the next run.
* reset_time (bool) - Ignore things that would normally alter the next fire, like tick_overrun, and last_fire. (also resets postpone)
*/
/datum/controller/subsystem/proc/update_nextfire(reset_time = FALSE)
var/queue_node_flags = flags

if (reset_time)
postponed_fires = 0
if (queue_node_flags & SS_TICKER)
next_fire = world.time + (world.tick_lag * wait)
else
next_fire = world.time + wait
return

if (queue_node_flags & SS_TICKER)
next_fire = world.time + (world.tick_lag * wait)
else if (queue_node_flags & SS_POST_FIRE_TIMING)
next_fire = world.time + wait + (world.tick_lag * (tick_overrun/100))
else if (queue_node_flags & SS_KEEP_TIMING)
next_fire += wait
else
next_fire = queued_time + wait + (world.tick_lag * (tick_overrun/100))

///Queue it to run.
/// (we loop thru a linked list until we get to the end or find the right point)
/// (this lets us sort our run order correctly without having to re-sort the entire already sorted list)
Expand Down Expand Up @@ -226,8 +251,8 @@
//could be used to postpone a costly subsystem for (default one) var/cycles, cycles
//for instance, during cpu intensive operations like explosions
/datum/controller/subsystem/proc/postpone(cycles = 1)
if(next_fire - world.time < wait)
next_fire += (wait*cycles)
if(can_fire && cycles >= 1)
postponed_fires += cycles

//usually called via datum/controller/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash)
//should attempt to salvage what it can from the old instance of subsystem
Expand All @@ -238,7 +263,7 @@
if ("can_fire")
//this is so the subsystem doesn't rapid fire to make up missed ticks causing more lag
if (var_value)
next_fire = world.time + wait
update_nextfire(reset_time = TRUE)
if ("queued_priority") //editing this breaks things.
return 0
. = ..()
136 changes: 89 additions & 47 deletions code/controllers/subsystem/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ SUBSYSTEM_DEF(atoms)
init_order = INIT_ORDER_ATOMS
flags = SS_NO_FIRE

var/old_initialized
/// A count of how many initalize changes we've made. We want to prevent old_initialize being overriden by some other value, breaking init code
var/initialized_changed = 0
/// A stack of list(source, desired initialized state)
/// We read the source of init changes from the last entry, and assert that all changes will come with a reset
var/list/initialized_state = list()
var/base_initialized

var/list/late_loaders = list()

Expand Down Expand Up @@ -47,11 +48,16 @@ SUBSYSTEM_DEF(atoms)
if(initialized == INITIALIZATION_INSSATOMS)
return

set_tracked_initalized(INITIALIZATION_INNEW_MAPLOAD)
// Generate a unique mapload source for this run of InitializeAtoms
var/static/uid = 0
uid = (uid + 1) % (SHORT_REAL_LIMIT - 1)
var/source = "subsystem init [uid]"
set_tracked_initalized(INITIALIZATION_INNEW_MAPLOAD, source)

// This may look a bit odd, but if the actual atom creation runtimes for some reason, we absolutely need to set initialized BACK
CreateAtoms(atoms, atoms_to_return)
clear_tracked_initalize()
CreateAtoms(atoms, atoms_to_return, source)
clear_tracked_initalize(source)
SSicon_smooth.free_deferred(source)

if(length(late_loaders))
for(var/I in 1 to length(late_loaders))
Expand All @@ -78,36 +84,54 @@ SUBSYSTEM_DEF(atoms)
#endif

/// Actually creates the list of atoms. Exists soley so a runtime in the creation logic doesn't cause initalized to totally break
/datum/controller/subsystem/atoms/proc/CreateAtoms(list/atoms, list/atoms_to_return = null)
/datum/controller/subsystem/atoms/proc/CreateAtoms(list/atoms, list/atoms_to_return = null, mapload_source = null)
if (atoms_to_return)
LAZYINITLIST(created_atoms)

#ifdef TESTING
var/count
#endif

var/list/mapload_arg = list(TRUE)

if(atoms)
#ifdef TESTING
count = length(atoms)
for(var/I in 1 to count)
#endif

for(var/I in 1 to length(atoms))
var/atom/A = atoms[I]
if(A.flags_atom & INITIALIZED)
continue
CHECK_TICK
// Unrolled CHECK_TICK setup to let us enable/disable mapload based off source
if(TICK_CHECK)
clear_tracked_initalize(mapload_source)
stoplag()
if(mapload_source)
set_tracked_initalized(INITIALIZATION_INNEW_MAPLOAD, mapload_source)
PROFILE_INIT_ATOM_BEGIN()
InitAtom(A, TRUE, mapload_arg)
PROFILE_INIT_ATOM_END(A)
else
#ifdef TESTING
count = 0
for(var/atom/A in world)
#endif
for(var/atom/A as anything in world)
if(A.flags_atom & INITIALIZED)
continue
PROFILE_INIT_ATOM_BEGIN()
InitAtom(A, FALSE, mapload_arg)
PROFILE_INIT_ATOM_END(A)
#ifdef TESTING
++count
CHECK_TICK
#endif
if(TICK_CHECK)
clear_tracked_initalize(mapload_source)
stoplag()
if(mapload_source)
set_tracked_initalized(INITIALIZATION_INNEW_MAPLOAD, mapload_source)

testing("Initialized [count] atoms")
pass(count)

/// Init this specific atom
/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, from_template = FALSE, list/arguments)
Expand All @@ -116,30 +140,33 @@ SUBSYSTEM_DEF(atoms)
BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE
return TRUE

// This is handled and battle tested by dreamchecker. Limit to UNIT_TESTS just in case that ever fails.
#ifdef UNIT_TESTS
var/start_tick = world.time
#endif

var/result = A.Initialize(arglist(arguments))

#ifdef UNIT_TESTS
if(start_tick != world.time)
BadInitializeCalls[the_type] |= BAD_INIT_SLEPT
#endif

var/qdeleted = FALSE

if(result != INITIALIZE_HINT_NORMAL)
switch(result)
if(INITIALIZE_HINT_LATELOAD)
if(arguments[1]) //mapload
late_loaders += A
else
A.LateInitialize()
if(INITIALIZE_HINT_QDEL)
qdel(A)
qdeleted = TRUE
if(INITIALIZE_HINT_QDEL_FORCE)
qdel(A, force = TRUE)
qdeleted = TRUE
switch(result)
if(INITIALIZE_HINT_NORMAL)
EMPTY_BLOCK_GUARD // pass
if(INITIALIZE_HINT_LATELOAD)
if(arguments[1]) //mapload
late_loaders += A
else
BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT
A.LateInitialize()
if(INITIALIZE_HINT_QDEL)
qdel(A)
qdeleted = TRUE
else
BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT

if(!A) //possible harddel
qdeleted = TRUE
Expand All @@ -152,31 +179,46 @@ SUBSYSTEM_DEF(atoms)

return qdeleted || QDELING(A)

/datum/controller/subsystem/atoms/proc/map_loader_begin()
set_tracked_initalized(INITIALIZATION_INSSATOMS)

/datum/controller/subsystem/atoms/proc/map_loader_stop()
clear_tracked_initalize()

/// Use this to set initialized to prevent error states where old_initialized is overriden. It keeps happening and it's cheesing me off
/datum/controller/subsystem/atoms/proc/set_tracked_initalized(value)
if(!initialized_changed)
old_initialized = initialized
initialized = value
else
stack_trace("We started maploading while we were already maploading. You doing something odd?")
initialized_changed += 1

/datum/controller/subsystem/atoms/proc/clear_tracked_initalize()
initialized_changed -= 1
if(!initialized_changed)
initialized = old_initialized
/datum/controller/subsystem/atoms/proc/map_loader_begin(source)
set_tracked_initalized(INITIALIZATION_INSSATOMS, source)

/datum/controller/subsystem/atoms/proc/map_loader_stop(source)
clear_tracked_initalize(source)

/// Returns the source currently modifying SSatom's init behavior
/datum/controller/subsystem/atoms/proc/get_initialized_source()
var/state_length = length(initialized_state)
if(!state_length)
return null
return initialized_state[state_length][1]

/// Use this to set initialized to prevent error states where the old initialized is overriden, and we end up losing all context
/// Accepts a state and a source, the most recent state is used, sources exist to prevent overriding old values accidentially
/datum/controller/subsystem/atoms/proc/set_tracked_initalized(state, source)
if(!length(initialized_state))
base_initialized = initialized
initialized_state += list(list(source, state))
initialized = state

/datum/controller/subsystem/atoms/proc/clear_tracked_initalize(source)
if(!length(initialized_state))
return
for(var/i in length(initialized_state) to 1 step -1)
if(initialized_state[i][1] == source)
initialized_state.Cut(i, i+1)
break

if(!length(initialized_state))
initialized = base_initialized
base_initialized = INITIALIZATION_INNEW_REGULAR
return
initialized = initialized_state[length(initialized_state)][2]

/datum/controller/subsystem/atoms/Recover()
initialized = SSatoms.initialized
if(initialized == INITIALIZATION_INNEW_MAPLOAD)
InitializeAtoms()
old_initialized = SSatoms.old_initialized
initialized_state = SSatoms.initialized_state
BadInitializeCalls = SSatoms.BadInitializeCalls

/datum/controller/subsystem/atoms/proc/InitLog()
Expand All @@ -189,7 +231,7 @@ SUBSYSTEM_DEF(atoms)
if(fails & BAD_INIT_NO_HINT)
. += "- Didn't return an Initialize hint\n"
if(fails & BAD_INIT_QDEL_BEFORE)
. += "- Qdel'd in New()\n"
. += "- Qdel'd before Initialize proc ran\n"
if(fails & BAD_INIT_SLEPT)
. += "- Slept during Initialize()\n"

Expand Down
Loading

0 comments on commit 2176e2b

Please sign in to comment.