diff --git a/baystation12.dme b/baystation12.dme index a837576e39875..57e7f9e784aed 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -235,6 +235,7 @@ #include "code\controllers\subsystems\initialization\culture.dm" #include "code\controllers\subsystems\initialization\customitems.dm" #include "code\controllers\subsystems\initialization\fabrication.dm" +#include "code\controllers\subsystems\initialization\icon_updates.dm" #include "code\controllers\subsystems\initialization\materials.dm" #include "code\controllers\subsystems\initialization\misc.dm" #include "code\controllers\subsystems\initialization\misc_early.dm" @@ -247,7 +248,6 @@ #include "code\controllers\subsystems\processing\disposals.dm" #include "code\controllers\subsystems\processing\fast_process.dm" #include "code\controllers\subsystems\processing\graphs.dm" -#include "code\controllers\subsystems\processing\icon_updates.dm" #include "code\controllers\subsystems\processing\nano.dm" #include "code\controllers\subsystems\processing\obj.dm" #include "code\controllers\subsystems\processing\processing.dm" diff --git a/code/__defines/subsystem-priority.dm b/code/__defines/subsystem-priority.dm index 37cb53dc05767..8312622663f97 100644 --- a/code/__defines/subsystem-priority.dm +++ b/code/__defines/subsystem-priority.dm @@ -8,7 +8,7 @@ // SS_TICKER #define SS_PRIORITY_TIMER 30 #define SS_PRIORITY_OVERLAYS 20 -#define SS_PRIORITY_ICON_UPDATE 10 + // Normal #define SS_PRIORITY_TICKER 100 // Gameticker. @@ -26,6 +26,7 @@ #define SS_PRIORITY_CHAT 40 // Chat #define SS_PRIORITY_AI 25 // Mob AI #define SS_PRIORITY_ALARM 20 // Alarm processing. +#define SS_PRIORITY_ICON_UPDATE 20 // Queued icon updates. Mostly used by APCs and tables. #define SS_PRIORITY_EVENT 20 // Event processing and queue handling. #define SS_PRIORITY_SHUTTLE 20 // Shuttle movement. #define SS_PRIORITY_CIRCUIT_COMP 20 // Processing circuit component do_work. diff --git a/code/controllers/subsystems/initialization/icon_updates.dm b/code/controllers/subsystems/initialization/icon_updates.dm new file mode 100644 index 0000000000000..6434ad1e889e4 --- /dev/null +++ b/code/controllers/subsystems/initialization/icon_updates.dm @@ -0,0 +1,79 @@ +SUBSYSTEM_DEF(icon_update) + name = "Icon Updates" + wait = 1 + priority = SS_PRIORITY_ICON_UPDATE + init_order = SS_INIT_ICON_UPDATE + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT // If you make it not fire in lobby, you also have to remove atoms from queue in Destroy. + + // Linked lists, queue_refs[x] should have null or args stored in queue_args[x] + var/list/queue_refs = list() // Atoms + var/list/queue_args = list() // null or args + + +/datum/controller/subsystem/icon_update/UpdateStat(time) + if (PreventUpdateStat(time)) + return ..() + ..("queue: [length(queue_refs)]") + + +/datum/controller/subsystem/icon_update/Initialize(start_uptime) + fire(FALSE, TRUE) + + +/datum/controller/subsystem/icon_update/fire(resumed = FALSE, no_mc_tick = FALSE) + if(!queue_refs.len) + suspend() + return + + while (queue_refs.len) + + if(Master.map_loading) + return + + // Pops the atom and it's args + var/atom/A = queue_refs[queue_refs.len] + var/myArgs = queue_args[queue_args.len] + + queue_refs.len -= 1 + queue_args.len -= 1 + + if(QDELETED(A)) + continue + + A.icon_update_queued = FALSE + + if (islist(myArgs)) + A.update_icon(arglist(myArgs)) + else + A.update_icon() + + if (no_mc_tick) + CHECK_TICK + else if (MC_TICK_CHECK) + return + +/atom + var/icon_update_queued = FALSE + +/atom/proc/queue_icon_update(...) + // Skips if this is already queued + if(!icon_update_queued) + + icon_update_queued = TRUE + SSicon_update.queue_refs.Add(src) + + // Makes sure these are in sync, in case runtimes/badmin + var/length = length(SSicon_update.queue_refs) + SSicon_update.queue_args.len = length + SSicon_update.queue_args[length] = args.len ? args : null + + // SSicon_update sleeps when it runs out of things in its + // queue, so wake it up. + if(!Master.map_loading) // Don't wake early if we're loading a map, it'll get woken up when the map loads. + SSicon_update.wake() + +/datum/controller/subsystem/icon_update/StartLoadingMap() + suspend() + +/datum/controller/subsystem/icon_update/StopLoadingMap() + wake() diff --git a/code/controllers/subsystems/processing/icon_updates.dm b/code/controllers/subsystems/processing/icon_updates.dm deleted file mode 100644 index 6990045ef69f7..0000000000000 --- a/code/controllers/subsystems/processing/icon_updates.dm +++ /dev/null @@ -1,62 +0,0 @@ -SUBSYSTEM_DEF(icon_update) - name = "Icon Updates" - wait = 1 // ticks - flags = SS_TICKER - priority = SS_PRIORITY_ICON_UPDATE - init_order = SS_INIT_ICON_UPDATE - var/static/list/queue = list() - - -/datum/controller/subsystem/icon_update/Recover() - LIST_RESIZE(queue, 0) - queue = list() - - -/datum/controller/subsystem/icon_update/UpdateStat(time) - if (PreventUpdateStat(time)) - return ..() - ..("queue: [length(queue)]") - - -/datum/controller/subsystem/icon_update/Initialize(start_uptime) - fire(FALSE, TRUE) - - -/datum/controller/subsystem/icon_update/fire(resumed, no_mc_tick) - var/atom/atom - var/list/params - var/queue_length = length(queue) - for (var/i = 1 to queue_length) - atom = queue[i] - if (QDELETED(atom)) - continue - params = queue[atom] - if (islist(params)) - atom.update_icon(arglist(params)) - else - atom.update_icon() - if (no_mc_tick) - if (i % 100) - continue - CHECK_TICK - else if (MC_TICK_CHECK) - queue.Cut(1, i + 1) - return - if (queue_length) - queue.Cut(1, queue_length + 1) - suspend() - - -/** - * Adds the atom to the icon_update subsystem to be queued for icon updates. Use this if you're going to be pushing a - * lot of icon updates at once. - */ -/atom/proc/queue_icon_update(...) - SSicon_update.queue[src] = length(args) ? args : TRUE - if (SSicon_update.suspended) - SSicon_update.wake() - - -/hook/game_ready/proc/FlushIconUpdateQueue() - SSicon_update.fire(FALSE, TRUE) - return TRUE