![]() |
MCRO
C++23 utilities for Unreal Engine.
|
A base class which can bring type based class-composition to a derived class. More...
#include <Composition.h>
Public Member Functions | |
| IComposable ()=default | |
| IComposable (const IComposable &other) | |
| IComposable (IComposable &&other) noexcept | |
| ranges::any_view< FAny * > | GetComponentsDynamic (FTypeHash typeHash) const |
| Get components determined at runtime. | |
| template<typename MainType , typename Self > requires CCompatibleComponent<MainType, Self> | |
| void | AddComponent (this Self &&self, MainType *newComponent, TAnyTypeFacilities< MainType > const &facilities={}) |
| Add a component to this composable class. | |
| template<CDefaultInitializable MainType, typename Self > requires CCompatibleComponent<MainType, Self> | |
| void | AddComponent (this Self &&self, TAnyTypeFacilities< MainType > const &facilities={}) |
| Add a default constructed component to this composable class. | |
| template<typename... ValidAs> | |
| void | AddAlias () |
| Add a list of types the last added component is convertible to and may be used to get the last component among others which may list the same aliases. | |
| template<typename MainType , CSharedFromThis Self> requires CCompatibleComponent<MainType, Self> | |
| auto | With (this Self &&self, MainType *newComponent, TAnyTypeFacilities< MainType > const &facilities={}) |
| Add a component to this composable class with a fluent API. | |
| template<typename MainType , CSharedFromThis Self> requires CCompatibleComponent<MainType, Self> | |
| auto | WithAnsi (this Self &&self, MainType *newComponent) |
| Add a component to this composable class with a fluent API, enforcing standard memory allocators. | |
| template<CDefaultInitializable MainType, CSharedFromThis Self> requires CCompatibleComponent<MainType, Self> | |
| auto | With (this Self &&self, TAnyTypeFacilities< MainType > const &facilities={}) |
| Add a default constructed component to this composable class with a fluent API. | |
| template<CDefaultInitializable MainType, CSharedFromThis Self> requires CCompatibleComponent<MainType, Self> | |
| auto | WithAnsi (this Self &&self) |
| Add a default constructed component to this composable class with a fluent API, enforcing standard memory allocators. | |
| template<typename MainType , typename Self > requires (CCompatibleComponent<MainType, Self> && !CSharedFromThis<Self>) | |
| decltype(auto) | With (this Self &&self, MainType *newComponent, TAnyTypeFacilities< MainType > const &facilities={}) |
| Add a component to this composable class with a fluent API. | |
| template<typename MainType , typename Self > requires (CCompatibleComponent<MainType, Self> && !CSharedFromThis<Self>) | |
| decltype(auto) | WithAnsi (this Self &&self, MainType *newComponent) |
| Add a component to this composable class with a fluent API, enforcing standard memory allocators. | |
| template<CDefaultInitializable MainType, typename Self > requires (CCompatibleComponent<MainType, Self> && !CSharedFromThis<Self>) | |
| decltype(auto) | With (this Self &&self, TAnyTypeFacilities< MainType > const &facilities={}) |
| Add a default constructed component to this composable class with a fluent API. | |
| template<CDefaultInitializable MainType, typename Self > requires (CCompatibleComponent<MainType, Self> && !CSharedFromThis<Self>) | |
| decltype(auto) | WithAnsi (this Self &&self) |
| Add a default constructed component to this composable class with a fluent API, enforcing standard memory allocators. | |
| template<typename ValidAs , CSharedFromThis Self> | |
| auto | WithAlias (this Self &&self) |
| Add a type, the last added component is convertible to and may be used to get the last component among others which may list the same aliases. | |
| template<typename ValidAs , typename Self > requires (!CSharedFromThis<Self>) | |
| decltype(auto) | WithAlias (this Self &&self) |
| Add a type, the last added component is convertible to and may be used to get the last component among others which may list the same aliases. | |
| template<CSharedFromThis Self, typename... ValidAs> | |
| auto | With (this Self &&self, TTypes< ValidAs... > &&) |
| Add a list of types the last added component is convertible to and may be used to get the last component among others which may list the same aliases. | |
| template<typename Self , typename... ValidAs> requires (!CSharedFromThis<Self>) | |
| decltype(auto) | With (this Self &&self, TTypes< ValidAs... > &&) |
| Add a list of types the last added component is convertible to and may be used to get the last component among others which may list the same aliases. | |
| template<CSharedFromThis Self, CFunctionLike Function> requires (TFunction_ArgCount<Function> == 1) | |
| auto | With (this Self &&self, Function &&function) |
| Modify a component inline, with a lambda function. The component type is inferred from the function's first argument, and a reference of that component is passed into it. The component must exist before calling this method, or if it doesn't, the application will crash. | |
| template<typename Self , CFunctionLike Function> requires (!CSharedFromThis<Self> && TFunction_ArgCount<Function> == 1) | |
| decltype(auto) | With (this Self &&self, Function &&function) |
| Modify a component inline, with a lambda function. The component type is inferred from the function's first argument, and a reference of that component is passed into it. The component must exist before calling this method, or if it doesn't, the application will crash. | |
| template<typename T > | |
| ranges::any_view< T * > | GetComponents () const |
| Get all components added matching~ or aliased by the given type. | |
| template<typename T > | |
| const T * | TryGet () const |
| Get the first component matching~ or aliased by the given type. | |
| template<typename T > | |
| T * | TryGet () |
| Get the first component matching~ or aliased by the given type. | |
| template<typename T > | |
| T const & | Get () const |
| Get the first component matching~ or aliased by the given type. | |
| template<typename T > | |
| T & | Get () |
| Get the first component matching~ or aliased by the given type. | |
Protected Attributes | |
| TFunction< void(FAny &)> | OnComponentAdded |
| Override this function in your composable class to do custom logic when a component is added. A bit of dynamically typed programming is needed through the FAny API. | |
A base class which can bring type based class-composition to a derived class.
This exists because indeed Unreal has its own composition model (actors / actor-components) or it has the subsystem architecture for non-actors, they still require to be used with UObjects. IComposable allows any C++ objects to have type-safe runtime managed optional components which can be configured separately for each instance.
The only requirement for components is that they need to be copy and move constructible (as is the default with plain-old-C++ objects, if they don't have members where either constructors are deleted or inaccessible). This limitation is imposed by FAny only for easier interfacing, but the API for managing components will never move or copy them by itself. The composable class doesn't have that limitation.
Usage:
As mentioned earlier, components are not required to have any arbitrary type traits, but if they inherit from IComponent or IStrictComponent they can receive extra information when they're registered for a composable class. The difference between the two is that IComponent doesn't mind if it's attached to a composable class it doesn't know about, however it is a compile error if an IStrictComponent is attempted to be attached to an incompatible class.
For example
Explicit components can explicitly support multiple composable classes via function overloading or templating (with deduced type parameters).
If a component type uses TInherit template or has a using Bases = TTypes<...> member alias in a similar way:
Then the specified base classes will be automatically registered as component aliases. When this is used for explicit components, IComponent or IStrictComponent is strongly discouraged to be used in TInherit's parameter pack. So declare inheritance the following way:
__bases would be perfect for the job, but other popular compilers don't have similar intrinsics. Once such a feature becomes widely available base classes can be automatically added as aliases for registered components. Definition at line 269 of file Composition.h.
|
default |
| Mcro::Composition::IComposable::IComposable | ( | const IComposable & | other | ) |
|
noexcept |
|
inline |
Add a list of types the last added component is convertible to and may be used to get the last component among others which may list the same aliases.
| ValidAs | The list of other types the last added component is convertible to and may be used to get the last component among others which may list the same aliases. |
Definition at line 448 of file Composition.h.
|
inline |
Add a component to this composable class.
| MainType | The exact component type (deduced from newComponent |
| Self | Deducing this |
| self | Deducing this |
| newComponent | A pointer to the new component being added. IComposable will assume ownership of the new component adhering to RAII. Make sure the lifespan of the provided object is not managed by something else or the stack, in fact better to stick with the new operator. |
| facilities | Customization point for object copy/move and delete methods. See TAnyTypeFacilities |
Definition at line 355 of file Composition.h.
|
inline |
Add a default constructed component to this composable class.
| MainType | The exact component type |
| Self | Deducing this |
| self | Deducing this |
| facilities | Customization point for object copy/move and delete methods. See TAnyTypeFacilities |
Definition at line 430 of file Composition.h.
|
inline |
Get the first component matching~ or aliased by the given type.
The order of components are non-deterministic so this method only make sense when it is trivial that only one component will be available for that particular type.
TryGet instead as this function can crash at runtime.| T | Desired component type. |
Definition at line 985 of file Composition.h.
|
inline |
Get the first component matching~ or aliased by the given type.
The order of components are non-deterministic so this method only make sense when it is trivial that only one component will be available for that particular type.
TryGet instead as this function can crash at runtime.| T | Desired component type. |
Definition at line 961 of file Composition.h.
|
inline |
Get all components added matching~ or aliased by the given type.
| T | Desired component type. |
Definition at line 900 of file Composition.h.
| ranges::any_view< FAny * > Mcro::Composition::IComposable::GetComponentsDynamic | ( | FTypeHash | typeHash | ) | const |
Get components determined at runtime.
| typeHash | The runtime determined type-hash the desired components are represented with |
|
inline |
Get the first component matching~ or aliased by the given type.
The order of components are non-deterministic so this method only make sense when it is trivial that only one component will be available for that particular type.
| T | Desired component type. |
Definition at line 939 of file Composition.h.
|
inline |
Get the first component matching~ or aliased by the given type.
The order of components are non-deterministic so this method only make sense when it is trivial that only one component will be available for that particular type.
| T | Desired component type. |
Definition at line 921 of file Composition.h.
|
inline |
Modify a component inline, with a lambda function. The component type is inferred from the function's first argument, and a reference of that component is passed into it. The component must exist before calling this method, or if it doesn't, the application will crash.
| Self | Deducing this |
| Function | Function type for modifying a component inline. The component type is deduced from the first parameter of the function. CV-ref qualifiers are not enforced but mutable-ref or const-ref are the only useful options. Function result is discarded when returning anything. |
| self | Deducing this |
| function | Function for modifying a component inline. The component type is deduced from the first parameter of the function. CV-ref qualifiers are not enforced but mutable-ref or const-ref are the only useful options. Function result is discarded when returning anything. |
TSharedFromThis return a shared ref. Definition at line 848 of file Composition.h.
|
inline |
Modify a component inline, with a lambda function. The component type is inferred from the function's first argument, and a reference of that component is passed into it. The component must exist before calling this method, or if it doesn't, the application will crash.
| Self | Deducing this |
| Function | Function type for modifying a component inline. The component type is deduced from the first parameter of the function. CV-ref qualifiers are not enforced but mutable-ref or const-ref are the only useful options. Function result is discarded when returning anything. |
| self | Deducing this |
| function | Function for modifying a component inline. The component type is deduced from the first parameter of the function. CV-ref qualifiers are not enforced but mutable-ref or const-ref are the only useful options. Function result is discarded when returning anything. |
Definition at line 882 of file Composition.h.
|
inline |
Add a component to this composable class with a fluent API.
This overload is available for composable classes which also inherit from TSharedFromThis.
| MainType | The exact component type (deduced from newComponent |
| Self | Deducing this |
| self | Deducing this |
| newComponent | A pointer to the new component being added. IComposable will assume ownership of the new component adhering to RAII. Make sure the lifespan of the provided object is not managed by something else or the stack, in fact better to stick with the new operator. |
| facilities | Customization point for object copy/move and delete methods. See TAnyTypeFacilities |
TSharedFromThis return a shared ref. Definition at line 480 of file Composition.h.
|
inline |
Add a component to this composable class with a fluent API.
This overload is available for composable classes which are not explicitly meant to be used with shared pointers.
| MainType | The exact component type (deduced from newComponent |
| Self | Deducing this |
| self | Deducing this |
| newComponent | A pointer to the new component being added. IComposable will assume ownership of the new component adhering to RAII. Make sure the lifespan of the provided object is not managed by something else or the stack, in fact better to stick with the new operator. |
| facilities | Customization point for object copy/move and delete methods. See TAnyTypeFacilities |
Definition at line 584 of file Composition.h.
|
inline |
Add a default constructed component to this composable class with a fluent API.
This overload is available for composable classes which also inherit from TSharedFromThis.
| MainType | The exact component type |
| Self | Deducing this |
| self | Deducing this |
| facilities | Customization point for object copy/move and delete methods. See TAnyTypeFacilities |
TSharedFromThis return a shared ref. Definition at line 530 of file Composition.h.
|
inline |
Add a default constructed component to this composable class with a fluent API.
This overload is available for composable classes which are not explicitly meant to be used with shared pointers.
| MainType | The exact component type |
| Self | Deducing this |
| self | Deducing this |
| facilities | Customization point for object copy/move and delete methods. See TAnyTypeFacilities |
Definition at line 634 of file Composition.h.
|
inline |
Add a list of types the last added component is convertible to and may be used to get the last component among others which may list the same aliases.
Usage:
This overload is available for composable classes which also inherit from TSharedFromThis.
| ValidAs | The list of other types the last added component is convertible to and may be used to get the last component among others which may list the same aliases. |
| Self | Deducing this |
| self | Deducing this |
TSharedFromThis return a shared ref. Definition at line 776 of file Composition.h.
|
inline |
Add a list of types the last added component is convertible to and may be used to get the last component among others which may list the same aliases.
Usage:
This overload is available for composable classes which are not explicitly meant to be used with shared pointers.
| ValidAs | The list of other types the last added component is convertible to and may be used to get the last component among others which may list the same aliases. |
| Self | Deducing this |
| self | Deducing this |
Definition at line 814 of file Composition.h.
|
inline |
Add a type, the last added component is convertible to and may be used to get the last component among others which may list the same aliases.
Only one alias may be specified this way because of templating syntax intricacies, but it may be called multiple times in a sequence to add multiple aliases for the same component.
Usage:
For declaring multiple aliases in one go, use With(TTypes<...>) member template method.
This overload is available for composable classes which also inherit from TSharedFromThis.
| ValidAs | A type, the last added component is convertible to and may be used to get the last component among others which may list the same aliases. |
| Self | Deducing this |
| self | Deducing this |
TSharedFromThis return a shared ref. Definition at line 697 of file Composition.h.
|
inline |
Add a type, the last added component is convertible to and may be used to get the last component among others which may list the same aliases.
Only one alias may be specified this way because of templating syntax intricacies, but it may be called multiple times in a sequence to add multiple aliases for the same component.
Usage:
For declaring multiple aliases in one go, use With(TTypes<...>) member template method.
This overload is available for composable classes which are not explicitly meant to be used with shared pointers.
| ValidAs | A type, the last added component is convertible to and may be used to get the last component among others which may list the same aliases. |
| Self | Deducing this |
| self | Deducing this |
Definition at line 739 of file Composition.h.
|
inline |
Add a default constructed component to this composable class with a fluent API, enforcing standard memory allocators.
This overload is available for composable classes which also inherit from TSharedFromThis.
| MainType | The exact component type |
| Self | Deducing this |
| self | Deducing this |
| facilities | Customization point for object copy/move and delete methods. See TAnyTypeFacilities |
TSharedFromThis return a shared ref. Definition at line 555 of file Composition.h.
|
inline |
Add a default constructed component to this composable class with a fluent API, enforcing standard memory allocators.
This overload is available for composable classes which are not explicitly meant to be used with shared pointers.
| MainType | The exact component type |
| Self | Deducing this |
| self | Deducing this |
Definition at line 656 of file Composition.h.
|
inline |
Add a component to this composable class with a fluent API, enforcing standard memory allocators.
This overload is available for composable classes which also inherit from TSharedFromThis.
| MainType | The exact component type (deduced from newComponent |
| Self | Deducing this |
| self | Deducing this |
| newComponent | A pointer to the new component being added. IComposable will assume ownership of the new component adhering to RAII. Make sure the lifespan of the provided object is not managed by something else or the stack, in fact better to stick with the new operator. |
TSharedFromThis return a shared ref. Definition at line 506 of file Composition.h.
|
inline |
Add a component to this composable class with a fluent API, enforcing standard memory allocators.
This overload is available for composable classes which are not explicitly meant to be used with shared pointers.
| MainType | The exact component type (deduced from newComponent |
| Self | Deducing this |
| self | Deducing this |
| newComponent | A pointer to the new component being added. IComposable will assume ownership of the new component adhering to RAII. Make sure the lifespan of the provided object is not managed by something else or the stack, in fact better to stick with the new operator. |
Definition at line 610 of file Composition.h.
|
protected |
Override this function in your composable class to do custom logic when a component is added. A bit of dynamically typed programming is needed through the FAny API.
This is executed in AddComponent before IComponent::OnCreatedAt and after automatic aliases has been set up (if they're available). This is not executed with subsequent setup of manual aliases.
| component | The component being added. Query component type with the FAny API |
Definition at line 322 of file Composition.h.