Skip to content

Events: writing less shit code

DamianX edited this page Aug 2, 2022 · 2 revisions

What is an event?

Let's start this off with an example. Say you had a machine that tracked a mob's movement; how would you go about this? In the past it was common for oldcoders to hardcode this into the mob's movement functions like this:

/mob/Move()
	...

	special_machine.mob_moved()

This is terrible. It fragments the code, makes maintaining the code harder, etc...

An event is an action on an object that anybody can listen to, and be notified when said object does this action. With our movement tracking machine example the machine could listen to the moved event on the mob in question. When this even triggers it can do whatever it needs to do.

That sounds great! How do I use them?

The full list of events, and their parameters, is in code/_hooks/events.dm

Listening to events.

To register to be notified of an event, you call the register_event() proc on the datum on which the event is invoked. For example:

my_mob.register_event(/event/moved, src, .proc/mob_moved)

register_event() takes 3 arguments:

  • The type of the event that you're interested in.
  • The object that owns the proc that will be called when the event is invoked.
  • The proc to be called when the event is invoked.

To stop listening, you call unregister_event() on the event datum in question, passing the same arguments.

my_mob.unregister_event(/event/moved, src, .proc/mob_moved)

The proc name passed as the third argument to register_event() will be called with a list of arguments passed from the event's invocation. The contents of this list are different on an event-to-event basis, and are documented next to the definition of the event type.

The specific event I want doesn't exist!

Fear not! Adding events is not frowned upon and incredibly simple!

Creating an event

To add an event, first you'll have to define a type for it, inside code/_hooks/events.dm:

/event/power_changed

Invoking an event

So now you have your shiny event ready for action, how do you trigger it? It's simple: just use INVOKE_EVENT!

INVOKE_EVENT is a simple macro to handle triggering the event, it takes at least 2 arguments:

  • The datum to invoke the event on.
  • The event to invoke.
  • OPTIONAL: The list of arguments to be passed down to any potential listeners.

For example: The /event/moved event gets invoked in atom/movable/Move(), like this:

INVOKE_EVENT(src, /event/moved, "mover" = src)