Optimizes moved registrations.

Now limits moved registrations to when strictly necessary. That is:
* When entering a movable atom, the entering object only registers to its moved event if it has moved listeners on its own.
* Instead, when registering to a moved event, registrations occur recursively until a non-/atom/movable is encountered or a prior movement registration from the same object is reached.
This commit is contained in:
PsiOmegaDelta
2016-01-20 11:11:27 +01:00
parent 1210a6e42f
commit cc09a86601
4 changed files with 42 additions and 16 deletions
+20 -6
View File
@@ -1,19 +1,33 @@
/datum/observ/moved/New(var/atom/movable/event_holder)
if(!istype(event_holder))
CRASH("Improper event holder type: '[event_holder]'/[event_holder.type]")
..()
/datum/observ/moved/register(var/datum/procOwner, var/proc_call)
. = ..()
var/atom/movable/child = event_holder
if(.)
var/atom/movable/parent = child.loc
while(istype(parent) && parent.moved && !parent.moved.is_listening(child))
parent.moved.register(child, /atom/movable/proc/recursive_move)
child = parent
parent = child.loc
/***********************
* Movement Handling *
***********************/
/atom/movable
var/datum/observ/moved
var/datum/observ/moved/moved
/atom/movable/Move()
var/old_loc = loc
if(..() && moved)
moved.raise_event(list(src, old_loc, loc))
/atom/movable/init_observers()
/atom/movable/init_observers(var/event_holder)
. = ..()
if(.)
moved = new()
moved = new(event_holder)
/atom/movable/destroy_observers()
. = ..()
@@ -32,14 +46,14 @@
/atom/Entered(var/atom/movable/am, atom/old_loc)
..()
if(am.moved)
am.moved.raise_event(list(am, old_loc, src.loc))
am.moved.raise_event(list(am, old_loc, am.loc))
/atom/movable/Entered(var/atom/movable/am, atom/old_loc)
..()
if(src.moved)
if(src.moved && am.moved && am.moved.has_listeners() && !src.moved.is_listening(am))
src.moved.register(am, /atom/movable/proc/recursive_move)
/atom/movable/Exited(var/atom/movable/am, atom/old_loc)
..()
if(src.moved)
if(src.moved && src.moved.is_listening(am, /atom/movable/proc/recursive_move))
src.moved.unregister(am)
+19 -5
View File
@@ -1,26 +1,40 @@
/datum/observ
var/event_holder
var/list/listeners
/datum/observ/New(var/event_holder)
src.event_holder = event_holder
..()
/datum/observ/Destroy()
event_holder = null
if(listeners)
for(var/listener in listeners)
unregister(listener)
listeners.Cut()
return ..()
/datum/observ/proc/is_listening(var/datum/procOwner, var/proc_call)
return listeners && (procOwner in listeners) && (!proc_call || listeners[procOwner] == proc_call)
/datum/observ/proc/has_listeners()
return listeners && listeners.len
/datum/observ/proc/register(var/datum/procOwner, var/proc_call)
if(!(procOwner && procOwner.destruction))
return
return FALSE
if(!listeners)
listeners = list()
listeners[procOwner] = proc_call
procOwner.destruction.register(src, /datum/observ/proc/unregister)
return TRUE
/datum/observ/proc/unregister(var/datum/procOwner)
if(!(listeners && procOwner && procOwner.destruction))
return
return FALSE
listeners -= procOwner
procOwner.destruction.unregister(src)
return TRUE
/datum/observ/proc/raise_event(var/list/args = list())
if(!listeners)
@@ -35,15 +49,15 @@
var/datum/observ/destruction
/datum/New()
init_observers()
init_observers(src)
..()
/datum/Destroy()
destroy_observers()
return ..()
/datum/proc/init_observers()
destruction = new()
/datum/proc/init_observers(var/event_holder)
destruction = new(event_holder)
return TRUE
/datum/proc/destroy_observers()