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 12:49:58 +01:00
parent b4d66210b2
commit 6089ccccea
19 changed files with 145 additions and 163 deletions
+4 -1
View File
@@ -212,8 +212,11 @@
#include "code\datums\helper_datums\global_iterator.dm"
#include "code\datums\helper_datums\teleport.dm"
#include "code\datums\helper_datums\topic_input.dm"
#include "code\datums\observation\move.dm"
#include "code\datums\observation\_debug.dm"
#include "code\datums\observation\destroyed.dm"
#include "code\datums\observation\moved.dm"
#include "code\datums\observation\observation.dm"
#include "code\datums\observation\task_triggered.dm"
#include "code\datums\uplink\ammunition.dm"
#include "code\datums\uplink\announcements.dm"
#include "code\datums\uplink\badassery.dm"
+1 -1
View File
@@ -10,7 +10,7 @@
/obj/screen/movable
var/snap2grid = FALSE
var/has_moved = FALSE
var/moved = FALSE
//Snap Screen Object
//Tied to the grid, snaps to the nearest turf
+4 -16
View File
@@ -31,12 +31,12 @@
/datum/controller/process/scheduler/proc/schedule(var/datum/scheduled_task/st)
scheduled_tasks += st
st.destruction.register(src, /datum/controller/process/scheduler/proc/unschedule)
destroyed_event.register(st, src, /datum/controller/process/scheduler/proc/unschedule)
/datum/controller/process/scheduler/proc/unschedule(var/datum/scheduled_task/st)
if(st in scheduled_tasks)
scheduled_tasks -= st
st.destruction.unregister(src)
destroyed_event.unregister(st, src)
/**********
* Helpers *
@@ -76,7 +76,6 @@
var/list/arguments
var/task_after_process
var/list/task_after_process_args
var/datum/observ/triggered
/datum/scheduled_task/New(var/trigger_time, var/procedure, var/list/arguments, var/proc/task_after_process, var/list/task_after_process_args)
..()
@@ -94,19 +93,8 @@
task_after_process_args.Cut()
return ..()
/datum/scheduled_task/init_observers()
. = ..()
if(.)
triggered = new()
/datum/scheduled_task/destroy_observers()
. = ..()
if(.)
qdel(triggered)
triggered = null
/datum/scheduled_task/proc/pre_process()
triggered.raise_event(list(src))
task_triggered_event.raise_event(list(src))
/datum/scheduled_task/proc/process()
if(procedure)
@@ -124,7 +112,7 @@
/datum/scheduled_task/source/New(var/trigger_time, var/datum/source, var/procedure, var/list/arguments, var/proc/task_after_process, var/list/task_after_process_args)
src.source = source
src.source.destruction.register(src, /datum/scheduled_task/source/proc/source_destroyed)
destroyed_event.register(src.source, src, /datum/scheduled_task/source/proc/source_destroyed)
..(trigger_time, procedure, arguments, task_after_process, task_after_process_args)
/datum/scheduled_task/source/Destroy()
+4 -1
View File
@@ -25,7 +25,7 @@
usr.client.debug_variables(antag)
message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.")
/client/proc/debug_controller(controller in list("Master","Ticker","Ticker Process","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano","Chemistry","Wireless"))
/client/proc/debug_controller(controller in list("Master","Ticker","Ticker Process","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano","Chemistry","Wireless","Observation"))
set category = "Debug"
set name = "Debug Controller"
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
@@ -95,5 +95,8 @@
if("Wireless")
debug_variables(wirelessProcess)
feedback_add_details("admin_verb", "DWifi")
if("Observation")
debug_variables(all_observable_events)
feedback_add_details("admin_verb", "DObservation")
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
return
+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
+3 -3
View File
@@ -17,7 +17,7 @@
/obj/item/device/multitool/hacktool/Destroy()
for(var/T in known_targets)
var/atom/target = T
target.destruction.unregister(src)
destroyed_event.unregister(target, src)
known_targets.Cut()
qdel(hack_state)
hack_state = null
@@ -68,7 +68,7 @@
return 0
known_targets.Insert(1, target) // Insert the newly hacked target first,
target.destruction.register(src, /obj/item/device/multitool/hacktool/proc/on_target_destroy)
destroyed_event.register(target, src, /obj/item/device/multitool/hacktool/proc/on_target_destroy)
return 1
/obj/item/device/multitool/hacktool/proc/sanity_check()
@@ -77,7 +77,7 @@
if(known_targets.len > max_known_targets)
for(var/i = (max_known_targets + 1) to known_targets.len)
var/atom/A = known_targets[i]
A.destruction.unregister(src)
destroyed_event.unregister(A, src)
known_targets.Cut(max_known_targets + 1)
/obj/item/device/multitool/hacktool/proc/on_target_destroy(var/target)
+2 -2
View File
@@ -48,13 +48,13 @@
unregister_buffer(buffer_object)
buffer_object = buffer
if(buffer_object)
buffer_object.destruction.register(src, /obj/item/device/multitool/proc/unregister_buffer)
destroyed_event.register(buffer_object, src, /obj/item/device/multitool/proc/unregister_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(buffer_to_unregister == buffer_object && buffer_object)
buffer_object.destruction.unregister(src)
destroyed_event.unregister(buffer_object, src)
buffer_object = null
/obj/item/device/multitool/resolve_attackby(atom/A, mob/user)
@@ -66,13 +66,13 @@
unset_registered_user()
registered_user = user
user.set_id_info(src)
user.destruction.register(src, /obj/item/weapon/card/id/syndicate/proc/unset_registered_user)
destroyed_event.register(user, src, /obj/item/weapon/card/id/syndicate/proc/unset_registered_user)
return TRUE
/obj/item/weapon/card/id/syndicate/proc/unset_registered_user(var/mob/user)
if(!registered_user || (user && user != registered_user))
return
registered_user.destruction.unregister(src)
destroyed_event.unregister(registered_user, src)
registered_user = null
/obj/item/weapon/card/id/syndicate/CanUseTopic(mob/user)
+1 -1
View File
@@ -30,7 +30,7 @@
unwet_task.trigger_task_in(8 SECONDS)
else
unwet_task = schedule_task_in(8 SECONDS)
unwet_task.triggered.register(src, /turf/simulated/proc/task_unwet_floor)
task_triggered_event.register(unwet_task, src, /turf/simulated/proc/task_unwet_floor)
/turf/simulated/proc/task_unwet_floor(var/triggered_task)
if(triggered_task == unwet_task)
+4 -4
View File
@@ -326,8 +326,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
stop_following()
following = target
following.moved.register(src, /atom/movable/proc/move_to_destination)
following.destruction.register(src, /mob/dead/observer/proc/stop_following)
moved_event.register(following, src, /atom/movable/proc/move_to_destination)
destroyed_event.register(following, src, /mob/dead/observer/proc/stop_following)
src << "<span class='notice'>Now following \the [following]</span>"
move_to_destination(following, following.loc, following.loc)
@@ -335,8 +335,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/proc/stop_following()
if(following)
src << "<span class='notice'>No longer following \the [following]</span>"
following.moved.unregister(src)
following.destruction.unregister(src)
moved_event.unregister(following, src)
destroyed_event.unregister(following, src)
following = null
/mob/dead/observer/move_to_destination(var/atom/movable/am, var/old_loc, var/new_loc)
+3 -3
View File
@@ -339,7 +339,7 @@
hud_used.hide_actions_toggle = new(hud_used)
hud_used.hide_actions_toggle.UpdateIcon()
if(!hud_used.hide_actions_toggle.has_moved)
if(!hud_used.hide_actions_toggle.moved)
hud_used.hide_actions_toggle.screen_loc = hud_used.ButtonNumberToScreenCoords(1)
//hud_used.SetButtonCoords(hud_used.hide_actions_toggle,1)
@@ -362,7 +362,7 @@
client.screen += B
if(!B.has_moved)
if(!B.moved)
B.screen_loc = hud_used.ButtonNumberToScreenCoords(button_number)
//hud_used.SetButtonCoords(B,button_number)
@@ -370,7 +370,7 @@
if(!hud_used.hide_actions_toggle)
hud_used.hide_actions_toggle = new(hud_used)
hud_used.hide_actions_toggle.InitialiseIcon(src)
if(!hud_used.hide_actions_toggle.has_moved)
if(!hud_used.hide_actions_toggle.moved)
hud_used.hide_actions_toggle.screen_loc = hud_used.ButtonNumberToScreenCoords(button_number+1)
//hud_used.SetButtonCoords(hud_used.hide_actions_toggle,button_number+1)
client.screen += hud_used.hide_actions_toggle
@@ -171,9 +171,9 @@ obj/aiming_overlay/proc/update_aiming_deferred()
locked = 0
update_icon()
lock_time = world.time + 35
owner.moved.register(src, /obj/aiming_overlay/proc/update_aiming)
aiming_at.moved.register(src, /obj/aiming_overlay/proc/target_moved)
aiming_at.destruction.register(src, /obj/aiming_overlay/proc/cancel_aiming)
moved_event.register(owner, src, /obj/aiming_overlay/proc/update_aiming)
moved_event.register(aiming_at, src, /obj/aiming_overlay/proc/target_moved)
destroyed_event.register(aiming_at, src, /obj/aiming_overlay/proc/cancel_aiming)
/obj/aiming_overlay/update_icon()
if(locked)
@@ -208,10 +208,10 @@ obj/aiming_overlay/proc/update_aiming_deferred()
if(!no_message)
owner.visible_message("<span class='notice'>\The [owner] lowers \the [aiming_with].</span>")
owner.moved.unregister(src)
moved_event.unregister(owner, src)
if(aiming_at)
aiming_at.moved.unregister(src)
aiming_at.destruction.unregister(src)
moved_event.unregister(aiming_at, src)
destroyed_event.unregister(aiming_at, src)
aiming_at.aimed -= src
aiming_at = null
+1 -1
View File
@@ -1,5 +1,5 @@
/proc/is_listening_to_movement(var/atom/movable/listening_to, var/listener)
return listening_to.moved.is_listening(listener)
return moved_event.is_listening(listening_to, listener)
datum/unit_test/observation
name = "OBSERVATION template"
+2 -8
View File
@@ -25,21 +25,15 @@ var/global/datum/global_init/init = new ()
qdel(src) //we're done
/datum/global_init/init_observers()
return FALSE
/datum/global_init/destroy_observers()
return FALSE
/var/game_id = null
/proc/generate_gameid()
if(game_id != null)
return
game_id = ""
var/list/c = list("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
var/l = c.len
var/t = world.timeofday
for(var/_ = 1 to 4)
game_id = "[c[(t % l) + 1]][game_id]"