diff --git a/code/controllers/subsystems/tgui.dm b/code/controllers/subsystems/tgui.dm index eb0d566f4b..73494cbf46 100644 --- a/code/controllers/subsystems/tgui.dm +++ b/code/controllers/subsystems/tgui.dm @@ -1,12 +1,16 @@ - /** - * tgui subsystem - * - * Contains all tgui state and subsystem code. - **/ - +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ +/** + * tgui subsystem + * + * Contains all tgui state and subsystem code. + * + */ SUBSYSTEM_DEF(tgui) - name = "TGUI" + name = "tgui" wait = 9 flags = SS_NO_INIT priority = FIRE_PRIORITY_TGUI @@ -14,10 +18,8 @@ SUBSYSTEM_DEF(tgui) /// A list of UIs scheduled to process var/list/current_run = list() - /// A list of open UIs - var/list/open_uis = list() - /// A list of open UIs, grouped by src_object and ui_key. - var/list/open_uis_by_src = list() + /// A list of all open UIs + var/list/all_uis = list() /// The HTML base used for all UIs. var/basehtml @@ -33,11 +35,11 @@ SUBSYSTEM_DEF(tgui) close_all_uis() /datum/controller/subsystem/tgui/stat_entry() - ..("P:[open_uis.len]") + ..("P:[all_uis.len]") /datum/controller/subsystem/tgui/fire(resumed = 0) if(!resumed) - src.current_run = open_uis.Copy() + src.current_run = all_uis.Copy() // Cache for sanic speed (lists are references anyways) var/list/current_run = src.current_run while(current_run.len) @@ -47,7 +49,7 @@ SUBSYSTEM_DEF(tgui) if(ui && ui.user && ui.src_object) ui.process() else - open_uis.Remove(ui) + ui.close(0) if(MC_TICK_CHECK) return @@ -162,11 +164,10 @@ SUBSYSTEM_DEF(tgui) * return datum/tgui The found UI. **/ /datum/controller/subsystem/tgui/proc/get_open_ui(mob/user, datum/src_object) - var/key = "[REF(src_object)]" // No UIs opened for this src_object - if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list)) - return null // No UIs open. - for(var/datum/tgui/ui in open_uis_by_src[key]) // Find UIs for this object. + if(!LAZYLEN(src_object?.open_tguis)) + return null + for(var/datum/tgui/ui in src_object.open_tguis) // Make sure we have the right user if(ui.user == user) return ui @@ -182,14 +183,14 @@ SUBSYSTEM_DEF(tgui) * return int The number of UIs updated. **/ /datum/controller/subsystem/tgui/proc/update_uis(datum/src_object) + // No UIs opened for this src_object + if(!LAZYLEN(src_object?.open_tguis)) + return 0 var/count = 0 - var/key = "[REF(src_object)]" - if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list)) - return count // Couldn't find any UIs for this object. - for(var/datum/tgui/ui in open_uis_by_src[key]) + for(var/datum/tgui/ui in src_object.open_tguis) // Check the UI is valid. if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) - ui.process(force = 1) // Update the UI. + INVOKE_ASYNC(ui, TYPE_PROC_REF(/datum/tgui, process), wait * 0.1, TRUE) count++ // Count each UI we update. return count @@ -203,12 +204,11 @@ SUBSYSTEM_DEF(tgui) * return int The number of UIs closed. **/ /datum/controller/subsystem/tgui/proc/close_uis(datum/src_object) - var/count = 0 - var/key = "[REF(src_object)]" // No UIs opened for this src_object - if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list)) - return count - for(var/datum/tgui/ui in open_uis_by_src[key]) + if(!LAZYLEN(src_object?.open_tguis)) + return 0 + var/count = 0 + for(var/datum/tgui/ui in src_object.open_tguis) if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) // Check the UI is valid. ui.close() // Close the UI. count++ // Count each UI we close. @@ -223,11 +223,11 @@ SUBSYSTEM_DEF(tgui) **/ /datum/controller/subsystem/tgui/proc/close_all_uis() var/count = 0 - for(var/key in open_uis_by_src) - for(var/datum/tgui/ui in open_uis_by_src[key]) - if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) // Check the UI is valid. - ui.close() // Close the UI. - count++ // Count each UI we close. + for(var/datum/tgui/ui in all_uis) + // Check if UI is valid. + if(ui?.src_object && ui.user && ui.src_object.tgui_host(ui.user)) + ui.close() + count++ return count /** @@ -278,13 +278,9 @@ SUBSYSTEM_DEF(tgui) * required ui datum/tgui The UI to be added. **/ /datum/controller/subsystem/tgui/proc/on_open(datum/tgui/ui) - var/key = "[REF(ui.src_object)]" - if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list)) - open_uis_by_src[key] = list() - ui.user.tgui_open_uis |= ui - var/list/uis = open_uis_by_src[key] - uis |= ui - open_uis |= ui + ui.user?.tgui_open_uis |= ui + LAZYOR(ui.src_object.open_tguis, ui) + all_uis |= ui /** * private @@ -296,18 +292,14 @@ SUBSYSTEM_DEF(tgui) * return bool If the UI was removed or not. **/ /datum/controller/subsystem/tgui/proc/on_close(datum/tgui/ui) - var/key = "[REF(ui.src_object)]" - if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list)) - return FALSE // Remove it from the list of processing UIs. - open_uis.Remove(ui) + all_uis -= ui + current_run -= ui // If the user exists, remove it from them too. if(ui.user) - ui.user.tgui_open_uis.Remove(ui) - var/list/uis = open_uis_by_src[key] - uis.Remove(ui) - if(length(uis) == 0) - open_uis_by_src.Remove(key) + ui.user.tgui_open_uis -= ui + if(ui.src_object) + LAZYREMOVE(ui.src_object.open_tguis, ui) return TRUE /** @@ -342,7 +334,7 @@ SUBSYSTEM_DEF(tgui) for(var/datum/tgui/ui in source.tgui_open_uis) // Inform the UIs of their new owner. ui.user = target - target.tgui_open_uis.Add(ui) + target.tgui_open_uis += ui // Clear the old list. source.tgui_open_uis.Cut() return TRUE diff --git a/code/datums/datum.dm b/code/datums/datum.dm index 4e3fd10a08..624dfa70df 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -17,6 +17,10 @@ */ var/gc_destroyed + /// Open uis owned by this datum + /// Lazy, since this case is semi rare + var/list/open_tguis // CHOMPEdit: FIXME: open_uis + /// Active timers with this datum as the target var/list/active_timers diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index 5c39c756ad..cf75db176c 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -253,7 +253,6 @@ ), "user" = list( "name" = "[user]", - "ckey" = "[user.ckey]", "observer" = isobserver(user), ), )