From f74bd5e1d9e133f578993b8c6c5ac6fcfd798e53 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Sat, 12 Dec 2015 12:05:57 +0100 Subject: [PATCH] Observer fixups. Adds a proper proc for raising events. Now only creates the observer lists when an object registers itself. Multitools now unregister themselves properly from buffers on Destroy(). --- .../observer_listener/datum/observer.dm | 32 ++++++++++++------- code/game/objects/items/devices/multitool.dm | 14 +++++--- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/code/controllers/observer_listener/datum/observer.dm b/code/controllers/observer_listener/datum/observer.dm index cc0ef0612a3..e6cca2049ce 100644 --- a/code/controllers/observer_listener/datum/observer.dm +++ b/code/controllers/observer_listener/datum/observer.dm @@ -4,28 +4,38 @@ var/list/observer_events /datum/Destroy() - var/list/destroy_listeners = get_listener_list_from_event(OBSERVER_EVENT_DESTROY) - if(destroy_listeners) - for(var/destroy_listener in destroy_listeners) - call(destroy_listener, destroy_listeners[destroy_listener])(src) - + raise_event(OBSERVER_EVENT_DESTROY, list(src)) for(var/list/listeners in observer_events) listeners.Cut() return ..() /datum/proc/register(var/event, var/procOwner, var/proc_call) - var/list/listeners = get_listener_list_from_event(event) + var/list/listeners = get_listener_list_from_event(event, TRUE) listeners[procOwner] = proc_call /datum/proc/unregister(var/event, var/procOwner) - var/list/listeners = get_listener_list_from_event(event) + var/list/listeners = get_listener_list_from_event(event, FALSE) listeners -= procOwner -/datum/proc/get_listener_list_from_event(var/observer_event) - if(!observer_events) observer_events = list() +/datum/proc/raise_event(var/event, var/list/args = list()) + var/list/listeners = get_listener_list_from_event(event, FALSE) + if(listeners) + for(var/listener in listeners) + call(listener, listeners[listener])(arglist(args)) + +/datum/proc/get_listener_list_from_event(var/observer_event, var/create_list) + if(!observer_events) + if(create_list) + observer_events = list() + else + return + var/list/listeners = observer_events[observer_event] if(!listeners) - listeners = list() - observer_events[observer_event] = listeners + if(create_list) + listeners = list() + observer_events[observer_event] = listeners + else + return return listeners diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index a804041694a..cc47b871661 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -23,6 +23,10 @@ var/buffer_name var/atom/buffer_object +/obj/item/device/multitool/Destroy() + unregister_buffer(buffer_object) + return ..() + /obj/item/device/multitool/proc/get_buffer(var/typepath) // Only allow clearing the buffer name when someone fetches the buffer. // Means you cannot be sure the source hasn't been destroyed until the very moment it's needed. @@ -41,16 +45,16 @@ if(!buffer || istype(buffer)) buffer_name = buffer ? buffer.name : null if(buffer != buffer_object) - if(buffer_object) - buffer_object.unregister(OBSERVER_EVENT_DESTROY, src) + unregister_buffer(buffer_object) buffer_object = buffer if(buffer_object) - buffer_object.register(OBSERVER_EVENT_DESTROY, src, /obj/item/device/multitool/proc/on_buffer_destroyed) + buffer_object.register(OBSERVER_EVENT_DESTROY, src, /obj/item/device/multitool/proc/unregister_buffer) -/obj/item/device/multitool/proc/on_buffer_destroyed(var/atom/destroyed_buffer) +/obj/item/device/multitool/proc/unregister_buffer(var/atom/buffer_to_unregister) // Only remove the buffered object, don't reset the name // This means one cannot know if the buffer has been destroyed until one attempts to use it. - if(destroyed_buffer == buffer_object) + if(buffer_to_unregister == buffer_object && buffer_object) + buffer_object.unregister(OBSERVER_EVENT_DESTROY, src) buffer_object = null /obj/item/device/multitool/resolve_attackby(atom/A, mob/user)