Navigation
API > API/Runtime > API/Runtime/Engine
Notes on the Visitor Pattern (https://en.wikipedia.org/wiki/Visitor_pattern) this is a pattern that helps solve two things:
- adds operations for a class without modifying the class itself (and more importantly for Quartz's use-case:)
- implements Double-Dispatch (https://en.wikipedia.org/wiki/Double_dispatch)
C++ supports single-dispatch through polymorphism, where a concrete function called depends on the dynamic type of a SINGLE object.
i.e.: MyBasePtr->DoThing(MyConcreteType);
Double dispatch is being able resolve to a concrete function for how TWO dynamic types should interact
i.e.: MyBaseA_ptr->DoThing(MyBaseB_ptr)
where we could resolve to different concrete functions for each combination of the RUNTIME TYPES of objects derived from MyBaseA and MyBaseB.
Concretely, Quartz has metronome listeners, command listeners, etc and has things that can be both a metronome and a command listener.
The DOWNSIDE to the visitor pattern is the element (or listener) types must be known at compile time. This makes it hard to write reusable objects like command queues.
This implementation uses some template metaprogramming to abstract away the visitor pattern and let client code build reusable things like command queues and FSMs without needing to know the final concrete types.
It also helps avoid some diamond inheritance problems that are easy to run into when attempting to have a "consumer" base type, and then types that can be multiple kinds of consumers. class TVisitorPatternBase: Summary: Used as a base class to implement the visitor pattern for the provided Ts types.
Examples: For an example usage for client code derived from this see TQuartzCommandQueue For an example of TQuartzCommandQueue client code that accepts multiple visitors see FQuartzTickableObject
| Name | TVisitorPatternBase |
| Type | class |
| Header File | /Engine/Source/Runtime/Engine/Classes/Sound/QuartzCompileTimeVisitor.h |
| Include Path | #include "Sound/QuartzCompileTimeVisitor.h" |
Syntax
template<typename... Ts>
class TVisitorPatternBase
Derived Classes
Classes
| Name | Remarks |
|---|---|
| TElementBase | TElementBase: Client code defines listener interfaces, and then the client's concrete types should inherit from those through this template base class. |
| TVisitorInterface | Forward declaration for the primary template. |
| TVisitWithLambda | TVisitWithLambda This templatized visitor is used in ::PushLambda() external code does not need to worry about the visitor pattern |
Interfaces
| Name | Remarks |
|---|---|
| IListenerBase | IListenerBase: this should not be inherited from directly, but is public for polymorphic access to client listeners via IListenerBase* |
| IVisitorBase |