From 57c8c10be7584874d0d1f46ddc42ab8a36b46006 Mon Sep 17 00:00:00 2001 From: ninjanomnom Date: Wed, 22 Aug 2018 14:04:48 -0400 Subject: [PATCH 1/2] Move signal registration from components to datums --- code/datums/components/_component.dm | 24 +++++++------------ code/datums/datum.dm | 11 ++++++++- .../game/gamemodes/clown_ops/clown_weapons.dm | 8 +++---- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 1b6e8a69268..b3d3b464348 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -1,8 +1,6 @@ /datum/component - var/enabled = FALSE var/dupe_mode = COMPONENT_DUPE_HIGHLANDER var/dupe_type - var/list/signal_procs var/datum/parent /datum/component/New(datum/P, ...) @@ -57,15 +55,11 @@ return /datum/component/Destroy(force=FALSE, silent=FALSE) - enabled = FALSE - var/datum/P = parent - if(!force) + if(!force && parent) _RemoveFromParent() if(!silent) - SEND_SIGNAL(P, COMSIG_COMPONENT_REMOVING, src) + SEND_SIGNAL(parent, COMSIG_COMPONENT_REMOVING, src) parent = null - for(var/target in signal_procs) - UnregisterSignal(target, signal_procs[target]) return ..() /datum/component/proc/_RemoveFromParent() @@ -89,7 +83,7 @@ /datum/component/proc/UnregisterFromParent() return -/datum/component/proc/RegisterSignal(datum/target, sig_type_or_types, proc_or_callback, override = FALSE) +/datum/proc/RegisterSignal(datum/target, sig_type_or_types, proc_or_callback, override = FALSE) if(QDELETED(src) || QDELETED(target)) return @@ -122,9 +116,9 @@ else // Many other things have registered here lookup[sig_type][src] = TRUE - enabled = TRUE + signal_enabled = TRUE -/datum/component/proc/UnregisterSignal(datum/target, sig_type_or_types) +/datum/proc/UnregisterSignal(datum/target, sig_type_or_types) var/list/lookup = target.comp_lookup if(!signal_procs || !signal_procs[target] || !lookup) return @@ -174,15 +168,15 @@ /datum/proc/_SendSignal(sigtype, list/arguments) var/target = comp_lookup[sigtype] if(!length(target)) - var/datum/component/C = target - if(!C.enabled) + var/datum/C = target + if(!C.signal_enabled) return NONE var/datum/callback/CB = C.signal_procs[src][sigtype] return CB.InvokeAsync(arglist(arguments)) . = NONE for(var/I in target) - var/datum/component/C = I - if(!C.enabled) + var/datum/C = I + if(!C.signal_enabled) continue var/datum/callback/CB = C.signal_procs[src][sigtype] . |= CB.InvokeAsync(arglist(arguments)) diff --git a/code/datums/datum.dm b/code/datums/datum.dm index 88608d21ba1..e74e30b5366 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -2,7 +2,9 @@ var/gc_destroyed //Time when this object was destroyed. var/list/active_timers //for SStimer var/list/datum_components //for /datum/components - var/list/comp_lookup //for /datum/components + var/list/comp_lookup //it used to be for looking up components which had registered a signal but now anything can register + var/list/signal_procs + var/signal_enabled = FALSE var/datum_flags = NONE var/datum/weakref/weak_reference @@ -31,6 +33,9 @@ continue qdel(timer) + //BEGIN: ECS SHIT + signal_enabled = FALSE + var/list/dc = datum_components if(dc) var/all_components = dc[/datum/component] @@ -56,6 +61,10 @@ comp.UnregisterSignal(src, sig) comp_lookup = lookup = null + for(var/target in signal_procs) + UnregisterSignal(target, signal_procs[target]) + //END: ECS SHIT + return QDEL_HINT_QUEUE #ifdef DATUMVAR_DEBUGGING_MODE diff --git a/code/game/gamemodes/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm index bf401e5ad2d..a3440fad39a 100644 --- a/code/game/gamemodes/clown_ops/clown_weapons.dm +++ b/code/game/gamemodes/clown_ops/clown_weapons.dm @@ -74,7 +74,7 @@ . = ..() AddComponent(/datum/component/slippery, 60, GALOSHES_DONT_HELP) GET_COMPONENT(slipper, /datum/component/slippery) - slipper.enabled = active + slipper.signal_enabled = active /obj/item/melee/transforming/energy/sword/bananium/attack(mob/living/M, mob/living/user) ..() @@ -99,7 +99,7 @@ /obj/item/melee/transforming/energy/sword/bananium/transform_weapon(mob/living/user, supress_message_text) ..() GET_COMPONENT(slipper, /datum/component/slippery) - slipper.enabled = active + slipper.signal_enabled = active /obj/item/melee/transforming/energy/sword/bananium/ignition_effect(atom/A, mob/user) return "" @@ -131,12 +131,12 @@ . = ..() AddComponent(/datum/component/slippery, 60, GALOSHES_DONT_HELP) GET_COMPONENT(slipper, /datum/component/slippery) - slipper.enabled = active + slipper.signal_enabled = active /obj/item/shield/energy/bananium/attack_self(mob/living/carbon/human/user) ..() GET_COMPONENT(slipper, /datum/component/slippery) - slipper.enabled = active + slipper.signal_enabled = active /obj/item/shield/energy/bananium/throw_at(atom/target, range, speed, mob/thrower, spin=1) if(active) From 19db8965a6de82558110250edc8c568fe24bad27 Mon Sep 17 00:00:00 2001 From: ninjanomnom Date: Thu, 23 Aug 2018 12:11:07 -0400 Subject: [PATCH 2/2] Updates readme --- code/datums/components/README.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/code/datums/components/README.md b/code/datums/components/README.md index b617c8a25b1..76e78f0e8b2 100644 --- a/code/datums/components/README.md +++ b/code/datums/components/README.md @@ -32,8 +32,12 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo 1. `/datum/var/list/datum_components` (private) * Lazy associated list of type -> component/list of components. -1. `/datum/component/var/enabled` (protected, boolean) - * If the component is enabled. If not, it will not react to signals +1. `/datum/var/list/comp_lookup` (private) + * Lazy associated list of signal -> registree/list of registrees +1. `/datum/var/list/signal_procs` (private) + * Associated lazy list of signals -> `/datum/callback`s that will be run when the parent datum receives that signal +1. `/datum/var/signal_enabled` (protected, boolean) + * If the datum is signal enabled. If not, it will not react to signals * `FALSE` by default, set to `TRUE` when a signal is registered 1. `/datum/component/var/dupe_mode` (protected, enum) * How duplicate component types are handled when added to the datum. @@ -45,8 +49,6 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo * Definition of a duplicate component type * `null` means exact match on `type` (default) * Any other type means that and all subtypes -1. `/datum/component/var/list/signal_procs` (private) - * Associated lazy list of signals -> `/datum/callback`s that will be run when the parent datum receives that signal 1. `/datum/component/var/datum/parent` (protected, read-only) * The datum this component belongs to * Never `null` in child procs @@ -88,6 +90,14 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo 1. `/datum/proc/_SendSignal(signal, list/arguments)` (private, final) * Handles most of the actual signaling procedure * Will runtime if used on datums with an empty component list +1. `/datum/proc/RegisterSignal(datum/target, signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final) + * If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments + * Makes the datum listen for the specified `signal` on it's `parent` datum. + * When that signal is received `proc_ref` will be called on the component, along with associated arguments + * Example proc ref: `.proc/OnEvent` + * If a previous registration is overwritten by the call, a runtime occurs. Setting `override` to TRUE prevents this + * These callbacks run asyncronously + * Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `SendSignal()` that initiated it 1. `/datum/component/New(datum/parent, ...)` (private, final) * Runs internal setup for the component * Extra arguments are passed to `Initialize()` @@ -121,13 +131,5 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo 1. `/datum/component/proc/UnregisterFromParent` (abstract, no-sleep) * Counterpart to `RegisterWithParent()` * Used to unregister the signals that should only be on the `parent` object -1. `/datum/component/proc/RegisterSignal(datum/target, signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final) - * If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments - * Makes a component listen for the specified `signal` on it's `parent` datum. - * When that signal is received `proc_ref` will be called on the component, along with associated arguments - * Example proc ref: `.proc/OnEvent` - * If a previous registration is overwritten by the call, a runtime occurs. Setting `override` to TRUE prevents this - * These callbacks run asyncronously - * Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `SendSignal()` that initiated it ### See/Define signals and their arguments in __DEFINES\components.dm