Makes events global.

Greatly decreases the number of objects that need to be created (currently 3 event handlers in total vs basically 3 per datum)
The price is a slower lookup of listeners but on a per round basis it should still be much less than the current startup time penalty.
This commit is contained in:
PsiOmegaDelta
2016-01-26 13:12:37 +01:00
parent b4d66210b2
commit 6089ccccea
19 changed files with 145 additions and 163 deletions
+11
View File
@@ -0,0 +1,11 @@
/****************
* Debug Support *
****************/
var/datum/all_observable_events/all_observable_events = new()
/datum/all_observable_events
var/list/events
/datum/all_observable_events/New()
events = list()
..()
+8
View File
@@ -0,0 +1,8 @@
var/datum/observ/destroyed/destroyed_event = new()
/datum/observ/destroyed
name = "Destroyed"
/datum/Destroy()
destroyed_event.raise_event(list(src))
. = ..()
-59
View File
@@ -1,59 +0,0 @@
/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/moved
/atom/movable/Move()
var/old_loc = loc
if(..() && moved)
moved.raise_event(list(src, old_loc, loc))
/atom/movable/init_observers(var/event_holder)
. = ..()
if(.)
moved = new(event_holder)
/atom/movable/destroy_observers()
. = ..()
if(.)
qdel(moved)
moved = null
/atom/movable/proc/move_to_destination(var/atom/movable/am, var/old_loc, var/new_loc)
var/turf/T = get_turf(new_loc)
if(T && T != loc)
forceMove(T)
/atom/movable/proc/recursive_move(var/atom/movable/am, var/old_loc, var/new_loc)
moved.raise_event(list(src, old_loc, new_loc))
/atom/Entered(var/atom/movable/am, atom/old_loc)
..()
if(am.moved)
am.moved.raise_event(list(am, old_loc, am.loc))
/atom/movable/Entered(var/atom/movable/am, atom/old_loc)
..()
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 && src.moved.is_listening(am, /atom/movable/proc/recursive_move))
src.moved.unregister(am)
+46
View File
@@ -0,0 +1,46 @@
var/datum/observ/moved/moved_event = new()
/datum/observ/moved
name = "Moved"
expected_type = /atom/movable
/datum/observ/moved/register(var/eventSource, var/datum/procOwner, var/proc_call)
. = ..()
var/atom/movable/child = eventSource
if(.)
var/atom/movable/parent = child.loc
while(istype(parent) && !moved_event.is_listening(parent, child))
moved_event.register(parent, child, /atom/movable/proc/recursive_move)
child = parent
parent = child.loc
/********************
* Movement Handling *
********************/
/atom/movable/Move()
var/old_loc = loc
if(..())
moved_event.raise_event(list(src, old_loc, loc))
/atom/movable/proc/move_to_destination(var/atom/movable/am, var/old_loc, var/new_loc)
var/turf/T = get_turf(new_loc)
if(T && T != loc)
forceMove(T)
/atom/movable/proc/recursive_move(var/atom/movable/am, var/old_loc, var/new_loc)
moved_event.raise_event(list(src, old_loc, new_loc))
/atom/Entered(var/atom/movable/am, atom/old_loc)
..()
moved_event.raise_event(list(am, old_loc, am.loc))
/atom/movable/Entered(var/atom/movable/am, atom/old_loc)
..()
if(moved_event.has_listeners(am) && !moved_event.is_listening(src, am))
moved_event.register(src, am, /atom/movable/proc/recursive_move)
/atom/movable/Exited(var/atom/movable/am, atom/old_loc)
..()
if(moved_event.is_listening(src, am, /atom/movable/proc/recursive_move))
moved_event.unregister(src, am)
+38 -55
View File
@@ -1,78 +1,61 @@
/datum/observ
var/event_holder
var/list/listeners
var/name = "Unnamed Event"
var/expected_type = /datum
var/list/listeners_assoc
/datum/observ/New(var/event_holder)
src.event_holder = event_holder
/datum/observ/New()
all_observable_events.events += src
listeners_assoc = list()
..()
/datum/observ/Destroy()
event_holder = null
if(listeners)
for(var/listener in listeners)
unregister(listener)
listeners.Cut()
return ..()
/datum/observ/proc/is_listening(var/eventSource, var/datum/procOwner, var/proc_call)
var/listeners = listeners_assoc[eventSource]
if(!listeners)
return FALSE
/datum/observ/proc/is_listening(var/datum/procOwner, var/proc_call)
return listeners && (procOwner in listeners) && (!proc_call || listeners[procOwner] == proc_call)
var/stored_proc_call = listeners[procOwner]
return stored_proc_call && (!proc_call || stored_proc_call == proc_call)
/datum/observ/proc/has_listeners()
/datum/observ/proc/has_listeners(var/eventSource)
var/list/listeners = listeners_assoc[eventSource]
return listeners && listeners.len
/datum/observ/proc/register(var/datum/procOwner, var/proc_call)
if(!(procOwner && procOwner.destruction))
/datum/observ/proc/register(var/eventSource, var/datum/procOwner, var/proc_call)
if(!(eventSource && procOwner && procOwner))
return FALSE
if(istype(eventSource, /datum/observ))
return FALSE
if(!istype(eventSource, expected_type))
CRASH("Unexpected type. Expected [expected_type], was [eventSource]")
var/listeners = listeners_assoc[eventSource]
if(!listeners)
listeners = list()
listeners_assoc[eventSource] = listeners
listeners[procOwner] = proc_call
procOwner.destruction.register(src, /datum/observ/proc/unregister)
destroyed_event.register(procOwner, src, /datum/observ/proc/unregister)
return TRUE
/datum/observ/proc/unregister(var/datum/procOwner)
if(!(listeners && procOwner && procOwner.destruction))
/datum/observ/proc/unregister(var/eventSource, var/datum/procOwner)
if(!(eventSource && procOwner))
return FALSE
if(istype(eventSource, /datum/observ))
return FALSE
var/listeners = listeners_assoc[eventSource]
if(!listeners)
return FALSE
listeners -= procOwner
procOwner.destruction.unregister(src)
destroyed_event.unregister(procOwner, src)
return TRUE
/datum/observ/proc/raise_event(var/list/args = list())
if(!args.len)
return
var/listeners = listeners_assoc[args[1]]
if(!listeners)
return
for(var/listener in listeners)
call(listener, listeners[listener]) (arglist(args))
/***********************
* Destruction Handling *
***********************/
/datum
var/datum/observ/destruction
/datum/New()
init_observers(src)
..()
/datum/Destroy()
destroy_observers()
return ..()
/datum/proc/init_observers(var/event_holder)
destruction = new(event_holder)
return TRUE
/datum/proc/destroy_observers()
if(!destruction)
return FALSE
destruction.raise_event(list(src))
qdel(destruction)
destruction = null
return TRUE
// This ensures that observer handlers don't create their own observer handlers, which create their own handlers, which create...
/datum/observ/init_observers()
return FALSE
// And this ensures that observer handlers don't attempt to notify others about their own death while being unable to.
/datum/observ/destroy_observers()
return FALSE
@@ -0,0 +1,5 @@
var/datum/observ/task_triggered/task_triggered_event = new()
/datum/observ/task_triggered
name = "Task Triggered"
expected_type = /datum/scheduled_task