From 024c894f3163e68ad5fb90b3cdccf1117202bb40 Mon Sep 17 00:00:00 2001 From: variableundefined <40092670+variableundefined@users.noreply.github.com> Date: Tue, 9 Oct 2018 09:31:59 +0800 Subject: [PATCH 1/3] Improve poolcontroller performance --- code/game/atoms.dm | 5 ++ code/game/machinery/poolcontroller.dm | 55 +++++++++---------- code/game/turfs/simulated/floor/misc_floor.dm | 25 ++++++++- code/game/turfs/unsimulated/beach.dm | 23 ++++++++ 4 files changed, 77 insertions(+), 31 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 805e6b8834f..8f301f17f01 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -83,6 +83,9 @@ if(opacity && isturf(loc)) var/turf/T = loc T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guranteed to be on afterwards anyways. + + if(loc) + loc.InitializedOn(src) // Used for poolcontroller / pool to improve performance greatly. However it also open up path to other usage of observer pattern on turfs. ComponentInitialize() @@ -97,6 +100,8 @@ /atom/proc/ComponentInitialize() return +/atom/proc/InitializedOn(atom/A) // Proc for when something is initialized on a atom - Optional to call. Useful for observer pattern etc. + return /atom/proc/onCentcom() var/turf/T = get_turf(src) diff --git a/code/game/machinery/poolcontroller.dm b/code/game/machinery/poolcontroller.dm index 3d7f6a52e70..872be0e6116 100644 --- a/code/game/machinery/poolcontroller.dm +++ b/code/game/machinery/poolcontroller.dm @@ -11,18 +11,21 @@ icon_state = "airlock_control_standby" anchored = 1 //this is what I get for assuming /obj/machinery has anchored set to 1 by default var/list/linkedturfs = list() //List contains all of the linked pool turfs to this controller, assignment happens on New() + var/mobinpool = list() //List contains all of the mob in the pool, to prevent looping through the entire area to find mobs inside.. + var/decalinpool = list() // List containing all of the cleanable decals in pool var/linked_area = null var/temperature = NORMAL //The temperature of the pool, starts off on normal, which has no effects. var/temperaturecolor = "" //used for nanoUI fancyness var/srange = 5 //The range of the search for pool turfs, change this for bigger or smaller pools. var/list/linkedmist = list() //Used to keep track of created mist - var/deep_water = 0 //set to 1 to drown even standing people + var/deep_water = FALSE //set to 1 to drown even standing people /obj/machinery/poolcontroller/New() //This proc automatically happens on world start if(!linked_area) for(var/turf/simulated/floor/beach/water/W in range(srange,src)) //Search for /turf/simulated/floor/beach/water in the range of var/srange linkedturfs += W //Add found pool turfs to the central list. + W.linkedcontroller = src // And add the linked controller to itself. ..() //Changed to call parent as per MarkvA's recommendation /obj/machinery/poolcontroller/emag_act(user as mob) //Emag_act, this is called when it is hit with a cryptographic sequencer. @@ -48,21 +51,23 @@ ui_interact(user) /obj/machinery/poolcontroller/process() - updatePool() //Call the mob affecting/decal cleaning proc + processMob() //Call the mob affecting proc + cleanPool() //Call the decal cleaning proc -/obj/machinery/poolcontroller/proc/updatePool() - for(var/turf/T in linkedturfs) //Check for pool-turfs linked to the controller. - for(var/mob/M in T) //Check for mobs in the linked pool-turfs. - handleTemp(M) //handles pool temp effects on the swimmers +/obj/machinery/poolcontroller/proc/processMob() + for(var/M in mobinpool) //They're already typecasted when entering the turf + // Following two are sanity check. If the mob is no longer in the pool for whatever reason (Looking at you teleport), remove them + if(!(istype(get_turf(M), /turf/simulated/floor/beach/water/)) && !(istype(get_turf(M), /turf/unsimulated/beach/water/))) // Water component when? + mobinpool -= M + continue + handleTemp(M) //handles pool temp effects on the swimmers + if(ishuman(M)) //Only human types will drown, to keep things simple for non-human mobs that live in the water + handleDrowning(M) - if(ishuman(M)) //Make sure they are human before typecasting. - var/mob/living/carbon/human/drownee = M //Typecast them as human. - handleDrowning(drownee) //Only human types will drown, to keep things simple for non-human mobs that live in the water - - for(var/obj/effect/decal/cleanable/decal in T) //Cleans up cleanable decals like blood and such - animate(decal, alpha = 10, time = 20) - spawn(25) - qdel(decal) +/obj/machinery/poolcontroller/proc/cleanPool() + for(var/obj/effect/decal/cleanable/decal in decalinpool) //Cleans up cleanable decals like blood and such + animate(decal, alpha = 10, time = 20) + QDEL_IN(decal, 25) /obj/machinery/poolcontroller/proc/handleTemp(var/mob/M) if(!M || isAIEye(M) || issilicon(M) || isobserver(M) || M.stat == DEAD) @@ -190,26 +195,16 @@ name = "Sea Controller" desc = "A controller for the underwater portion of the sea. Players shouldn't see this." - deep_water = 1 //deep sea is deep water + var/numturf = 0 + deep_water = TRUE //deep sea is deep water -/obj/machinery/poolcontroller/seacontroller/New() +/obj/machinery/poolcontroller/seacontroller/Initialize() linked_area = get_area(src) + for(var/turf/unsimulated/beach/water/W in linked_area) + linkedturfs += W //Add found pool turfs to the central list. + W.linkedcontroller = src // And add the linked controller to itself. ..() -/obj/machinery/poolcontroller/seacontroller/updatePool() - for(var/turf/T in linked_area) - for(var/mob/M in T) - handleTemp(M) //handles pool temp effects on the swimmers - - if(ishuman(M)) //Make sure they are human before typecasting. - var/mob/living/carbon/human/drownee = M //Typecast them as human. - handleDrowning(drownee) //Only human types will drown, to keep things simple for non-human mobs that live in the water - - for(var/obj/effect/decal/cleanable/decal in T) - animate(decal, alpha = 10, time = 20) - spawn(25) - qdel(decal) - #undef FRIGID #undef COOL #undef NORMAL diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index 39d4e19034c..f77c8e39d38 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -48,10 +48,11 @@ icon = 'icons/misc/beach2.dmi' icon_state = "sandwater" -/turf/simulated/floor/beach/water +/turf/simulated/floor/beach/water // TODO - Refactor water so they share the same parent type - Or alternatively component something like that name = "water" icon_state = "water" mouse_opacity = MOUSE_OPACITY_TRANSPARENT + var/obj/machinery/poolcontroller/linkedcontroller = null /turf/simulated/floor/beach/water/pry_tile(obj/item/C, mob/user, silent = FALSE) return //cannot pry off tiles of water @@ -61,6 +62,28 @@ ..() overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1) +/turf/simulated/floor/beach/water/Entered(atom/movable/AM, atom/OldLoc) + . = ..() + if(!linkedcontroller) + return + if(ishuman(AM)) + var/mob/living/carbon/human/M = AM + linkedcontroller.mobinpool += M + +/turf/simulated/floor/beach/water/Exited(atom/movable/AM, atom/newloc) + . = ..() + if(!linkedcontroller) + return + if(ishuman(AM)) + var/mob/living/carbon/human/M = AM + linkedcontroller.mobinpool -= M + +/turf/simulated/floor/beach/water/InitializedOn(atom/A) + if(!linkedcontroller) + return + if(istype(A, /obj/effect/decal/cleanable)) // Better a typecheck than looping through thousands of turfs everyday + linkedcontroller.decalinpool += A + /turf/simulated/floor/noslip name = "high-traction floor" icon_state = "noslip" diff --git a/code/game/turfs/unsimulated/beach.dm b/code/game/turfs/unsimulated/beach.dm index aeea1e27659..e49e68f42dc 100644 --- a/code/game/turfs/unsimulated/beach.dm +++ b/code/game/turfs/unsimulated/beach.dm @@ -34,8 +34,31 @@ /turf/unsimulated/beach/water name = "Shallow Water" icon_state = "seashallow" + var/obj/machinery/poolcontroller/linkedcontroller = null water_overlay_image = "water_shallow" +/turf/unsimulated/beach/water/Entered(atom/movable/AM, atom/OldLoc) + . = ..() + if(!linkedcontroller) + return + if(ishuman(AM)) + var/mob/living/carbon/human/M = AM + linkedcontroller.mobinpool += M + +/turf/unsimulated/beach/water/Exited(atom/movable/AM, atom/newloc) + . = ..() + if(!linkedcontroller) + return + if(ishuman(AM)) + var/mob/living/carbon/human/M = AM + linkedcontroller.mobinpool -= M + +/turf/unsimulated/beach/water/InitializedOn(atom/A) + if(!linkedcontroller) + return + if(istype(A, /obj/effect/decal/cleanable)) // Better a typecheck than looping through thousands of turfs everyday + linkedcontroller.decalinpool += A + /turf/unsimulated/beach/water/dense //for boundary "walls" density = 1 From 1c6287f590113d45728f8e3b33ac2f3bfe257fb3 Mon Sep 17 00:00:00 2001 From: variableundefined <40092670+variableundefined@users.noreply.github.com> Date: Tue, 9 Oct 2018 10:11:31 +0800 Subject: [PATCH 2/3] Address tiger's concerns --- code/game/machinery/poolcontroller.dm | 9 ++++----- code/game/turfs/simulated/floor/misc_floor.dm | 10 ++++------ code/game/turfs/unsimulated/beach.dm | 10 ++++------ 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/code/game/machinery/poolcontroller.dm b/code/game/machinery/poolcontroller.dm index 872be0e6116..4fff66a43e7 100644 --- a/code/game/machinery/poolcontroller.dm +++ b/code/game/machinery/poolcontroller.dm @@ -57,7 +57,7 @@ /obj/machinery/poolcontroller/proc/processMob() for(var/M in mobinpool) //They're already typecasted when entering the turf // Following two are sanity check. If the mob is no longer in the pool for whatever reason (Looking at you teleport), remove them - if(!(istype(get_turf(M), /turf/simulated/floor/beach/water/)) && !(istype(get_turf(M), /turf/unsimulated/beach/water/))) // Water component when? + if(!istype(get_turf(M), /turf/simulated/floor/beach/water) && !istype(get_turf(M), /turf/unsimulated/beach/water)) // Water component when? mobinpool -= M continue handleTemp(M) //handles pool temp effects on the swimmers @@ -66,8 +66,9 @@ /obj/machinery/poolcontroller/proc/cleanPool() for(var/obj/effect/decal/cleanable/decal in decalinpool) //Cleans up cleanable decals like blood and such - animate(decal, alpha = 10, time = 20) - QDEL_IN(decal, 25) + if(!QDELETED(decal)) + animate(decal, alpha = 10, time = 20) + QDEL_IN(decal, 25) /obj/machinery/poolcontroller/proc/handleTemp(var/mob/M) if(!M || isAIEye(M) || issilicon(M) || isobserver(M) || M.stat == DEAD) @@ -192,10 +193,8 @@ /obj/machinery/poolcontroller/seacontroller invisibility = 101 unacidable = 1 - name = "Sea Controller" desc = "A controller for the underwater portion of the sea. Players shouldn't see this." - var/numturf = 0 deep_water = TRUE //deep sea is deep water /obj/machinery/poolcontroller/seacontroller/Initialize() diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index f77c8e39d38..6cfea0cb8f6 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -66,17 +66,15 @@ . = ..() if(!linkedcontroller) return - if(ishuman(AM)) - var/mob/living/carbon/human/M = AM - linkedcontroller.mobinpool += M + if(ismob(AM)) + linkedcontroller.mobinpool += AM /turf/simulated/floor/beach/water/Exited(atom/movable/AM, atom/newloc) . = ..() if(!linkedcontroller) return - if(ishuman(AM)) - var/mob/living/carbon/human/M = AM - linkedcontroller.mobinpool -= M + if(ismob(AM)) + linkedcontroller.mobinpool -= AM /turf/simulated/floor/beach/water/InitializedOn(atom/A) if(!linkedcontroller) diff --git a/code/game/turfs/unsimulated/beach.dm b/code/game/turfs/unsimulated/beach.dm index e49e68f42dc..a9cd62db26c 100644 --- a/code/game/turfs/unsimulated/beach.dm +++ b/code/game/turfs/unsimulated/beach.dm @@ -41,17 +41,15 @@ . = ..() if(!linkedcontroller) return - if(ishuman(AM)) - var/mob/living/carbon/human/M = AM - linkedcontroller.mobinpool += M + if(ismob(AM)) + linkedcontroller.mobinpool += AM /turf/unsimulated/beach/water/Exited(atom/movable/AM, atom/newloc) . = ..() if(!linkedcontroller) return - if(ishuman(AM)) - var/mob/living/carbon/human/M = AM - linkedcontroller.mobinpool -= M + if(ismob(AM)) + linkedcontroller.mobinpool -= AM /turf/unsimulated/beach/water/InitializedOn(atom/A) if(!linkedcontroller) From 0966b28e2bf44ba4d04f9a1c43ebd167de6d46c9 Mon Sep 17 00:00:00 2001 From: variableundefined <40092670+variableundefined@users.noreply.github.com> Date: Tue, 9 Oct 2018 23:32:55 +0800 Subject: [PATCH 3/3] One line change --- code/game/turfs/unsimulated/beach.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/turfs/unsimulated/beach.dm b/code/game/turfs/unsimulated/beach.dm index a9cd62db26c..b7c76359c46 100644 --- a/code/game/turfs/unsimulated/beach.dm +++ b/code/game/turfs/unsimulated/beach.dm @@ -34,8 +34,8 @@ /turf/unsimulated/beach/water name = "Shallow Water" icon_state = "seashallow" - var/obj/machinery/poolcontroller/linkedcontroller = null water_overlay_image = "water_shallow" + var/obj/machinery/poolcontroller/linkedcontroller = null /turf/unsimulated/beach/water/Entered(atom/movable/AM, atom/OldLoc) . = ..()