Apparatus Version 1.0.0
ECS-like data-driven workflow for Unreal Engine.
ApparatusFunctionLibrary.h
1 /*
2  * ░▒▓ APPARATUS ▓▒░
3  *
4  * File: ApparatusFunctionLibrary.h
5  * Created: Friday, 23rd October 2020 7:00:48 pm
6  * Author: Vladislav Dmitrievich Turbanov (vladislav@turbanov.ru)
7  * ───────────────────────────────────────────────────────────────────
8  * Last Modified: Tuesday, 6th April 2021 1:36:08 pm
9  * Modified By: Vladislav Dmitrievich Turbanov (vladislav@turbanov.ru)
10  * ───────────────────────────────────────────────────────────────────
11  *
12  * The Apparatus source code is for your internal usage only.
13  * Redistribution of this file is strictly prohibited.
14  *
15  * Community forums: https://talk.turbanov.ru
16  *
17  * Copyright 2020 - 2021, SP Vladislav Dmitrievich Turbanov
18  * Made in Russia, Moscow City, Chekhov City
19  */
20 
21 #pragma once
22 
23 #include <map>
24 #include <ostream>
25 #include <typeinfo>
26 
27 #include "CoreUObject.h"
28 #include "Engine.h"
29 #include "UObject/Class.h"
30 
31 #include "Fingerprint.h"
32 #include "Filter.h"
33 #include "Mechanism.h"
34 #include "SubjectiveActorComponent.h"
35 #include "SubjectiveUserWidget.h"
36 
37 #include "ApparatusFunctionLibrary.generated.h"
38 
42 UCLASS()
43 class APPARATUSRUNTIME_API UApparatusFunctionLibrary
44  : public UBlueprintFunctionLibrary
45 {
46  GENERATED_BODY()
47 
48  public:
49  UFUNCTION(BlueprintCallable, BlueprintPure,
50  Meta = (DisplayName = "Make Fingerprint From Details Array", NativeMakeFunc),
51  Category = "Apparatus|Fingerprint")
52  static FFingerprint
53  MakeFingerprint(const TArray<TSubclassOf<UDetail>>& Details,
54  const EBootFilter BootState);
55 
60  UFUNCTION(BlueprintCallable, BlueprintPure,
61  Meta = (DisplayName = "Make Filter From Details Arrays", NativeMakeFunc),
62  Category = "Apparatus|Filter")
63  static FFilter
64  MakeFilter(const TArray<TSubclassOf<UDetail>>& Details,
65  const TArray<TSubclassOf<UDetail>>& ExcludedDetails,
66  const EBootFilter Booting);
67 
72  UFUNCTION(BlueprintCallable, BlueprintPure,
73  Meta = (DisplayName = "Break Filter", NativeBreakFunc),
74  Category = "Apparatus|Filter")
75  static void
76  BreakFilter(const FFilter& Filter,
77  TArray<TSubclassOf<UDetail>>& Details,
78  TArray<TSubclassOf<UDetail>>& ExcludedDetails,
79  EBootFilter& Booting);
80 
81  UFUNCTION(BlueprintCallable, BlueprintPure,
82  Meta = (DisplayName = "Fingerprint Matches Filter"),
83  Category = "Apparatus")
84  static FORCEINLINE bool
85  FingerprintMatches(const FFingerprint& Fingerprint,
86  const FFilter& Filter)
87  {
88  return Fingerprint.Matches(Filter);
89  }
90 
91  UFUNCTION(BlueprintCallable, BlueprintPure,
92  Meta = (DisplayName = "Bit Mask OR", CompactNodeTitle = "|",
93  Keywords = "logical | or disjunction",
94  CommutativeAssociativeBinaryOperator = "true"),
95  Category = "Apparatus")
96  static FORCEINLINE FBitMask BitMaskOr(const FBitMask& A,
97  const FBitMask& B)
98  {
99  return A | B;
100  }
101 
102  UFUNCTION(BlueprintCallable, BlueprintPure,
103  Meta = (DisplayName = "Bit Mask AND", CompactNodeTitle = "&",
104  Keywords = "logical & and conjunction",
105  CommutativeAssociativeBinaryOperator = "true"),
106  Category = "Apparatus")
107  static FORCEINLINE FBitMask BitMaskAnd(const FBitMask& A,
108  const FBitMask& B)
109  {
110  return A & B;
111  }
112 
113  UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Apparatus")
114  static FFingerprint&
115  AddDetailToFingerprint(FFingerprint& Fingerprint,
116  const TSubclassOf<UDetail> DetailType);
117 
118  UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Apparatus")
119  static FORCEINLINE FFingerprint&
120  RemoveDetailFromFingerprint(FFingerprint& Fingerprint,
121  const TSubclassOf<UDetail> DetailType);
122 
123  UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Apparatus")
124  static FORCEINLINE USubjectiveActorComponent*
125  GetSubjectiveComponent(TScriptInterface<ISubjective> Subjective)
126  {
127  return CastChecked<USubjectiveActorComponent>(Subjective.GetObject());
128  }
129 
134  UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Apparatus",
135  Meta = (DisplayName = "Get Actor",
136  Keywords = "subject subjective"))
137  static FORCEINLINE AActor*
138  GetSubjectiveActor(TScriptInterface<ISubjective> Subjective)
139  {
140  USubjectiveActorComponent* SubjectComponent = Cast<USubjectiveActorComponent>(Subjective.GetObject());
141  if (!SubjectComponent) return nullptr;
142  AActor* Actor = SubjectComponent->GetOwner();
143  check(Actor);
144  return Actor;
145  }
146 
151  UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Apparatus",
152  Meta = (DisplayName = "Get Widget",
153  Keywords = "subject subjective"))
154  static FORCEINLINE UUserWidget*
155  GetSubjectiveWidget(TScriptInterface<ISubjective> Subjective)
156  {
157  UUserWidget* SubjectWidget = Cast<UUserWidget>(Subjective.GetObject());
158  return SubjectWidget;
159  }
160 
166  UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Apparatus",
167  Meta = (DisplayName = "Get Fingerprint",
168  Keywords = "subject subjective"))
169  static FORCEINLINE FFingerprint
170  GetSubjectiveFingerprint(TScriptInterface<ISubjective> Subjective)
171  {
172  return Subjective->GetFingerprint();
173  }
174 
183  UFUNCTION(BlueprintCallable, Category = "Apparatus",
184  Meta = (DeterminesOutputType = "DetailType",
185  DisplayName = "Enable Detail",
186  Keywords = "subject subjective"))
187  static FORCEINLINE class UDetail*
188  EnableSubjectiveDetail(TScriptInterface<ISubjective> Subjective,
189  TSubclassOf<UDetail> DetailType)
190  {
191  return Subjective->EnableDetail(DetailType);
192  }
193 
199  UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Apparatus",
200  Meta = (DisplayName = "Get Preferred Belt",
201  Keywords = "subject subjective"))
202  static FORCEINLINE class UBelt*
203  GetSubjectivePreferredBelt(TScriptInterface<ISubjective> Subjective)
204  {
205  return Subjective->GetPreferredBelt();
206  }
207 
211  UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Apparatus",
212  Meta = (DeterminesOutputType = "DetailType",
213  DisplayName = "Has Detail",
214  KeyWords = "subject subjective contains search"))
215  static FORCEINLINE bool
216  HasSubjectiveDetail(TScriptInterface<ISubjective> Subjective,
217  TSubclassOf<UDetail> DetailType,
218  const bool bIncludeDisabled = false)
219  {
220  return Subjective->HasDetail(DetailType, bIncludeDisabled);
221  }
222 
226  UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Apparatus",
227  Meta = (DeterminesOutputType = "DetailType",
228  DisplayName = "Find Detail",
229  KeyWords = "by type subject subjective search"))
230  static FORCEINLINE UDetail*
231  FindSubjectiveDetail(TScriptInterface<ISubjective> Subjective,
232  TSubclassOf<UDetail> DetailType,
233  const bool bIncludeDisabled = false)
234  {
235  return Subjective->FindDetail(DetailType, bIncludeDisabled);
236  }
237 
241  UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Apparatus",
242  Meta = (DisplayName = "Get Details",
243  KeyWords = "subject subjective"))
244  static void GetSubjectiveDetails(
245  TScriptInterface<ISubjective> Subjective,
246  const bool bIncludeDisabled,
247  TArray<UDetail*>& OutDetails);
248 
252  UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Apparatus",
253  Meta = (DeterminesOutputType = "DetailType",
254  DisplayName = "Find Details",
255  KeyWords = "subject subjective by type search"))
256  static TArray<UDetail*> FindSubjectiveDetails(
257  TScriptInterface<ISubjective> Subjective,
258  TSubclassOf<UDetail> DetailType,
259  const bool bIncludeDisabled = false);
260 
272  UFUNCTION(BlueprintCallable, Category = "Apparatus",
273  Meta = (DeterminesOutputType = "DetailType",
274  DefaultToSelf = "Subjective",
275  DisplayName = "Add Detail",
276  KeyWords = "subject subjective append"))
277  static FORCEINLINE class UDetail*
278  AddSubjectiveDetail(TScriptInterface<ISubjective> Subjective,
279  TSubclassOf<UDetail> DetailType,
280  const bool bReuseInactive = false)
281  {
282  checkf(Subjective, TEXT("The subject must not be a None."));
283  return Subjective->AddDetail(DetailType, bReuseInactive);
284  }
285 
296  UFUNCTION(BlueprintCallable, Category = "Apparatus",
297  Meta = (DisplayName = "Disable Detail",
298  KeyWords = "subject subjective delete remove"))
299  static FORCEINLINE bool
300  DisableSubjectiveDetail(TScriptInterface<ISubjective> Subjective,
301  TSubclassOf<UDetail> DetailType,
302  const bool bDisableMultiple = false)
303  {
304  return Subjective->DisableDetail(DetailType, bDisableMultiple);
305  }
306 
307 }; // class UApparatusFunctionLibrary
308 
310  TScriptInterface<ISubjective> Subjective, const bool bIncludeDisabled,
311  TArray<UDetail*>& OutDetails)
312 {
313  Subjective->GetDetails(bIncludeDisabled, OutDetails);
314 }
315 
317  TScriptInterface<ISubjective> Subjective, TSubclassOf<UDetail> DetailType,
318  const bool bIncludeDisabled)
319 {
320  TArray<UDetail*> DetailsOut;
321  Subjective->FindDetails(DetailType, DetailsOut, bIncludeDisabled);
322  return MoveTemp(DetailsOut);
323 }
324 
326  const TArray<TSubclassOf<UDetail>> &Types,
327  const EBootFilter BootFilter)
328 {
329  return FFingerprint(Types, BootFilter);
330 }
331 
333  const TArray<TSubclassOf<UDetail>> &Types,
334  const TArray<TSubclassOf<UDetail>> &ExcludedTypes,
335  const EBootFilter BootFilter)
336 {
337  return FFilter(Types, ExcludedTypes, BootFilter);
338 }
339 
341  FFingerprint &Fingerprint, TSubclassOf<UDetail> DetailType)
342 {
343  return Fingerprint += DetailType;
344 }
345 
346 FORCEINLINE FFingerprint&
348  FFingerprint& Fingerprint, TSubclassOf<UDetail> DetailType)
349 {
350  return Fingerprint -= DetailType;
351 }
352 
354  const FFilter& Filter, TArray<TSubclassOf<UDetail>>& Details,
355  TArray<TSubclassOf<UDetail>>& ExcludedDetails, EBootFilter& Booting)
356 {
357  Details = Filter.Fingerprint.Details;
358  Booting = Filter.Fingerprint.BootState;
359  ExcludedDetails = Filter.ExcludedDetails;
360 }
An interface for all sorts of subjects.
Definition: Subjective.h:42
The main Apparatus function library.
Definition: ApparatusFunctionLibrary.h:45
static FFilter MakeFilter(const TArray< TSubclassOf< UDetail >> &Details, const TArray< TSubclassOf< UDetail >> &ExcludedDetails, const EBootFilter Booting)
Make a filter from the list of details, exclusion details, and a boot filter.
Definition: ApparatusFunctionLibrary.h:332
static FFingerprint MakeFingerprint(const TArray< TSubclassOf< UDetail >> &Details, const EBootFilter BootState)
Definition: ApparatusFunctionLibrary.h:325
static bool FingerprintMatches(const FFingerprint &Fingerprint, const FFilter &Filter)
Definition: ApparatusFunctionLibrary.h:85
static TArray< UDetail * > FindSubjectiveDetails(TScriptInterface< ISubjective > Subjective, TSubclassOf< UDetail > DetailType, const bool bIncludeDisabled=false)
Find the details by their type.
Definition: ApparatusFunctionLibrary.h:316
static void BreakFilter(const FFilter &Filter, TArray< TSubclassOf< UDetail >> &Details, TArray< TSubclassOf< UDetail >> &ExcludedDetails, EBootFilter &Booting)
Break a filter to an array of details, excluded details and a booting filter.
Definition: ApparatusFunctionLibrary.h:353
static void GetSubjectiveDetails(TScriptInterface< ISubjective > Subjective, const bool bIncludeDisabled, TArray< UDetail * > &OutDetails)
Get the current list of details in the subject.
Definition: ApparatusFunctionLibrary.h:309
static FFingerprint & RemoveDetailFromFingerprint(FFingerprint &Fingerprint, const TSubclassOf< UDetail > DetailType)
Definition: ApparatusFunctionLibrary.h:347
static FFingerprint & AddDetailToFingerprint(FFingerprint &Fingerprint, const TSubclassOf< UDetail > DetailType)
Definition: ApparatusFunctionLibrary.h:340
The conveyor belt consisting of subjects.
Definition: Belt.h:60
The base subject detail (component) class.
Definition: Detail.h:35
Definition: SubjectiveActorComponent.h:39
A memory-efficient bit mask.
Definition: BitMask.h:38
The details filter specification.
Definition: Filter.h:44
The details fingerprint.
Definition: Fingerprint.h:117
bool Matches(const struct FFilter &Filter) const
Check if the fingerprint matches a filter.