mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-20 19:44:09 +01:00
Fix shuttle air even more. (#27889)
* Even better synchronization. * Lint.
This commit is contained in:
@@ -79,14 +79,14 @@ SUBSYSTEM_DEF(air)
|
||||
/// Which step we're currently on, used to let us resume if our time budget elapses.
|
||||
var/currentpart = SSAIR_DEFERREDPIPENETS
|
||||
|
||||
/// Is MILLA currently in synchronous mode? TRUE if data is fresh and changes can be made, FALSE if data is from last tick and changes cannot be made (because this tick is still processing).
|
||||
var/is_synchronous = TRUE
|
||||
/// Is MILLA currently idle? TRUE if the MILLA tick has finished, meaning data is fresh and changes can be made. FALSE if MILLA is currently running a tick, meaning data is from last tick and changes cannot be made.
|
||||
var/milla_idle = TRUE
|
||||
|
||||
/// Are we currently running in a MILLA-safe context, i.e. is is_synchronous *guaranteed* to be TRUE. Nothing outside of this file should change this.
|
||||
/// Are we currently running in a MILLA-safe context, i.e. is milla_idle *guaranteed* to be TRUE. Nothing outside of this file should change this.
|
||||
VAR_PRIVATE/in_milla_safe_code = FALSE
|
||||
|
||||
/// Are we in MILLA-safe code that can safely sleep?
|
||||
VAR_PRIVATE/safe_to_sleep = FALSE
|
||||
/// What sleeping callbacks are currently running?
|
||||
VAR_PRIVATE/list/sleepers = list()
|
||||
|
||||
/// A list of callbacks waiting for MILLA to finish its tick and enter synchronous mode.
|
||||
var/list/waiting_for_sync = list()
|
||||
@@ -176,23 +176,26 @@ SUBSYSTEM_DEF(air)
|
||||
machinery_to_construct = SSair.machinery_to_construct
|
||||
currentrun = SSair.currentrun
|
||||
currentpart = SSair.currentpart
|
||||
is_synchronous = SSair.is_synchronous
|
||||
milla_idle = SSair.milla_idle
|
||||
|
||||
#define SLEEPABLE_TIMER (world.time + world.tick_usage * world.tick_lag / 100)
|
||||
/datum/controller/subsystem/air/fire(resumed = 0)
|
||||
// All atmos stuff assumes MILLA is synchronous. Ensure it actually is.
|
||||
if(!is_synchronous)
|
||||
if(!milla_idle || length(sleepers) > 0)
|
||||
var/timer = SLEEPABLE_TIMER
|
||||
|
||||
while(!is_synchronous)
|
||||
while(!milla_idle || length(sleepers) > 0)
|
||||
// Sleep for 1ms.
|
||||
sleep(0.01)
|
||||
if(MC_TICK_CHECK)
|
||||
time_slept.record_progress((SLEEPABLE_TIMER - timer) * 100, FALSE)
|
||||
return
|
||||
var/new_timer = SLEEPABLE_TIMER
|
||||
time_slept.record_progress((new_timer - timer) * 100, FALSE)
|
||||
timer = new_timer
|
||||
|
||||
time_slept.record_progress((SLEEPABLE_TIMER - timer) * 100, TRUE)
|
||||
|
||||
// Run the sleepless callbacks again in case more showed up since on_milla_tick_finished()
|
||||
run_sleepless_callbacks()
|
||||
|
||||
fire_sleepless(resumed)
|
||||
#undef SLEEPABLE_TIMER
|
||||
|
||||
@@ -311,7 +314,7 @@ SUBSYSTEM_DEF(air)
|
||||
timer = TICK_USAGE_REAL
|
||||
|
||||
spawn_milla_tick_thread()
|
||||
is_synchronous = FALSE
|
||||
milla_idle = FALSE
|
||||
|
||||
cost_milla_tick = MC_AVERAGE(cost_milla_tick, get_milla_tick_time())
|
||||
cost_full.record_progress(TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer), state != SS_PAUSED && state != SS_PAUSING)
|
||||
@@ -716,10 +719,10 @@ SUBSYSTEM_DEF(air)
|
||||
// Just in case someone is naughty and decides to sleep, make sure that this method runs fully anyway.
|
||||
set waitfor = FALSE
|
||||
|
||||
if(is_synchronous)
|
||||
if(milla_idle)
|
||||
var/was_safe = SSair.in_milla_safe_code
|
||||
SSair.in_milla_safe_code = TRUE
|
||||
// This is one of two intended places to call this otherwise-unsafe proc.
|
||||
// This is one of four intended places to call this otherwise-unsafe proc.
|
||||
CB.private_unsafe_invoke()
|
||||
SSair.in_milla_safe_code = was_safe
|
||||
return
|
||||
@@ -728,23 +731,22 @@ SUBSYSTEM_DEF(air)
|
||||
|
||||
/// Similar to addtimer, but triggers once MILLA enters synchronous mode. This version allows for sleeping if it's absolutely necessary.
|
||||
/datum/controller/subsystem/air/proc/sleepable_synchronize(datum/milla_safe_must_sleep/CB)
|
||||
if(safe_to_sleep)
|
||||
var/was_safe = SSair.in_milla_safe_code
|
||||
SSair.in_milla_safe_code = TRUE
|
||||
// This is one of two intended places to call this otherwise-unsafe proc.
|
||||
if(length(sleepers))
|
||||
sleepers += CB
|
||||
// This is one of four intended places to call this otherwise-unsafe proc.
|
||||
CB.private_unsafe_invoke()
|
||||
SSair.in_milla_safe_code = was_safe
|
||||
sleepers -= CB
|
||||
return
|
||||
|
||||
sleepable_waiting_for_sync += CB
|
||||
|
||||
/datum/controller/subsystem/air/proc/is_in_milla_safe_code()
|
||||
return in_milla_safe_code
|
||||
return in_milla_safe_code || length(sleepers) > 0
|
||||
|
||||
/datum/controller/subsystem/air/proc/on_milla_tick_finished()
|
||||
run_sleeping_callbacks()
|
||||
is_synchronous = TRUE
|
||||
milla_idle = TRUE
|
||||
run_sleepless_callbacks()
|
||||
run_sleeping_callbacks()
|
||||
|
||||
/datum/controller/subsystem/air/proc/run_sleepless_callbacks()
|
||||
// Just in case someone is naughty and decides to sleep, make sure that this method runs fully anyway.
|
||||
@@ -752,20 +754,23 @@ SUBSYSTEM_DEF(air)
|
||||
|
||||
in_milla_safe_code = TRUE
|
||||
for(var/datum/milla_safe/CB as anything in waiting_for_sync)
|
||||
// This is one of two intended places to call this otherwise-unsafe proc.
|
||||
// This is one of four intended places to call this otherwise-unsafe proc.
|
||||
CB.private_unsafe_invoke()
|
||||
waiting_for_sync.Cut()
|
||||
in_milla_safe_code = FALSE
|
||||
|
||||
/datum/controller/subsystem/air/proc/run_sleeping_callbacks()
|
||||
in_milla_safe_code = TRUE
|
||||
safe_to_sleep = TRUE
|
||||
for(var/datum/milla_safe_must_sleep/CB as anything in sleepable_waiting_for_sync)
|
||||
// This is one of two intended places to call this otherwise-unsafe proc.
|
||||
sleepers += CB
|
||||
// This is one of four intended places to call this otherwise-unsafe proc.
|
||||
CB.private_unsafe_invoke()
|
||||
sleepers -= CB
|
||||
sleepable_waiting_for_sync.Cut()
|
||||
in_milla_safe_code = FALSE
|
||||
safe_to_sleep = FALSE
|
||||
|
||||
/datum/controller/subsystem/air/proc/has_sleeper(datum/milla_safe_must_sleep/sleeper)
|
||||
return sleeper in sleepers
|
||||
|
||||
/proc/milla_tick_finished()
|
||||
// Any proc that wants MILLA to be synchronous should not sleep.
|
||||
@@ -861,7 +866,7 @@ SUBSYSTEM_DEF(air)
|
||||
|
||||
/// Used internally to check that we're running safely, but without breaking things worse if we aren't.
|
||||
/datum/milla_safe_must_sleep/proc/soft_assert_safe()
|
||||
ASSERT(SSair.is_in_milla_safe_code())
|
||||
ASSERT(SSair.has_sleeper(src))
|
||||
|
||||
/// Fetch the air for a turf. Only use from `on_run`.
|
||||
/datum/milla_safe_must_sleep/proc/get_turf_air(turf/T)
|
||||
|
||||
@@ -50,13 +50,6 @@ What are the archived variables for?
|
||||
/// Is this mixture currently synchronized with MILLA? Always true for non-bound mixtures.
|
||||
var/synchronized = TRUE
|
||||
|
||||
/// Tracks the callbacks from synchronize() that haven't run yet.
|
||||
var/list/waiting_for_sync = list()
|
||||
|
||||
/datum/gas_mixture/Destroy()
|
||||
waiting_for_sync.Cut()
|
||||
return ..()
|
||||
|
||||
/// Marks this gas mixture as changed from MILLA. Does nothing on non-bound mixtures.
|
||||
/datum/gas_mixture/proc/set_dirty()
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user