ZAS Performance Improvements (#2308)

This PR converts ZAS' c_airblock procs into a single macro for performance reasons, as well as allows CanPass to be bypassed for atoms that do not require special air blocking behavior.

Appears to have a significant effect on performance, needs more detailed testing.

Some objects are likely missing canpass flags, I only set the obvious ones. Please comment if you find one I missed.

Might fix #2152.
This commit is contained in:
Lohikar
2017-05-20 19:00:15 +03:00
committed by skull132
parent 4ade21551e
commit d8b6ba2c6c
12 changed files with 130 additions and 53 deletions
+3
View File
@@ -74,3 +74,6 @@ turf/c_airblock(turf/other)
result |= M.c_airblock(other)
if(result == BLOCKED) return BLOCKED
return result
/atom/movable
var/atmos_canpass = CANPASS_ALWAYS
+7 -3
View File
@@ -45,7 +45,9 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
return
if(direction == "N/A")
if(!(T.c_airblock(T) & AIR_BLOCKED))
var/res
ATMOS_CANPASS_TURF(res, T, T)
if(!(res & AIR_BLOCKED))
mob << "The turf can pass air! :D"
else
mob << "No air passage :x"
@@ -55,8 +57,10 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
if(!istype(other_turf))
return
var/t_block = T.c_airblock(other_turf)
var/o_block = other_turf.c_airblock(T)
var/t_block
ATMOS_CANPASS_TURF(t_block, T, other_turf)
var/o_block
ATMOS_CANPASS_TURF(o_block, other_turf, T)
if(o_block & AIR_BLOCKED)
if(t_block & AIR_BLOCKED)
+16 -8
View File
@@ -11,7 +11,8 @@
cut_overlay(graphic_remove.Copy(), TRUE)
/turf/proc/update_air_properties()
var/block = c_airblock(src)
var/block
ATMOS_CANPASS_TURF(block, src, src)
if(block & AIR_BLOCKED)
//dbg(blocked)
return 1
@@ -27,13 +28,14 @@
if(!unsim)
continue
block = unsim.c_airblock(src)
ATMOS_CANPASS_TURF(block, unsim, src)
if(block & AIR_BLOCKED)
//unsim.dbg(air_blocked, turn(180,d))
continue
var/r_block = c_airblock(unsim)
var/r_block
ATMOS_CANPASS_TURF(r_block, src, unsim)
if(r_block & AIR_BLOCKED)
continue
@@ -82,8 +84,11 @@
#endif
for(var/dir in to_check)
var/turf/simulated/other = get_step(T, dir)
if(istype(other) && other.zone == T.zone && !(other.c_airblock(T) & AIR_BLOCKED) && get_dist(src, other) <= 1)
. |= dir
if (istype(other) && other.zone == T.zone)
var/block
ATMOS_CANPASS_TURF(block, other, T)
if (!(block & AIR_BLOCKED) && get_dist(src, other) <= 1)
. |= dir
/turf/simulated/update_air_properties()
@@ -91,7 +96,8 @@
c_copy_air() //not very efficient :(
zone = null //Easier than iterating through the list at the zone.
var/s_block = c_airblock(src)
var/s_block
ATMOS_CANPASS_TURF(s_block, src, src)
if(s_block & AIR_BLOCKED)
#ifdef ZASDBG
if(verbose) log_debug("Self-blocked.")
@@ -123,7 +129,8 @@
if(!unsim) //edge of map
continue
var/block = unsim.c_airblock(src)
var/block
ATMOS_CANPASS_TURF(block, unsim, src)
if(block & AIR_BLOCKED)
#ifdef ZASDBG
@@ -133,7 +140,8 @@
continue
var/r_block = c_airblock(unsim)
var/r_block
ATMOS_CANPASS_TURF(r_block, src, unsim)
if(r_block & AIR_BLOCKED)
#ifdef ZASDBG
+45
View File
@@ -7,3 +7,48 @@
#define BLOCKED 3
#define ZONE_MIN_SIZE 14 //zones with less than this many turfs will always merge, even if the connection is not direct
#define CANPASS_ALWAYS 1
#define CANPASS_DENSITY 2
#define CANPASS_PROC 3
#define CANPASS_NEVER 4
#define ATMOS_CANPASS_TURF(ret,A,B) \
if (A.blocks_air & AIR_BLOCKED || B.blocks_air & AIR_BLOCKED) { \
ret = BLOCKED; \
} \
else { \
if (B.z != A.z) { \
if (!istype(A, /turf/simulated/open)) { \
ret = BLOCKED; \
} \
} \
else if (A.blocks_air & ZONE_BLOCKED || B.blocks_air & ZONE_BLOCKED) { \
ret = (A.z == B.z) ? ZONE_BLOCKED : AIR_BLOCKED; \
} \
else if (A.contents.len) { \
ret = 0;\
for (var/thing in A) { \
var/atom/movable/AM = thing; \
switch (AM.atmos_canpass) { \
if (CANPASS_ALWAYS) { \
continue; \
} \
if (CANPASS_DENSITY) { \
if (AM.density) { \
ret |= AIR_BLOCKED; \
} \
} \
if (CANPASS_PROC) { \
ret |= AM.c_airblock(B); \
} \
if (CANPASS_NEVER) { \
ret = BLOCKED; \
} \
} \
if (ret == BLOCKED) { \
break;\
}\
}\
}\
}
+2 -2
View File
@@ -37,13 +37,13 @@
#define SS_PRIORITY_MACHINERY 95 // Machinery + powernet ticks.
#define SS_PRIORITY_CHEMISTRY 90 // Multi-tick chemical reactions.
#define SS_PRIORITY_SHUTTLE 85 // Shuttle movement.
#define SS_PRIORITY_CALAMITY 80 // Singularity, Tesla, Nar'sie, blob, etc.
#define SS_PRIORITY_AIR 80 // ZAS processing.
#define SS_PRIORITY_CALAMITY 75 // Singularity, Tesla, Nar'sie, blob, etc.
#define SS_PRIORITY_EVENT 70
#define SS_PRIORITY_DISEASE 60 // Disease ticks.
#define SS_PRIORITY_ALARMS 50
#define SS_PRIORITY_PLANTS 40 // Spreading plant effects.
#define SS_PRIORITY_EFFECTS 35 // Effect master (Sparks)
#define SS_PRIORITY_AIR 25 // ZAS processing.
#define SS_PRIORITY_LIGHTING 20 // Queued lighting engine updates.
#define SS_PRIORITY_AIRFLOW 15 // Handles object movement due to ZAS airflow.
+15 -5
View File
@@ -121,7 +121,12 @@ Class Procs:
can_fire = TRUE
/datum/controller/subsystem/air/stat_entry()
..("TtU:[tiles_to_update.len] ZtU:[zones_to_update.len] AFZ:[active_fire_zones.len] AH:[active_hotspots.len] AE:[active_edges.len]")
var/out = "TtU:[tiles_to_update.len] "
out += "ZtU:[zones_to_update.len] "
out += "AFZ:[active_fire_zones.len] "
out += "AH:[active_hotspots.len] "
out += "AE:[active_edges.len]"
..(out)
/datum/controller/subsystem/air/New()
NEW_SS_GLOBAL(SSair)
@@ -184,7 +189,9 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
continue
//check if the turf is self-zone-blocked
if(T.c_airblock(T) & ZONE_BLOCKED)
var/c_airblock
ATMOS_CANPASS_TURF(c_airblock, T, T)
if(c_airblock & ZONE_BLOCKED)
deferred += T
if (no_mc_tick)
CHECK_TICK
@@ -290,9 +297,12 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
ASSERT(isturf(A))
ASSERT(isturf(B))
#endif
var/ablock = A.c_airblock(B)
if(ablock == BLOCKED) return BLOCKED
return ablock | B.c_airblock(A)
var/ablock
ATMOS_CANPASS_TURF(ablock, A, B)
if(ablock == BLOCKED)
return BLOCKED
ATMOS_CANPASS_TURF(., B, A)
return ablock | .
/datum/controller/subsystem/air/proc/has_valid_zone(turf/simulated/T)
#ifdef ZASDBG
+2
View File
@@ -49,6 +49,8 @@
// turf animation
var/atom/movable/overlay/c_animation = null
atmos_canpass = CANPASS_PROC
/obj/machinery/door/attack_generic(var/mob/user, var/damage)
if(damage >= 10)
visible_message("<span class='danger'>\The [user] smashes into the [src]!</span>")
+2
View File
@@ -16,6 +16,8 @@
explosion_resistance = 5
air_properties_vary_with_direction = 1
atmos_canpass = CANPASS_PROC
/obj/machinery/door/window/Initialize()
. = ..()
update_nearby_tiles()
+32 -29
View File
@@ -36,6 +36,8 @@
icon = 'icons/obj/inflatable.dmi'
icon_state = "wall"
atmos_canpass = CANPASS_DENSITY
var/undeploy_path = null
var/health = 50.0
@@ -113,10 +115,12 @@
if(!undeploy_path)
return
visible_message("\The [src] slowly deflates.")
spawn(50)
var/obj/item/inflatable/R = new undeploy_path(src.loc)
src.transfer_fingerprints_to(R)
qdel(src)
addtimer(CALLBACK(src, .proc/post_deflate), 26)
/obj/structure/inflatable/proc/post_deflate()
var/obj/item/inflatable/R = new undeploy_path(src.loc)
src.transfer_fingerprints_to(R)
qdel(src)
/obj/structure/inflatable/verb/hand_deflate()
set name = "Deflate"
@@ -134,7 +138,7 @@
user.do_attack_animation(src)
if(health <= 0)
user.visible_message("<span class='danger'>[user] [attack_verb] open the [src]!</span>")
spawn(1) deflate(1)
addtimer(CALLBACK(src, .proc/deflate, 1), 1)
else
user.visible_message("<span class='danger'>[user] [attack_verb] at [src]!</span>")
return 1
@@ -190,28 +194,30 @@
update_nearby_tiles()
/obj/structure/inflatable/door/proc/Open()
spawn()
if(isSwitchingStates) return
isSwitchingStates = 1
flick("door_opening",src)
sleep(10)
density = 0
opacity = 0
state = 1
update_icon()
isSwitchingStates = 0
set waitfor = FALSE
if(isSwitchingStates)
return
isSwitchingStates = 1
flick("door_opening",src)
sleep(10)
density = 0
opacity = 0
state = 1
update_icon()
isSwitchingStates = 0
/obj/structure/inflatable/door/proc/Close()
spawn()
if(isSwitchingStates) return
isSwitchingStates = 1
flick("door_closing",src)
sleep(10)
density = 1
opacity = 0
state = 0
update_icon()
isSwitchingStates = 0
set waitfor = FALSE
if(isSwitchingStates)
return
isSwitchingStates = 1
flick("door_closing",src)
sleep(10)
density = 1
opacity = 0
state = 0
update_icon()
isSwitchingStates = 0
/obj/structure/inflatable/door/update_icon()
if(state)
@@ -228,10 +234,7 @@
qdel(src)
else
visible_message("[src] slowly deflates.")
spawn(50)
var/obj/item/inflatable/door/R = new /obj/item/inflatable/door(loc)
src.transfer_fingerprints_to(R)
qdel(src)
addtimer(CALLBACK(src, .proc/post_deflate), 26)
/obj/item/inflatable/torn
name = "torn inflatable wall"
+2
View File
@@ -20,6 +20,8 @@
var/glasstype = null // Set this in subtypes. Null is assumed strange or otherwise impossible to dismantle, such as for shuttle glass.
var/silicate = 0 // number of units of silicate
atmos_canpass = CANPASS_PROC
/obj/structure/window/examine(mob/user)
. = ..(user)
+2 -6
View File
@@ -9,6 +9,7 @@
density = 1
opacity = 0
anchored = 1
atmos_canpass = CANPASS_NEVER
CanPass(atom/movable/mover, turf/target, height, air_group)
if(!height || air_group) return 0
@@ -18,12 +19,7 @@
name = "engine"
density = 1
anchored = 1.0
CanPass(atom/movable/mover, turf/target, height, air_group)
if (!height || air_group)
return FALSE
else
return ..()
atmos_canpass = CANPASS_NEVER
/obj/structure/shuttle/engine/heater
name = "heater"
+2
View File
@@ -13,6 +13,8 @@
var/strength = 0
var/ticks_recovering = 10
atmos_canpass = CANPASS_NEVER
/obj/effect/energy_field/New()
..()
update_nearby_tiles()