Unreal Engine - CallOrRegister Pattern
Minimizing Code Duplication When Handling Non-Deterministic Events
Introduction
In games, one system or object will often need to respond to an event that happens elsewhere in the code. One common scenario is showing or updating the HUD when part of the game simulation changes, e.g. the player’s actor spawning in the world. Delegates are Unreal Engine’s method of declaring, subscribing to, and executing events at runtime.
Example
Given the above example scenario, it would be best to structure the code in a deterministic way such that the HUD always subscribes to the actor’s Begin Play delegate before that event is triggered. This leads to simple and straightforward code. Here’s an example of a demo actor and view model.



Here is a video of this code in action
As expected, as soon as the button is pressed, the callback subscriptions are made, the actor begins play, and the event is triggered in one frame.
Problem
Given the number of different ways an actor may spawn, for example via the network, level loading, manual spawning, etc., having a deterministic order and a simple setup won’t always be possible. Take the following case where the subscription to and triggering of the event is purposefully out of order as a demonstration.
In this function, the following happens:
The first callback subscribes to the event immediately
The second callback subscribes to the event after two seconds
The actor finishes spawning, triggering the event, after one second
Here is the video of this sequence
As expected, the second callback is never triggered since the subscription happens after the event fires.
Solution 1
One naive solution is to check if the event being subscribed to has already happened. In the event the actor has already begun play, instead of subscribing to the event, immediately run the callback code. Here’s the same function as above with those checks.
Although the checks aren’t necessary in this case since the order is known, this demonstrates what will be scattered throughout a codebase when it’s unclear what comes first: the subscription to or the triggering of an event.
Here is the video of this function running:
This fixes the out of order subscription issue and is logically correct. The problem is that every subscription to this event must manually check and handle the case where the event has already fired.
Solution 2
The CallOrRegister pattern can assist in writing simple, straightforward, and easy to understand event handling code while removing the unnecessary code duplication. The concept is simple: move the branching logic into a function that called instead of subscribing to the delegate directly. Unreal uses the pattern CallOrRegister_X where the X is the name of the event. Here is the updated version of the Demo Actor with the CallOrRegister pattern.


The header defines a new function.
The source file has two changes:
The CallOrRegister_OnBeginPlay implementation
This function takes in a type of X::FDelegate&&, where X is the type of delegate
If the actor has already begun play, immediately trigger the callback that was passed in
If the actor hasn’t already begun play, add the callback to the OnBeginPlay delegate for later
After the event is triggered in BeginPlay, clear out the list of callbacks
Here’s the View Model function that uses the new pattern
When comparing to the other out of order subscriptions, this has the simplicity of the first example, but also has the correct logic of the second example
Conclusion
Delegates in Unreal Engine are not conceptionally complex; they are essentially a list of callbacks that are triggered when the delegate is invoked. Those callbacks can be manually triggered or manually added to the delegate. Understanding this allows for the CallOrRegister pattern to be a simple and straightforward way to write event handling code when the order of the subscription to and triggering of an event is not deterministic.
Example code can be found here.
Example data can be found here.