From ffcf79b15c0304dafd8cfd5086a45a8db85d80cb Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Mon, 27 Dec 2021 03:26:39 +0100 Subject: [PATCH] [MIRROR] Move MouseEntered to a queue, such that only the most recently hovered atom will be processed [MDB IGNORE] (#10296) * Move MouseEntered to a queue, such that only the most recently hovered atom will be processed (#63567) bout The Pull Request MouseEntered currently fires multiple (multiple) times per frame, presumably over every atom that was hovered in some timeframe (though it appears to be much worse than that). This makes MouseEntered only add to a queue, while a per-tick subsystem ensures only the most recent MouseEntered gets the screentip work done on it, through a generic on_mouse_enter proc call. Contextual screen tips are coming and are going to make the screen tip code more computationally expensive, so slimming it down is going to be a must. Would like to hear from @ LemonInTheDark if this makes any obvious difference in time dilation, since it of course won't be as easy as just checking MouseEntered overtime anymore. * Move MouseEntered to a queue, such that only the most recently hovered atom will be processed Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com> --- code/__DEFINES/subsystems.dm | 1 + code/controllers/subsystem/mouse_entered.dm | 23 +++++++++++++++++++++ code/game/atoms.dm | 14 ++++++++++--- code/modules/client/client_procs.dm | 1 + tgstation.dme | 1 + 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 code/controllers/subsystem/mouse_entered.dm diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index ff463fb44c6..155a2b16888 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -198,6 +198,7 @@ #define FIRE_PRIORITY_STATPANEL 390 #define FIRE_PRIORITY_CHAT 400 #define FIRE_PRIORITY_RUNECHAT 410 +#define FIRE_PRIORITY_MOUSE_ENTERED 450 #define FIRE_PRIORITY_OVERLAYS 500 #define FIRE_PRIORITY_EXPLOSIONS 666 #define FIRE_PRIORITY_TIMER 700 diff --git a/code/controllers/subsystem/mouse_entered.dm b/code/controllers/subsystem/mouse_entered.dm new file mode 100644 index 00000000000..6dc8d995a52 --- /dev/null +++ b/code/controllers/subsystem/mouse_entered.dm @@ -0,0 +1,23 @@ +/// Defers MouseEntered inputs to only apply to the most recently hovered over atom in the tick +SUBSYSTEM_DEF(mouse_entered) + name = "MouseEntered" + wait = 1 + flags = SS_NO_INIT | SS_TICKER + priority = FIRE_PRIORITY_MOUSE_ENTERED + runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY + + var/list/hovers = list() + +/datum/controller/subsystem/mouse_entered/fire() + for (var/hovering_client in hovers) + var/atom/hovering_atom = hovers[hovering_client] + if (isnull(hovering_atom)) + continue + + hovering_atom.on_mouse_enter(hovering_client) + + // This intentionally runs `= null` and not `-= hovering_client`, as we want to prevent the list from shrinking, + // which could cause problems given the heat of MouseEntered. + // Lummox has teased this for 515: https://www.byond.com/forum/post/2621745 + // ...though you're most likely reading this on BYOND version 600. + hovers[hovering_client] = null diff --git a/code/game/atoms.dm b/code/game/atoms.dm index b12cd643804..73ae564f216 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -2101,11 +2101,19 @@ return TRUE -//Update the screentip to reflect what we're hoverin over /atom/MouseEntered(location, control, params) - . = ..() + SSmouse_entered.hovers[usr.client] = src + +/// Fired whenever this atom is the most recent to be hovered over in the tick. +/// Preferred over MouseEntered if you do not need information such as the position of the mouse. +/// Especially because this is deferred over a tick, do not trust that `client` is not null. +/atom/proc/on_mouse_enter(client/client) + SHOULD_NOT_SLEEP(TRUE) + + var/mob/user = client?.mob + // Screentips - var/datum/hud/active_hud = usr.hud_used + var/datum/hud/active_hud = user?.hud_used if(active_hud) if(!active_hud.screentips_enabled || (flags_1 & NO_SCREENTIPS_1)) active_hud.screentip_text.maptext = "" diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 9588a786128..a1bf1831fe3 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -548,6 +548,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( active_mousedown_item = null SSambience.remove_ambience_client(src) + SSmouse_entered.hovers -= src QDEL_NULL(view_size) QDEL_NULL(void) QDEL_NULL(tooltips) diff --git a/tgstation.dme b/tgstation.dme index 2b799411731..6151bead8ad 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -486,6 +486,7 @@ #include "code\controllers\subsystem\minor_mapping.dm" #include "code\controllers\subsystem\mobs.dm" #include "code\controllers\subsystem\moods.dm" +#include "code\controllers\subsystem\mouse_entered.dm" #include "code\controllers\subsystem\nightshift.dm" #include "code\controllers\subsystem\npcpool.dm" #include "code\controllers\subsystem\overlays.dm"