Files
Bubberstation/lua/docs/handler_group.md
SkyratBot 7d0d702ec7 [MIRROR] Fixes SS13.register_signal throwing unclear errors when called on deleted datums (#27293)
* Cleans up the SS13_base lua file and adds a new lua file for easily handling multiple signals on different objects. (#82458)

## About The Pull Request
Cleaned up the SS13.register_signal and SS13.unregister_signal, removing
the weird list shifting.
Also adds a new lua file that can be included for the use of registering
different signals on various datums and being able to clear them all in
1 function.
Removed the make_easy_clear_function option when registering a signal
via lua because I don't think it's used by anyone and it lacks any sort
of versatility. Users can just create their own function for clearing
signals from a datum.

Also updates the documentation for HARDDELETES.md as
COMSIG_PARENT_QDELETING was renamed to COMSIG_QDELETING

## Why It's Good For The Game
New handler file makes registering signals in batches a lot easier if
you want to clear them in one go without clearing unrelated callbacks on
the same datum. The list shifting in SS13.register_signal had pretty
significant performance problems, so removing that will make registering
and unregistering signals faster.

## Changelog
🆑
admin: LUA - Adds a new library called handler_group. Include it in your
files by doing require('handler_group')
/🆑

---------

Co-authored-by: Watermelon914 <3052169-Watermelon914@users.noreply.gitlab.com>

* Fixes SS13.register_signal throwing unclear errors when called on deleted datums (#82597)

## About The Pull Request
See title

## Why It's Good For The Game
More descriptive error message

## Changelog
🆑
fix: LUA: Registering a signal on a deleted datum will throw a more
descriptive error message.
/🆑

---------

Co-authored-by: Watermelon914 <3052169-Watermelon914@users.noreply.gitlab.com>

---------

Co-authored-by: Watermelon914 <37270891+Watermelon914@users.noreply.github.com>
Co-authored-by: Watermelon914 <3052169-Watermelon914@users.noreply.gitlab.com>
2024-04-18 10:21:35 +02:00

2.6 KiB

Handler Group

This module is for registering signals on a datum or several datums and being able to clear them all at once without having to unregister them manually. This is particularly useful if you register signals on a datum and need to clear them later without accidentally unregistering unrelated signals

Functions

HandlerGroup.new()

Creates a new handler group instance

HandlerGroup:register_signal(datum, signal, func)

Registers a signal on a datum, exactly the same as SS13.register_signal

HandlerGroup:clear()

Clears all registered signals that have been registered by this handler group.

HandlerGroup:clear_on(datum, signal, func)

Clears all registered signals that have been registered by this handler group when a signal is called on the specified datum. Additionally, a function can be ran before it is cleared

HandlerGroup.register_once(datum, signal func)

Identical to just creating a new HandlerGroup instance and calling clear_on(datum, signal, func).

The idea is to register a signal and clear it after it has been called once.

Examples

The following examples showcase why using handler groups can make life easier in specific situations.

Explode when mob enters location

This function creates a 1 tile-wide explosion at the specified location if a specific mob walks over it. The explosion won't happen if the mob dies. This function should be callable on the same mob for different locations. The function should be self-contained, it should not affect other registered signals that the mob may have registered.

Without Handler Groups

local function explodeAtLocation(mobVar, position)
	local deathCallback
	local moveCallback
	local function unlinkFromMob()
		SS13.unregister_signal(mobVar, "living_death", deathCallback)
		SS13.unregister_signal(mobVar, "movable_moved", moveCallback)
	end
	deathCallback = SS13.register_signal(mobVar, "living_death", function(_, gibbed)
		unlinkFromMob()
	end)
	moveCallback = SS13.register_signal(mobVar, "movable_moved", function(_, oldLoc)
		if mobVar:get_var("loc") == position then
			-- Creates a 1 tile-wide explosion at the specified position
			dm.global_proc("explosion", position, 1, 0, 0)
			unlinkFromMob()
		end
	end)
end

With Handler Groups

local function explodeAtLocation(mobVar, position)
	local handler = handler_group.new()
	handler:clear_on(mobVar, "living_death")
	handler:register_signal(mobVar, "movable_moved", function(_, oldLoc)
		if mobVar:get_var("loc") == position then
			-- Creates a 1 tile-wide explosion at the specified position
			dm.global_proc("explosion", position, 1, 0, 0)
			handler:clear()
		end
	end)
end