OpenPF2 / Plugin

Core C++ Game Logic for OpenPF2 (Status: Pre-alpha)
https://www.openpf2.org/
Other
23 stars 6 forks source link

[Game Designers] Implement Event Emitter Pattern for Delegates on All Interface-referenced Objects #39

Closed GuyPaddock closed 12 months ago

GuyPaddock commented 1 year ago

In https://github.com/OpenPF2/PF2Core/pull/38, we are implementing a new design pattern called the "Event Emitter" pattern. At the moment, that MR is just updating objects needed for input binding events. This issue tracks the technical debt remaining to update all of our other classes referenced through interfaces with the pattern.

Implementing the Pattern

Each Event Emitter, which is an object behind a UInterface (e.g., UPF2Party is behind IPF2PartyInterface, UPF2CharacterQueueComponent is behind IPF2CharacterQueueInterface, etc.), does the following:

  1. Moves all its BlueprintAssignable, dynamic, multicast delegates out and into an Events Object, which is a new UObject class that is named after the interface but has Events at the end of the name (e.g., IPF2PartyInterface, IPF2CharacterQueueInterfaceEvents, etc). This new class is defined in the same file as the UInterface (e.g., put it in Source/OpenPF2Core/Public/PF2PartyInterface.h, Source/OpenPF2Core/Public/PF2CharacterQueueInterface.h, etc.).
  2. In the primary UInterface of the object: Exposes a new Blueprint-callable GetEvents method that returns an instance of the new events class. The return type for this method must be specific to the Events Object type. For example, UPF2CharacterQueueInterfaceEvents defines its GetEvents() method as follows:
    /**
     * Gets the events object used for binding Blueprint callbacks to events from this component.
     *
     * @return
     *  The events object for this interface.
     */
    UFUNCTION(BlueprintCallable, Category="OpenPF2|Components|Player Controllers|Character Queues")
    virtual UPF2CharacterQueueInterfaceEvents* GetEvents() const = 0;
  3. In the Event Emitter: Defines a constructor that instantiates the Events Object and stores it in a UPROPERTY of the instance.
  4. In the Event Emitter: Implements the GetEvents() method on the Event Emitter, returning the instance of the Events Object initialized in the constructor.
  5. In the Event Emitter:
    1. Extends the IPF2EventEmitterInterface interface as a public base class.
    2. Implements an override of the GetGenericEventsObject() method, just returning the result of the GetEvents() method. This method is used internally by editor support so that the delegate properties defined in the Events Object can be bound in a blueprint as if they were declared on the Event Emitter.