mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Co-authored-by: Guti <32563288+TheCaramelion@users.noreply.github.com> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
67 lines
2.5 KiB
Plaintext
67 lines
2.5 KiB
Plaintext
/// This component behaves similar to connect_loc, hooking into a signal on a tracked object's turf
|
|
/// It has the ability to react to that signal on behalf of a separate listener however
|
|
/// This has great use, primarily for components, but it carries with it some overhead
|
|
/// So we do it separately as it needs to hold state which is very likely to lead to bugs if it remains as an element.
|
|
/datum/component/connect_loc_behalf
|
|
dupe_mode = COMPONENT_DUPE_UNIQUE
|
|
|
|
/// An assoc list of signal -> procpath to register to the loc this object is on.
|
|
var/list/connections
|
|
var/atom/movable/tracked
|
|
var/atom/tracked_loc
|
|
|
|
/datum/component/connect_loc_behalf/Initialize(atom/movable/tracked, list/connections)
|
|
. = ..()
|
|
if(!istype(tracked))
|
|
return COMPONENT_INCOMPATIBLE
|
|
src.connections = connections
|
|
src.tracked = tracked
|
|
|
|
/datum/component/connect_loc_behalf/RegisterWithParent()
|
|
RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
|
|
RegisterSignal(tracked, COMSIG_PARENT_QDELETING, PROC_REF(handle_tracked_qdel))
|
|
update_signals()
|
|
|
|
/datum/component/connect_loc_behalf/UnregisterFromParent()
|
|
unregister_signals()
|
|
UnregisterSignal(tracked, list(
|
|
COMSIG_MOVABLE_MOVED,
|
|
COMSIG_PARENT_QDELETING,
|
|
))
|
|
|
|
tracked = null
|
|
|
|
/datum/component/connect_loc_behalf/proc/handle_tracked_qdel()
|
|
SIGNAL_HANDLER // COMSIG_PARENT_QDELETING
|
|
qdel(src)
|
|
|
|
/datum/component/connect_loc_behalf/proc/update_signals()
|
|
unregister_signals()
|
|
//You may ask yourself, isn't this just silencing an error?
|
|
//The answer is yes, but there's no good cheap way to fix it
|
|
//What happens is the tracked object or hell the listener gets say, deleted, which makes targets[old_loc] return a null
|
|
//The null results in a bad index, because of course it does
|
|
//It's not a solvable problem though, since both actions, the destroy and the move, are sourced from the same signal send
|
|
//And sending a signal should be agnostic of the order of listeners
|
|
//So we need to either pick the order agnositic, or destroy safe
|
|
//And I picked destroy safe. Let's hope this is the right path!
|
|
if(isnull(tracked.loc))
|
|
return
|
|
|
|
tracked_loc = tracked.loc
|
|
|
|
for(var/signal in connections)
|
|
parent.RegisterSignal(tracked_loc, signal, connections[signal])
|
|
|
|
/datum/component/connect_loc_behalf/proc/unregister_signals()
|
|
if(isnull(tracked_loc))
|
|
return
|
|
|
|
parent.UnregisterSignal(tracked_loc, connections)
|
|
|
|
tracked_loc = null
|
|
|
|
/datum/component/connect_loc_behalf/proc/on_moved(sigtype, atom/movable/tracked, atom/old_loc)
|
|
SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED
|
|
update_signals()
|