TauCetiClassic
TauCetiClassic copied to clipboard
[Task] Moved signals/hooks
Пока очень примерно набросаю мысли, это не готовое ТЗ.
Проблема - нам требуется лучший контроль за перемещением атомов.
https://github.com/TauCetiStation/TauCetiClassic/blob/08b998ba499b1a0ef7026df246930fa4666e6de9/code/game/atoms_movable.dm#L130-L163
- COMSIG_MOVABLE_MOVED работает только для движения самого атома, но не его контента. В целом, так и должен, просто факт что нам сложно отслеживать перемещение, если атом не на первом уровне.
- Для решения этой проблемы у нас сделан COMSIG_MOVABLE_LOC_MOVED, который кидает сигнал на каждый атом внутри, что он переместился. Рекурсивно. Причем, в большинстве случаев атому пофигу, но мы всё равно идем и делаем сигнал со всеми его оверхедами. Про то, что рекурсия в бьенде это тоже плохо, даже вспоминать не хочется.
https://github.com/TauCetiStation/TauCetiClassic/blob/08b998ba499b1a0ef7026df246930fa4666e6de9/code/controllers/subsystem/parallax.dm#L18-L43
- Параллакс не может отслеживать перемещения client.eye, и вынужден каждый тик проходится по всем клиентам на сервере и заново проверять их положение и вручную обновлять
clients_in_contents
(который позже и используется при движении для анимации паралакса).
https://github.com/TauCetiStation/TauCetiClassic/blob/08b998ba499b1a0ef7026df246930fa4666e6de9/code/modules/mob/dead/observer/observer.dm#L121-L125
- Не так давно передо мной была задача отслеживать смену z-уровня у мобов, и тут не нашлось более надежной идеи, чем это делать в life цикле. На tg кстати для этого сделали свой рекурсивный метод
on_changed_z_level
для каждого moved, так что мы не далеко от них (или они от нас).
Как вариант решения, вместо того, чтоб самим каждый раз идти в рекурсию и искать атомы, которые надо дергать по ивентам, мы могли бы сделать, чтоб сами эти атомы добавлялись в специальный список на верхний существующий atom/movable
. Примерно как уже сделано с /datum/light_source
- он всегда всплывает наверх и добавляется в list/light_sources
верхнего атома. Или как уже сделано с clients_in_contents
, только в случае клиентов они не сами всплывают, а их пересчитывает сабсистема, и это можно было бы изменить.
Соответственно, при любых перемещениях этого atom/movable, нам достаточно будет просто заглянуть в его собственный список объектов, которым был важен факт перемещения, и вызвать им специальный хук.
В перспективе может быть это можно сделать не только для сигналов движения, но еще каких-нибудь hear-слушателей, там тоже каждый раз их рекурсивно ищем. Но это уже что-то близкое с Spacial Grid с тг.
Обновил описание. Пока очень абстрактно, и я думаю, как к этому можно было бы приспособить уже существующие сигналы (атом подписался на сигнал moved - ему это важно, автоматом отслеживаем его на верхнем уровне).
Про то, что надо еще починить все loc вместо forcemove, не буду писать, это очевидно.