Skip to content

Commit

Permalink
Optimizes connect_range and promxity_monitors
Browse files Browse the repository at this point in the history
We know what turfs exist before and after a move
We can use this information to prevent trying to update turfs we don't
care about.

This is important because post these changes mobs with fields will be
moving a lot more, so it's gotta be cheap
  • Loading branch information
LemonInTheDark committed Apr 13, 2024
1 parent 8314859 commit bcf7d7c
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 37 deletions.
31 changes: 19 additions & 12 deletions code/datums/components/connect_range.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

/// An assoc list of signal -> procpath to register to the loc this object is on.
var/list/connections
/// The turfs currently connected to this component
var/list/turfs = list()
/**
* The atom the component is tracking. The component will delete itself if the tracked is deleted.
* Signals will also be updated whenever it moves (if it's a movable).
Expand Down Expand Up @@ -41,15 +43,15 @@
if(src.range == range && src.works_in_containers == works_in_containers)
return
//Unregister the signals with the old settings.
unregister_signals(isturf(tracked) ? tracked : tracked.loc)
unregister_signals(isturf(tracked) ? tracked : tracked.loc, turfs)
src.range = range
src.works_in_containers = works_in_containers
//Re-register the signals with the new settings.
update_signals(src.tracked)

/datum/component/connect_range/proc/set_tracked(atom/new_tracked)
if(tracked) //Unregister the signals from the old tracked and its surroundings
unregister_signals(isturf(tracked) ? tracked : tracked.loc)
unregister_signals(isturf(tracked) ? tracked : tracked.loc, turfs)
UnregisterSignal(tracked, list(
COMSIG_MOVABLE_MOVED,
COMSIG_QDELETING,
Expand All @@ -66,28 +68,34 @@
SIGNAL_HANDLER
qdel(src)

/datum/component/connect_range/proc/update_signals(atom/target, atom/old_loc, forced = FALSE)
/datum/component/connect_range/proc/update_signals(atom/target, atom/old_loc)
var/turf/current_turf = get_turf(target)
var/on_same_turf = current_turf == get_turf(old_loc) //Only register/unregister turf signals if it's moved to a new turf.
unregister_signals(old_loc, on_same_turf)

if(isnull(current_turf))
unregister_signals(old_loc, turfs)
turfs = list()
return

if(ismovable(target.loc))
if(!works_in_containers)
unregister_signals(old_loc, turfs)
turfs = list()
return
//Keep track of possible movement of all movables the target is in.
for(var/atom/movable/container as anything in get_nested_locs(target))
RegisterSignal(container, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))

if(on_same_turf && !forced)
//Only register/unregister turf signals if it's moved to a new turf.
if(current_turf == get_turf(old_loc))
unregister_signals(old_loc, null)
return
for(var/turf/target_turf in RANGE_TURFS(range, current_turf))
var/list/old_turfs = turfs
turfs = RANGE_TURFS(range, current_turf)
unregister_signals(old_loc, old_turfs - turfs)
for(var/turf/target_turf as anything in turfs - old_turfs)
for(var/signal in connections)
parent.RegisterSignal(target_turf, signal, connections[signal])

/datum/component/connect_range/proc/unregister_signals(atom/location, on_same_turf = FALSE)
/datum/component/connect_range/proc/unregister_signals(atom/location, list/remove_from)
//The location is null or is a container and the component shouldn't have register signals on it
if(isnull(location) || (!works_in_containers && !isturf(location)))
return
Expand All @@ -96,10 +104,9 @@
for(var/atom/movable/target as anything in (get_nested_locs(location) + location))
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)

if(on_same_turf)
if(!length(remove_from))
return
var/turf/previous_turf = get_turf(location)
for(var/turf/target_turf in RANGE_TURFS(range, previous_turf))
for(var/turf/target_turf as anything in remove_from)
parent.UnregisterSignal(target_turf, connections)

/datum/component/connect_range/proc/on_moved(atom/movable/movable, atom/old_loc)
Expand Down
53 changes: 34 additions & 19 deletions code/datums/proximity_monitor/field.dm
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,47 @@
/datum/proximity_monitor/advanced/proc/cleanup_field()
for(var/turf/turf as anything in edge_turfs)
cleanup_edge_turf(turf)
edge_turfs = list()
for(var/turf/turf as anything in field_turfs)
cleanup_field_turf(turf)
field_turfs = list()

//Call every time the field moves (done automatically if you use update_center) or a setup specification is changed.
/datum/proximity_monitor/advanced/proc/recalculate_field()
/datum/proximity_monitor/advanced/proc/recalculate_field(full_recalc = FALSE)
var/list/new_turfs = update_new_turfs()

var/list/new_field_turfs = new_turfs[FIELD_TURFS_KEY]
var/list/new_edge_turfs = new_turfs[EDGE_TURFS_KEY]
var/list/old_field_turfs = field_turfs
var/list/old_edge_turfs = edge_turfs
field_turfs = new_turfs[FIELD_TURFS_KEY]
edge_turfs = new_turfs[EDGE_TURFS_KEY]
if(!full_recalc)
field_turfs = list()
edge_turfs = list()

for(var/turf/old_turf as anything in field_turfs - new_field_turfs)
for(var/turf/old_turf as anything in old_field_turfs - field_turfs)
if(QDELETED(src))
return
cleanup_field_turf(old_turf)
for(var/turf/old_turf as anything in edge_turfs)
for(var/turf/old_turf as anything in old_edge_turfs - edge_turfs)
if(QDELETED(src))
return
cleanup_edge_turf(old_turf)

for(var/turf/new_turf as anything in new_field_turfs)
if(full_recalc)
old_field_turfs = list()
old_edge_turfs = list()
field_turfs = new_turfs[FIELD_TURFS_KEY]
edge_turfs = new_turfs[EDGE_TURFS_KEY]

for(var/turf/new_turf as anything in field_turfs - old_field_turfs)
if(QDELETED(src))
return
field_turfs |= new_turf
field_turfs += new_turf
setup_field_turf(new_turf)
for(var/turf/new_turf as anything in new_edge_turfs)
for(var/turf/new_turf as anything in edge_turfs - old_edge_turfs)
if(QDELETED(src))
return
edge_turfs |= new_turf
edge_turfs += new_turf
setup_edge_turf(new_turf)

/datum/proximity_monitor/advanced/on_initialized(turf/location, atom/created, init_flags)
Expand All @@ -79,7 +92,7 @@
if(isturf(old_loc))
cleanup_field()
return
recalculate_field()
recalculate_field(full_recalc = FALSE)

/datum/proximity_monitor/advanced/on_uncrossed(turf/source, atom/movable/gone, direction)
if(get_dist(source, host) == current_range)
Expand All @@ -92,30 +105,32 @@
return

/// Called when a turf in the field of the monitor is unlinked
/// Do NOT call this manually, requires management of the field_turfs list
/datum/proximity_monitor/advanced/proc/cleanup_field_turf(turf/target)
field_turfs -= target
return

/// Called when a turf in the edge of the monitor is linked
/datum/proximity_monitor/advanced/proc/setup_edge_turf(turf/target)
if(edge_is_a_field) // If the edge is considered a field, set it up like one
setup_field_turf(target)

/// Called when a turf in the edge of the monitor is unlinked
/// Do NOT call this manually, requires management of the edge_turfs list
/datum/proximity_monitor/advanced/proc/cleanup_edge_turf(turf/target)
if(edge_is_a_field) // If the edge is considered a field, clean it up like one
cleanup_field_turf(target)
edge_turfs -= target

/datum/proximity_monitor/advanced/proc/update_new_turfs()
. = list(FIELD_TURFS_KEY = list(), EDGE_TURFS_KEY = list())
var/list/local_field_turfs = list()
var/list/local_edge_turfs = list()
. = list(FIELD_TURFS_KEY = local_field_turfs, EDGE_TURFS_KEY = local_edge_turfs)
if(ignore_if_not_on_turf && !isturf(host.loc))
return
var/turf/center = get_turf(host)
for(var/turf/target in RANGE_TURFS(current_range, center))
if(get_dist(center, target) == current_range)
.[EDGE_TURFS_KEY] += target
else
.[FIELD_TURFS_KEY] += target
if(current_range > 0)
local_field_turfs = RANGE_TURFS(current_range - 1, center)
if(current_range > 1)
local_edge_turfs = local_field_turfs - RANGE_TURFS(current_range, center)

//Gets edge direction/corner, only works with square radius/WDH fields!
/datum/proximity_monitor/advanced/proc/get_edgeturf_direction(turf/T, turf/center_override = null)
Expand Down Expand Up @@ -164,7 +179,7 @@
current = new(src, 5, FALSE)
current.set_fieldturf_color = "#aaffff"
current.set_edgeturf_color = "#ffaaff"
current.recalculate_field()
current.recalculate_field(full_recalc = TRUE)

/obj/item/multitool/field_debug/attack_self(mob/user)
operating = !operating
Expand Down
21 changes: 19 additions & 2 deletions code/datums/proximity_monitor/fields/ai_target_tracking.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,26 @@
. = ..()
src.on_new_turf = on_new_turf
src.on_new_movable = on_new_movable
RegisterSignal(controller, COMSIG_AI_CONTROLLER_PICKED_BEHAVIORS, PROC_REF(controller_think))
src.behavior_type = behavior_type
recalculate_field()
RegisterSignal(controller, COMSIG_AI_CONTROLLER_PICKED_BEHAVIORS, PROC_REF(controller_think))
RegisterSignal(controller, COMSIG_AI_CONTROLLER_POSSESSED_PAWN, PROC_REF(pawn_changed))
RegisterSignal(controller, AI_CONTROLLER_BEHAVIOR_QUEUED(owning_behavior.type), PROC_REF(behavior_requeued))
RegisterSignal(controller, COMSIG_AI_BLACKBOARD_KEY_SET(targetting_datum_key), PROC_REF(targeting_datum_changed))
RegisterSignal(controller, COMSIG_AI_BLACKBOARD_KEY_CLEARED(targetting_datum_key), PROC_REF(targeting_datum_cleared))
recalculate_field(full_recalc = TRUE)

/datum/proximity_monitor/advanced/ai_target_tracking/Destroy()
. = ..()
owning_behavior = null
controller = null
target_key = null
targetting_datum_key = null
hiding_location_key = null
filter = null

/datum/proximity_monitor/advanced/ai_target_tracking/recalculate_field(full_recalc = FALSE)
. = ..()
first_build = FALSE

/datum/proximity_monitor/advanced/ai_target_tracking/setup_field_turf(turf/target)
. = ..()
Expand Down
2 changes: 1 addition & 1 deletion code/datums/proximity_monitor/fields/gravity.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/datum/proximity_monitor/advanced/gravity/New(atom/_host, range, _ignore_if_not_on_turf = TRUE, gravity)
. = ..()
gravity_value = gravity
recalculate_field()
recalculate_field(full_recalc = TRUE)

/datum/proximity_monitor/advanced/gravity/setup_field_turf(turf/target)
. = ..()
Expand Down
4 changes: 2 additions & 2 deletions code/datums/proximity_monitor/fields/projectile_dampener.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
/datum/proximity_monitor/advanced/projectile_dampener/New(atom/_host, range, _ignore_if_not_on_turf = TRUE, atom/projector)
..()
RegisterSignal(projector, COMSIG_QDELETING, PROC_REF(on_projector_del))
recalculate_field()
recalculate_field(full_recalc = TRUE)
START_PROCESSING(SSfastprocess, src)

/datum/proximity_monitor/advanced/projectile_dampener/Destroy()
Expand Down Expand Up @@ -48,7 +48,7 @@
LAZYSET(edgeturf_effects, target, effect)

/datum/proximity_monitor/advanced/projectile_dampener/on_z_change(datum/source)
recalculate_field()
recalculate_field(full_recalc = TRUE)

/datum/proximity_monitor/advanced/projectile_dampener/cleanup_edge_turf(turf/target)
. = ..()
Expand Down
2 changes: 1 addition & 1 deletion code/datums/proximity_monitor/fields/timestop.dm
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
src.immune = immune
src.antimagic_flags = antimagic_flags
src.channelled = channelled
recalculate_field()
recalculate_field(full_recalc = TRUE)
START_PROCESSING(SSfastprocess, src)

/datum/proximity_monitor/advanced/timestop/Destroy()
Expand Down

0 comments on commit bcf7d7c

Please sign in to comment.